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 配置使用自定义证书
---
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