使用免密组件跨账号拉取镜像

在阿里云多账号体系中,容器服务ACK集群与容器镜像服务ACR企业版实例可能由不同业务组织的不同账号管理,需要确保网络互联并且账号得到授权才能实现ACKACR拉取容器镜像部署工作负载。本文介绍如何使用aliyun-acr-credential-helper免密组件跨账号拉取镜像。

选型思路

建议您优先考虑满足业务需求的网络连接方式和账号授权方式,再选择支持该授权方式的免密组件。

具体操作步骤请按照配置网络连接配置账号授权和免密组件的流程,并完成验证跨账号镜像拉取
image
说明

本文的跨账号指的是不同阿里云账号(主账号),而非RAM用户(子账号)

前提条件

  • 已为免密组件使用的RAM角色授权

  • ACK集群已支持使用免密组件。

    • aliyun-acr-credential-helper(托管形态)

      • 1.22及以上版本的ACK托管集群Pro

      • 1.22及以上版本的ACK Serverless集群

      • 1.22及以上版本的ACK Edge集群

    • aliyun-acr-credential-helper(自行运维)

      • 1.20.0及以上版本的ACK托管集群基础版

      • 1.20.0及以上版本的ACK托管集群Pro

      • 1.20.0及以上版本的ACK专有集群

  • 容器镜像服务ACR实例类型为企业版实例。

    重要
    • 免密组件目前仅支持与ACR企业版及20240908日及更早创建的ACR个人版配合使用。

    • 20240909日及之后新建的ACR个人版不支持使用免密组件。使用新建的ACR个人版实例时,建议通过Secret保存用户名与登录密码的方式,在imagePullSecrets字段中使用。

操作步骤

步骤一:配置网络连接

跨账号拉取镜像时,需要拉取镜像的ACK集群与镜像所在的ACR企业版实例处于不同用户账户下的不同VPC,并有可能处于不同地域,在拉取镜像前需要确保双方的网络连通和相关域名可解析,有以下几种实现方式:

  • 公网连接:即为ACR企业版实例配置公网端点,并为ACK集群开启访问公网的能力,双方通过公网传输镜像。但通过公网传输安全性较低,并会产生弹性公网IP与流量费用。

  • VPC对等连接:您可使用VPC对等连接打通两个VPC,使ACK集群可以访问ACR企业版实例。VPC处于同一地域时,对等连接功能不收取费用,处于不同地域时收费。但使用功能需要两个VPC共享网段,会导致VPC网段减少。并且,如果两个VPC中已使用的网段大量重合,您需要对现存网络架构进行改造。

  • 云企业网连接:1个云企业网实例可包含1个或多个转发路由器,多个转发路由器之间可通过跨地域连接互联,从而实现跨地域跨账号VPC互通。

关于VPC对等连接和云企业网连接的对比,请参见云企业网与VPC对等连接有什么区别?

对比项

公网连接

VPC对等连接

云企业网连接

网络类型

公网

私网

私网

计费

弹性公网IP计费方式产生费用。

按云企业网计费规则产生费用。

主要特点

无需对现有网络架构进行修改,安全性方面需要考虑出入方向规则、访问控制等。

  • 镜像通过内网传输,安全性较高。VPC处于同地域时不产生费用。

  • 使用该功能使两个VPC共享网段,会导致VPC可用网段减少。如果两个VPC中已使用的网段大量重合,您需要对现存网络架构进行改造。

  • 镜像通过内网传输,安全性较高。

  • 云企业网为高安全需求的企业生产环境设计。

