k8s中级篇-cert-manager+Let's Encrypt自动证书签发

3,644 阅读5分钟

前言

说到免费的SSL证书,大家首先想到的肯定是Let's Encrypt,而使用过Let's Encrypt的同学应该也知道,其有效期只有三个月,三个月后要重新续期。github上也有类似的脚本可以做到自动续期。那如果是在k8s上使用该免费证书,又如何操作的呢?这里cert-manager就派上用场了。

环境

主机名ip角色
mldong01192.168.0.245master
mldong02192.168.0.54node01
mldong03192.168.0.22node02

三台主机为华为软开云的ECS,CentOS Linux release 7.6.1810 (Core)

什么是cert-manager

cert-manager 是一个云原生证书管理开源项目,用于在 Kubernetes 集群中提供 HTTPS 证书并自动续期,支持 Let’s Encrypt, HashiCorp Vault 这些免费证书的签发。在Kubernetes集群中,我们可以通过 Kubernetes Ingress 和 Let’s Encrypt 实现外部服务的自动化 HTTPS。

在Kubernetes集群中使用 HTTPS 协议,需要一个证书管理器、一个证书自动签发服务,主要通过 Ingress 来发布 HTTPS 服务,因此需要Ingress Controller并进行配置,启用 HTTPS 及其路由。

img

  • Issuer/ClusterIssuer: 用于指示 cert-manager 用什么方式签发证书,本文主要讲解签发免费证书的 ACME 方式。ClusterIssuer 与 Issuer 的唯一区别就是 Issuer 只能用来签发自己所在 namespace 下的证书,ClusterIssuer 可以签发任意 namespace 下的证书。
  • Certificate: 用于告诉 cert-manager 我们想要什么域名的证书以及签发证书所需要的一些配置,包括对 Issuer/ClusterIssuer 的引用。

安装cert-manager

安装方式一

  1. 添加Jestack Helm存储库

    helm repo add jetstack https://charts.jetstack.io
    
  2. 本地仓库搜

    helm search repo cert-manager
    
  3. 创建命名空间

    kubectl create namespace cert-manager
    
  4. 开始安装

    helm install \
      cert-manager jetstack/cert-manager \
      --namespace cert-manager \
      --version v1.1.0 \
      --set installCRDs=true # 这个要开启,要不然创建ClusterIssuer会报错
    

    这里可能存在一个坑,就是拉取镜像失败,pod创建失败,可以提前下载镜像-所有worker节点

    ## 注意版本号
    docker pull quay.io/jetstack/cert-manager-cainjector:v1.1.0
    docker pull quay.io/jetstack/cert-manager-controller:v1.1.0
    docker quay.io/jetstack/cert-manager-webhook:v1.1.0
    
  5. 查看安装情况

    kubectl get pods -n cert-manager -w
    
    docker pull quay.io/jetstack/cert-manager-cainjector:v1.1.0
    docker pull quay.io/jetstack/cert-manager-controller:v1.1.0
    docker quay.io/jetstack/cert-manager-webhook:v1.1.0
    

    image-20201229235807659

    image-20201230082800102

  6. 卸载(按需)

    helm uninstall cert-manager -n cert-manager
    
  7. 删除命名空间(按需)

    kubectl delete ns cert-manager
    

安装方式二

  • 安装cert-manager

    # Kubernetes 1.16+
    $ kubectl apply -f https://github.com/jetstack/cert-manager/releases/download/v1.1.0/cert-manager.yaml
    
    # Kubernetes <1.16
    $ kubectl apply --validate=false -f https://github.com/jetstack/cert-manager/releases/download/v1.1.0/cert-manager-legacy.yaml
    
  • 安装crds-要不然创建ClusterIssuer会报错

    # Kubernetes 1.15+
    $ kubectl apply -f https://github.com/jetstack/cert-manager/releases/download/v1.1.0/cert-manager.crds.yaml
    
    # Kubernetes <1.15
    $ kubectl apply --validate=false -f https://github.com/jetstack/cert-manager/releases/download/v1.1.0/cert-manager-legacy.crds.yaml
    

