新:获取项目更新 推特Mastodon

在 Azure Kubernetes Service (AKS) 上部署 cert-manager 并使用 Let's Encrypt 为 HTTPS 网站签名证书

最后验证:2024 年 1 月 11 日

在本教程中,您将了解如何在 Azure Kubernetes Service (AKS) 上部署和配置 cert-manager,以及如何部署 HTTPS Web 服务器并使其在互联网上可用。您将学习如何配置 cert-manager 以从 Let's Encrypt 获取签名证书,这将允许客户端安全地连接到您的 HTTPS 网站。您将配置 cert-manager 使用 Let's Encrypt DNS-01 挑战协议 与 Azure DNS,使用工作负载身份联合身份验证到 Azure。

Microsoft Azure:微软提供的云计算服务套件。
Kubernetes:运行在您的服务器上。自动执行容器化应用程序的部署、扩展和管理。
cert-manager:运行在 Kubernetes 中。获取 TLS/SSL 证书,并确保证书有效且更新。
Let's Encrypt:一个互联网服务。允许您生成免费的短期 SSL 证书。

第 1 部分

在本教程的第一部分,您将学习使用 cert-manager 创建 Web 服务器的 SSL 证书,在 Azure Kubernetes 集群上部署 HTTPS 网站所需的知识。您将为您的网站创建一个 DNS 域名,创建一个 Azure Kubernetes 集群,安装 cert-manager,创建一个 SSL 证书,然后部署一个 Web 服务器,该服务器将响应来自互联网上客户端的 HTTPS 请求。但是,第 1 部分中的 SSL 证书仅用于测试目的。

在第 2 部分,您将学习如何配置 cert-manager 使用 Let's Encrypt 和 Azure DNS 创建一个受信任的 SSL 证书,您可以在生产环境中使用该证书。

配置 Azure CLI (az)

如果您还没有这样做,请下载并安装 Azure CLI (az)

设置 az 命令以进行交互式使用

az init

如果您还没有登录,请登录

az login

设置默认资源组和位置

export AZURE_DEFAULTS_GROUP=your-resource-group # ❗ Your Azure resource group
export AZURE_DEFAULTS_LOCATION=eastus2 # ❗ Your Azure location.

ℹ️ 您将需要一个 az 版本 >=2.40.0。运行 az version 以打印当前版本。

ℹ️ 当您运行 az init 时,在提示时选择“Optimize for interaction”。

ℹ️ 当您运行 az login 时,将在 https://login.microsoftonline.com/organizations/oauth2/v2.0/authorize 打开一个网页浏览器。在网页浏览器中继续登录,然后返回您的终端。

📖 阅读 Azure 命令行界面 (CLI) 文档

📖 阅读 CLI 配置值和环境变量,了解配置 az 默认值的更多方法。

创建公共域名

在本教程中,您将部署一个具有公共访问域名的 HTTPS 网站,因此您需要注册一个域名,除非您已经拥有一个。您可以使用任何 域名注册商 为您的网站注册一个域名。这里我们将使用一个名为 Gandi 的注册商,并为本教程的目的注册一个便宜的域名。我们将使用域名: cert-manager-tutorial-22.site,但您应该选择自己的。

现在您知道了域名,请将其保存在环境变量中

export DOMAIN_NAME=cert-manager-tutorial-22.site # ❗ Replace this with your own DNS domain name

并将其添加到 Azure DNS 作为区域

az network dns zone create --name $DOMAIN_NAME

登录到您的域名注册商的控制面板,并将您的域的 NS 记录设置为与 Azure 权威 DNS 服务器 的 DNS 名称匹配。您可以通过查找 Azure 托管 DNS 区域的 NS 记录来找到它们

az network dns zone show --name $DOMAIN_NAME --output yaml

您可以使用 dig 来检查 NS 记录是否已更新,以“跟踪” NS 记录的层次结构,而不是使用您的本地 DNS 解析器

dig $DOMAIN_NAME ns +trace +nodnssec