配置流程

  1. ACR实例配置公网端点

    通过配置公网的访问控制策略,来实现远程安全地管理和访问ACR企业版实例。
  2. ACK集群开启访问公网的能力

    ACK集群配置访问外部公网资源能力,从ACR企业版实例拉取镜像。
  1. ACR实例绑定VPC内网域名解析

    打通ACR企业版实例与VPC后,才能在VPC内通过内网域名访问企业版实例。完成配置后需要获取VPC IDACR企业版实例内网访问IP地址。
  2. 获取ACR实例相关域名信息和IP地址

    获取访问ACR企业版实例使用的认证服务域名和IP地址、关联OSS Bucket域名和IP地址。
  3. 创建VPC对等连接并配置路由表

    需要在VPC对等连接的两端添加指向对端的路由条目以实现ACK集群绑定的VPCACR企业版实例绑定的VPC私网互通。ACK集群绑定的VPC对等连接端还需要配置认证服务IP地址、关联OSS BucketIP地址的路由条目。
  4. ACK集群解析ACR实例域名

    通过添加内网DNS解析节点池自定义数据脚本批量修改/etc/hosts文件等方式,为ACK集群将ACR实例域名解析为ACR实例内网访问IP地址,从而通过VPC对等连接路由条目转发到ACR实例绑定的VPC。
  1. ACR实例绑定VPC内网域名解析

    打通ACR企业版实例与VPC后,才能在VPC内通过内网域名访问企业版实例。完成配置后需要获取VPC IDACR企业版实例内网访问IP地址。
  2. 获取ACR实例相关域名信息和IP地址

    获取访问ACR企业版实例使用的认证服务域名和IP地址、关联OSS Bucket域名和IP地址。
  3. 通过CEN配置跨账号VPC互通

    ACR企业版实例绑定的VPC连接该账号地域的转发路由器,将ACK集群绑定的VPC连接该账号地域的转发路由器,然后通过跨地域连接实现两个地域间的转发路由器互通。
  4. 配置VPC和转发路由器路由表

    ACK集群绑定的VPC和转发路由器还需要配置认证服务IP地址、关联OSS BucketIP地址的路由条目。
  5. ACK集群解析ACR实例域名

    通过添加内网DNS解析节点池自定义数据脚本批量修改/etc/hosts文件等方式,为ACK集群将ACR实例域名解析为ACR实例内网访问IP地址,从而通过CEN路由条目转发到ACR实例绑定的VPC。

步骤二:配置账号授权和免密组件

以下是实现跨账号免密拉取镜像的三种授权方式,您可以根据场景需求选择最适合的配置方案。

对比项

使用RRSA

使用Worker RAM角色扮演

使用RAM用户的AKSK

集群类型

支持在1.22及以上版本的ACK托管集群基础版ACK托管集群ProACK Edge集群ACK Serverless集群Pro

支持在1.20及以上版本的ACK托管集群基础版ACK托管集群Pro、和ACK专有集群

支持在1.20及以上版本的ACK托管集群基础版ACK托管集群Pro、和ACK专有集群

支持组件

  • aliyun-acr-credential-helper托管组件

  • aliyun-acr-credential-helper组件

    需升级到v23.02.06.1-74e2172-aliyun或以上版本。

关于以上组件差异详情请参见免密组件对比

aliyun-acr-credential-helper组件

aliyun-acr-credential-helper组件

权限粒度

Pod级别(细粒度)

集群级别(中粒度)

账号级别(粗粒度)

安全性

高,提供更精细的权限控制和隔离,使用STS临时凭证,无硬编码AK/SK。

中,所有Pod共享权限,存在过度授权风险。

低,访问密钥暴露风险较大。

适用场景

适用于安全敏感型业务、需要严格权限管控的生产环境。

适用于统一权限需求的场景、有一定权限控制需求的开发和测试环境。

适用于快速部署或者demo环境。

使用RRSA

A用户账号ACK集群中,配置特定ServiceAccount扮演具有免密拉取镜像权限B用户账号RAM角色,使ACK集群能够访问并拉取B用户账号的私有镜像。

说明

启用免密组件的RRSA功能需先在集群中启用RRSA,然后配置免密组件RRSA。若顺序错误,需删除免密插件的Pod以激活RRSA功能。

