一文搞懂AWS EKS权限管理 下篇 service account测试

一文搞懂AWS EKS权限管理 下篇 service account测试


简介


本文利用前文创建的AWS EKS环境,对service account访问AWS资源做一些实战测试。

其实在《AWS EKS 集群配置 ALB Ingress》一文中,我们已经为service account配置了访问AWS的权限,只是那篇文章介绍的重点在于创建Ingress而不是权限管理。

本文中,我们做一个更简单更直接的测试,在Pod中访问S3,可以让大家更好的理解如何从Pod内部访问AWS资源。

我们先在本地创建一个安装用AWS CLi的镜像,然后推入AWS ECR,最后在EKS中用这个镜像生成Pod,并在Pod中测试。

目录


- 环境(配置)

- 实战步骤

1. 创建安装有AWS CLi的docker镜像

- 在容器中安装AWS CLi

- 由容器创建docker镜像

- 把镜像推入ECR仓库

2. 在EKS中下载ECR仓库镜像

3. 在EKS中访问S3

- 创建面向service account的IAM Role

- service account绑定IAM Role

- Pod中使用service account

- 总结

- 后记

环境(配置)


  • AWS Global帐号,可在官网申请,一年内使用指定资源免费
  • AWS EKS
  • Win10 + WSL2
  • Dockder deskstop
  • AWS CLI 2.2.17 如何aws版本太低还需要手工安装插件,建议升级到高版本
  • Kubectl

实战步骤


1. 创建安装有AWS CLi的docker镜像

为了下面测试,我们先创建一个安装有AWS CLi的docker镜像。这次我们创建docker镜像时,不用Dockerfile,而用一种更直接的方法。

在容器中安装AWS CLi

运行以下命令,在WLS2中利用官方的ubuntu镜像创建一个容器“tsubuntu”

docker run -d --name tsubuntu ubuntu:20.04 tail -f /dev/null

运行结果

说明:“tail -f /dev/null”是让容器创建好后持续运行的命令,因为这个是前台命令(不会退出),容器会一直运行

可以用下列命令查看容器“tsubuntu”正在运行中

docker ps

下面我们准备在容器中安装AWS CLi

运行以下命令,进入容器内部

docker exec -it tsubuntu bash

运行结果


我们已经进入容器内部,然后就像普通ubuntu一样,可以安装软件了。需要注意的是,容器内的ubuntu已安装的软件比较少,所以需要自己添加依赖软件。

依次运行以下命令,先安装AWS CLi依赖软件

#设置代理
export http_proxy=http://YOUR_PROXY_SERVER:PORT
export https_proxy=http://YOUR_PROXY_SERVER:PORT
#更新apt-get软件仓库
apt-get update
#安装依赖软件
apt-get install -y wget unzip groff apt-utils less

运行结果


在安装groff,会弹出选择时区信息的框,随便选择就可以


安装完成后,可能有下面提示

W: Operation was interrupted before it could finish

我们可以再运行一次安装命令,看看需要的软件是否都安装成功,如果都在了,那就可以继续进行下一步,一般可以忽略这个提示。

第二个红框显示都安装成功了


下面我们安装AWS Cli,依次运行以下命令安装

#下载软件
wget https://awscli.amazonaws.com/awscli-exe-linux-x86_64.zip --no-check-certificate
unzip awscli-exe-linux-x86_64.zip
#安装AWS CLi
./aws/install
#查看AWS CLi版本
aws --version

运行结果


运行以下命令,配置AWS CLI,然后用AWS sts测试一下

aws configure
aws sts get-caller-identity --no-verify-ssl

可以正确返回用户信息,说明容器内的AWS CLi可以正常运行


由容器创建docker镜像

容器内AWS CLi安装完毕,接下来我们由这个容器创建一个镜像。

退出容器,运行以下命令停止容器并制作镜像

docker stop tsubuntu
docker commit -a tansong -m "ubuntu with awscli" tsubuntu tansong0091/ubuntu-awscli:1


说明:docker commit命令可以把当前系统中的容器制成镜像

  • -a:作者
  • -m:镜像说明
  • tsubuntu:被制成镜像的容器的名称
  • tansong0091/ubuntu-awscli:1: 镜像的Tag

运行以下命令把镜像推到docker公共仓库

docker push tansong0091/ubuntu-awscli:1

运行结果

说明:tansong0091/ubuntu-awscli:1是公共仓库,任何人都可以下载,大家也可以直接下载这个镜像测试

把镜像推入ECR仓库

下面,我们把这个镜像也推送到ECR中

我们先在AWS ECR中创建一个仓库,具体方法可以参考《AWS CICD之CodeCommit/Build/Deploy 下篇》


运行以下命令,给我们新建的镜像打上AWS ECR的Tag

docker tag tansong0091/ubuntu-awscli:1 252557384592.dkr.ecr.us-east-1.amazonaws.com/ubuntu-awscli:1

运行结果


依次运行以下命令,把镜像推入ECR

#设置AWS用户信息
export AWS_ACCESS_KEY_ID=YOUR_AWS_KEY_ID
export AWS_SECRET_ACCESS_KEY=YOUR_AWS_ACCESS_KEY
export AWS_DEFAULT_REGION=us-east-1
#登录AWS ECR
aws ecr get-login-password --region us-east-1 --no-verify-ssl| docker login --username AWS --password-stdin 252557384592.dkr.ecr.us-east-1.amazonaws.com
#推入镜像
docker push 252557384592.dkr.ecr.us-east-1.amazonaws.com/ubuntu-awscli:1