⏲ NS 记录可能需要超过 1 小时才能在父区域中更新,如果在更新 NS 记录之前查询了 DNS 名称,则可能需要一些时间才能在 DNS 解析器服务器的缓存中替换旧的 NS 记录。

📖 阅读 如何更新我的 DNS 记录?Gandi.net 文档中,或查找您自己的域名注册商的等效文档。

创建 Kubernetes 集群

首先,让我们在 Microsoft Azure 中创建一个 Kubernetes 集群。您需要为您的集群选择一个名称。这里,我们将使用“test-cluster-1”。将其保存在环境变量中

export CLUSTER=test-cluster-1

现在,使用以下命令创建集群

az aks create \
--name ${CLUSTER} \
--node-count 1 \
--node-vm-size "Standard_B2s" \
--load-balancer-sku basic

使用您的新集群的凭据更新您的 kubectl 配置文件

az aks get-credentials --admin --name "$CLUSTER"

现在检查您是否可以连接到集群

kubectl get nodes -o wide

⏲ 创建集群大约需要 4-5 分钟。

💵 为了最大限度地减少您的云账单,此命令使用低成本虚拟机和负载均衡器创建了一个 1 节点集群。

⚠️ 此集群仅适用于学习目的,不适合生产使用。

📖 阅读 以经济实惠的方式在 Azure 中运行 Kubernetes,以获取更多节省成本的技巧。

安装 cert-manager

现在您可以安装和配置 cert-manager。

使用 helm 如下安装 cert-manager

helm repo add jetstack https://charts.jetstack.io --force-update
helm install \
cert-manager jetstack/cert-manager \
--namespace cert-manager \
--create-namespace \
--version v1.16.1 \
--set crds.enabled=true

这将在名为 cert-manager 的新命名空间中创建三个部署和一些服务和 Pod。它还安装了各种集群范围的支撑资源,例如 RBAC 角色和自定义资源定义。

您可以使用以下方法查看已安装的一些资源

kubectl -n cert-manager get all

您可以使用 kubectl explain 探索自定义资源定义(cert-manager 的 API),如下所示

kubectl explain Certificate
kubectl explain CertificateRequest
kubectl explain Issuer

📖 阅读关于 安装 cert-manager 的其他方法

📖 详细了解 证书和颁发者

创建测试 ClusterIssuer 和证书

现在一切准备就绪,您可以创建您的第一个证书。这将是一个自签名证书,但稍后我们将用 Let's Encrypt 签名的证书替换它。

# clusterissuer-selfsigned.yaml
apiVersion: cert-manager.io/v1
kind: ClusterIssuer
metadata:
name: selfsigned
spec:
selfSigned: {}

🔗 clusterissuer-selfsigned.yaml

kubectl apply -f clusterissuer-selfsigned.yaml

然后使用 envsubst 将您选择的域名替换到以下证书模板中

# certificate.yaml
apiVersion: cert-manager.io/v1
kind: Certificate
metadata:
name: www
spec:
secretName: www-tls
privateKey:
rotationPolicy: Always
commonName: www.$DOMAIN_NAME
dnsNames:
- www.$DOMAIN_NAME
usages:
- digital signature
- key encipherment
- server auth
issuerRef:
name: selfsigned
kind: ClusterIssuer

🔗 certificate.yaml

envsubst < certificate.yaml | kubectl apply -f -

🔗 如果您还没有安装 envsubst,您可以下载并安装 envsubst 的 Go 实现

使用 cmctl status certificate 检查证书的状态

cmctl status certificate www

如果成功,私钥和已签名证书将存储在名为 www-tls 的 Secret 中。您可以使用 cmctl inspect secret www-tls 解码 Secret 的 base64 编码的 X.509 内容

$ cmctl inspect secret www-tls
...
Valid for:
DNS Names:
- www.cert-manager-tutorial-22.site
URIs: <none>
IP Addresses: <none>
Email Addresses: <none>
Usages:
- digital signature
- key encipherment
- server auth
...

部署示例 Web 服务器

