k8s权限管理
权限介绍
k8s的资源访问控制支持多种模式,对于资源的管理模式基于RBAC(role basic access control)。主要涉及到以下个k8s对象类型:
- serviceaccout
- role
- rolebinding
- clusterrole
- clusterrolebinding
role 和 clusterrole 的一个区别在于,role授予的权限只能是在所属的namespace,而clusterrole是全局的。在k8s资源中,有些资源是有namespace scope的,可以通过kubectl api-resources 进行查看
NAME SHORTNAMES APIVERSION NAMESPACED KIND
bindings v1 true Binding
componentstatuses cs v1 false ComponentStatus
configmaps cm v1 true ConfigMap
endpoints ep v1 true Endpoints
events ev v1 true Event
对于serviceaccount(以下简称sa)类型的用户,在1.24版本之前,创建sa用户时,会对应生成一个secret用于访问认证,1.24版本之后,官方建议使用kubectl create token serviceaccount来进行生成,可以对token的使用期限,对象进行控制,比较安全。
K8s的资源访问严格遵循resetful风格,从3方面进行资源限制
-
apiGroups
对服务器的api端口进行控制
-
resources
对k8s的资源类型进行控制
-
verbs
对k8s的资源进行操作控制
详细的控制权限可以看官方文档:https://kubernetes.io/zh-cn/docs/reference/access-authn-authz/authorization/
操作实践
笔者的版本为1.26,所以在创建完成sa之后,没有生成对应的secret来存储token,需要使用kubectl create token来进行生成。
以下来进行演示一个role权限
-
创建测试的命名空间
笔者建议使用一个新的命名空间来进行测试
kubectl create ns authority-test
-
创建serviceaccount用户myuser
kubectl create serviceaccount myuser
-
创建role角色myrole并设置权限
kubectl create role myrole kubectl edit role myrole
设置权限规则如下:
rules: - apiGroups: - "*" resources: - '*' verbs: - '*'
注意:生产环境请勿如此设置,可能带来极大的安全隐患,因为这个权限规则对于所在的命名空间具有完全的控制权限!
-
创建rolebinding资源,将sa和role进行关联
kubectl create rolebinding myuser-myrole-bingding --serviceaccount=authority-test:myuser --role=myrole
-
配置kubectl客户端
kubectl config set-credentials --token=$(kubectl create token myuser) myuser kubectl config set-context --user=myuser --cluster=kubernetes myuser@kubernetes --namespace=authrity-test
-
使用配置信息访问k8s
kubectl config use-context myuser@kubernetes
-
验证权限
创建并查看deployment - 成功
kubectl create deployment mydemo --image=nginx deployment.apps/mydemo created kubectl get deployments.apps NAME READY UP-TO-DATE AVAILABLE AGE mydemo 1/1 1 1 2m44s
创建并查看pod - 成功
kubectl run --image=nginx mypod pod/mypod created kubectl get pods NAME READY STATUS RESTARTS AGE mydemo-58f8b87566-c9tzs 1/1 Running 0 4m6s mypod 1/1 Running 0 5m22s
创建并查看service - 成功
kubectl expose deployment mydemo --port=80 --target-port=80 service/mydemo exposed kubectl get svc NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE mydemo ClusterIP 10.101.160.207 <none> 80/TCP 8s
创建并查看account - 成功
kubectl create serviceaccount mytest serviceaccount/mytest created yeqing@k8s-master-ubantu:~$ kubectl get serviceaccounts NAME SECRETS AGE default 0 32m mytest 0 16s myuser 0 32m
查看k8s节点信息 - 失败
kubectl get node Error from server (Forbidden): nodes is forbidden: User "system:serviceaccount:authority-test:myuser" cannot list resource "nodes" in API group "" at the cluster scope
使用curl访问
在没有kubectl工具的情况下,使用curl也是可以直接对k8s进行运维操作
如下命令,可以输出某个pod的日志
curl -XGET -H 'Authorization: Bearer eyJhbGciOiJSUzI1NiIsImtpZCI6IlVwM0htNGFMeHVvYnltV1paQmVqU0xVNDI2bzZacExqcG5LTU1qSHFwR0UifQ.eyJhdWQiOlsiaHR0cHM6Ly9rdWJlcm5ldGVzLmRlZmF1bHQuc3ZjLmNsdXN0ZXIubG9jYWwiXSwiZXhwIjoxNjczNzc4NjczLCJpYXQiOjE2NzM3NzUwNzMsImlzcyI6Imh0dHBzOi8va3ViZXJuZXRlcy5kZWZhdWx0LnN2Yy5jbHVzdGVyLmxvY2FsIiwia3ViZXJuZXRlcy5pbyI6eyJuYW1lc3BhY2UiOiJhdXRob3JpdHktdGVzdCIsInNlcnZpY2VhY2NvdW50Ijp7Im5hbWUiOiJteXVzZXIiLCJ1aWQiOiI4YzMzZWI4Zi02M2ZjLTQyZGQtYmVhZC0zYTkxOWZjN2ZmNjIifX0sIm5iZiI6MTY3Mzc3NTA3Mywic3ViIjoic3lzdGVtOnNlcnZpY2VhY2NvdW50OmF1dGhvcml0eS10ZXN0Om15dXNlciJ9.SsAdg72x9JHW11D_Tk7O2IXjG6DtgNoJN3gpcBNGUIZ3_xTBV8bDVULisAx1l5OLHrjMMVebjI3rAMrmLaoQ-fUwye2Xn-pJ9ddMcltPZHXw7gFPR57bU5tXN40MJq905ww-9-QWkkjQt1Fq8GW7m0DIWAuEhbhlRRfUs8yZa9QLoZ76raRhePdgMTlH97VG_wEvXTgNFBfaz0X3en-Wult6SJtUkBrqLIh6GjYrP2h1UD7O0eOGcZMRZjoDu7b-qKwm_iNzl41YzYL5VenB1-C_V1Q_KjBSp9pzwwTnjHz_DmhefYHYnLnlTN8MspuXHbRTnfu0YJX0aQR8qDIqNA' https://192.168.31.40:6443/api/v1/namespaces/authority-test/pods/mydemo-58f8b87566-c9tzs/log --insecure
日志内容如下
/docker-entrypoint.sh: /docker-entrypoint.d/ is not empty, will attempt to perform configuration
/docker-entrypoint.sh: Looking for shell scripts in /docker-entrypoint.d/
/docker-entrypoint.sh: Launching /docker-entrypoint.d/10-listen-on-ipv6-by-default.sh
10-listen-on-ipv6-by-default.sh: info: Getting the checksum of /etc/nginx/conf.d/default.conf
10-listen-on-ipv6-by-default.sh: info: Enabled listen on IPv6 in /etc/nginx/conf.d/default.conf
/docker-entrypoint.sh: Launching /docker-entrypoint.d/20-envsubst-on-templates.sh
/docker-entrypoint.sh: Launching /docker-entrypoint.d/30-tune-worker-processes.sh
/docker-entrypoint.sh: Configuration complete; ready for start up
2023/01/15 09:11:42 [notice] 1#1: using the "epoll" event method
2023/01/15 09:11:42 [notice] 1#1: nginx/1.23.3
2023/01/15 09:11:42 [notice] 1#1: built by gcc 10.2.1 20210110 (Debian 10.2.1-6)
2023/01/15 09:11:42 [notice] 1#1: OS: Linux 5.4.0-136-generic
2023/01/15 09:11:42 [notice] 1#1: getrlimit(RLIMIT_NOFILE): 1048576:1048576
2023/01/15 09:11:42 [notice] 1#1: start worker processes
2023/01/15 09:11:42 [notice] 1#1: start worker process 29
2023/01/15 09:11:42 [notice] 1#1: start worker process 30
2023/01/15 09:11:42 [notice] 1#1: start worker process 31
2023/01/15 09:11:42 [notice] 1#1: start worker process 32
2023/01/15 09:11:42 [notice] 1#1: start worker process 33
2023/01/15 09:11:42 [notice] 1#1: start worker process 34
2023/01/15 09:11:42 [notice] 1#1: start worker process 35
2023/01/15 09:11:42 [notice] 1#1: start worker process 36
kubectl工具是对k8s的api接口调用做了一个高级封装。