Kubernetes 使用 acme.sh 生成的通配符证书

概述

一般推荐使用 cert-manager 之类的工具自动生成和管理证书,但是总有一些场景需要手动处理。这里记录了使用 acme.sh + DNSPod 来生成通配符证书的过程。以及如何加载到 Kubernetes 集群中。

使用 acme.sh 生成

参考文档

# 任意服务器安装,可以不用 root 用户
curl https://get.acme.sh | sh -s email=phyng@phyng.com

# 配置环境变量签发证书
export TZ='Asia/Shanghai'
export DP_Id="******"
export DP_Key="******"

# 生成打包多个域名的证书,这样可以兼容更多场景
acme.sh --issue --dns dns_dp -d test.phyng.com -d '*.test.phyng.com'

# 上述配置会自动保存到 ~/.acme.sh/account.conf
# 检查更新任务
acme.sh --list
crontab -l
-----END CERTIFICATE-----
[Sat May 18 04:29:12 PM CST 2025] Your cert is in: /home/ubuntu/.acme.sh/test.phyng.com_ecc/test.phyng.com.cer
[Sat May 18 04:29:12 PM CST 2025] Your cert key is in: /home/ubuntu/.acme.sh/test.phyng.com_ecc/test.phyng.com.key
[Sat May 18 04:29:12 PM CST 2025] The intermediate CA cert is in: /home/ubuntu/.acme.sh/test.phyng.com_ecc/ca.cer
[Sat May 18 04:29:12 PM CST 2025] And the full-chain cert is in: /home/ubuntu/.acme.sh/test.phyng.com_ecc/fullchain.cer

手动加载自定义证书

# 创建
kubectl -n production create secret tls self-tls-wildcard-test.phyng.com --key 'certs/test.phyng.com.key' --cert 'certs/fullchain.cer'

# 后续手动更新证书
kubectl create secret tls self-tls-wildcard-test.phyng.com \
  --key certs/test.phyng.com.key \
  --cert certs/fullchain.cer \
  --namespace production \
  --dry-run=client -o yaml | \
  kubectl apply -f -

ingress 配置使用自定义证书

阿里云版本 ACK 已经支持通配符域名

---
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  annotations:
    nginx.ingress.kubernetes.io/service-weight: ''
    nginx.ingress.kubernetes.io/force-ssl-redirect: 'true' # 添加这行来强制 HTTP 到 HTTPS 的跳转
  name: test-ingress
  namespace: production
spec:
  ingressClassName: nginx
  rules:
    - host: '*.test.phyng.com'
      http:
        paths:
          - backend:
              service:
                name: test-service
                port:
                  number: 8080
            path: /
            pathType: ImplementationSpecific
  tls:
    - hosts:
        - '*.test.phyng.com'
      secretName: self-tls-wildcard-test.phyng.com

调试证书加载过程

下面是一些常见的调试命。Nginx Ingress 可以直接查看生成的 nginx.conf 文件来验证证书是否加载成功。

# 查看 ingress 整体配置
kubectl describe ingress test-ingress -n production

# 获取 nginx-ingress-controller 的 Pod 名称
PODNAME=$(kubectl -n kube-system get pods | grep nginx-ingress-controller | awk '{print $1}' | head -n 1)

# 查看配置
kubectl exec -n kube-system $PODNAME -- cat /etc/nginx/nginx.conf | grep -C3 "test.phyng.com"

# 查看日志
kubectl logs -n kube-system $PODNAME -c nginx-ingress-controller --tail 10000 -f \
  | grep -iE "(error|warn)" | grep test.phyng.com

从下面输出可以看到通配符被自动转换为下面的配置

## start server *.test.phyng.com
server {
    server_name ~^(?<subdomain>[\w-]+)\.test\.phyng\.com$ ;

    listen 80  ;
    listen [::]:80  ;
    listen 443  ssl http2 ;
    listen [::]:443  ssl http2 ;
        proxy_redirect                          off;
    }

}
## end server *.test.phyng.com