image
  1. A用户账号下操作,启用ACK集群的RRSA功能,并创建支持角色扮演权限的RAM角色。

    1. ACK集群开启RRSA功能。

      1. 登录容器服务管理控制台,在左侧导航栏选择集群列表

      2. 集群列表页面,单击目标集群名称,然后在左侧导航栏,选择集群信息

      3. 基本信息页签的安全与审计区域,单击RRSA OIDC右侧的开启image

      4. 在弹出的启用RRSA对话框,单击确定

        基本信息区域,当集群状态由更新中变为运行中后,表明该集群的RRSA特性已变更完成。

      5. 集群中RRSA功能开启后,在基本信息页签的安全与审计区域,将鼠标悬浮至RRSA OIDC右侧已开启上面,即可查看提供商的URL链接和ARN信息。image

    2. 使用脚本编辑信任策略,创建OIDC身份提供商的RAM角色

      • 将示例中的<oidc_issuer_url>替换为上一步获取的当前集群中OIDC提供商的URL。

      • 将示例中的<oidc_provider_arn>替换为上一步获取的当前集群OIDC提供商的ARN。

      {
        "Statement": [
          {
            "Action": "sts:AssumeRole",
            "Condition": {
              "StringEquals": {
                "oidc:aud": "sts.aliyuncs.com",
                "oidc:iss": "<oidc_issuer_url>",
                "oidc:sub": "system:serviceaccount:kube-system:aliyun-acr-credential-helper"
              }
            },
            "Effect": "Allow",
            "Principal": {
              "Federated": [
                "<oidc_provider_arn>"
              ]
            }
          }
        ],
        "Version": "1"
      }
    3. 为该角色添加AliyunSTSAssumeRoleAccess权限以授予角色扮演能力,并记录其ARN信息。更多详情,请参见RAM角色授权

      1. 在角色详情页面的权限管理页签下,单击新增授权

      2. 新增授权面板的权限策略区域,定位并选中AliyunSTSAssumeRoleAccess权限策略,然后单击确认新增授权

      3. 在角色详情页面的基本信息区域,查看并记录该RAM角色ARN。详细操作,请参见如何查看RAM角色的ARN?

  2. B用户账号下操作,创建RAM角色授予拉取私有镜像的权限,并允许A用户账号RAM角色扮演此角色。

    1. 使用脚本编辑信任策略,创建可信实体为阿里云账号的RAM角色,允许A用户账号进行角色扮演。

      {
        "Statement": [
          {
            "Action": "sts:AssumeRole",
            "Effect": "Allow",
            "Principal": {
              "RAM": [
                "<A用户账号创建角色的ARN>"
              ]
            }
          }
        ],
        "Version": "1"
      }
    2. 使用以下内容创建自定义权限策略,并将该策略RAM角色授权,以赋予该角色获取实例信息和拉取镜像的权限。

      {
          "Version": "1",
          "Statement": [
              {
                  "Action": [
                      "cr:GetAuthorizationToken",
                      "cr:ListInstanceEndpoint",
                      "cr:PullRepository"
                  ],
                  "Resource": "*",
                  "Effect": "Allow"
              }
          ]
      }
    3. 为其设置RAM角色最大会话时间,设置为3600秒到43200秒之间,默认3600秒。

      建议确保该值与下文修改其配置项中的expireDuration一致,且expireDuration需不超过最大会话时间。
    4. 在角色详情页面的基本信息区域,查看并记录该RAM角色ARN。

  3. A用户账号下操作,为ACK集群安装免密组件并修改其配置项。

    关于以下组件差异详情请参见免密组件对比

    aliyun-acr-credential-helper托管组件

    1. 登录容器服务管理控制台,在左侧导航栏单击集群列表

    2. 集群列表页面,单击目标集群名称,然后在左侧导航栏,单击组件管理

    3. 组件管理页面,选择安全页签,找到aliyun-acr-credential-helper托管卡片,单击安装

    4. aliyun-acr-credential-helper参数配置对话框,勾选中是否开启RRSA,然后单击右侧的添加,输入以下参数,单击确定

      791184c653f445f62c3387d88ad8bdcf

      关联ACR企业版实例配置:

      参数

      描述

      示例

      instanceId

      ACR实例ID,若要指定多个,以英文半角逗号(,)分隔。

      cri-XXXXX

      regionId

      ACR实例所在的RegionID。

      cn-hangzhou

      domains

      ACR实例所使用的域名。填入的ACR实例的所有访问域名(公网、VPC)。若要指定个别域名,多个以英文半角逗号(,)分隔。

      XXXXX-registry.cn-hangzhou.cr.aliyuncs.com

      assumeRoleARN

      ACR 实例所有者的 RAM 角色 ARN。输入B用户账号下所创建的RAM角色的ARN。

      acs:ram::100XXXXXXXX9630:role/XXXX

      expireDuration

      跨账号场景下临时凭证的有效时间。输入B用户账号下所创建的RAM角色的最大会话时间。

      3600

      rrsaRoleARN

      ACK集群所有者的 RAM 角色 ARN。输入A用户账号下所创建的RAM角色的ARN。

      acs:ram::128XXXXXXXXXX09011:role/XXXX

      rrsaOIDCProviderRoleARN

      ACK集群的提供商ARN,输入A用户账号ACK集群RRSA OIDC提供商 ARN 信息

      acs:ram::128XXXXXXXXXX09011:oidc-provider/ack-rrsa-c8864XXXXXXXXXXXXXXXXXX99356a636

      其他参数配置请参见组件配置

    aliyun-acr-credential-helper组件

    1. 登录容器服务管理控制台,在左侧导航栏单击集群列表

    2. 集群列表页面,单击目标集群名称,然后在左侧导航栏,单击组件管理

    3. 组件管理页面,单击安全页签,定位到aliyun-acr-credential-helper组件并单击安装。在弹框中,将tokenMode选项设置为auto,然后单击确认

      04479cf3d9857845bf530ea2f0850a60

    4. 修改免密组件的ConfigMap配置项。

      1. 在左侧导航栏,选择配置管理 > 配置项

      2. 配置项页面顶部的命名空间下拉列表,选择kube-system,然后单击acr-configuration操作列下的YAML 编辑,参考下列示例修改配置。

        data:
          service-account: "default"
          watch-namespace: "all"
          expiring-threshold: "15m"
          notify-email: "c*@example.com"
          acr-registry-info: |
            - instanceId: "cri-xxx"                                   # ACR实例ID。
              regionId: "cn-hangzhou"                                 # ACR实例地域ID。
              domains: "xxxxx-registry.cn-hangzhou.cr.aliyuncs.com"   # ACR实例访问域名。
              rrsaRoleARN: "<A用户账号创建角色的ARN>"
              rrsaOIDCProviderRoleARN: "<A用户账号ACK控制台集群基本信息中的提供商ARN。>"
              assumeRoleARN: "<B用户账号创建角色的ARN>"
              expireDuration: 3600                                    # B用户账号中的RAM角色设置最大会话时间,默认值为3600。             
          rrsa: |
            enable: true                                              # 免密组件开启RRSA功能。 

