介绍
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/FullAcce***oleForCloud9/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