概述
如果域名通过 DNSPod 管理,由于 cert-manager 自身并未实现 DNSPod 的 provider,但提供了 webhook 扩展机制,因此通过 cert-manager-webhook-dnspod 可以实现为 DNSPod 上的域名自动签发免费证书与续期。
操作步骤
创建 cert-manager 命名空间
请确保已创建 cert-manager 命名空间。如果没有该命名空间,请执行以下命令创建:
kubectl create ns cert-manager
安装 cert-manager
安装 cert-manager-webhook-dnspod
创建腾讯云 API 密钥
要求账号至少具有以下权限:
{"version": "2.0","statement": [{"effect": "allow","action": ["dnspod:CreateRecord","dnspod:DescribeRecordList","dnspod:DeleteRecord",],"resource": ["*"]}]}
创建 Secret
在 cert-manager 所在命名空间中创建一个
Secret
对象,用于保存前面创建的腾讯云 API 密钥:apiVersion: v1kind: Secretmetadata:name: dnspod-secretnamespace: cert-managertype: OpaquestringData:secretId: xxxsecretKey: xxx
注意:
请将 xxx 替换为您的 SecretId 和 SecretKey。
创建 ClusterIssuer
创建一个 DNSPod 的
ClusterIssuer
对象,用于为 DNSPod 管理的域名签发免费证书:apiVersion: cert-manager.io/v1kind: ClusterIssuermetadata:name: dnspodspec:acme:email: your-email-address@example.comprivateKeySecretRef:name: dnspod-letsencryptserver: https://acme-v02.api.letsencrypt.org/directorysolvers:- dns01:webhook:config:secretIdRef:key: secretIdname: dnspod-secretsecretKeyRef:key: secretKeyname: dnspod-secretttl: 600recordLine: ""groupName: acme.dnspod.comsolverName: dnspod
注意:
email
可替换成您的邮箱地址,用于接收来自 Let's Encrypt 的证书过期提醒(只有没正常自动续期的情况才会有通知)。创建 Certificate
创建
Certificate
对象来签发您想要的免费证书:apiVersion: cert-manager.io/v1kind: Certificatemetadata:name: example-crtnamespace: istio-systemspec:secretName: example-crt-secret # 证书签发后会保存到这个 Secret 中issuerRef:name: dnspod # 这里引用前面创建的 ClusterIssuer 名称kind: ClusterIssuergroup: cert-manager.iodnsNames: # 填入需要签发证书的域名列表,支持泛域名,确保域名是使用当前账号下的 dnspod 管理的- "example.com"- "*.example.com"
等待 Ready 变为 True 表示签发成功:
$ kubectl -n istio-system get certificates.cert-manager.ioNAME READY SECRET AGEexample-crt True example-crt-secret 25d
若签发失败,可通过 describe 查看详细原因:
kubectl -n istio-system describe certificates.cert-manager.io example-crt
使用证书
证书签发成功后会保存到我们指定的 Secret 中,下面给出一些使用示例。
在 Ingress 中使用
apiVersion: networking.k8s.io/v1beta1kind: Ingressmetadata:name: test-ingressannotations:kubernetes.io/ingress.class: nginxspec:rules:- host: test.example.comhttp:paths:- path: /backend:serviceName: webservicePort: 80tls:hosts:- test.example.comsecretName: example-crt-secret # 引用证书 secret
在 Istio 的 IngressGateway 中使用
如果集群中安装了 Istio,可在
Gateway
中引用证书 Secret:apiVersion: networking.istio.io/v1alpha3kind: Gatewaymetadata:name: example-gwnamespace: istio-systemspec:selector:app: istio-ingressgatewayistio: ingressgatewayservers:- port:number: 80name: HTTP-80protocol: HTTPhosts:- example.com- "*.example.com"tls:httpsRedirect: true- port:number: 443name: HTTPS-443protocol: HTTPShosts:- example.com- "*.example.com"tls:mode: SIMPLEcredentialName: example-crt-secret # 引用证书 secret---apiVersion: networking.istio.io/v1beta1kind: VirtualServicemetadata:name: example-vsnamespace: testspec:gateways:- istio-system/example-gw # 将转发规则应用到指定 IngressGatewayhosts:- 'test.example.com'http:- route:- destination:host: exampleport:number: 80
在 Gateway API 中使用
apiVersion: gateway.networking.k8s.io/v1kind: Gatewaymetadata:name: egnamespace: envoy-gateway-systemspec:gatewayClassName: eglisteners:- allowedRoutes:namespaces:from: Allname: httpsport: 443protocol: HTTPStls:certificateRefs:- group: ""kind: Secretname: example-crt-secret # 引用证书 secretmode: Terminate- allowedRoutes:namespaces:from: Allname: httpport: 80protocol: HTTP---apiVersion: gateway.networking.k8s.io/v1kind: HTTPRoutemetadata:name: examplenamespace: testspec:hostnames:- example.comparentRefs: # 将转发规则应用到指定 Gateway- group: gateway.networking.k8s.iokind: Gatewayname: egnamespace: envoy-gateway-systemsectionName: httpsrules:- backendRefs:- group: ""kind: Servicename: websiteport: 80weight: 1matches:- path:type: PathPrefixvalue: /
注意事项
Private DNS 与 DNSPod 的 zone 需保持一致
如果满足以下条件:
1. 使用了 Private DNS 管理域名解析。
2. Private DNS 关联了当前 TKE 集群所在 VPC。
3. Private DNS 中也配置了待签发免费证书的域名的解析。
4. DNSPod 中有将子域名独立出来(单独成 zone)管理域名解析。
则必须确保 Private DNS 中也要有相同的 zone 配置,即也将相同子域名独立出来管理解析,在 Private DNS 控制台点击新建私有域,输入与 DNSPod 中相同的子域名。
这是因为在签发证书时,cert-manager 会通过 SOA 查询要签发的域名的 zone,在有 Private DNS 的环境中,如果 Private DNS 里也配置了相同的域名,会优先根据 Private DNS 中的配置返回,如果与 DNSPod 中配置的 zone 不一致,最终校验就会失败,导致一直无法签发成功。