现在部署一个简单的 Web 服务器,该服务器将使用“hello world!”响应 HTTPS 请求。SSL/TLS 密钥和证书是通过将 www-tls Secret 作为卷提供给 Web 服务器,并通过将它的内容安装到 Pod 中的 hello-app 容器的文件系统中来提供给 Web 服务器

# deployment.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: helloweb
labels:
app: hello
spec:
selector:
matchLabels:
app: hello
tier: web
template:
metadata:
labels:
app: hello
tier: web
spec:
containers:
- name: hello-app
image: us-docker.pkg.dev/google-samples/containers/gke/hello-app-tls:1.0
imagePullPolicy: Always
ports:
- containerPort: 8443
volumeMounts:
- name: tls
mountPath: /etc/tls
readOnly: true
env:
- name: TLS_CERT
value: /etc/tls/tls.crt
- name: TLS_KEY
value: /etc/tls/tls.key
volumes:
- name: tls
secret:
secretName: www-tls

🔗 deployment.yaml

kubectl apply -f deployment.yaml

您还需要创建一个 Kubernetes LoadBalancer 服务,以便来自互联网的连接可以路由到 Web 服务器 Pod。当您创建以下 Kubernetes 服务时,还将创建一个具有短暂公共 IP 地址的 Azure 负载均衡器

# service.yaml
apiVersion: v1
kind: Service
metadata:
name: helloweb
annotations:
service.beta.kubernetes.io/azure-dns-label-name: $AZURE_LOADBALANCER_DNS_LABEL_NAME
spec:
ports:
- port: 443
protocol: TCP
targetPort: 8443
selector:
app: hello
tier: web
type: LoadBalancer

🔗 service.yaml

为 LoadBalancer 服务创建一个唯一的 DNS 名称,然后应用它

export AZURE_LOADBALANCER_DNS_LABEL_NAME=lb-$(uuidgen) # ❗ The label must start with a lowercase ASCII letter
envsubst < service.yaml | kubectl apply -f -

在 2-3 分钟内,应该会配置一个带有公共 IP 的负载均衡器。

kubectl get service helloweb

示例输出

$ kubectl get service helloweb
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
helloweb LoadBalancer 10.0.141.1 20.114.151.62 443:30394/TCP 7m15s

你的 EXTERNAL-IP 将与我的不同,并且每次重新创建 LoadBalancer 服务时都可能不同,但它将拥有一个与之关联的稳定 DNS 主机名,因为你使用 azure-dns-label-name 对服务进行了标注。这个稳定的 DNS 主机名可以作为你选择的 $DOMAIN_NAME 的别名,通过创建一个 DNS CNAME 记录 来实现。

az network dns record-set cname set-record \
--zone-name $DOMAIN_NAME \
--cname $AZURE_LOADBALANCER_DNS_LABEL_NAME.$AZURE_DEFAULTS_LOCATION.cloudapp.azure.com \
--record-set-name www

检查 www.$DOMAIN_NAME 是否现在解析到负载均衡器的短暂公共 IP 地址。

$ dig www.$DOMAIN_NAME A
...
;; QUESTION SECTION:
;www.cert-manager-tutorial-22.site. IN A
...
;; ANSWER SECTION:
www.cert-manager-tutorial-22.site. 3600 IN CNAME lb-ec8776e1-d067-4d4c-8cce-fdf07ce48260.eastus2.cloudapp.azure.com.
lb-ec8776e1-d067-4d4c-8cce-fdf07ce48260.eastus2.cloudapp.azure.com. 10 IN A 20.122.27.189
...

如果 DNS 正确,并且负载均衡器正在工作,并且 Hello World Web 服务器正在运行,你现在应该能够使用 curl 或使用你的 Web 浏览器连接到它。

curl --insecure -v https://www.$DOMAIN_NAME

⚠️ 我们使用了 curl 的 --insecure 选项,因为它默认情况下会拒绝自签名证书。稍后你将学习如何创建由 Let's Encrypt 签名的受信任证书。

你应该看到证书具有预期的 DNS 名称,并且它是自签名的。

