为了账号安全,请及时绑定邮箱和手机立即绑定

Kubernetes: 使用 Azure 身份进行 DNS-01 挑战的证书管理器

通过联合身份凭证提升工作负载的安全性

注意: 这篇博客文章简要介绍了 Workload Identity 如何与 Azure Kubernetes Service (AKS) 一起工作。在开始之前,请确保安装了 Azure CLI (az)、HelmKubectl CLITerraform CLI

在这里,我将展示如何利用带有联合凭证的工作负载身份功能来实现零信任策略。

图1 本博客设置情况概述

最初,(1)我们将使用Terraform来配置Azure Kubernetes Service (AKS)、DNS、托管身份,并设置必要的凭据联合。接下来,(2)我们将使用Helm来部署Cert-Manager,从而使用托管身份来管理DNS记录,以应对DNS-01挑战。

配置環境——讓我們用Terraform來配置環境

注意: 我们将使用一个 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_zonenameadmin_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_urlcert_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
使用 Helm 部署带有工作负载身份的 Cert-Manager

在基础设施准备就绪后,你可以开始创建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 订阅 ID
  • your-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,这样你就不会错过任何更新哦!

点击查看更多内容
TA 点赞

若觉得本文不错,就分享一下吧!

评论

作者其他优质文章

正在加载中
  • 推荐
  • 评论
  • 收藏
  • 共同学习,写下你的评论
感谢您的支持,我会继续努力的~
扫码打赏,你说多少就多少
赞赏金额会直接到老师账户
支付方式
打开微信扫一扫,即可进行扫码打赏哦
今天注册有机会得

100积分直接送

付费专栏免费学

大额优惠券免费领

立即参与 放弃机会
意见反馈 帮助中心 APP下载
官方微信

举报

0/150
提交
取消