使用Worker RAM角色扮演

A用户账号ACK集群中,将集群默认的Worker RAM角色配置为扮演具有免密拉取镜像权限的B用户账号RAM角色,使ACK集群可以访问并拉取B用户账号的私有镜像。

image
  1. A用户账号下操作,查看集群的Worker RAM角色并授予其角色扮演权限。

    1. 登录容器服务管理控制台,在左侧导航栏选择集群列表

    2. 集群列表页面,单击目标集群名称,然后在左侧导航栏,选择集群信息

    3. 集群信息页面,单击基本信息页签,然后在集群资源区域,单击Worker RAM 角色右侧链接。

    4. 为该角色添加AliyunSTSAssumeRoleAccess权限以授予角色扮演能力,并记录其ARN信息。更多详情,请参见RAM角色授权

      1. 在角色详情页面的权限管理页签下,单击新增授权

      2. 新增授权面板的权限策略区域,定位并选中AliyunSTSAssumeRoleAccess权限策略,然后单击确认新增授权

      3. 在角色详情页面的基本信息区域,查看并记录该RAM角色ARN。详细操作,请参见如何查看RAM角色的ARN?

  2. B用户账号下操作,创建RAM角色并授予拉取私有镜像的权限,并允许A用户账号ACK集群Worker RAM角色扮演此角色。

    1. 创建可信实体为阿里云账号的RAM角色

    2. 使用以下内容创建自定义权限策略,并将该策略RAM角色授权,以赋予该角色获取实例信息和拉取镜像的权限。

      {
          "Version": "1",
          "Statement": [
              {
                  "Action": [
                      "cr:GetAuthorizationToken",
                      "cr:ListInstanceEndpoint",
                      "cr:PullRepository"
                  ],
                  "Resource": "*",
                  "Effect": "Allow"
              }
          ]
      }
    3. RAM角色基本信息页,单击信任策略页签,使用以下内容编辑信任策略。允许A用户账号ACK集群的Worker RAM角色来扮演B用户账号RAM角色。

      {
        "Statement": [
          {
            "Action": "sts:AssumeRole",
            "Effect": "Allow",
            "Principal": {
              "RAM": [
                "<A用户创建角色的ARN>"
              ]
            }
          }
        ],
        "Version": "1"
      }
    4. 在角色详情页面的基本信息区域,查看并记录该RAM角色ARN。详细操作,请参见如何查看RAM角色的ARN?

  3. A用户账号下操作,为ACK集群安装免密组件并修改其配置项。

    1. 登录容器服务管理控制台,在左侧导航栏单击集群列表

    2. 集群列表页面,单击目标集群名称,然后在左侧导航栏,单击组件管理

    3. 组件管理页面,单击安全页签,定位到aliyun-acr-credential-helper组件并单击安装。在弹框中,将tokenMode选项设置为workerRole,然后单击确定

      100f8cde3395436575996fbbd290dc56

    4. 修改免密组件的ConfigMap配置项。

      1. 在左侧导航栏,选择配置管理 > 配置项

      2. 配置项页面顶部的命名空间下拉列表,选择kube-system,然后单击acr-configuration操作列下的YAML 编辑,参考下列示例修改配置。

        data:
            service-account: "default"
            watch-namespace: "all"
            expiring-threshold: "15m"
            notify-email:"c*@example.com"
            acr-registry-info: |
              - instanceId: "cri-xxx"                                    # ACR企业版实例ID。
                regionId: "cn-hangzhou"                                  # ACR企业版地域ID。
                domains: "xxxxx-registry.cn-hangzhou.cr.aliyuncs.com"    # ACR企业版访问域名。
                assumeRoleARN: "<B用户账号创建角色的ARN>"
                expireDuration: 3600                                     # B用户下,为RAM角色设置最大会话时间,默认值为3600。