...
* Server certificate:
* subject: CN=www.cert-manager-tutorial-22.site
* start date: Jan 4 15:28:30 2023 GMT
* expire date: Apr 4 15:28:30 2023 GMT
* issuer: CN=www.cert-manager-tutorial-22.site
* SSL certificate verify result: self-signed certificate (18), continuing anyway.
...
Hello, world!
Protocol: HTTP/2.0!
Hostname: helloweb-55cb4cd887-tjlvh

📖 了解有关 使用服务公开应用程序 的更多信息。

📖 了解有关 在 Azure Kubernetes Service (AKS) 负载均衡器中使用公共 IP 地址和 DNS 标签 的更多信息。

第 2 部分

在第 1 部分中,你创建了一个测试证书。现在你将学习如何配置 cert-manager 使用 Let's Encrypt 和 Azure DNS 创建一个受信任的证书,你可以将其用于生产环境。你需要向 Let's Encrypt 证明你拥有证书的域名,一种方法是在该域名中创建一个特殊的 DNS 记录。这被称为 DNS-01 挑战类型

cert-manager 可以通过使用 Azure DNS API 为你创建该 DNS 记录,但它需要首先向 Azure 进行身份验证,目前最安全的身份验证方法是使用 工作负载身份联合。这种方法的优点是 cert-manager 将使用一个短暂的 Kubernetes ServiceAccount 令牌来对 Azure 进行身份验证,并且该令牌不需要存储在 Kubernetes Secret 中。

