使用 cert-manager 为 dnspod 域名签发免费证书 ZeroSSL ¶
线下的 ssl 证书过期了、续签失败导致内网网关挂了、查看原因发现之前的 apikey 失效了。重新安装并从 Let's Encrypt
切换成 zerossl
。
1. 配置并安装 cert-manager ¶
1. 添加 cert-manager 仓库 ¶
https://cert-manager.k8s.ac.cn/docs/installation/helm/
helm repo add jetstack https://charts.jetstack.io --force-update
helm repo update
2. 切换 zerossl ¶
# cat values.yaml
ingressShim:
defaultIssuerName: "zerossl-production"
defaultIssuerKind: "ClusterIssuer"
helm upgrade --install --namespace cert-manager --version v1.17.2 cert-manager jetstack/cert-manager -f values.yaml
3. 安装 zerossl 的 cert-manager ¶
helm install \
cert-manager jetstack/cert-manager \
--namespace cert-manager \
--create-namespace \
--version v1.16.1 \
--set crds.enabled=true \
-f values.yaml
等待安装
kubectl wait --for=condition=Ready pods --all -n cert-manager
kubectl get pods -n cert-manager | grep cert-manager-webhook-dnspod
2. 配置并安装 zerossl ¶
官方链接:https://cert-manager.k8s.ac.cn/docs/tutorials/zerossl/zerossl/
1. 获取 zerossl 账号的密钥 ¶
https://app.zerossl.com/developer
2. 创建 zerossl 账号的secret ¶
首先将其编码为 base64。
# cat /cert/secret/1-zero-secretkey.yaml
apiVersion: v1
kind: Secret
metadata:
name: zero-ssl-eabsecret
namespace: cert-manager
type: Opaque
stringData:
secret: YOUR_ENCODED_ZEROSSL_EAB_HMAC_KEY
kubectl apply -f /cert/secret/1-zero-secretkey.yaml
kubectl get secret zero-ssl-eabsecret -n cert-manager -o jsonpath='{.data.secret}' | base64 -d
查看是否创建成功
kubectl -n cert-manager get Secret zero-ssl-eabsecret
3. 切换 zerossl ¶
# cat zero-values.yaml
ingressShim:
defaultIssuerName: "zerossl-production"
defaultIssuerKind: "ClusterIssuer"
helm upgrade --install --namespace cert-manager --version v1.17.2 cert-manager jetstack/cert-manager -f values.yaml
helm upgrade --install --namespace cert-manager --version v1.16.1 cert-manager jetstack/cert-manager -f zero-values.yaml
kubectl delete certificate linuxcdn-crt -n cert-manager
kubectl delete certificaterequest linuxcdn-crt-1 -n cert-manager
kubectl delete order linuxcdn-crt-1-1879590116 -n cert-manager
kubectl delete challenge -l "cert-manager.io/certificate-name=linuxcdn-crt" -n cert-manager
3. 使用 dnspod 配置 DNS 记录 ¶
1. 安装 webhook-dnspod 插件 ¶
# 此文件包含 DNSPod Webhook 的完整部署配置(RBAC、服务、部署、证书等)
wget https://raw.githubusercontent.com/imroc/cert-manager-webhook-dnspod/master/bundle.yaml -O 3-webhook-dnspod.yaml
kubectl apply -f 3-webhook-dnspod.yaml
2. 申请腾讯云 dnspod 的 apikey ¶
记录 secretId 和 secretKey
3. 创建包含 apikey 的 secret ¶
使用上面的 secretId 和 secretKey 创建 secret
# cat /cert/secret/1-dnspod-secretkey.yaml
apiVersion: v1
kind: Secret
metadata:
name: dnspod-secret
namespace: cert-manager
type: Opaque
stringData:
secretId: xxx
secretKey: xxx
kubectl apply -f /cert/secret/1-dnspod-secretkey.yaml
查看是否成功
kubectl -n cert-manager get Secret dnspod-secret
4. 创建 ClusterIssuer ¶
Issuer 定义了 cert-manager 将如何请求 TLS 证书,ClusterIssuer
,它被认为是集群范围内的版本。
1. 创建 letsencrypt 和 dnspod ¶
# cat /cert/clusterissuer/1-letsencrypt-dnspod.yaml
apiVersion: cert-manager.io/v1
kind: ClusterIssuer
metadata:
name: dnspod
namespace: cert-manager
spec:
acme:
email: huichengcheng@datarc.cn # 当域名即将到期时,通知将发送到此电子邮件地址。
privateKeySecretRef:
name: dnspod-letsencrypt
server: https://acme-v02.api.letsencrypt.org/directory
solvers:
- dns01:
webhook:
config:
secretIdRef:
key: secretId # secretId是secretKey您的腾讯云账号的SecretId和SecretKey。
name: dnspod-secret
secretKeyRef:
key: secretKey
name: dnspod-secret
ttl: 600 # webhook 创建的 dns TXT 记录的可选 ttl。
recordLine: "" # dnspod 的可选 recordLine 参数。
groupName: acme.dnspod.com # 安装中指定的 groupName,默认为 acme.dnspod.com。
solverName: dnspod # dnspod
kubectl apply -f /cert/clusterissuer/1-letsencrypt-dnspod.yaml
查看是否成功
kubectl describe clusterissuer dnspod
Status:
Acme:
Last Private Key Hash: dasdasdasdasda
Last Registered Email: dsadasda.com
Uri: https://acme-v02.api.letsencrypt.org/acme/acct/2411639967
Conditions:
Message: The ACME account was registered with the ACME server
Observed Generation: 1
Reason: ACMEAccountRegistered
Status: True
Type: Ready
kubectl get clusterissuer dnspod
2. 创建 zero 和 dnspod ¶
# cat /cert/clusterissuer/2-zerossl-dnspod.yaml
apiVersion: cert-manager.io/v1
kind: ClusterIssuer
metadata:
name: zerossl-production-dnspod
namespace: cert-manager
spec:
acme:
# ZeroSSL ACME server
server: https://acme.zerossl.com/v2/DV90
email: dummy-email@yopmail.com
# name of a secret used to store the ACME account private key
privateKeySecretRef:
name: zerossl-prod
# for each cert-manager new EAB credencials are required
externalAccountBinding:
keyID: YOUR_ZEROSSL_EAB_KEY_ID
keySecretRef:
name: zero-ssl-eabsecret
key: secret
keyAlgorithm: HS256
solvers:
- dns01:
webhook:
config:
secretIdRef:
key: secretId # secretId是secretKey您的腾讯云账号的SecretId和SecretKey。
name: dnspod-secret
secretKeyRef:
key: secretKey
name: dnspod-secret
ttl: 600 # webhook 创建的 dns TXT 记录的可选 ttl。
recordLine: "" # dnspod 的可选 recordLine 参数。
groupName: acme.dnspod.com # 安装中指定的 groupName,默认为 acme.dnspod.com。
solverName: dnspod # dnspod
kubectl apply -f /cert/clusterissuer/2-zerossl-dnspod.yaml
查看是否成功
kubectl describe clusterissuer zerossl-production-dnspod
Status:
Acme:
Last Private Key Hash: dasdasdasdasda
Last Registered Email: dsadasda.com
Uri: https://acme.zerossl.com/v2/DV90/account/aWsL-PiH52Hgasodsadas
Conditions:
Message: The ACME account was registered with the ACME server
Observed Generation: 1
Reason: ACMEAccountRegistered
Status: True
Type: Ready
kubectl get clusterissuer zerossl-production-dnspod
5. 申请泛域名证书 ¶
1. 签发 letsencrypt 免费证书 ¶
创建 Certificate
对象来签发 letsencrypt
免费证书:
# /cert/Certificate/1-letsencrypt-linuxcdn.yaml
apiVersion: cert-manager.io/v1
kind: Certificate
metadata:
name: example-crt
namespace: cert-manager
spec:
secretName: example-crt-secret # 证书保存在这个 secret 中
issuerRef:
name: dnspod # 这里使用自动生成出来的 ClusterIssuer
kind: ClusterIssuer
group: cert-manager.io
dnsNames: # 填入需要签发证书的域名列表,支持泛域名,确保域名是使用 dnspod 管理的
- "example.com"
- "*.example.com"
kubectl apply -f /cert/Certificate/1-letsencrypt-linuxcdn.yaml
2. 签发 zero 免费证书 ¶
创建 Certificate
对象来签发 zero
免费证书:
# /cert/Certificate/2-zerossl-linuxcdn.yaml
apiVersion: cert-manager.io/v1
kind: Certificate
metadata:
name: linuxcdn-crt
namespace: cert-manager
spec:
secretName: linuxcdn-crt-secret # 证书保存在这个 secret 中
issuerRef:
name: zerossl-production-dnspod # 这里使用自动生成出来的 ClusterIssuer
kind: ClusterIssuer
group: cert-manager.io
dnsNames: # 填入需要签发证书的域名列表,支持泛域名,确保域名是使用 dnspod 管理的
- "*.linuxcdn.com"
kubectl apply -f /cert/Certificate/2-zerossl-linuxcdn.yaml
等待状态变成 Ready 表示签发成功:
kubectl -n cert-manager get certificates.cert-manager.io
kubectl -n cert-manager get secret linuxcdn-crt-secret
若签发失败可 describe 一下看下原因:
#查看状态
kubectl get Certificate --all-namespaces
kubectl -n cert-manager describe Certificate
kubectl -n cert-manager describe CertificateRequest
kubectl -n cert-manager describe order
kubectl -n cert-manager describe challenges
# 使用 dig 命令查询 TXT 记录
dig +short TXT
# 检查 DNSPod Webhook 日志
查看 Webhook Pod 的日志,确认是否成功调用 DNSPod API:
kubectl logs -n cert-manager -l app=cert-manager-webhook-dnspod
kubectl -n cert-manager describe order | grep -A 3 "Challenges:"
dns 检验
> https://dnschecker.org/
6. ingress 使用证书 ¶
证书签发成功后会保存到我们指定的 secret 中,下面给出一些使用示例。
在 ingress 中使用:
apiVersion: networking.k8s.io/v1beta1
kind: Ingress
metadata:
name: test-ingress
spec:
ingressClassName: nginx
tls:
- hosts:
- test.example.com
secretName: example-crt-secret # 引用证书 secret
rules:
- host: test.example.com
http:
paths:
- path: /
pathType: ImplementationSpecific
backend:
service:
name: nginx-service
port:
number: 80
1. 检查证书 ¶
openssl s_client -showcerts -connect test.example.com:443
# verify server certificate and its chain
issuer=C = AT, O = ZeroSSL, CN = ZeroSSL RSA Domain Secure Site CA
7. 配置证书复制到其他 namespace ¶
https://cert-manager.k8s.ac.cn/docs/devops-tips/syncing-secrets-across-namespaces/
1. 安装 reflector ¶
kubectl apply -f https://github.com/emberstack/kubernetes-reflector/releases/latest/download/reflector.yaml -n kube-system
2. 修改 Certificated 文件 ¶
修改 Certificated 文件,为 certificated 对象设置 secretTemplate, 设置需要同步到哪些 namespace。
# /cert/Certificate/2-zerossl-linuxcdn.yaml
apiVersion: cert-manager.io/v1
kind: Certificate
metadata:
name: linuxcdn-crt
namespace: cert-manager
spec:
secretName: linuxcdn-crt-secret # 证书保存在这个 secret 中
issuerRef:
name: zerossl-production-dnspod # 这里使用自动生成出来的 ClusterIssuer
kind: ClusterIssuer
group: cert-manager.io
dnsNames: # 填入需要签发证书的域名列表,支持泛域名,确保域名是使用 dnspod 管理的
- "*.linuxcdn.com"
secretTemplate:
annotations:
reflector.v1.k8s.emberstack.com/reflection-allowed: "true" # 开启 Secret 资源的跨命名空间反射(同步)功能。
reflector.v1.k8s.emberstack.com/reflection-allowed-namespaces: "default,staging,prod-[0-9]*"
reflector.v1.k8s.emberstack.com/reflection-auto-enabled: "true"
reflector.v1.k8s.emberstack.com/reflection-auto-namespaces: "dev,staging,prod-[0-9]*"
3. 创建测试 namespace ¶
上面的 secretTemplate
指定了同步namespace
label
的过滤条件,我们使用这条规则测试 prod-[0-9]*
kubectl create ns prod-1
4. 查看目标 namespace 是否成功 ¶
kubectl get secret -n prod-1
![]() |