使用RAM用户的AKSK

A用户账号ACK集群中,免密组件保存B用户账号RAM用户的AKSK以拉取B用户账号的私有镜像。尽管这种方法配置简单,但由于AKSK以明文形式存储,存在泄露的风险。

  1. B用户账号下操作,创建一个RAM用户并确保该RAM用户拥有cr.*的相关权限。

    1. 创建RAM用户

    2. 使用以下内容创建自定义权限策略,并将该策略RAM用户授权,授予其获取实例信息和拉取镜像的权限。

      {
          "Version": "1",
          "Statement": [
              {
                  "Action": [
                      "cr:GetAuthorizationToken",
                      "cr:ListInstanceEndpoint",
                      "cr:PullRepository"
                  ],
                  "Resource": "*",
                  "Effect": "Allow"
              }
          ]
      }
    3. 查看RAM用户的AccessKey信息并记录。

  2. A用户账号下操作,为ACK集群安装免密组件并修改其配置项。

    1. 登录容器服务管理控制台,在左侧导航栏单击集群列表

    2. 集群列表页面,单击目标集群名称,然后在左侧导航栏,选择集群信息

    3. 集群列表页面,单击目标集群名称,然后在左侧导航栏,单击组件管理

    4. 组件管理页面,单击安全页签,定位到aliyun-acr-credential-helper组件并单击安装。在弹框中,将tokenMode选项设置为auto,然后单击确认

      04479cf3d9857845bf530ea2f0850a60

    5. 修改免密组件的ConfigMap配置项。

      1. 在左侧导航栏,选择配置管理 > 配置项

      2. 配置项页面顶部的命名空间下拉列表,选择kube-system,然后单击acr-configuration操作列下的YAML 编辑,参考下列示例修改配置。

      3. data:
            service-account: "default"
            watch-namespace: "all"
            expiring-threshold: "15m"
            notify-email:"c*@example.com"
            acr-registry-info: |
              - instanceId: ""                        # ACR企业版实例ID。             
                regionId: "cn-hangzhou"               # ACR企业版地域ID。    
                customAccessKey: "xxxxx"              # B账号下RAM用户的AccessKey ID。
                customAccessKeySecret: "xxxxxx"       # B账号下RAM用户的AccessKey Secret。 