ℹ️ cert-manager >= v1.11.0 支持使用 Azure DNS 对 ACME (Let's Encrypt) DNS-01 进行工作负载身份联合。旧版本的 cert-manager 支持本教程中未涵盖的其他身份验证机制。

📖 了解有关 使用 Azure DNS 配置 ACME 发行者(其他方法) 的更多信息。

安装 Azure 工作负载身份功能

Azure AKS 中的工作负载身份功能相对较新(在撰写本文时),它们需要启用一些非默认功能。

安装 Azure CLI AKS 预览扩展,你将需要使用它在 AKS 集群上配置一些高级工作负载身份联合功能。

az extension add --name aks-preview

注册 EnableWorkloadIdentityPreview 功能标志,这是本演示中 AKS 集群所必需的。

az feature register --namespace "Microsoft.ContainerService" --name "EnableWorkloadIdentityPreview"
# It takes a few minutes for the status to show Registered. Verify the registration status by using the az feature list command:
az feature list -o table --query "[?contains(name, 'Microsoft.ContainerService/EnableWorkloadIdentityPreview')].{Name:name,State:properties.state}"
# When ready, refresh the registration of the Microsoft.ContainerService resource provider by using the az provider register command:
az provider register --namespace Microsoft.ContainerService

📖 了解有关 注册 EnableWorkloadIdentityPreview 功能标志 的更多信息。

重新配置集群

接下来,在之前创建的集群上启用工作负载身份联合功能。

az aks update \
--name ${CLUSTER} \
--enable-oidc-issuer \
--enable-workload-identity # ℹ️ This option is currently only available when using the aks-preview extension.

📖 阅读 在 Azure Kubernetes Service (AKS) 集群上部署和配置工作负载身份,以了解有关 --enable-workload-identity 功能的更多信息。

重新配置 cert-manager

我们将为 cert-manager 控制器 Pod 和 ServiceAccount 添加标签,以提醒 Azure 工作负载身份 Webhook,这将导致 cert-manager 控制器 Pod 拥有一个额外的卷,其中包含一个 Kubernetes ServiceAccount 令牌,它将用于对 Azure 进行身份验证。

可以使用以下 Helm 值文件配置标签。

# values.yaml
podLabels:
azure.workload.identity/use: "true"
serviceAccount:
labels:
azure.workload.identity/use: "true"

🔗 values.yaml

existing_cert_manager_version=$(helm get metadata -n cert-manager cert-manager | grep '^VERSION' | awk '{ print $2 }')
helm upgrade cert-manager jetstack/cert-manager \
--reuse-values \
--namespace cert-manager \
--version $existing_cert_manager_version \
--values values.yaml

新部署的 cert-manager Pod 将设置一些新的环境变量,以及 Azure 工作负载身份 ServiceAccount 令牌作为投影卷。

kubectl describe pod -n cert-manager -l app.kubernetes.io/component=controller
Containers:
...
cert-manager-controller:
...
Environment:
...
AZURE_CLIENT_ID:
AZURE_TENANT_ID: f99bd6a4-665c-41cf-aff1-87a89d5c62d4
AZURE_FEDERATED_TOKEN_FILE: /var/run/secrets/azure/tokens/azure-identity-token
AZURE_AUTHORITY_HOST: https://login.microsoftonline.com/
Mounts:
/var/run/secrets/azure/tokens from azure-identity-token (ro)
Volumes:
...
azure-identity-token:
Type: Projected (a volume that contains injected data from multiple sources)
TokenExpirationSeconds: 3600

📖 了解有关 Azure AD 工作负载身份 for Kubernetes 中变异接收 Webhook 的作用 的更多信息。

📖 了解有关 cert-manager Helm 图表中可以自定义的其他值 的更多信息。

创建 Azure 托管身份

当 cert-manager 使用 Let's Encrypt 创建证书时,它可以使用 DNS 记录来证明它控制证书中的 DNS 域名。为了让 cert-manager 使用 Azure API 并操作 Azure DNS 区域中的记录,它需要一个 Azure 帐户,最适合使用的帐户类型称为“托管身份”。该帐户没有密码或 API 密钥,并且专为机器使用而设计,而不是为人类使用。

选择一个托管身份名称。

export USER_ASSIGNED_IDENTITY_NAME=cert-manager-tutorials-1 # ❗ Replace with your preferred managed identity name

创建托管身份。

az identity create --name "${USER_ASSIGNED_IDENTITY_NAME}"

授予它修改 DNS 区域记录的权限。

export USER_ASSIGNED_IDENTITY_CLIENT_ID=$(az identity show --name "${USER_ASSIGNED_IDENTITY_NAME}" --query 'clientId' -o tsv)
az role assignment create \
--role "DNS Zone Contributor" \
--assignee $USER_ASSIGNED_IDENTITY_CLIENT_ID \
--scope $(az network dns zone show --name $DOMAIN_NAME -o tsv --query id)

📖 阅读 什么是 Azure 资源的托管身份?,以了解托管身份及其用途的概述。

📖 阅读 Azure 内置角色,以了解“DNS 区域贡献者”角色。

添加联合身份

现在我们将配置 Azure 以信任某些 Kubernetes ServiceAccount 令牌,特别是来自我们特定 Kubernetes 集群的 ServiceAccount 令牌,以及仅与 cert-manager ServiceAccount 关联的令牌。cert-manager 将使用短时效 Kubernetes ServiceAccount 令牌对 Azure 进行身份验证,并且它将能够模拟你在上一步中创建的托管身份。

首先导出以下包含 Kubernetes ServiceAccount 名称和命名空间的环境变量,该 ServiceAccount 由 cert-manager 控制器使用。

export SERVICE_ACCOUNT_NAME=cert-manager # ℹ️ This is the default Kubernetes ServiceAccount used by the cert-manager controller.
export SERVICE_ACCOUNT_NAMESPACE=cert-manager # ℹ️ This is the default namespace for cert-manager.

然后,通过提供其“主体”(Kubernetes ServiceAccount 的区别名称)及其“发行者”(可以从中下载 JWT 签名证书和其他元数据的 URL)来配置托管身份以信任 cert-manager Kubernetes ServiceAccount。

export SERVICE_ACCOUNT_ISSUER=$(az aks show --resource-group $AZURE_DEFAULTS_GROUP --name $CLUSTER --query "oidcIssuerProfile.issuerUrl" -o tsv)
az identity federated-credential create \
--name "cert-manager" \
--identity-name "${USER_ASSIGNED_IDENTITY_NAME}" \
--issuer "${SERVICE_ACCOUNT_ISSUER}" \
--subject "system:serviceaccount:${SERVICE_ACCOUNT_NAMESPACE}:${SERVICE_ACCOUNT_NAME}"

📖 了解有关 Microsoft 身份平台文档中 工作负载身份联合 的更多信息。

为 Let's Encrypt 暂存环境创建 ClusterIssuer

ClusterIssuer 是一个自定义资源,它告诉 cert-manager 如何签署证书。在本例中,ClusterIssuer 将被配置为连接到 Let's Encrypt 暂存服务器,这使我们能够在不使用 Let's Encrypt 证书配额的情况下测试所有内容。

将以下内容保存到名为 clusterissuer-lets-encrypt-staging.yaml 的文件中,更改 email 字段以使用你的电子邮件地址并应用它。

# clusterissuer-lets-encrypt-staging.yaml
apiVersion: cert-manager.io/v1
kind: ClusterIssuer
metadata:
name: letsencrypt-staging
spec:
acme:
server: https://acme-staging-v02.api.letsencrypt.org/directory
email: $EMAIL_ADDRESS
privateKeySecretRef:
name: letsencrypt-staging
solvers:
- dns01:
azureDNS:
resourceGroupName: $AZURE_DEFAULTS_GROUP
subscriptionID: $AZURE_SUBSCRIPTION_ID
hostedZoneName: $DOMAIN_NAME
environment: AzurePublicCloud
managedIdentity:
clientID: $USER_ASSIGNED_IDENTITY_CLIENT_ID

🔗 clusterissuer-lets-encrypt-staging.yaml

如你所见,clusterissuer-lets-encrypt-staging.yaml 中有一些变量需要在应用之前填写;大多数变量在本教程中已定义,但你需要设置以下内容。

export EMAIL_ADDRESS=<email-address> # ❗ Replace this with your email address
export AZURE_SUBSCRIPTION=<your-subscription-or-billing-account> # ❗ Replace this with your Azure account name

现在使用 envsubst 填写变量,并将其通过管道传递到 kubectl apply,如下所示。

export AZURE_SUBSCRIPTION_ID=$(az account show --name $AZURE_SUBSCRIPTION --query 'id' -o tsv)
envsubst < clusterissuer-lets-encrypt-staging.yaml | kubectl apply -f -

你可以检查 ClusterIssuer 的状态。

kubectl describe clusterissuer letsencrypt-staging

示例输出。

Status:
Acme:
Last Registered Email: [email protected]
Uri: https://acme-staging-v02.api.letsencrypt.org/acme/acct/77882854
Conditions:
Last Transition Time: 2022-11-29T13:05:33Z
Message: The ACME account was registered with the ACME server
Observed Generation: 1
Reason: ACMEAccountRegistered
Status: True
Type: Ready

ℹ️ Let's Encrypt 使用自动证书管理环境 (ACME) 协议,这就是为什么上面的配置位于名为 acme 的键下的原因。

ℹ️ 电子邮件地址仅供 Let's Encrypt 在证书到期前 30 天内提醒你续订证书。只有在使用 cert-manager 续订证书时出现问题时,你才会收到此电子邮件。

ℹ️ Let's Encrypt 生产发行者具有 非常严格的速率限制。在进行实验和学习时,很容易达到这些限制。由于这种风险,我们将从 Let's Encrypt 暂存发行者开始,一旦我们满意它可以正常工作,我们将切换到生产发行者。

📖 了解有关 配置 ACME 发行者 的更多信息。

使用 Let's Encrypt 重新颁发证书

修补证书以使用暂存 ClusterIssuer。

kubectl patch certificate www --type merge -p '{"spec":{"issuerRef":{"name":"letsencrypt-staging"}}}'

这应该会触发 cert-manager 续订证书:使用 cmctl 检查。

cmctl status certificate www
cmctl inspect secret www-tls

最后,当新的证书颁发后,你必须重新启动 Web 服务器才能使用它。

kubectl rollout restart deployment helloweb

你现在应该能够再次连接到网站,但这次你将看到 Let's Encrypt 暂存证书。

$ curl -v --insecure https://www.$DOMAIN_NAME
...
* Server certificate:
* subject: CN=www.cert-manager-tutorial-22.site
* start date: Jan 5 12:41:14 2023 GMT
* expire date: Apr 5 12:41:13 2023 GMT
* issuer: C=US; O=(STAGING) Let's Encrypt; CN=(STAGING) Artificial Apricot R3
* SSL certificate verify result: unable to get local issuer certificate (20), continuing anyway.
...
Hello, world!
Protocol: HTTP/2.0!
Hostname: helloweb-9b8bcdd56-6rxm8

⚠️ 我们在这里再次使用 curl 的 --insecure 选项,因为 Let's Encrypt 暂存颁发机构创建了不受信任的证书。接下来您将学习如何创建由 Let's Encrypt 生产颁发机构签署的可信证书。

创建生产就绪证书

现在一切都在 Let's Encrypt 暂存服务器上正常运行,我们可以切换到生产服务器并获得可信证书。

通过复制暂存 ClusterIssuer YAML 并修改服务器 URL 和名称来创建 Let's Encrypt 生产颁发机构,然后应用它。

# clusterissuer-lets-encrypt-production.yaml
apiVersion: cert-manager.io/v1
kind: ClusterIssuer
metadata:
name: letsencrypt-production
spec:
acme:
server: https://acme-v02.api.letsencrypt.org/directory
email: $EMAIL_ADDRESS
privateKeySecretRef:
name: letsencrypt-production
solvers:
- dns01:
azureDNS:
resourceGroupName: $AZURE_DEFAULTS_GROUP
subscriptionID: $AZURE_SUBSCRIPTION_ID
hostedZoneName: $DOMAIN_NAME
environment: AzurePublicCloud
managedIdentity:
clientID: $USER_ASSIGNED_IDENTITY_CLIENT_ID

🔗 clusterissuer-lets-encrypt-production.yaml

envsubst < clusterissuer-lets-encrypt-production.yaml | kubectl apply -f -

检查 ClusterIssuer 的状态。

kubectl describe clusterissuer letsencrypt-production

修补证书以使用生产 ClusterIssuer。

kubectl patch certificate www --type merge -p '{"spec":{"issuerRef":{"name":"letsencrypt-production"}}}'

这应该会触发 cert-manager 续订证书:使用 cmctl 检查。

cmctl status certificate www
cmctl inspect secret www-tls

最后,当新的证书颁发后,你必须重新启动 Web 服务器才能使用它。

kubectl rollout restart deployment helloweb

现在您应该能够安全地连接到 Web 服务器,而无需使用 --insecure 标志,并且如果您在 Web 浏览器中访问该网站,它应该在 URL 旁边显示一个挂锁 (🔒) 符号。

curl -v https://www.$DOMAIN_NAME
...
* Server certificate:
* subject: CN=cert-manager-tutorial-22.site
* start date: Nov 30 15:41:40 2022 GMT
* expire date: Feb 28 15:41:39 2023 GMT
* subjectAltName: host "www.cert-manager-tutorial-22.site" matched cert's "www.cert-manager-tutorial-22.site"
* issuer: C=US; O=Let's Encrypt; CN=R3
* SSL certificate verify ok.
...

本教程到此结束。您已经学习了如何在 Azure AKS 上部署 cert-manager 以及如何配置它以使用 DNS-01 协议与 Azure DNS 颁发 Let's Encrypt 签署的证书。您已经了解了 Azure 中的工作负载身份联合,并学习了如何配置 cert-manager 以使用 Kubernetes ServiceAccount 令牌对 Azure 进行身份验证。

清理

完成本教程后,您可以通过以下方式删除集群、域名和托管身份来清理。

az aks delete --name $CLUSTER
az network dns zone delete --name $DOMAIN_NAME
az identity delete --name $USER_ASSIGNED_IDENTITY_NAME

下一步

📖 阅读其他 cert-manager 教程入门指南.

📖 了解有关 使用 Azure DNS 配置 cert-manager ACME 颁发机构 的更多信息。