aliyun-acr-credential-helper是一个可以在ACK集群中免密拉取ACR默认版或企业版私有镜像的组件。该组件会默认安装在所有ACK集群中。本文列举四个场景介绍如何使用免密组件拉取私有镜像。

前提条件

创建Kubernetes托管版集群
注意
  • 在Kubernetes资源(例如无状态应用Deployment)模板中配置拉取凭证(imagePullSecret)会导致免密组件失效,如果需使用免密组件,请避免手工配置拉取凭证(imagePullSecret)。
  • 如果部署的Kubernetes资源(例如无状态应用Deployment)使用了自定义的ServiceAccount,需先调整免密组件配置文件中Service-Account字段,使其作用于自定义的ServiceAccount,再进行部署资源操作。
  • 确认Kubernetes集群所属地域与要拉取的镜像所在的地域是否一致,默认配置只可以拉取本地域的镜像。如果需要跨地域拉取镜像,请参见下面的场景三。
  • 使用自定义RAM角色的AccessKey ID和AccessKey Secret进行镜像拉取的情况下,需要把访问密钥写入configMap,这样存在一定的密钥泄露风险。请确定AccessKey ID和AccessKey Secret所属的RAM角色只拥有拉取容器镜像的相关权限。

背景信息

免密组件通过读取ACK集群内的kube-system命名空间中的acr-configuration的配置,进行私有镜像拉取。当前支持针对私有镜像仓库使用以下三种权限之一的策略进行配置:
  • 使用默认的ACK Worker RAM角色权限进行拉取(默认策略)。
  • 使用自定义RAM角色的AccessKey ID和AccessKey Secret的权限进行拉取。
  • 通过配置RAM AssumeRole权限, 使用其他用户的权限进行拉取。

使用免密组件涉及的镜像及集群限制如下:

  • 镜像
    • 支持拉取容器镜像服务企业版实例和默认实例中的私有镜像。
    • 支持拉取集群当前用户容器镜像服务中的私有镜像,通过跨账号授权或AccessKey ID和AccessKey Secret配置可以拉取其他用户的私有镜像。
    • 支持跨地域拉取容器镜像服务中的私有镜像。
  • 集群
    • 支持集群多命名空间免密拉取。
    • 支持的集群类型:
      • 专有版Kubernetes集群。
      • 托管版Kubernetes集群。
    • 支持的集群版本:
      • 专有版Kubernetes集群:高于或等于1.11.2的版本默认支持免密拉取镜像。低于1.11.2版本请您手动升级,请参见升级集群
      • 托管版Kubernetes集群:所有版本。

升级组件并对组件进行配置

在使用免密组件拉取镜像前,您可能需要升级组件并对组件进行配置,操作步骤如下。

  1. 升级组件。
    1. 登录容器服务管理控制台
    2. 在控制台左侧导航栏中,单击集群
    3. 集群列表页面,单击目标集群操作列下的更多 > 系统组件管理
    4. 在组件列表区域中找到aliyun-acr-credential-helper,单击升级
  2. 配置组件。
    1. 登录容器服务管理控制台
    2. 在控制台左侧导航栏中,单击集群
    3. 集群列表页面,单击目标集群下的详情
    4. 集群信息页面左侧导航栏,选择应用配置 > 配置项
    5. 配置项页面,单击目标配置项名称,单击编辑,修改配置项名称。

      如果您没有该配置项,请参见创建配置项。更新配置项,请参见修改配置项

      以下是一个组件的YAML配置示例。

      • 企业版实例:
        acr-registry-info: |
             - instanceId: cri-xxx
               regionId: cn-hangzhou
               domains: xxx.com,yyy.com
        watch-namespace: "all"
        service-account: "default"
        expiring-threshold: "15m"
      • 默认版实例:
        acr-registry-info: |
        watch-namespace: "all"
        service-account: "default"
        expiring-threshold: "15m"
      配置项 配置项说明 默认值
      service-account 使免密组件作用于指定的服务账号。 Default。
      说明 如果要配置多个请以逗号分隔, 如果设置为“*”, 表示支持Namespace下的所有ServiceAccount。
      acr-registry-info 容器镜像的实例信息数组,YAML多行字符串格式,每个实例以三元组方式配置。
      说明 实例信息三元组:
      • instanceId:实例ID,企业版实例必须配置此项。
      • regionId:可选,默认为本地地域。
      • domains:可选,默认为相应实例的所有域名。若要指定个别域名,多个以逗号分隔。
      空,表示免密拉取本地地域的默认容器镜像实例仓库。
      watch-namespace 期望能免密拉取镜像的Namespace。 Default。
      说明 当取值为ALL时,表示期望所有Namespace都能免密拉取。如果需要配置多个Namespace时,以逗号分隔。
      expiring-threshold 本地Cache Token过期阈值。 15 m(建议使用15 m)。

场景一:配置跨账号拉取权限

跨账号拉取权限分为:
  • 使用角色扮演进行跨账号拉取:A用户扮演B用户的角色拉取B用户的私有镜像。
  • 使用自定义RAM角色的访问密钥进行跨账号私有镜像拉取:需要使用指定的用户的权限拉取特定的私有镜像。

使用角色扮演进行跨账号拉取

