介绍

Role-based access control (RBAC)是一种细颗粒度的权限访问和控制方式。有兴趣的读者可以参考 K8s 关于RBAC的官方文档

1.如下是几个常用的概念:

  • 实体:Entity,包括 user / group / service account 等
  • 资源:Resource,包括 pod / service / secret 等
  • 角色:Role,操作资源和实体的 Rules 等
  • 角色绑定:Role Binding,把 Role 和 Entity 绑定使用。包括 Roles 和 ClusterRole 两类。
  • 命名空间:Namespace,主要用来定义安全边界和资源边界。

在这个动手实验中,我们将听过创建一个叫 rbac-user 的IAM用户来访问和使用EKS集群服务,给它配置的命名空间叫 rbac-test

2.部署测试Pod

使用如下方式创建一个测试用 Pod

kubectl create namespace rbac-test
kubectl create deploy nginx --image=nginx -n rbac-test

kubectl get all -n rbac-test

会返回类似如下的结果

NAME                         READY   STATUS              RESTARTS   AGE
pod/nginx-6799fc88d8-48x8k   0/1     ContainerCreating   0          1s

NAME                    READY   UP-TO-DATE   AVAILABLE   AGE
deployment.apps/nginx   0/1     1            0           2s

NAME                               DESIRED   CURRENT   READY   AGE
replicaset.apps/nginx-6799fc88d8   1         1         0       2s

RBAC测试

1.创建IAM用户

创建用户

mkdir -p ~/environment/rbac && cd ~/environment/rbac
aws iam create-user --user-name rbac-user
aws iam create-access-key --user-name rbac-user | tee create_output.json

创建用户返回

{
    "User": {
        "Path": "/",
        "UserName": "rbac-user",
        "UserId": "AIDA5NAGHF6N43LTPEXA3",
        "Arn": "arn:aws:iam::921283538843:user/rbac-user",
        "CreateDate": "2021-05-21T10:03:22+00:00"
    }
}

创建key返回

{
    "AccessKey": {
        "UserName": "rbac-user",
        "AccessKeyId": "AKIA5NAGHF6N4QSQWTWO",
        "Status": "Active",
        "SecretAccessKey": "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",
        "CreateDate": "2021-05-21T10:03:24+00:00"
    }
}

管理切换用户的 Crendential

cd ~/environment/rbac

cat << EoF > rbacuser_creds.sh
export AWS_SECRET_ACCESS_KEY=$(jq -r .AccessKey.SecretAccessKey create_output.json)
export AWS_ACCESS_KEY_ID=$(jq -r .AccessKey.AccessKeyId create_output.json)
EoF

2.映射 IAM 用户到 K8s

使用 eksctl 创建,或者手动编辑

eksctl create iamidentitymapping \
  --cluster my-cluster \
  --arn arn:aws:iam::921283538843:user/rbac-user \
  --username rbac-user

查看 aws-auth 配置的映射情况

eksctl get iamidentitymapping \
  --cluster my-cluster \
  --region eu-west-1 \
  --arn arn:aws:iam::921283538843:user/rbac-user

显示结果如下

ARN                                             USERNAME        GROUPS
arn:aws:iam::921283538843:user/rbac-user        rbac-user

3.IAM用户测试

执行脚本并获得 sts 配置信息

cd ~/environment/rbac
. rbacuser_creds.sh
aws sts get-caller-identity

返回类似如下信息

{
    "UserId": "AIDA5NAGHF6N43LTPEXA3",
    "Account": "921283538843",
    "Arn": "arn:aws:iam::921283538843:user/rbac-user"
}

此时如果我们去查询会返回错误(因为我们还创建Role和绑定,所以不能访问集群中的资源)

kubectl get pods -n rbac-test

如下

Error from server (Forbidden): pods is forbidden: User "rbac-user" cannot list resource "pods" in API group "" in the namespace "rbac-test"

4.创建 Role 并 Binding

重设 sts:

unset AWS_SECRET_ACCESS_KEY
unset AWS_ACCESS_KEY_ID
aws sts get-caller-identity

会返回正常的sts(没有rbac-user的)

{
    "UserId": "AROA5NAGHF6NUMSLJ7TLA:i-0bfe140c9ab80a6dc",
    "Account": "921283538843",
    "Arn": "arn:aws:sts::921283538843:assumed-role/FullAccessRoleForCloud9/i-0bfe140c9ab80a6dc"
}

创建 Role 定义

cd ~/environment/rbac
cat << EoF > rbacuser-role.yaml
kind: Role
apiVersion: rbac.authorization.k8s.io/v1
metadata:
  namespace: rbac-test
  name: pod-reader
rules:
- apiGroups: [""] # "" indicates the core API group
  resources: ["pods"]
  verbs: ["list","get","watch"]
- apiGroups: ["extensions","apps"]
  resources: ["deployments"]
  verbs: ["get", "list", "watch"]
EoF

创建 Binding 定义

cd ~/environment/rbac
cat << EoF > rbacuser-role-binding.yaml
kind: RoleBinding
apiVersion: rbac.authorization.k8s.io/v1
metadata:
  name: read-pods
  namespace: rbac-test
subjects:
- kind: User
  name: rbac-user
  apiGroup: rbac.authorization.k8s.io
roleRef:
  kind: Role
  name: pod-reader
  apiGroup: rbac.authorization.k8s.io
EoF

应用绑定

cd ~/environment/rbac
kubectl apply -f rbacuser-role.yaml
kubectl apply -f rbacuser-role-binding.yaml

5.验证 Role 和 Binding

用如下方式验证

cd ~/environment/rbac
. rbacuser_creds.sh
aws sts get-caller-identity
kubectl get pods -n rbac-test

执行成功

wangzan:~/environment/rbac $ kubectl get pods -n rbac-test
NAME                     READY   STATUS    RESTARTS   AGE
nginx-6799fc88d8-48x8k   1/1     Running   0          12m

此时,我们在尝试一个别的:

kubectl get pods -n kube-system

会报错

Error from server (Forbidden): pods is forbidden: User "rbac-user" cannot list resource "pods" in API group "" in the namespace "kube-system"

原因是,我们没有在 Role 和 Binding 里面对别的 namespace 授权。

清理环境

当你不需要 rbac 的时候,可以通过如下方式删除

unset AWS_SECRET_ACCESS_KEY
unset AWS_ACCESS_KEY_ID

kubectl delete namespace rbac-test
aws iam delete-access-key --user-name=rbac-user --access-key-id=$(jq -r .AccessKey.AccessKeyId create_output.json)
aws iam delete-user --user-name rbac-user

删除 rbac-user 在 configMap 里面的配置(修改 aws-auth的 data 里面的 mapUsers 部分)

eksctl delete iamidentitymapping --cluster my-cluster --arn arn:aws:iam::921283538843:user/rbac-user

欢迎大家扫码关注,获取更多信息

EKS 训练营-IAM用户权限控制(5)