cert-manager使用案例

  1. 创建一个集群级的签发机构

    # 配置
    cat <<EOF >  cluster-issuer.yaml
    apiVersion: cert-manager.io/v1
    kind: ClusterIssuer
    metadata:
      name: letsencrypt-prod
    spec:
      acme:
        server: https://acme-v02.api.letsencrypt.org/directory
        email: 524719755@qq.com
        privateKeySecretRef:
          name: letsencrypt-prod
        solvers:    
        - http01:
            ingress:
              class: nginx
    EOF
    

    说明:

    • metadata.name 是我们创建的签发机构的名称,后面我们创建证书的时候会引用它
    • spec.acme.email 是你自己的邮箱,证书快过期的时候会有邮件提醒,不过 cert-manager 会利用 acme 协议自动给我们重新颁发证书来续期
    • spec.acme.server 是 acme 协议的服务端,我们这里用 Let’s Encrypt,这个地址就写死成这样就行
    • spec.acme.privateKeySecretRef 指示此签发机构的私钥将要存储到哪个 Secret 对象中,名称不重要
    • spec.acme.http01 这里指示签发机构使用 HTTP-01 的方式进行 acme 协议 (还可以用 DNS 方式,acme 协议的目的是证明这台机器和域名都是属于你的,然后才准许给你颁发证书)
    # 执行发布命令
    kubectl apply -f cluster-issuer.yaml
    
  2. 域名解析添加A记录-记录值为集群中的任意worker节点,这里是阿里云

    image-20201230084839274

  3. 创建一个命名空间

    kubectl create ns mldong-test
    
  4. 创建一个证书

    # 配置
    cat <<EOF >  b-cert.yaml
    apiVersion: cert-manager.io/v1
    kind: Certificate
    metadata:
      name: b.mldong.com-tls
      namespace: mldong-test
    spec:
      secretName: b.mldong.com-tls
      issuerRef:
        name: letsencrypt-prod
        kind: ClusterIssuer
      dnsNames:
      - b.mldong.com
    EOF
    

    说明:

    • spec.secretName 指示证书最终存到哪个 Secret 中
    • spec.issuerRef.kind 值为 ClusterIssuer 说明签发机构不在本 namespace 下,而是在全局
    • spec.issuerRef.name 我们创建的签发机构的名称 (ClusterIssuer.metadata.name)
    • spec.dnsNames 指示该证书的可以用于哪些域名,与域名解析的一致
  5. 另开终端查看cert-manager运行日志

    kubectl logs -f $(kubectl get pods -n cert-manager | grep cert-manager | grep -v 'cainjector\|webhook' | awk '{print $1}') -n cert-manager
    
  6. 当然,也可以查看临时生成的专门验证证书的 Ingress 对象的运行情况

    kubectl get pods -n mldong-test -w
    

    临时对象cm-acme-http-solver-xxxx从创建到消亡的过程

    image-20201230101648602

  7. 执行发布命令

    kubectl apply -f b-cert.yaml
    
  8. 查看certificate创建结果

    [root@mldong cert-manager]# kubectl get certificate -n mldong-test
    NAME               READY   SECRET             AGE
    b.mldong.com-tls   True    b.mldong.com-tls   2m27s
    

    当READY为True时即为成功,详细可看cert-manager运行日志。

发布一个nginx服务

上一篇已经装的阿里仓库中有nginx,我可以搜一下

  1. 本地仓库搜nginx

    helm search repo nginx
    

    image-20201229233444301

  2. 查看nginx配置说明

    helm show values aliyuncs/nginx
    

    详细配置说明见:https://github.com/bitnami/charts/tree/master/bitnami/nginx/

  3. 新建一个values.yaml配置

    cat <<EOF >  nginx-values.yaml
    ingress: 
      enabled: true
      hostname: b.mldong.com
      tls:
        - hosts:
          - b.mldong.com
          secretName: b.mldong.com-tls
    EOF
    

    注意,这里的secertName要与上面生成的certificate保持一致

  4. 安装nginx

    helm install nginx aliyuncs/nginx -f nginx-values.yaml -n mldong-test 
    
  5. 查看部署情况

    kubectl get svc --namespace mldong-test -w nginx
    
  6. 我们也可以查看一下ingress的详情

    kubectl get ingress nginx -o yaml -n mldong-test
    

    image-20201230095145028

  7. 浏览器访问效果

    image-20201230094920031

  8. 删除nginx(按需)

    helm uninstall nginx -n mldong-test
    

小结

使用cert-manager来管理https证书,是不是很方便?值得一得的是,当你第一次创建完certificate,之后续期啥都由cert-manager来自动管理,贼省心。这里简单总结一下流程。

  • 创建一个集群级的签发机构-ClusterIssuer-仅第一次需要
  • 添加一条域名解析记录-指向集群的任意worker节点
  • 根据解析的域名生成certificate
  • 发布应用
    • 发布Pod
    • 发布Service
    • 发布Ingress-这里配置tls证书,指向certificate

相关文章

k8s中级篇-使用rke安装k8s集群

k8s中级篇-Helm安装与入门

k8s中级篇-Helm安装nfs-client-provisioner