多账号共享一套ACR方案

简介: 一家多业务组织的客户来说往往会有多个云账号,分别部署各个业务线的容器服务。但集团可能想使用一套统一的容器镜像仓库(ACR),就会面临多账号内多个ACK共享一套ACR了。那如何合理规划好ACR实例上的命名空间,打通各个业务ACK集群与ACR的网络,包括如何精细化授权,都是客户需要考虑的。

1. 背景

对于一家多业务组织的客户来说往往会有多个云账号,分别部署各个业务线的容器服务。但集团可能想使用一套统一的容器镜像仓库(ACR),就会面临多账号内多个ACK共享一套ACR了。那如何合理规划好ACR实例上的命名空间,打通各个业务ACK集群与ACR的网络,包括如何精细化授权,都是客户需要考虑的。

2. 架构图

参考Landing Zone给客户推荐的多账号体系:

  • 运维账号:部署集团共享的一套ACR(企业版)、编译构建主机(用于各业务线代码编译打包,生成镜像)、云企业网。

  • 业务A账号:具体A业务在用的账号,里面会部署一套ACK-Pro集群。

  • 业务B账号:具体B业务在用的账号,里面会部署一套ACK-Pro集群。

3. 数据规划

为了让下面的操作更加通俗易懂,假设有一家企业X 。架构如下:

3.1 账号数据

账号

VPC

功能说明

运维账号,别名:A账号(以下操作均用A账号表示)

账号UID:1146716667364888

VPC1:172.16.0.0/24

ID:vpc-uf686s17jq8sdqm5c2uqy

1、部署了一套ACR服务

2、配置CEN实例,配置跨账号加载

cainiao账号,别名:B账号(以下操作均用B账号表示)

账号UID:1951216667354857

VPC2:192.168.0.0/16

ID:vpc-uf6mmky3rmmqv6mcdrcoh

1、部署了一套ACK集群

2、开通PrivateZone服务

3.2 ACR规划

账号

命名空间

功能

运维账号,别名:A账号

cainiao

存放cainiao业务线的镜像

alipay

存放alipay业务线的镜像

4. 围绕场景介绍步骤

4.1 前提准备

  • 在运维账号(A)中完成VPC创建,完成开通ACR高级版。

  • 在运维账号(A)中购买一台ECS用于当持续集成机(有Docker环境)。

  • 在cainiao账号(B)中配置VPC,用于部署ACK用的。

  • 在cainiao账号(B)中完成ACK购买(网络架构选择Terway),并开通PrivateZone服务。

4.2 场景1:编译机(ECS)推镜像到ACR

步骤一:配置访问控制

在运维账号A 的ACR访问控制页添加A账号内的VPC (编译机所在的VPC)

创建专有网络成功后,ACR会自动在云解析PrivateZone中创建解析Zone,为您解析域名。您可以在云解析PrivateZone查看解析Zone。相关链接

这样在当前这个VPC里面的ECS就能够正常解析到这个域名了。

$ PING shareacr-registry-vpc.cn-shanghai.cr.aliyuncs.com (172.XX.XX.12) 56(84) bytes of data.

步骤二:配置ACR设置账号登录信息

配置命名空间

注意!这个命名空间需要设置成私有。

配置访问密码

因为是编译机,所以可以设置一个固定密码。

步骤三:ECS推送镜像到ACR

注意!这里我们没有去做精细化权限控制,考虑到是编译机,所以没对Namespace粒度授权。

1、登录

$ docker login --username=xx@xxxxx shareacr-registry-vpc.cn-shanghai.cr.aliyuncs.com

2、推镜像

a.dockerfile

FROM nginx:1.8
RUN mkdir /app
$ docker build -t  shareacr-registry-vpc.cn-shanghai.cr.aliyuncs.com/cainiao/a1:v0.1 -f a.dockerfile ./
$ docker push shareacr-registry-vpc.cn-shanghai.cr.aliyuncs.com/cainiao/a1:v0.1

注意,这里的地址是 -vpc,这样走的就是内网流量。

这样镜像推上去之后,在业务账号cainiao(B账号)中的ACK拉取镜像。

4.3 场景2:在B账号的ACK集群上面访问运维账号里面的ACR私有镜像

步骤一:打通A账号与B账号VPC互通

1、在B账号的VPC中配置跨账号授权,其中对方账号UID请写A账号。

2、登录A账号,完成CEN配置。需要将A\B账号对应的VPC都加进去,高级选择默认都勾上。

3、验证A与B账号两个VPC内的ECS网络互通

登录A账号的ECS(编译机),Ping B账号ACK对应的worker节点内网IP。如果正常Ping通,则说明网络打通。

步骤二:配置B账号的PrivateZone

1、配置Zone

2、配置PrivateZone域名解析

注意!这里A记录,对应的IP地址需要跟A账号里面的保持一致。

3、配置PrivateZone关联VPC

注意!这里面需要选择ACK所在的VPC。

