在部署签名的映像到 Azure Kubernetes 服务 (AKS) 群集(预览版)之前,请使用映像完整性对其进行验证

Azure Kubernetes 服务 (AKS) 及其基础容器模型为云原生应用程序提供了更高的可伸缩性和可管理性。 借助 AKS,可以根据系统的运行时需求启动灵活的软件应用程序。 但是,这种灵活性可能会带来新的挑战。

在这些应用程序环境中,使用签名的容器映像有助于验证部署由受信任的实体生成,并且映像自创建以来没有被篡改过。 映像完整性是一项服务,可用于添加Azure Policy 内置定义,以验证是否仅将签名的映像部署到 AKS 群集。

注意

映像完整性是基于批准的一项功能。 在 AKS 群集上,功能名称和属性名称为 ImageIntegrity,而相关的映像完整性 pod 名称包含 Ratify

重要

AKS 预览功能是可选择启用的自助功能。 预览功能是“按现状”和“按可用”提供的,不包括在服务级别协议和有限保证中。 AKS 预览功能是由客户支持尽最大努力部分覆盖。 因此,这些功能并不适合用于生产。 有关详细信息,请参阅以下支持文章:

先决条件

  • Azure 订阅。 如果你没有 Azure 订阅,可以创建一个试用版订阅

  • Azure CLIAzure PowerShell

  • aks-preview CLI 扩展版本 0.5.96 或更高版本。

  • 确保在群集上启用了适用于 AKS 的Azure Policy 加载项。 如果尚未安装此加载项,请参阅安装 Azure Policy AKS 加载项

  • 使用 OIDC 颁发者启用的 AKS 群集。 若要创建新群集或更新现有群集,请参阅使用 OIDC 颁发者配置 AKS 群集

  • 在 Azure 订阅上注册的 EnableImageIntegrityPreviewAKS-AzurePolicyExternalData 功能标志。 使用以下命令注册功能标志:

    1. 使用 az feature register 命令注册 EnableImageIntegrityPreviewAKS-AzurePolicyExternalData 功能标志。

      # Register the EnableImageIntegrityPreview feature flag
      az feature register --namespace "Microsoft.ContainerService" --name "EnableImageIntegrityPreview"
      
      # Register the AKS-AzurePolicyExternalData feature flag
      az feature register --namespace "Microsoft.ContainerService" --name "AKS-AzurePolicyExternalData"
      

      可能需要花费几分钟时间,状态才会显示为“已注册”。

    2. 使用 az feature show 命令验证注册状态。

      # Verify the EnableImageIntegrityPreview feature flag registration status
      az feature show --namespace "Microsoft.ContainerService" --name "EnableImageIntegrityPreview"
      
      # Verify the AKS-AzurePolicyExternalData feature flag registration status
      az feature show --namespace "Microsoft.ContainerService" --name "AKS-AzurePolicyExternalData"
      
    3. 当状态显示“已注册”时,使用 az provider register 命令刷新 Microsoft.ContainerService 资源提供程序的注册。

      az provider register --namespace Microsoft.ContainerService
      

注意事项和限制

  • AKS 群集必须运行 Kubernetes 版本 1.26 或更高版本。
  • 不应将此功能用于生产 Azure 容器注册表 (ACR) 注册或工作负载。
  • 映像完整性在群集范围内可支持最多 200 个唯一签名并发。
  • 表示法是唯一受支持的验证程序。
  • 审核是唯一受支持的验证策略效果。

映像完整性的工作原理

屏幕截图显示映像完整性的基本体系结构。

映像完整性在部署签名的映像到 AKS 群集之前,使用批准、Azure Policy 和 Gatekeeper 来验证这些映像。 在群集上启用映像完整性将会部署 Ratify Pod。 此 Ratify 方法执行以下任务:

  1. 依据通过 Ratify CRD 设置的配置,协调来自 Azure 密钥保管库的证书。
  2. 当验证请求来自 Azure Policy 时,访问存储在 ACR 中的图像。 若要启用此体验,Azure Policy 扩展了 Gatekeeper,这是用于开放策略代理 (OPA) 的允许控制器 Webhook。
  3. 确定目标映像是否使用受信任的证书进行签名,从而是否将其视为“受信任的”证书。
  4. AzurePolicyGatekeeper 使用验证结果作为符合性状态,以决定是否允许部署请求。

在 AKS 群集上启用映像完整性

注意

映像签名验证是一种以治理为导向的方案,利用 Azure Policy 大规模验证 AKS 群集上的映像签名。 建议使用 AKS 的映像完整性内置 Azure Policy 计划,该计划在 Azure Policy 的内置定义库中提供。

  • 使用 [Preview]: Use Image Integrity to ensure only trusted images are deployed 命令通过 AKS 策略计划az policy assignment create创建策略分配。

    export SCOPE="/subscriptions/${SUBSCRIPTION}/resourceGroups/${RESOURCE_GROUP}"
    export LOCATION=$(az group show --name ${RESOURCE_GROUP} --query location -o tsv)
    
    az policy assignment create --name 'deploy-trustedimages' --policy-set-definition 'af28bf8b-c669-4dd3-9137-1e68fdc61bd6' --display-name 'Audit deployment with unsigned container images' --scope ${SCOPE} --mi-system-assigned --role Contributor --identity-scope ${SCOPE} --location ${LOCATION}
    

    Ratify Pod 将在启用该功能后部署。

注意

当策略检测到群集上有任何更新操作时,它会在群集上部署映像完整性功能。 如果要立即启用该功能,则需要使用 az policy remediation create 命令创建策略修正。

assignment_id=$(az policy assignment show --name 'deploy-trustedimages' --scope ${SCOPE} --query id -o tsv)
az policy remediation create --policy-assignment "$assignment_id" --definition-reference-id deployAKSImageIntegrity --name remediation --resource-group ${RESOURCE_GROUP}

