Kubernetes 部署证书

本文主要介绍如何使用 Kubernetes 配合 Cert-Manager 在 CertCloud 进行 SSL 证书申请、签发及部署。

准备工作

必要准备

如果是 DNS 验证需要进行如下准备

  • 已经申请成功的 CertCloud 订单。

证书申请

配置文件验证转发

DNS 验证请跳过此步骤

  • 创建 nginx-ingress-controller.yaml(访问代理)文件并执行,示例:

其他访问代理可以参考示例中的配置,保证域名、访问路径、端口匹配即可,命名空间可根据需要自行调整,但是必须与下方的服务转发中的资源在同一命名空间下。

apiVersion: networking.k8s.io/v1beta1
kind: Ingress
metadata:
  name: certcloud-file-auth
  annotations:
    kubernetes.io/ingress.class: nginx
spec:
  rules:
    # 你的域名
    - host: <example.com>
      http:
        paths:
          - path: /.well-known/pki-validation/fileauth.txt
            backend:
              serviceName: certcloud-nginx-svc
              servicePort: 80
    # 多个域名在此处添加,以此类推。
    # 你的域名
    - host: <www.example.com>
      http:
        paths:
          - path: /.well-known/pki-validation/fileauth.txt
            backend:
              serviceName: certcloud-nginx-svc
              servicePort: 80
  • 创建 certcloud-server-proxy.yaml(服务转发)文件并执行,示例:

示例中的 server 要替换成 CertCloud 中 证书->订单->要部署的订单->证明对域的控制权 所展示的 Nginx 代码段

apiVersion: v1
kind: ConfigMap
metadata:
  name: certcloud-nginx-config-map
data:
  nginx.conf: |-
    user  nginx;
    worker_processes  1;

    error_log  /var/log/nginx/error.log warn;
    pid        /var/run/nginx.pid;


    events {
        worker_connections  1024;
    }


    http {
        default_type  application/octet-stream;

        log_format  main  '$remote_addr - $remote_user [$time_local] "$request" '
                          '$status $body_bytes_sent "$http_referer" '
                          '"$http_user_agent" "$http_x_forwarded_for"';

        sendfile        on;

        keepalive_timeout  65;

       # 验证域名所有权弹窗显示的代码段。
       server {
          listen         80;
          server_name    <example.com>;
          # CertCloud file verify
          location ^~ /.well-known/pki-validation/fileauth.txt {
          proxy_set_header X-CMC-DCV-Host $host;
          proxy_pass https://file.httpsauto.com/.well-known/pki-validation/<example-token>.txt;
        }
      }
    }
---
apiVersion: v1
kind: Service
metadata:
  name: certcloud-nginx-svc
spec:
  selector:
    app: certcloud-nginx-deploy
  ports:
    - port: 80
      targetPort: 80
---
apiVersion: apps/v1
kind: Deployment
metadata:
  name: certcloud-nginx-deploy
spec:
  selector:
    matchLabels:
      app: certcloud-nginx-deploy
  template:
    metadata:
      labels:
        app: certcloud-nginx-deploy
    spec:
      containers:
        - name: certcloud-nginx-deploy
          image: nginx:1.19
          ports:
            - containerPort: 80
          resources:
            limits:
              memory: "128Mi"
          volumeMounts:
            - mountPath: /etc/nginx
              name: certcloud-nginx-config-map-volumes
      volumes:
        - name: certcloud-nginx-config-map-volumes
          configMap:
            name: certcloud-nginx-config-map
创建 ACME 目录 URL
  1. 登录 CertCloud 账户,点击【自动化】->【ACME】->【添加 ACME 目录 URL】。
  2. 在弹出框中的 订单 项选择要部署的订单,完善其他信息,点击添加。
  3. 添加成功后,页面会新增一条记录,点击 URL 列下的 复制图标,复制 URL 并保存。
配置 Issuer 资源

创建 issuer.yaml 文件并执行,示例:

apiVersion: v1
kind: Secret
metadata:
  # Secret 名称
  name: <example-api-token-secret>
type: Opaque
stringData:
  # 这个参数可以自定义,不会验证。
  api-token: <example-token>
---
apiVersion: cert-manager.io/v1alpha2
kind: Issuer
metadata:
  # Issuer 名称
  name: <example-issuer>
spec:
  acme:
    # 刚刚保存的 ACME 目录 URL
    server: <example-ACME-Directory-URL>
    privateKeySecretRef:
      name: <example-issuer-account-key>
    solvers:
      - dns01:
          cloudflare:
            # 你的邮箱
            email: <your-email>
            apiTokenSecretRef:
              name: <example-api-token-secret>
              key: api-token
配置 Certificate 资源

创建 certificate.yaml 文件并执行,示例:

apiVersion: cert-manager.io/v1alpha2
kind: Certificate
metadata:
  # 证书名称
  name: <example-name>
  # 命名空间
  namespace: <example-namespaces>
spec:
  # 密钥名称
  secretName: <example-com-secret>
  # 有效期 ( h ) 以小时为单位
  duration: <example-duration>h
  # 续期 ( h ) 以小时为单位
  renewBefore: <example-renewBefore>h
  # 你的域名
  commonName: <your-domain>
  # 是否是 CA 证书
  isCA: false
  # 算法强度
  keySize: <example-keySize>
  # 算法
  keyAlgorithm: <example-keyAlgorithm>
  # 私钥格式
  keyEncoding: pkcs1
  # 用途
  usages:
    - server auth
    - client auth
  # 至少填写一个备用名称
  dnsNames:
  - <your domain>
  - <your domain 2>
  issuerRef:
    # 使用的 Issuer 名称
    name: <example-issuer>
    kind: Issuer
    group: cert-manager.io
查看证书申请结果
  1. 查看所有 Certificate 资源:
$ kubectl get Certificates -A
  1. 查看 Certificate 资源状态:
$ kubectl describe Certificate <证书名称>

如果执行获取如下结果 ( Status : True , Type : Ready ),恭喜你,证书申请成功。

Status:
  Conditions:
    Last Transition Time:  <timestramp>
    Message:               Certificate is up to date and has not expired
    Reason:                Ready
    Status:                True
    Type:                  Ready

证书部署

  • 修改 nginx-ingress-controller.yaml 并执行,示例:
apiVersion: networking.k8s.io/v1beta1
kind: Ingress
metadata:
  name: certcloud-file-auth
  annotations:
    kubernetes.io/ingress.class: nginx
spec:
  # 将证书添加到此处
  tls:
    - hosts:
        - <example.com>
        - <www.example.com>
      secretName: <example-com-secret>
  rules:
    # 你的域名
    - host: <example.com>
      http:
        paths:
          - path: /.well-known/pki-validation/fileauth.txt
            backend:
              serviceName: certcloud-nginx-svc
              servicePort: 80
    # 多个域名在此处添加,以此类推。
    # 你的域名
    - host: <www.example.com>
      http:
        paths:
          - path: /.well-known/pki-validation/fileauth.txt
            backend:
              serviceName: certcloud-nginx-svc
              servicePort: 80
  • 使用 https://<example.com> 访问您的网址,可以看到安全标志(不同浏览器标志不同,Chrome 是一个锁),恭喜您,证书部署成功。

October 22, 2020