K8S Ingress + Cert Manager + 阿里云 DNS + Let’s encrypt 自动管理 HTTPS 证书

内容纲要

练习两年半之后,久违的分享~😂

注意

本文仅使用了 Cert Manager 的 DNS-01 方案,HTTP-01 方案未验证

背景需求

公司名下产品有几十个域名都需要配置 HTTPS 证书,国内各大厂商的 1 年免费证书都变为了 3 个月的。再使用手动更新证书已不现实,需要达成证书更新自动化。

解决方案

  • Cert Manager 为核心,基于 ACME 协议,以 Let’s encrypt 为证书申请机构,部署 K8S 自动证书更新服务
  • 域名解析为阿里云(需要搭建具有阿里云 DNS 管理权限的 Webhook 服务
  • 方案执行流程简介
    1. 集群部署 Cert Manager 服务(包括 Webhook 等)
    2. 修改(新增) Web 服务的 Ingress 注解配置(cert-manager.io/cluster-issuer: "letsencrypt")和配置 TLS 信息
    3. Cert Manager 被触发
      • 创建 Certificate
      • 创建临时 DNS 记录(通过 Webhook)
      • 验签证书
      • 删除临时 DNS 记录(通过 Webhook)
    4. 证书被应用到 Ingress 上

运行环境

  • K8S:1.16.9(别问我为什么还用低版本~~)

方案实施

  1. 安装 Cert Manager
      # Helm 安装 Cert Manager(Cert Manager 需要安装 K8S 匹配的版本)
      helm repo add jetstack https://charts.jetstack.io
      helm repo update
      helm install cert-manager jetstack/cert-manager \
        --namespace cert-manager --create-namespace \
          --version v1.5.5 \
          --set installCRDs=true
  2. 安装 Aliyun Webhook

      # 创建阿里云 DNS 访问权限
      apiVersion: v1
      kind: Secret
      metadata:
        name: alidns-secrets
        namespace: cert-manager
      stringData:
        access-key: LTAI5tR28CcThmHb5uvtxx
        secret-key: uoLIfyBFWbentEcxe10MioFJB0xxx
      # 部署 阿里云 DNS Webhook
      helm repo add cert-manager-alidns-webhook https://devmachine-fr.github.io/cert-manager-alidns-webhook
      helm repo update
      helm upgrade -i alidns-webhook cert-manager-alidns-webhook/alidns-webhook \
        --set groupName=webhook.cert-manager.entertech.cn
  3. 创建 Issuer / ClusterIssuer
      # 创建 Issuer / ClusterIssuer
      apiVersion: cert-manager.io/v1
      kind: ClusterIssuer
      metadata:
        name: letsencrypt
      spec:
        acme:
          email: [email protected]  # 证书到期会发邮件
          server: https://acme-v02.api.letsencrypt.org/directory  # 测试阶段可以用 staging (https://acme-staging-v02.api.letsencrypt.org/directory)
          privateKeySecretRef:
            name: letsencrypt
          solvers:
          - dns01:
              webhook:
                  config:
                    accessTokenSecretRef:
                      key: access-key  # 跟访问权限 Secret 对应
                      name: alidns-secrets  # 跟访问权限 Secret 对应
                    regionId: cn-shanghai
                    secretKeySecretRef:
                      key: secret-key  # 跟访问权限 Secret 对应
                      name: alidns-secrets  # 跟访问权限 Secret 对应
                  solverName: alidns-solver  # 固定名称
                  groupName: webhook.cert-manager.entertech.cn  # 需要跟部署的 Webhook 设置的一致
  4. 创建使用证书
      # 配置 Ingress,自动申请证书
      apiVersion: extensions/v1beta1
      kind: Ingress
      metadata:
        namespace: naptime
        name: help
        annotations:
          nginx.ingress.kubernetes.io/ssl-redirect: 'true'
          cert-manager.io/cluster-issuer: "letsencrypt"  # 名称跟 ClusterIssuer 一致
      spec:
        rules:
        - host: test.example.com
          http:
            paths:
            - path: /
              backend:
                serviceName: test
                servicePort: 80
        tls:
        - hosts:
          - test.example.com
          secretName: test.example.com-tls
  • 查询生成情况
      kubectl logs -f $(kubectl get pods -n cert-manager | \
        grep cert-manager | grep -v 'cainjector\|webhook' | \
          awk '{print $1}') -n cert-manager
      # 查询证书生成情况
      k get certificate -A  -w

发表回复

您的电子邮箱地址不会被公开。 必填项已用*标注