4、登录B账号中的ACK所在的某台worker节点,去ping 下这个域名:shareacr-registry-vpc.cn-shanghai.cr.aliyuncs.com 只要能够正常解析并且可达,则说明网络层正常。

步骤三:配置B账号的免密访问ACR私有镜像

到此,网络层已经正常了。接下来就是需要配置权限及免密访问。

整个操作分4步:

  1. A账号:配置一个RAM角色,具备拉取指定私有仓库下的私有镜像(精细化授权由这个角色决定)。

  2. A账号:这个RAM角色需要允许让B用户下的ACK Worker RAM角色扮演(信任策略)。

  3. B账号:B账号下的ACK集群的Worker RAM角色有扮演其他账号角色的权限(AliyunAssumeRoleAccess)。

  4. B账号:设置B账号下的Worker RAM角色扮演A账号中的角色(configMap中的assumeRoleARN)。

接下来详细介绍一下每一步的操作过程

第一步:配置一个RAM角色,并授权

1、在A账号创建RAM角色:受信实体为阿里云账号类型的RAM角色。

2、自定义RAM角色权限策略内容,确保该RAM角色拥有拉取A用户私有镜像的权限。创建自定义策略名称:acr-policy

{
    "Version": "1",
    "Statement": [
        {
            "Effect": "Allow",
            "Action": "cr:*",
            "Resource": "*"
        },
        {
            "Action": [
                "cr:GetAuthorizationToken",
                "cr:ListInstanceEndpoint",
                "cr:PullRepository"
            ],
            "Resource": "*",
            "Effect": "Allow"
        }
    ]
}

3、将这个策略与角色相关联

第二步:修改这个RAM角色对应的信任策略。

1、查看B账号ACK集群的worker RAM角色的ARN信息

   

2、修改A账号下的角色acr-role对应的信任策略

对应的信任策略:

{
  "Statement": [
    {
      "Action": "sts:AssumeRole",
      "Effect": "Allow",
      "Principal": {
        "RAM": [
          
          "acs:ram::{B账号UID}:role/{B账号ACK对应的Worker RAM角色的ARN}"
        ]
      }
    }
  ],
  "Version": "1"
}

第三步:修改B账号worker RAM角色添加AssumeRole权限

选择这个角色,添加AssumeRole权限。

第四步:配置B账号下的Worker RAM角色扮演A账号中的角色

  1. 升级aliyun-acr-credential-helper组件。

    1. 登录容器服务管理控制台

    2. 在控制台左侧导航栏中,单击集群

    3. 集群列表页面,单击目标集群操作列下的更多 > 系统组件管理

    4. 安全区域,找到aliyun-acr-credential-helper,单击升级

  2. 配置acr-configuration配置项。

需要修改的配置:

acr-registry-info: |
  - instanceId: "{ACR实例ID}"
    domains: "shareacr-registry-vpc.cn-shanghai.cr.aliyuncs.com"
    assumeRoleARN: "{A账号角色的ARN}"

注意!

1、这里面的domains需要填的是VPC内网地址。

2、assumeRoleARN写的是A账号对应角色的ARN(即第一步创建的Role对应的ARN)。

完成以上4步操作之后,可以在ACK中创建一个Deployment资源,试一下是不是正常能够pull到镜像。

创建YAML格式:

apiVersion: apps/v1 # for versions before 1.8.0 use apps/v1beta1
kind: Deployment
metadata:
  name: nginx-deployment-basic
  labels:
    app: nginx
spec:
  replicas: 2
  selector:
    matchLabels:
      app: nginx
  template:
    metadata:
      labels:
        app: nginx
    spec:
      containers:
      - name: nginx
        image: shareacr-registry-vpc.cn-shanghai.cr.aliyuncs.com/cainiao/a1:v0.1
        ports:
        - containerPort: 80

4.4 延展

B账号的ACK只能拉特定命名空间下的私有镜像

常见的场景比如cainiao账号不能拉取alipay下面的镜像。

修改A账号里面的acr-policy策略:

{
    "Version": "1",
    "Statement": [
        {
            "Effect": "Allow",
            "Action": [
                "cr:ListInstance*",
                "cr:GetInstance*",
                "cr:ListSignature*"
            ],
            "Resource": "*"
        },
        {
            "Action": [
                "cr:GetAuthorizationToken",
                "cr:ListInstanceEndpoint",
                "cr:PullRepository"
            ],
            "Resource": "acs:cr:*:{uid}:repository/*/cainiao/*",
            "Effect": "Allow"
        }
    ]
}

再到B账号的ACK中去尝试拉另外一个namespace的镜像(shareacr-registry-vpc.cn-shanghai.cr.aliyuncs.com/alipay/a1:v0.1),会报错:server message: insufficient_scope: authorization failed。

这样的话,可以在A账号里面针对不同成员账号(cainiao\alipay)配置不同的角色,进而能够达到精细化授权。

4.5 参考材料

使用免密组件拉取容器镜像

作者介绍
目录