在私有 AKS 配置 Cert Manager 管理TLS证书
Cert Manager 是 Kubernetes 生态中用于自动化管理和签发 TLS 证书的工具,支持多种证书颁发机构。其提供的主要挑战方法包括 HTTP-01(通过 HTTP 验证域名控制权)和 DNS-01(通过 DNS 记录记录验证)等。本文介绍在私有 AKS 里使用 Cert Manager 的方法。
关键要点 🔗
- 私有 AKS 没有暴露给互联网。因此无法使用 HTTP-01 挑战;而应该使用 DNS-01 挑战;
- 私有 AKS 的虚拟网络可能关联了私有DNS区域,因此 Cert Manager在验证 DNS TXT 的时候,无法访问公共 DNS 区域。
安装和配置 Cert Manager 🔗
创建 UAI 并授予权限 🔗
确保 UAI 能够读写公共 DNS 区域的域名的 TXT 记录。如果能够接受不那么严格的最小权限原则,那么可以给它授予 DNS Zone Contributor
角色。
确保 Cert Manager 可创建 cert-manager.io:ClusterIssuer
🔗
Cert Manager 会创建集群级别的资源 cert-manager.io:ClusterIssuer
,应该确保它有权限创建。
创建 Helm chart 🔗
Cert Manager 提供了使用 Helm 部署的详细文档 文档。可创建一个新的 Helm Chart,然后 cert-manager
作为依赖项。比如:
apiVersion: v2
name: cert-manager
description: Cert Manager
type: application
version: 1.0.0
appVersion: v1.18.2
dependencies:
- name: cert-manager
version: v1.18.2
repository: https://charts.jetstack.io
alias: cert-manager
condition: cert-manager.enabled
其默认的 values 文件为:
global:
leaderElection:
namespace: cert-manager
cert-manager:
enabled: true
namespace: cert-manager
crds:
enabled: true
podLabels:
azure.workload.identity/use: "true"
prometheus:
enabled: false
serviceAccount:
labels:
azure.workload.identity/use: "true"
dns01RecursiveNameserversOnly: true
dns01RecursiveNameservers: 8.8.8.8:53,1.1.1.1:53
注意:这里实质上给 cert-manager-controller 设置了 --dns01-recursive-nameservers-only=true --dns01-recursive-nameservers=8.8.8.8:53,1.1.1.1:53
选项。这是因为如果 Cert Manager 所在的节点如果启用了私有DNS区域,那么无法访问公共 DNS 上的 TXT 记录来验证域名;启用这两个选项后,那么 Cert Manage 机会使用这两个公共的递归 DNS 服务器进行 TXT 记录查询。
除此之外,还需要创建一个模板,用于创建 ClusterIssuer
。比如:
apiVersion: cert-manager.io/v1
kind: ClusterIssuer
metadata:
name: letsencrypt-dns-01
spec:
acme:
server: https://acme-v02.api.letsencrypt.org/directory
email: {{ .Values.clusterIssuer.email }}
privateKeySecretRef:
name: letsencrypt-dns-01
solvers:
- dns01:
azureDNS:
subscriptionID: {{ .Values.clusterIssuer.subscriptionID }}
resourceGroupName: {{ .Values.clusterIssuer.resourceGroupName }}
hostedZoneName: {{ .Values.clusterIssuer.hostedZoneName }}
environment: AzurePublicCloud
managedIdentity:
resourceID: {{ .Values.clusterIssuer.managedIdentityResourceID }}
这样 Helm Chart 就创建好了。
Values 文件 🔗
Helm Chart 里的 values 文件已经包含了大部分配置。在需要部署时,还需要执行 workload identity id 等。为此,创建部署时需要的额外的 values 文件,内部大致如下:
cert-manager:
serviceAccount:
annotations:
azure.workload.identity/client-id: {uai_client_id}
clusterIssuer:
email: ''
resourceGroupName: {resource_group_name}
hostedZoneName: {zone_name}
subscriptionID: {subscription_id}
managedIdentityResourceID: /subscriptions/{subscription_id}/resourceGroups/{resource_group_name}/providers/Microsoft.ManagedIdentity/userAssignedIdentities/{uai_name}
使用证书 🔗
在 Ingress 中使用证书 🔗
在 Ingress 中使用证书是一个常见的场景,见文档《Annotated Ingress resource》,使用 cert-manager.io/cluster-issuer
注解即可。
创建 Certificate 🔗
可创建如下的模板,用于创建证书:
apiVersion: cert-manager.io/v1
kind: Certificate
metadata:
name: {{ .Value.certificate.name }}
namespace: {{ .Release.Namespace }}
spec:
secretName: {{ .Values.certificate.secretName }}
issuerRef:
name: {{ .Values.certificate.issuerName }}
kind: ClusterIssuer
commonName: {{ .Values.certificate.domain }}
dnsNames:
- {{ .Values.certificate.domain }}
在应用中,使用 Certificate 创建的 Secret,即可加载证书。但是需要注意的是创建顺序,因为这个 Secret 的创建会有延迟:创建了 Certificate 创建之后的,需要等一段时间才会成功签发证书,此后才会创建 Secret。