运行结果


提示:我们可以在ECR仓库里,获得如何登录ECR的命令

进入ECR,我们的仓库,点击“View push command”


可以在这里复制登录ECR仓库的命令


2. 在EKS中下载ECR仓库镜像

下面,我们在EKS中利用ECR中镜像生成Pod

新建文件testserviceaccount.yaml,并粘贴以下内容

---
apiVersion: v1
kind: Namespace
metadata:
  name: tstestserviceaccount
apiVersion: v1
kind: ServiceAccount
metadata:
  name: tssvcaccount
  namespace: tstestserviceaccount
apiVersion: apps/v1
kind: Deployment
metadata:
  namespace: tstestserviceaccount
  name: deployment-tstestserviceaccount
spec:
  selector:
    matchLabels:
      app.kubernetes.io/name: app-tstestserviceaccount
  replicas: 1
  template:
    metadata:
      labels:
        app.kubernetes.io/name: app-tstestserviceaccount
    spec:
      serviceAccountName: tssvcaccount
      containers:
      - image: 252557384592.dkr.ecr.us-east-1.amazonaws.com/ubuntu-awscli:1
        imagePullPolicy: Always
        name: app-tstestserviceaccount
        ports:
        - containerPort: 80
        command: ["/bin/sh", "-c"]
        args:
        - tail -f /dev/null

说明:

  • 我们在文件中创建了三个K8s对象,namespace,ServiceAccount和deployment。
  • ServiceAccount和deployment都属于namespace “tstestserviceaccount”
  • 在deployment中容器定义部分,我们指定了ECR仓库中的镜像,同时用“tail -f /dev/null”确保容器会一直运行
  • 在deployment中容器定义部分,我们还指定了service account “tssvcaccount”

下面,我们运行命令在EKS中创建这三个对象,注意先设置高权限用户

#设置AWS CLi用户
export AWS_PROFILE=252557384592:user/tansong
#配置kubctl用户
aws eks --region us-east-1 update-kubeconfig --name tsEKS
#创建K8s对象
kubectl apply -f testserviceaccount.yaml

运行结果


我们查看一下新建的Pod

#获取pod名称
kubectl get pods -n tstestserviceaccount
#查看pod详细信息
kubectl describe pods/deployment-tstestserviceaccount-55c896d7d9-s88r2 -n tstestserviceaccount

运行结果

说明:

这里EKS可以成功从ECR中下载了镜像,说明EKS有访问ECR的权限。因为我们在EKS Nodegroup的role “tsEKSnoderole”中赋予了“AmazonEC2ContainerRegistryReadOnly” policy


3. 在EKS中访问S3

下面,我们通过给service account赋予Role,让Pod可以访问AWS S3

创建面向service account的IAM Role

我们在AWS IAM中为service account创建授权访问S3的Role,以下只列出需要注意的点,详细步骤可以参考《AWS EKS 集群配置 ALB Ingress》

在“Select type of trusted entity”部分选择“Web identity”,在“Identity provider”中选择 EKS 中“OpenID Connect provider URL”一样的 Ip,在“Audience”中选择“sts.amazonaws.com”,点击“Next: Permissions”


搜索上面创建的 Policy “S3”,勾选“AmazonS3FullAccess”后,点击“Next: Tags”,直到最后创建成功


点击创建好的Role “tsserviceaccounts3”,选择“Trust relationships”,点击“Edit trust relationship”


替换以下内容,后点击“Update Trust Policy”

#原始内容
"oidc.eks.us-east-1.amazonaws.com/id/695A195646056642325EA732A2B46977:aud": "sts.amazonaws.com"
#替换成为
"oidc.eks.us-east-1.amazonaws.com/id/695A195646056642325EA732A2B46977:sub": "system:serviceaccount:tstestserviceaccount:tssvcaccount"


说明:

"system:serviceaccount:tstestserviceaccount:tssvcaccount"中指定namespace为“tstestserviceaccount”,service account为“tssvcaccount

记下Role “tsserviceaccounts3”的ARN

service account绑定IAM Role

用文本编辑打开文件“testserviceaccount.yaml”,在ServiceAccount对象下面增加annotations,绑定我们刚刚新建的Role “tsserviceaccounts3”

annotations:
    eks.amazonaws.com/role-arn: arn:aws:iam::252557384592:role/tsserviceaccounts3

保存退出,再次运行命令更新service account

kubectl apply -f testserviceaccount.yaml

运行结果


查看更改后的service account详情

kubectl describe serviceaccount/tssvcaccount -n tstestserviceaccount


说明:现在service account已经和IAM Role绑定了

Pod中使用service account

我们在创建Depolyment时,在容器模板部分指定了service account,现在我们进入容器测试一下

运行以下命令进入容器

#先查看Pod名称
kubectl get pods -n tstestserviceaccount
#用pod名称进入容器内部
kubectl exec -it deployment-tstestserviceaccount-55c896d7d9-s88r2 tstestserviceaccount -- bash

进入容器内部


我们先运行一下sts,查看当前的AWS用户

aws sts get-caller-identity

结果显示的是我之前测试AWS CLi的AWS用户

说明:

因为我们在本地创建镜像前,在容器中配置了一个这个用户来测试AWS CLi,所以这个用户信息被记录到容器中了,并在制作镜像时保存在了镜像里。

为了测试service account,我们要把这个用户信息删除掉,运行以下命令

cd ~/.aws
rm -rf *

再次运行sts,查看当前的AWS用户

aws sts get-caller-identity