需求场景:
一个kubernetes集群中会有多个不同的命名空间,有时,我们需要限制某用户对某些特定命名空间的权限,比如,除了集群管理员外,我们的开发和测试工程师可能需要登录集群,了解应用的运行情况,查看pod的日志,甚至是修改某些配置。显然,我们不希望直接把管理员帐号提供给所有人,这时,可以通过创建受限的kubeconfig文件,将该config分发给特定的人员,让他们能通过kubectl命令实现一些允许的操作
操作步骤:
#1. 创建集群级别的角色 ClusterRole
clusterrole.cr-devlog.yaml 用于提供对pod的完全权限和其它资源的查看权限
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 |
# clusterrole.cr-devlog.yaml 提供基本权限 apiVersion: rbac.authorization.k8s.io/v1 kind: ClusterRole metadata: name: cr-devlog rules: - apiGroups: - "" resources: - pods - pods/attach - pods/exec - pods/log - pods/status - configmaps verbs: - get - list - watch - update - create - delete - apiGroups: - "" resources: - configmaps verbs: - get - list - watch - apiGroups: - "" resources: - services verbs: - get - list - watch - apiGroups: - extensions - apps resources: - deployments - daemonset verbs: - get - list - watch |
clusterrole.cr-namespace-devlog.yaml 提供kubectl get namespace能力
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 |
# clusterrole.cr-namespace-devlog.yaml 提供namespace的查看权限 apiVersion: rbac.authorization.k8s.io/v1 kind: ClusterRole metadata: name: cr-namespace-devlog rules: - apiGroups: - "" resources: - namespaces/status - namespaces verbs: - get - list - watch |
应用yaml文件:
kubectl apply -f clusterrole.cr-devlog.yaml
kubectl apply -f clusterrole.cr-namespace-devlog.yaml
#2. 在default命名空间创建 ServiceAccount
kubectl create serviceaccount devlog
注意,创建sa后,会自动创建一个绑定的 secret ,后面在kubeconfig文件中,会用到该secret中的token
#3. 对sa和集群角色建立绑定关系
这里对dev和test两个namespace授权
kubectl create rolebinding rbd-devlog --clusterrole=cr-devlog --serviceaccount=default:devlog --namespace=dev
kubectl create rolebinding rbd-devlog --clusterrole=cr-devlog --serviceaccount=default:devlog --namespace=test
这里namespace会将集群级别的权限限定在某个namespace下,cr-devlog中定认的集群权限仅作用于dev和test名称空间
kubectl create clusterrolebinding crbd-devlog --clusterrole=cr-namespace-devlog --serviceaccount=default:devlog
该命令提供kubectl get namespace的能力
需要注意的是,这里分别使用了rolebinding和clusterrolebinding
#4. 获取sa的secret中的token
kubectl get serviceaccounts devlog -oyaml
从返回内容中可查到,对应的secret名称为:devlog-token-n6psl
kubectl get secrets devlog-token-n6psl -oyaml
从返回内容中可查到,该secret的token为:
token=<这里为token的内容>
该token是经过base64处理的,需要进行解码处理
echo $token | base64 -d
应该会得到如下字符串
<这里是解码后的token字符串>
#5. 组装config文件
将上一步的token写入到config中
注意,cluster部分的值都是一样的
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 |
# config apiVersion: v1 kind: Config clusters: - cluster: server: https://10.10.1.100:6443 certificate-authority-data: <这里省略> name: k8s-dev users: - name: "devlog" user: token: <这里是解码后的token字符串> contexts: - context: cluster: k8s-dev user: "devlog" name: devlog-ct preferences: {} current-context: devlog-ct |
将该文件保存为 config 并放入 $HOME/.kube/ 目录下即可
补充:添加对 elastic-system 名称空间 port-forward 的支持
clusterrole.allow-port-forward.yaml
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 |
kind: ClusterRole apiVersion: rbac.authorization.k8s.io/v1 metadata: name: allow-port-forward rules: - apiGroups: [""] resources: ["pods","pods/portforward"] verbs: ["get", "list", "create"] - apiGroups: - "" resources: - services verbs: - get - list - watch |
kubectl create namespace elastic-system
kubectl apply -f clusterrole.allow-port-forward.yaml
kubectl create rolebinding rbd-devlog-allow-port-forward --clusterrole=allow-port-forward --serviceaccount=default:devlog --namespace=elastic-system
测试:
kubectl run --image=nginx:alpine nginx-app --port=80 -n elastic-system
kubectl expose deployment nginx-app --port=80 --target-port=80 --type=ClusterIP -n elastic-system
kubectl port-forward svc/nginx-app 1234:80 -n elastic-system