在 K8S 中使用 cert-manager 签发阿里云 DNS 免费 HTTPS 证书
cert-manager 本身是不支持国内 DNS解析服务商的,但官方给出了一些社区的提供方案:cert-manager Webhook
阿里云 DNS Webhook 官方推荐了两个社区方案:
原理其实一样只是实现稍微不同,这里使用 cert-manager-alidns-webhook
准备条件
- cert-manager 已部署在 K8S 集群内
- 阿里云账号管理员权限
Helm 安装 cert-manager-alidns-webhook
安装仓库
helm repo add cert-manager-alidns-webhook https://devmachine-fr.github.io/cert-manager-alidns-webhook
helm repo update
查看版本
$ helm search repo cert-manager-alidns-webhook/alidns-webhook
NAME CHART VERSION APP VERSION DESCRIPTION
cert-manager-alidns-webhook/alidns-webhook 0.8.2 0.8.2 Deploys alidns webhook for cert-manager.
安装 Chart
helm -n cert-manager install alidns-webhook cert-manager-alidns-webhook/alidns-webhook
获取阿里云访问密钥
获取阿里云账号访问密钥:
为账号授权 云解析 权限:
创建保存阿里巴巴凭证的secret,access-token需要输入AccessKeyId,secret-key需要输入AccessKeySecret:
kubectl -n cert-manager create secret generic alidns-secrets --from-literal="access-token=yourtoken" --from-literal="secret-key=yoursecretkey"
或使用 YAML 编排(base64加密):secret.yaml
apiVersion: v1
kind: Secret
metadata:
name: alidns-secrets
namespace: cert-manager
data:
access-token: yourtoken # echo -n "AccessKey ID" | base64
secret-key: yoursecretkey # echo -n "AccessKey Secret" | base64
创建 issuer(可选)
要使用的求解器名称是 solverName: alidns-solver
apiVersion: cert-manager.io/v1
kind: Issuer
metadata:
name: letsencrypt
namespace: default
spec:
acme:
email: contact@example.com
privateKeySecretRef:
name: letsencrypt
server: https://acme-staging-v02.api.letsencrypt.org/directory
solvers:
- dns01:
webhook:
config:
accessTokenSecretRef:
key: access-token
name: alidns-secrets
regionId: cn-beijing
secretKeySecretRef:
key: secret-key
name: alidns-secrets
groupName: example.com
solverName: alidns-solver
selector:
dnsNames:
- example.com
- '*.example.com'
创建 ClusterIssuer(推荐)
前文已经说过 Issuer 与 ClusterIssuer 的区别,这里推荐使用可跨命名空间的 ClusterIssuer
以下 YAML 使用了 Let's Encrypt 的 ACME 协议通过 DNS-01
来验证域名所有权,并集成了阿里云 DNS(AliDNS)作为验证方式。
apiVersion: cert-manager.io/v1
kind: ClusterIssuer
metadata:
name: letsencrypt
spec:
acme:
email: contact@example.com
server: https://acme-staging-v02.api.letsencrypt.org/directory
privateKeySecretRef:
name: letsencrypt
solvers:
- dns01:
webhook:
config:
accessTokenSecretRef:
key: access-token
name: alidns-secrets
regionId: cn-beijing
secretKeySecretRef:
key: secret-key
name: alidns-secrets
groupName: example.com # groupName must match the one configured on webhook deployment (see Helm chart's values) !
solverName: alidns-solver
spec.acme.server
指定使用的 ACME 服务器地址,默认值为 staging(测试) 服务器,适用于开发和测试环境。生产环境应使用https://acme-v02.api.letsencrypt.org/directory
dns01参考文档
有关更多信息,请参阅 cert-manager 文档:https://cert-manager.io/docs/configuration/acme/dns01/
创建认证
使用 issuer 创建认证如下(可选)
apiVersion: cert-manager.io/v1
kind: Certificate
metadata:
name: example-tls
spec:
secretName: example-com-tls
commonName: example.com
dnsNames:
- example.com
- "*.example.com"
issuerRef:
name: letsencrypt
kind: Issuer
或者使用 ClusterIssuer 创建认证,如下所示:(推荐)
apiVersion: cert-manager.io/v1
kind: Certificate
metadata:
name: cert-star-example-com # cert 资源对象的名称
namespace: default # cert 与 secret 保存到名称空间
spec:
secretName: ssl-star-example-com # 指定用于存储生成的 TLS 证书和私钥的 Kubernetes Secret 名称
commonName: example.com # 证书的通用名称(Common Name),通常是主域名,
dnsNames:
- example.com # 主域名
- "*.example.com" # 通配符子域名,覆盖所有 example.com 下的子域。
issuerRef:
name: letsencrypt
kind: ClusterIssuer
查看 cert 资源对象,READY
列查看证书的签发状态:
$ kubectl get cert -A
NAMESPACE NAME READY SECRET AGE
cert-manager alidns-webhook-ca True alidns-webhook-ca 47m
cert-manager alidns-webhook-webhook-tls True alidns-webhook-webhook-tls 47m
default cert-star-example-com True ssl-star-example-com 8m37s
签发失败
遇到签发失败,可以通过以下命令捕获关键日志进行 TroubleShooting
kubectl describe cert
kubectl -n cert-manager logs -f alidns-webhook-7584b4d45d-8wtmn
kubectl -n cert-manager logs -f cert-manager-76df74df6d-4sr99
生产环境 SSL 证书
免费的 DV 类型 SSL 有效期3个月,多用于用户个人开发环境。
生产环境推荐使用权威 SSL 品牌提供的企业型 OV 证书,有效期为1年及以上。