注意: 这篇博客文章简要介绍了 Workload Identity 如何与 Azure Kubernetes Service (AKS) 一起工作。在开始之前,请确保安装了 Azure CLI (
az
)、Helm、Kubectl CLI 和 Terraform CLI。
在这里,我将展示如何利用带有联合凭证的工作负载身份功能来实现零信任策略。
图1 本博客设置情况概述
最初,(1)我们将使用Terraform来配置Azure Kubernetes Service (AKS)、DNS、托管身份,并设置必要的凭据联合。接下来,(2)我们将使用Helm来部署Cert-Manager,从而使用托管身份来管理DNS记录,以应对DNS-01挑战。
注意: 我们将使用一个 Terraform 模块来部署一个加固的 Azure Kubernetes 服务 (AKS),可以直接用于生产。按照最佳实践,将禁用本地管理员账户。你需要使用 Kubelogin 登录 AKS。
我们使用此仓库(this repository)来提供所有必要的资源。如果不需要Key Vault,可以删除它,或保留以演示如何使用Workload Identity与外部密钥控制器一起工作。
首先,让我们先修改一下 terraform.tfvars
文件里的值:
# DNS azure_cloud_zone = "midemo.example.com" # Kubernetes kubernetes_version = "1.29.4" orchestrator_version = "1.29.4" name = "midemo-development" node_pool_count = "3" vm_size = "Standard_B4ms" local_account_disabled = true load_balancer_sku = "负载均衡器SKU" admin_list = ["8a..."] oidc_issuer_enabled = true workload_identity_enabled = true # 密钥保管库 key_vault_name = "kv-midemo-c-dev-713" key_vault_admin_object_ids = ["8a...."] # 标签 tags = { TF-Managed = "true" Environment = "开发环境" }
您只需修改这些参数:azure_cloud_zone
,name
和 admin_list
,就可以授予 AKS 管理员权限。
现在,让我们来启动提供者这一环节:
terraform init # 初始化 Terraform
然后制定计划:
运行 `terraform plan -var-file=terraform.tfvars` 命令。
最后,应用这些更改:
terraform apply -var-file=terraform.tfvars --auto-approve
运行此命令来应用Terraform配置文件,自动确认无需手动输入。
你现在应该在Azure 门户看到这些创建的AKS、DNS区域和托管身份等,如下图所示:
图2:托管身份 — Azure角色分配:
如图3所示,你可以看到我们在cert-manager
命名空间中的cert-manager
服务账户中有联合证书。模式"system:serviceaccount:<命名空间>:<服务账户>"用于指代特定Kubernetes命名空间中的服务账户。
图3:到cert-manager命名空间中ServiceAccount的联邦证书(联邦凭证)
在继续到下一部分之前,我们需要获取clusterissuer-dns.yaml
文件(这个文件名保持英文)所需信息,以便建立Cert-Manager与工作负载身份之间的关联。
运行下面的命令来获取所需的数据:
terraform 输出结果 # 输出示例 cert_manager_managed_identity_client_id = "a802ae41-20fc-4cf1-a06a-93aea89da5f7" cert_manager_managed_identity_标识ID = "8f3c6988-a17a-4a5d-826a-d03c63d3fb4e" external_dns_managed_identity_client_id = "a376711c-0152-4b72-b3ce-2b348e29ec16" external_dns_managed_identity_标识ID = "80b0445f-f3e2-4e5a-b6d3-7f71559322df" external_secrets_operator_managed_identity_client_id = "563471e9-3fe8-4fb3-9cdd-a228e1329312" external_secrets_operator_managed_identity_标识ID = "69811382-ae44-448b-b671-ee1e3fb50c85" oidc_url = "https://westeurope.oic.prod-aks.azure.com/...."
保存好 oidc_url
和 cert_manager_managed_identity_client_id
。
最后,使用以下命令连接到AKS:
az aks login --name <myAKSCluster> --resource-group <myResourceGroup>
将<myAKSCluster>替换为你的集群名称,将<myResourceGroup>替换为你的资源组名称。
az aks get-credentials --resource-group rg-<REPLACE_ME>-development平台 --name aks-<REPLACE_ME>-development
在基础设施准备就绪后,你可以开始创建values.yaml
文件,使用以下值:
installCRDs: true podLabels: azure.workload.identity/use: "true" serviceAccount: labels: azure.workload.identity/use: "true"
我们需要首先添加Cert Manager Helm Chart的仓库地址,然后更新它,具体步骤如下:
运行以下命令来添加和更新 helm 仓库。
helm repo add jetstack https://charts.jetstack.io
helm repo update.
创建 Cert-Manager 的命名空间:
运行以下命令来创建一个新的命名空间 cert-manager
:
kubectl create ns cert-manager
将 Cert-Manager 部署到创建的命名空间,使用以下命令:
helm template cert-manager jetstack/cert-manager -f values.yaml --namespace cert-manager | kubectl apply -f -
使用上述命令序列,可以将 cert-manager
模板应用到 Kubernetes 集群中,并将其部署到指定的命名空间中。
这将根据 values.yaml
文件中的配置来生成并应用资源定义。
为DNS-01验证创建ClusterIssuer,请按照以下步骤来做:
创建一个名为 clusterissuer-dns.yaml
的 YAML 文件,内容如下:
apiVersion: cert-manager.io/v1 kind: 集群颁发者 (jíqún fànbǎozhě) metadata: name: letsencrypt-dns 规范: (guīfàn) acme: server: https://acme-v02.api.letsencrypt.org/directory email: your-email@example.com privateKeySecretRef: name: letsencrypt-dns solvers: - dns01: azureDNS: subscriptionID: "your-subscription-id" resourceGroupName: "your-resource-group" hostedZoneName: "your-hosted-zone.com" environment: Azure公共云 (Azure gōnggòng yún) managedIdentity: clientID: "your-managed-identity-client-id"
将占位符替换为具体值吧
your-email@example.com
用您的电邮地址your-subscription-id
用您的 Azure 订阅 IDyour-resource-group
用您的 Azure 资源组名your-hosted-zone.com
用您的 Azure DNS 主机区域名your-managed-identity-client-id
用您的托管标识客户端 ID(来自 terraform 输出的)使用_kubectl_来应用清单:
kubectl apply -f clusterissuer-dns.yaml
执行此命令来应用 clusterissuer-dns.yaml 文件。
现在,你应该能看到,ClusterIssuer 成功注册了,
图4:ACME账号是在ACME服务器上注册的
现在,为了演示的目的,试一下设置是否正常工作,如下所示,使用下面的命令:
cat <<EOF | kubectl apply -f - apiVersion: cert-manager.io/v1 kind: Certificate metadata: name: test-certificate namespace: default spec: secretName: test-tls issuerRef: name: letsencrypt-dns kind: ClusterIssuer commonName: test.midemo.example.com dnsNames: - test.midemo.example.com EOF
现在,你应该在你的域名下看到一些东西,类似这样的条目:
图5: Cert-Manager(证书管理器)— DNS-01 挑战界面
若想了解更多幕后的技术细节,欢迎访问我的博客文章:利用 Azure IAM 优化您的 Kubernetes 资源:托管身份和工作负载身份!
利用 Azure IAM 优化您的 Kubernetes 资源:托管身份与工作负载身份
恭喜你!您已成功为 Azure Workload Identity 的 DNS-01 挑战设置 Cert-Manager,并采用了零信任模式。此设置允许您的 Kubernetes 工作负载在无需静态凭据的情况下安全地管理 Azure 中的 DNS 记录。通过这些步骤,您不仅提高了 DNS 管理的安全性,还简化了其操作。做得好!👏
不过要记得:
图6:零信任
有疑问、想聊天,或者只是想保持联系吗?不要在Medium的评论区留言,我们可以在LinkedIn联系 🤙。别忘了订阅Medium Newsletter,这样你就不会错过任何更新哦!