Skip to content

SSL 证书验证文件部署到 K8s

🏷️ Kubernetes

申请免费证书时需要验证域名,一般有两种验证方式:

  1. DNS 验证
  2. 文件验证

一般使用 DNS 验证的方式,配置起来比较方便而且时效快。不过由于新网修改 DNS 解析时需要手机验证码,而手机号又不在我这,每次要验证码都比较麻烦,所以今天尝试了下使用文件的方式验证。

由于域名所在的服务是部署在 K8s 上的,所以需要部署一个专门用于访问校验文件的 Nginx 服务。

而为了避免每次添加或修改验证文件时需要重新制作镜像,这里使用在 Deployment 中挂载 ConfigMap 卷的方式来加载这些验证文件。

ConfigMap

yaml
apiVersion: v1
data:
  0EMPE2QCKR.txt: 8bnj57lz2twd1kll0rac53ei5kot1xdu
  CAFD2E57275C38A416EA308E168B234E.txt: |-
    RUJLV3GQLSOZYNL4TMQ5K9ODKPLA313YQJ6R5H5HZEWW7GQ1K3R5PE7ZJQ4QQF12
    trust-provider.com
    cmcdtcsuoolffg
kind: ConfigMap
metadata:
  name: domain-config
  namespace: prod

这里的 CAFD2E57275C38A416EA308E168B234E.txt 对应的值就是腾讯云 SSL 证书验证文件的内容。需要注意的是这里有换行符,默认是 Linux 格式的换行符( \n

直接从腾讯云的门户上下载的 txt 文件中使用的是 Windows 默认换行符( \r\n ),但是验证时使用 Linux 默认换行符的文件才能通过验证,而且这个验证感觉有延迟(可以请求到文件后隔一段时间才能验证通过),没有 DNS 验证的时效快(添加好 DNS 解析后很快就可以通过验证了)。

如果需要在配置文件中使用 Windows 默认换行符时可以采用如下写法:

yaml
apiVersion: v1
data:
  0EMPE2QCKR.txt: 8bnj57lz2twd1kll0rac53ei5kot1xdu
  CAFD2E57275C38A416EA308E168B234E.txt: "RUJLV3GQLSOZYNL4TMQ5K9ODKPLA313YQJ6R5H5HZEWW7GQ1K3R5PE7ZJQ4QQF12\r\ntrust-provider.com\r\ncmcdtcsuoolffg"
kind: ConfigMap
metadata:
  name: domain-config
  namespace: prod

Deployment

部署中挂载 ConfigMap 卷可以参考如下写法:

yaml
apiVersion: apps/v1
kind: Deployment
metadata:
  name: ui-domain-txt-deploy
  namespace: prod
spec:
  replicas: 1
  revisionHistoryLimit: 3
  selector:
    matchLabels:
      app: ui-domain-txt
  template:
    metadata:
      labels:
        app: ui-domain-txt
    spec:
      containers:
        - image: nginx:1.19.4
          imagePullPolicy: IfNotPresent
          name: ui-domain-txt
          ports:
            - containerPort: 80
          volumeMounts:
          - mountPath: /usr/share/nginx/html/
            name: txt-files
            readOnly: true
      volumes:
      - configMap:
          defaultMode: 420
          items:
          - key: 0EMPE2QCKR.txt
            path: 0EMPE2QCKR.txt
          - key: LE2K8S6JNHIA8RM8HQ9XC53TJYFQHY7U.txt
            path: .well-known/pki-validation/LE2K8S6JNHIA8RM8HQ9XC53TJYFQHY7U.txt
          name: domain-config
        name: txt-files

有一点需要注意的是配置中的 path: .well-known/pki-validation/LE2K8S6JNHIA8RM8HQ9XC53TJYFQHY7U.txt 在门户界面修改时会提示路径中有特殊字符,但是直接编辑 YAML 是可以这么写的。

Ingress

由于是新创建的一个服务,为了不影响其它的路由,这里使用的是 Exact 类型的路由匹配策略(只有当请求的路径完全匹配时才会将请求转发到后端的服务)。

yaml
apiVersion: networking.k8s.io/v1beta1
kind: Ingress
metadata:
  annotations:
    kubernetes.io/ingress.class: nginx-controller-blog
    kubernetes.io/ingress.rule-mix: "true"
    nginx.ingress.kubernetes.io/use-regex: "true"
  generation: 3
  name: ingress-domain-txt
  namespace: prod
spec:
  rules:
  - host: www.liujiajia.me
    http:
      paths:
      - backend:
          serviceName: svc-ui-domain-txt
          servicePort: 80
        path: /0EMPE2QCKR.txt
        pathType: Exact
  - host: www.liujiajia.me
    http:
      paths:
      - backend:
          serviceName: svc-ui-domain-txt
          servicePort: 80
        path: /.well-known/pki-validation/LE2K8S6JNHIA8RM8HQ9XC53TJYFQHY7U.txt
        pathType: Exact
  tls:
  - hosts:
    - www.liujiajia.me
    secretName: tls-www-liujiajia-me