设置验证配置

若要正确验证目标签名映像的映像完整性,需要使用 kubectl 通过 K8s CRD 设置 Ratify 配置。

在本文中,我们使用来自官方批准文档的自签名 CA 证书来设置验证配置。 有关更多示例,请参阅批准 CRD

  1. 创建名为 verify-config.yamlVerifyConfig 文件,并将其复制到以下 YAML 中:

    apiVersion: config.ratify.deislabs.io/v1beta1
    kind: CertificateStore
    metadata:
      name: certstore-inline
    spec:
      provider: inline
      parameters:
        value: |
          -----BEGIN CERTIFICATE-----
          MIIDQzCCAiugAwIBAgIUDxHQ9JxxmnrLWTA5rAtIZCzY8mMwDQYJKoZIhvcNAQEL
          BQAwKTEPMA0GA1UECgwGUmF0aWZ5MRYwFAYDVQQDDA1SYXRpZnkgU2FtcGxlMB4X
          DTIzMDYyOTA1MjgzMloXDTMzMDYyNjA1MjgzMlowKTEPMA0GA1UECgwGUmF0aWZ5
          MRYwFAYDVQQDDA1SYXRpZnkgU2FtcGxlMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8A
          MIIBCgKCAQEAshmsL2VM9ojhgTVUUuEsZro9jfI27VKZJ4naWSHJihmOki7IoZS8
          3/3ATpkE1lGbduJ77M9UxQbEW1PnESB0bWtMQtjIbser3mFCn15yz4nBXiTIu/K4
          FYv6HVdc6/cds3jgfEFNw/8RVMBUGNUiSEWa1lV1zDM2v/8GekUr6SNvMyqtY8oo
          ItwxfUvlhgMNlLgd96mVnnPVLmPkCmXFN9iBMhSce6sn6P9oDIB+pr1ZpE4F5bwa
          gRBg2tWN3Tz9H/z2a51Xbn7hCT5OLBRlkorHJl2HKKRoXz1hBgR8xOL+zRySH9Qo
          3yx6WvluYDNfVbCREzKJf9fFiQeVe0EJOwIDAQABo2MwYTAdBgNVHQ4EFgQUKzci
          EKCDwPBn4I1YZ+sDdnxEir4wHwYDVR0jBBgwFoAUKzciEKCDwPBn4I1YZ+sDdnxE
          ir4wDwYDVR0TAQH/BAUwAwEB/zAOBgNVHQ8BAf8EBAMCAgQwDQYJKoZIhvcNAQEL
          BQADggEBAGh6duwc1MvV+PUYvIkDfgj158KtYX+bv4PmcV/aemQUoArqM1ECYFjt
          BlBVmTRJA0lijU5I0oZje80zW7P8M8pra0BM6x3cPnh/oZGrsuMizd4h5b5TnwuJ
          hRvKFFUVeHn9kORbyQwRQ5SpL8cRGyYp+T6ncEmo0jdIOM5dgfdhwHgb+i3TejcF
          90sUs65zovUjv1wa11SqOdu12cCj/MYp+H8j2lpaLL2t0cbFJlBY6DNJgxr5qync
          cz8gbXrZmNbzC7W5QK5J7fcx6tlffOpt5cm427f9NiK2tira50HU7gC3HJkbiSTp
          Xw10iXXMZzSbQ0/Hj2BF4B40WfAkgRg=
          -----END CERTIFICATE-----
    ---
    apiVersion: config.ratify.deislabs.io/v1beta1
    kind: Store
    metadata:
      name: store-oras
    spec:
      name: oras
    # If you want to you use Workload Identity for Ratify to access Azure Container Registry,
    # uncomment the following lines, and fill the proper ClientID:
    # See more: https://ratify.dev/docs/reference/oras-auth-provider
    # parameters:
    #  authProvider:
    #    name: azureWorkloadIdentity
    #    clientID: XXX
    ---
    apiVersion: config.ratify.deislabs.io/v1beta1
    kind: Verifier
    metadata:
      name: verifier-notary-inline
    spec:
      name: notation
      artifactTypes: application/vnd.cncf.notary.signature
      parameters:
        verificationCertStores:  # certificates for validating signatures
          certs: # name of the trustStore
            - certstore-inline # name of the certificate store CRD to include in this trustStore
        trustPolicyDoc: # policy language that indicates which identities are trusted to produce artifacts
          version: "1.0"
          trustPolicies:
            - name: default
              registryScopes:
                - "*"
              signatureVerification:
                level: strict
              trustStores:
                - ca:certs
              trustedIdentities:
                - "*"
    
  2. 使用 kubectl apply 命令将 VerifyConfig 应用到群集。

    kubectl apply -f verify-config.yaml
    

将示例映像部署到 AKS 群集

  • 使用 kubectl run demo 命令部署签名的映像。

    kubectl run demo-signed --image=ghcr.io/deislabs/ratify/notary-image:signed 
    

    下面示例输出显示映像完整性允许进行部署:

    ghcr.io/deislabs/ratify/notary-image:signed
    pod/demo-signed created
    

如果要使用自己的映像,请参阅映像签名指南

禁用映像完整性

  • 使用带 --disable-image-integrity 标记的 az aks update 命令禁用群集上的映像完整性。

    az aks update --resource-group myResourceGroup --name MyManagedCluster --disable-image-integrity
    

移除策略计划

后续步骤

本文介绍了在部署签名映像到 Azure Kubernetes 服务 (AKS) 群集之前,如何使用映像完整性对其进行验证。 若要了解如何对自己的容器进行签名,请参阅使用 Notary 和 Azure 密钥保管库(预览版)生成、签名和验证容器映像