现在思考一个问题,我们假设CodeBuild是一台服务器,它要与EKS交互:例如执行kubectl create deploy xxx
命令。
那么它必须有kube credentials来访问k8s api server, 在EKS是通过aws eks update-kubeconfig --name EKS_NAME
生成的
在EKS里,创建完集群后,创建集群的IAM实体(例如user/role),是通过K8S的RBAC机制和集群绑定的,默认情况下,只有这个IAM实体才能调用kubectl
命令。
假设我们创建一个新用户,虽然它具有eks:Describe*
权限并拿到了credentials,但依旧执行不了kubectl
命令, 常见报错如下:
[ec2-user@ip-172-31-18-143 ~]$ kubectl get node
error: You must be logged in to the server (Unauthorized)
通过编辑aws-auth configmap
,往里面添加对应的用户,可以解决这个问题
所以,为了CodeBuild有权限往EKS上部署应用,我们先创建一个IAM Role, 并写到EKS的aws-auth configmap
中。CodeBuild再assume这个Role,就可以使用kubectl与EKS集群进行交互:
这一部分我们将创建一个Role,它将配置到aws-auth configmap
中,用于给CodeBuild来assume。
进入AWS控制台的IAM Roles页面,点击Create role
:
选择AWS account
类型:
进入下一步,Role的名称为EksWorkshopCodeBuildKubectlRole
, 点击创建:
创建完成后,进入到这个Role页面下,选择Create inline policy
选择使用JSON编辑,内容如下:
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Action": "eks:Describe*",
"Resource": "*"
}
]
}
进入下一步Review Policy
,命名为eks-describe
, 并点击创建:
创建完成后,复制下来Role的ARN,用于后面的实验:
以下命令行可以实现以上步骤,两种方式选择一种即可。
cd ~/environment
TRUST="{ \"Version\": \"2012-10-17\", \"Statement\": [ { \"Effect\": \"Allow\", \"Principal\": { \"AWS\": \"arn:aws:iam::${ACCOUNT_ID}:root\" }, \"Action\": \"sts:AssumeRole\" } ] }"
echo '{ "Version": "2012-10-17", "Statement": [ { "Effect": "Allow", "Action": "eks:Describe*", "Resource": "*" } ] }' > /tmp/iam-role-policy
aws iam create-role --role-name EksWorkshopCodeBuildKubectlRole --assume-role-policy-document "$TRUST" --output text --query 'Role.Arn'
aws iam put-role-policy --role-name EksWorkshopCodeBuildKubectlRole --policy-name eks-describe --policy-document file:///tmp/iam-role-policy
现在我们有IAM Role了,我们需要把它添加到aws-auth ConfigMap
中,参考: https://docs.aws.amazon.com/eks/latest/userguide/add-user-role.html
这样CodeBuild只要assume了这个Role,就能与EKS集群进行交互。
执行以下命令进行更新,第一行根据自己帐号id做替换:
ACCOUNT_ID=145197526627 # replace your account id here
ROLE=" - rolearn: arn:aws:iam::${ACCOUNT_ID}:role/EksWorkshopCodeBuildKubectlRole\n username: build\n groups:\n - system:masters"
kubectl get -n kube-system configmap/aws-auth -o yaml | awk "/mapRoles: \|/{print;print \"$ROLE\";next}1" > /tmp/aws-auth-patch.yml
kubectl patch configmap/aws-auth -n kube-system --patch "$(cat /tmp/aws-auth-patch.yml)"
上面这一行命令其实帮我们完成了kubectl edit configmap aws-auth -n kube-system
的动作,在执行更改前,aws-auth内容是这样:
kongpingfan:~/environment/sam-app $ kubectl get configmap aws-auth -n kube-system -o yaml
apiVersion: v1
data:
mapRoles: |
- groups:
- system:bootstrappers
- system:nodes
rolearn: arn:aws:iam::145197526627:role/eksctl-eks-asm-nodegroup-ng-3-NodeInstanceRole-1T2ZU3E6NA8C5
username: system:node:{{EC2PrivateDNSName}}
mapUsers: |
[]
执行更改后,添加了刚创建的EksWorkshopCodeBuildKubectlRole
:
kongpingfan:~/environment $ kubectl get configmap aws-auth -n kube-system -o yaml
apiVersion: v1
data:
mapRoles: |
- rolearn: arn:aws:iam::145197526627:role/EksWorkshopCodeBuildKubectlRole
username: build
groups:
- system:masters
- groups:
- system:bootstrappers
- system:nodes
rolearn: arn:aws:iam::145197526627:role/eksctl-eks-asm-nodegroup-ng-3-NodeInstanceRole-1T2ZU3E6NA8C5
username: system:node:{{EC2PrivateDNSName}}
mapUsers: |
[]