步骤三:验证跨账号镜像拉取

说明

验证过程仅作为示例。详细操作,请参见镜像构建创建工作负载

  1. B用户账号ACR企业版实例中,按需获取容器镜像的公网地址专有网络地址。

    image

  2. A用户账号ACK集群中,选择工作负载 > 无状态,使用该容器镜像创建工作负载。

    apiVersion: apps/v1
    kind: Deployment
    metadata:
      name: nginx-deployment-basic
      labels:
        app: nginx
    spec:
      replicas: 1
      selector:
        matchLabels:
          app: nginx
      template:
        metadata:
          labels:
            app: nginx
        spec:
          containers:
          - name: nginx
            image: ******.cn-hangzhou.cr.aliyuncs.com/instance/instancetest:v1 # 指定B用户账号的ACR镜像地址 
            ports:
            - containerPort: 80
  3. 若工作负载的Pod事件中出现Successfully pulled image "XXX" in XXXs (XXXs including waiting). Image size: XXX bytes.信息,说明使用免密组件跨账号拉取镜像成功。

    ecb56ef14d98a537ebe64f6bd9fd883d

常见问题

如何解决100网段IP冲突问题

在配置路由规则时,认证域名和OSS域名解析的IP地址都属于100网段。如果您的内网中也使用了该网段的IP,可能会导致访问容器镜像服务企业版时与认证域名和OSS域名发生冲突。为了避免这种冲突,您使用以下步骤来解决100网段的冲突问题。

认证域名网段冲突

您可以通过开启实例接管认证域名功能,只需访问实例域名解决认证域名网段冲突问题。

  1. 登录容器镜像服务控制台

  2. 在顶部菜单栏,选择所需地域。

  3. 实例列表页面单击目标企业版实例。

  4. 在企业版实例管理页面左侧导航栏选择仓库管理 > 域名管理 ,在域名管理页面打开实例接管认证域名开关。

    重要

    实例接管认证域名功能,您需要提交工单为企业版实例添加白名单后才能使用。

  5. 确认开启实例接管认证域名单击确定

OSS域名网段冲突

您可以通过PrivateLink私网访问OSS资源,然后将原目标的OSS域名CNAME指向PrivateLink的域名。