参考
- 十. k8s–访问控制 serviceaccount和RBAC 学习笔记
- 使用 kubeconfig 或 token 进行用户身份认证
- ServiceAccount 访问资源方法
- 生成特定权限和配额的kubeconfig
- 如何手动创建 k8s kubeconfig 文件以实现多环境切换
- K8S 集群中的认证、授权与 kubeconfig
一、kubeconfig 介绍
-[appuser@k8s-master-1 ~]$ cat /etc/kubernetes/kubeconfig
apiVersion: v1
kind: Config
clusters:
- name: shjq-dev01-chenqiang-cluster
cluster:
server: https://10.130.14.155:443
certificate-authority: /etc/kubernetes/ssl/ca.crt
users:
- name: shjq-dev01-chenqiang-user
user:
client-certificate: /etc/kubernetes/ssl/cs_client.crt
client-key: /etc/kubernetes/ssl/cs_client.key
contexts:
- context:
cluster: shjq-dev01-chenqiang-cluster
user: shjq-dev01-chenqiang-user
name: shjq-dev01-chenqiang
------
# 上面为 指定目录格式
# 我们要配置成单个 kubeconfig 配置文件,我们需要做如下操作:
- 修改 certificate-authority 成 certificate-authority-data
- 修改 client-certificate 成 client-certificate-data
- 修改 client-key 成 client-key-data
- 对 /etc/kubernetes/ssl/ca.crt, cs_client.crt, cs_client.key 进行 base64 编码,分别执行 /etc/kubernetes/ssl/ca.crt|base64 等。
-------
apiVersion: v1
clusters:
- cluster:
certificate-authority-data: LS0tLS1CRUdJTiBDRVJUSUZJQ0FURS0tLS0tCk1JSUZuVENDQTRXZ0F3SUJBZ0lKQVBuVlJIdW9zZXpqTUEwR0NTcUdTSWIzRFFFQkN3VUFNR1V4Q3pBSkJnTlYKQkFZVEFrTk9NUkV3RHdZRFZRUUlEQWhUYUdGdVoyaGhhVEVQTUEwR0ExVUVCd3dHVUhWa2IyNW5NUll3RkFZRApWUVFLREExellXbGpiVzkwYjNJdVkyOXRNUXd3Q2dZRFZRUUxEQU5yT0hNeEREQUtCZ05WQkFNTUEyczRjekFlCkZ3MHhPREF6TURnd05qSTJORE5hRncweE9UQXpNRGd3TmpJMk5ETmFNR1V4Q3pBSkJnTlZCQVlUQWtOT01SRXcKRHdZRFZRUUlEQWhUYUdGdVoyaGhhVEVQTUEwR0ExVUVCd3dHVUhWa2IyNW5NUll3RkFZRFZRUUtEQTF6WVdsagpiVzkwYbnpCSDQvOG9Od0NDaHkrcUdYVE9hNTY2UzhjNW5vQ2c2TlovTGxZVjFLUHlJdjFMblRmd3VselUKenpSTGUwVkRjZXpwUmY0RnJ4TVJLSzg # 太长了 有删减
server: https://10.130.14.155:443
name: shjq-dev01-chenqiang-cluster
contexts:
- context:
cluster: shjq-dev01-chenqiang-cluster
user: shjq-dev01-chenqiang-user
name: shjq-dev01-chenqiang
current-context: shjq-dev01-chenqiang
kind: Config
preferences: {}
users:
- name: shjq-dev01-chenqiang-user
user:
client-certificate-data: LS0tLS1CRUdJTiBDRVJUSUZJQ0FURS0tLS0tCk1JSUVBakNDQWVvQ0NRQ0NhYWdFUnFmNExEQU5CZ2txaGtpRzl3MEJBUXNGQURCbE1Rc3dDUVlEVlFRR0V3SkQ # 太长了 有删减
client-key-data: LS0tLS1CRUdJTiBSU0EgUFJJVkFURSBLRVktLS0tLQpNSUlFcEFJQkFBS0NBUUVBeUI4djN5YjlqRmxRU0x3L1FYaVUycFdGck5jNjB0bmp1ZVh5N3gvNTZOcXNpOUhwCjdlSzZaSG5LL1JabDcxZUltS0tPNjhrVm9aSUZsRmx2UTJMWmtJMkVrYXpndHNrdnpvQ3l4aEhQSndIV01sRloKQ1dndDFXVHdkTm93emI1ZEtpSnhGbHFvWlJtZ3BBMGJ # 太长了 有删减
- 以实际环境的 kubeconfig 为例进行分析,主要包含以下几部分信息
三大部分 | ||
---|---|---|
clusters | 用于集群认证 | Server 字段: 存储集群的地址 |
证书路径(certificate-authority: /etc/kubernetes/ssl/ca.crt )或证书内容( certificate-authority-data: LS0tLS1CRUdJTiBDRVJUSUZJQ0FURS0tLS0tCk1JSUZuVENDQTRXZ ) | ||
可以有多个 cluster 集群 | ||
users | 用于用户认证 | 存储用户的证书、密钥(两种形式,路径或内容) |
证书形式 client-certificate: /etc/kubernetes/ssl/cs_client.crt client-key: /etc/kubernetes/ssl/cs_client.key | ||
密钥token形式: client-certificate-data: LS0tLS1CRUdJTiBDRVJUSUZJQ0FURS0 client-key-data: LS0tLS1CRUdJTiBSU0EgUFJJVkFURSBLRVktL | ||
可以有多个 user 用户 | ||
context | 上下文,用户和集群的组合 | 采用某个 context :表示采用某个用户去管控某个集群 |
默认情况是,采用 admin 用户管控集群,具有所有资源的创建权限 |
二、明确一个问题
- 由于 RBAC 机制,ServiceAccount 可以(通过Rolebinding或 ClusterRolebinding)具有(Role 或 ClusterRole 定义的)某些权限
- 那么在默认 context 下(就是 admin user)下,创建一个具有 pod create 权限的 ServiceAccount,接下来使用该 ServiceAccount 去创建 Pod 等,并不能说是该 ServiceAccount 在管控集群,实际上仍是 admin user 在管控集群,所以此时不能成为 k8s 多用户管控集群
- 因为在该 k8s 环境中,仍可以创建 deployment 、Service、daemonset 等资源
- 若是该 ServiceAccount 管控集群,在k8s环境中,应该只能创建 pod
所以可以这么理解
- cluster 多集群
- user 多用户,user 的权限(可绑定 ServiceAccount,进行权限限制,下文将讲如何用 ServiceAccount 创建 User)
- context 表示使用用户管控集群(该集群的最大权限就是用户的权限)
SA 通过 RoleBinding 绑定 Role ,具有 Role 权限,只能操作 Role 所在 namespace
可以实现 SA 具有操作别的 namespace 中资源的权限(例如 SA 在 ns1, Role 在 ns2,SA 可操作 ns2 资源)
SA 通过 RoleBinding 绑定 ClusterRole, 具有 ClusterRole 权限,只能操作 SA 所在的 namespace
- 可以实现 SA 在所在 namespace 具有高权限,但不能跨出当前 namespace
SA 通过 ClusterRoleBinding 绑定 ClusterRole,具有 ClusterRole 权限,可操作所有 namespace 和集群资源
没有 ClusterRoleBinding 与 Role de 组合
三、使用 ServiceAccount 创建 kubeconfig 中的 User
3.1 创建 ServiceAccount 获取 Token
- 首先创建 role 或 clusterrole 进行权限定义
- 之后创建 ServiceAccount 用于与 role 或 clusterrole 绑定
- 最后取出 ServiceAccount 对应的 Token (创建 serviceaccount 时会自动创建个同名的 secret 并挂载上,其用于访问集群)
# 简单举例
# 创建命名空间
kubectl create ns ns-sa
# 创建 serviceaccount
kubectl create sa sa-test -n ns-sa
# 创建 role 赋予某些权限 也可以通过 yaml 编写
kubectl -n ns-sa create role role-1 --verb=get,list --resources=Pod,Deployment -n test-sa
# 绑定 赋予 sa 权限
kubectl -n ns-sa create rolebinding sa-rolebinding-1 --role=ns-sa:role-1 --serviceaccount=sa-test
# 获取 sa 的 token
# 首先查看对应的 secret
kubectl -n ns-sa get secret | grep sa-test # 获知 secret 的名称 如 sa-test-token-gz2jr
# 然后获取 token
kubectl -n ns-sa describe secret sa-test-token-gz2jr
# 或
kubectl -n kube-system get secret admin-token-nwphb -o jsonpath={.data.token}|base64 -d # 这种方法 后面可能多个 % 删除就好
3.2 创建 k8s user 管控
实际上就是创建个 user,使用的是上面 ServiceAccount 的 Token
第一步:设置一个账号鉴权信息(创建一个k8s user)
上面的<TokenOfSecret>
的内容就是我们上面通过kubectl describe secret
获取到的 Token 值,注意指定的值两边没有 符号
$ kubectl config set-credentials test-user(自定义) --token <TokenOfSecret>
第二步:设置集群的访问信息
-
若配置访问已有的集群信息,忽略此步
-
若添加新集群,则需要添加下面信息
$ kubectl config set-cluster new-cluster-name(自定义) --server https://10.192.0.2:6443 --certificate-authority /home/shiyanlou/ca.crt --embed-certs=true
Cluster "new-cluster-name" set.
第三步:创建一个 Context,把集群信息和鉴权信息绑定在一起
# 采用了自己的集群 minikube
$ kubectl config set-context your-context-name(自定义) --cluster minikube --user test-user
Context "your-context-name" created.
第四步:使用这个创建的 Context
$ kubectl config use-context your-context-name
Switched to context "your-context-name".
通过以上步骤的设置,我们就可以在本地通过 kubectl 使用我们创建的 ServiceAccount 来调用 API 接口,访问集群中资源的信息了。
好了,让我们来简单查看下默认命名空间 default 中的 Pod 列表
$ kubectl get pods
Error from server (Forbidden): pods is forbidden: User "system:serviceaccount:default:shiyanlou-admin" cannot list pods in the namespace "default"
为什么会出现此信息?
- 因为我们 role 赋予的权限是在 ns-sa 命名空间下查看 pod,因此无法获取 default 空间下的 pod
3.3 利用 mac 用户进行管控
因为 mac 用户不是 k8s user,所以不太清楚怎么利用mac user 创建 contxt
此处测试 mac user 与 clusterrole admin 绑定,验证是否有创建pod权限
-
新建mac 用户 yeah
-
赋予权限
-
# 绑定 admin clusterrole k create clusterrolebinding test-sa-admin2 --user=yeah --clusterrole=admin
-
-
验证权限
-
# 验证是否授权成功 kubectl auth can-i create pods --namespace default --as yeah
-
四、命令总结
- kubeconfig配置文件可通过kubectl config命令进行设定
kubectl config view #打印文件内容
kubectl config set-cluster # 设置clusters段
kubectl config set-credentials # 设置users段
kubectl config set-context # 设置contexts段
kubectl config set-use-context # 设置current-context段
- 获取secret的token
# 创建 serviceaccount 时会自动创建个同名的 secret 并挂载上,其用于访问集群
kubectl -n kube-system get secret|grep admin-token
# 用 jsonpath 方式获取 token 的值
kubectl -n kube-system get secret admin-token-nwphb -o jsonpath={.data.token}|base64 -d
- 使用指定用户创建资源
# mac 用户
$ k apply -f 1sysctl.yaml --as=yeah
# 使用 ServiceAccount
$ k apply -f 1sysctl.yaml --as system:serviceaccount:default:sa-test1
- 验证用户是否有某些权限
# 测试权限 因为 k8s User 绑定的 serveraccount, 所以 k8s User 本身并没有权限
$ kubectl auth can-i create pods --namespace default --as user-test1
no
# ServiceAccount 才有权限
$ kubectl auth can-i create pods --namespace default --as system:serviceaccount:default:sa-test1
yes