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步:
A账号:配置一个RAM角色,具备拉取指定私有仓库下的私有镜像(精细化授权由这个角色决定)。
A账号:这个RAM角色需要允许让B用户下的ACK Worker RAM角色扮演(信任策略)。
B账号:B账号下的ACK集群的Worker RAM角色有扮演其他账号角色的权限(AliyunAssumeRoleAccess)。
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账号中的角色
升级aliyun-acr-credential-helper组件。
登录容器服务管理控制台。
在控制台左侧导航栏中,单击集群。
在集群列表页面,单击目标集群操作列下的更多 > 系统组件管理。
在安全区域,找到aliyun-acr-credential-helper,单击升级。
配置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)配置不同的角色,进而能够达到精细化授权。