说明
配置原则如下:
  1. B用户(RAM角色)可以拉取指定私有仓库下的私有镜像(B用户RAM角色有cr.*相关的权限)。
  2. B用户(RAM角色)允许让A用户下的ACK Worker RAM角色扮演(信任策略)。
  3. A用户下的ACK集群的Worker RAM角色有扮演B用户(RAM角色)的权限(AliyunAssumeRoleAccess)。
  4. 设置A用户下的Worker RAM角色扮演B用户(configMap中的assumeRoleARN)。
  1. 创建B用户的受信实体为阿里云账号类型的RAM角色,并确保该RAM角色拥有拉取B用户私有镜像的权限。
    1. 创建RAM角色。
    2. 自定义RAM角色权限策略内容,确保该RAM角色拥有拉取B用户私有镜像的权限。
      具体操作请参见修改自定义策略内容
      注意 请确保该RAM角色有cr.*的相关权限。
      ```
      {
      "Action": [
       "cr:GetAuthorizationToken",
       "cr:ListInstanceEndpoint",
       "cr:PullRepository"
      ],
      "Resource": [
      "*"
      ],
      "Effect": "Allow"
      }
      
      ```
      添加字段位置如下图所示。RAM有CR的相关权限
  2. 在创建的B用户的RAM角色上配置信任策略,允许A用户(需要拉取B用户下的私有镜像)的ACK集群的Worker RAM角色来扮演B用户。在策略内容Principal处填写A用户的ACK集群的Worker RAM角色的ARN。
    1. 查看A用户的ACK集群的Worker RAM角色的ARN信息。
      查看ARN信息具体步骤,请参见如何查看RAM角色的ARN?
    2. 配置信任策略。
      1. RAM控制台左侧导航栏,单击RAM角色管理,找到目标RAM角色并单击RAM角色名称。
      2. 在RAM角色基本信息页,单击信任策略管理页签,然后使用A用户的Worker RAM角色的ARN修改信任策略。RamRoleARN
  3. 确认A用户的Worker RAM角色拥有AssumeRole权限。AssumeRule权限
    具体操作步骤,请参见查看权限策略基本信息
  4. 调整组件配置,新增assumeRoleARN配置。

    配置内容为B用户Worker RAM角色的ARN。查看ARN信息具体步骤,请参见如何查看RAM角色的ARN?YAML配置示例如下。配置步骤,请参见上述配置组件

    data:   
        service-account: "default"
        watch-namespace: "all"
        expiring-threshold: "15m"
        notify-email: "cs@aliyuncs.com"
        acr-registry-info: |
        - instanceId: ""
           regionId: cn-beijing
           domains: registry.cn-beijing.aliyuncs.com
           assumeRoleARN: acs:ram::.*:role/kubernetesworkerrole-test

使用RAM用户的访问密钥拉取跨账号私有镜像

  1. 创建一个RAM用户并为该用户添加cr镜像拉取权限。
    有关配置cr镜像拉取权限的具体操作步骤,请参见使用角色扮演进行跨账号拉取步骤1
  2. 配置kube-system命名空间中的配置项acr-configuration,并填入创建的RAM用户的访问密钥AccessKey ID和AccessKey Secret。
    此种方式可以使免密组件直接使用创建的RAM用户拉取私有镜像。查看访问密钥的具体步骤,请参见查看访问密钥基本信息

    配置示例如下。配置步骤请参见上述配置组件

    data:   
        service-account: "default"
        watch-namespace: "all"
        expiring-threshold: "15m"
        notify-email: "cs@aliyuncs.com"
        acr-registry-info: |
        - instanceId: ""
          customAccessKey: "xxxxx" // 此处填写刚创建的RAM用户的AccessKey ID。
          customAccessKeySecret: "xxxxxx" // 此处填写刚创建的RAM用户的AccessKey Secret。

场景二:配置当前账号拉取权限

您需要检查当前账号ACR拉取的权限。

  1. 登录容器服务管理控制台
  2. 在控制台左侧导航栏中,单击集群
  3. 集群列表页面中,单击目标集群名称或者目标集群右侧操作列下的详情
  4. 集群信息页面,单击集群资源页签,单击Worker RAM角色右侧链接。
  5. 在RAM角色基本信息的权限管理页签,单击目标权限策略名称
  6. 单击修改策略内容
  7. 策略内容区域增加以下字段后,单击确定
    {
      "Action": [
        "cr:Get*",
        "cr:List*",
        "cr:PullRepository"
      ],
      "Resource": "*",
      "Effect": "Allow"
    }
    添加字段位置如下图所示。RAM有CR的相关权限
说明 您还需要检查Pod中镜像字段的值是否存在于ACR仓库里面。
  • 如果存在,但不在当前账号下,您可能需要使用跨账号镜像拉取(参考场景一)。
  • 如果存在,且在当前账号下,您可以提交工单
  • 如果不存在,您需要确认该镜像是否存在于阿里云容器镜像服务上。如果不存在,则需要同步外部镜像到阿里云容器镜像服务商,或者变更改镜像为公网可拉取状态。

场景三:配置跨地域拉取镜像权限

如果需要拉取的镜像与当前ACK集群不属于同一地域的时候,需要修改配置项acr-configuration中的configMap

例如,默认仓库同时拉取北京地域与杭州地域的镜像,配置如下。配置步骤请参见上述配置组件

data:   
    service-account: "default"
    watch-namespace: "all"
    expiring-threshold: "15m"
    notify-email: "cs@aliyuncs.com"
    acr-registry-info: |
    - instanceId: ""
       regionId: cn-beijing
    - instanceId: ""
       regionId: cn-hangzhou
            

场景四:同时拉取默认实例和企业实例的私有镜像

如需同时拉取默认实例和企业版实例的私有镜像,请按照以下方式修改配置项acr-configuration中的configMap。配置步骤请参见上述配置组件
data:   
    service-account: "default"
    watch-namespace: "all"
    expiring-threshold: "15m"
    notify-email: "cs@aliyuncs.com"
    acr-registry-info: |
    - instanceId: ""
    - instanceId: "cri-xxxx"