Skip to main content

在 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年及以上。

参考文档