圈子太小,做人留一面,日後好相見。
其實這個文章就是使用者用jumpserver登入到k8s master節點
然後執行kubectl的時候只有自己namespaces的所有許可權。
背景
1,k8s 有一天突然kubectl 執行任何命令都報許可權不對。
2,最後查明是因為有一個開發不小心把admin的ClusterRoleBinding給刪除了。
3,jumpserver給所有開發的許可權都是同一個普通使用者。
4,因為我們是一個k8s叢集,然後用不同的namespaces區分不同的業務小組。每個小組有固定的node機器。
5,kubectl 的配置檔案都是用的同一個,許可權也是admin的。
要求
1,領導要求業務小組只有自己namespaces的許可權。
2,業務小組不能有一個叢集的大的許可權,比如刪除node,不能更新master node的一些資訊。
總體思路
1,在jumpserver上面新建各業務方系統使用者。
2,把系統使用者繫結給各業務方使用者組。(關於Jumpserver 系統使用者和管理使用者介紹,後期出一篇單獨的文章。)
3,在k8s master1節點上面的各個業務方系統使用者家目錄下面 新建不同的.kube/config檔案。
一、.kube/config 檔案生成
1,這裡我就用我這邊的需求寫了,有關於k8s rbac的分享,我在後期會寫一篇單獨的文章。
2,業務方有:axer,paas。這是我公司這邊的兩個業務方。
3,其實k8s的rbac確實非常的複雜,難理解,實現許可權劃分的方式
1.1 許可權劃分思路
1,首先是各種資源的許可權,k8s資源又分兩種,一種是叢集的資源,一種是ns資源。
2,然後是將許可權和誰繫結起來。 大概就是兩步:許可權和繫結許可權。
3,我這裡是用了兩個ClusterRole,一個是叢集的資源的許可權,一個是ns資源的許可權
4,我選擇的是sa來做授權的物件。然後用這個sa的token去做kubectl的許可權驗證
5,多個RoleBinding,每一個RoleBinding把ns的資源許可權固定在一個ns裡面。你想要這個sa有哪些ns的許可權,就寫幾個RoleBinding。
6,一個ClusterRoleBinding,用於繫結sa對叢集資源的許可權。
1.2 建立ClusterRole
1.2.1 叢集資源許可權
也就是說整個k8s叢集的一些許可權。比如:get ns,get node,get node status,git ns status......
# 其實這裡就是設定對k8s叢集的一些許可權的
apiVersion: rbac.authorization.k8s.io/v1 # api
kind: ClusterRole # 資源型別
metadata: # 後設資料 ClusterRole 不受ns的限制,所以不用寫ns
name: business-axer-get-auth # ClusterRole 的名稱,能區分就行
rules:
- apiGroups: # apiGroups 就是api資源組,你kubectl get apiservice 就可以看到叢集所有的api組
- "" # 我這裡代表為空,就是api組裡面有一個v1. 這樣的
resources: # 就是k8s資源的名稱。kubectl api-resources 這個命令可以檢視到,第一列是資源名稱,就是可以寫在這裡的。
# 第二列是簡寫,kubectl get 後面的可以簡寫。
# 第三列是APIGROUP組
# 第四列是是否屬於NAMESPACED資源,就是你可以在ns下面看到的資源
# 第五列是kind的時候寫的名稱
# 資源還分子資源,後期會寫一篇專門的文章介紹
- namespaces/status # 這個是ns狀態
- namespaces # 這個是ns
- persistentvolumes # pv
verbs: # verbs是定義動作的
- get # 就是可以檢視ns的許可權
- list
- watch
- apiGroups:
- ""
resources: # 這裡定義的是可以檢視node的許可權,更新node的許可權。
- nodes
- nodes/status
verbs:
- get
- list
- watch
- patch
- update
- apiGroups:
- "storage.k8s.io"
resources: # 這裡定義的是可以檢視sc的許可權,因為我們有後端的儲存叢集,他們可以對sc的所有許可權
- storageclasses
- storageclasses/status
resourceNames: # 因為sc屬於叢集資源,不同的業務方需要對自己的sc才有 全部許可權。
- axersc # 所有這裡可以指定對哪一個sc有全部許可權
verbs:
- create
- delete
- deletecollection
- get
- list
- patch
- update
- watch
1.2.2 ns資源許可權
就是定義業務方對自己ns的所有許可權,自己的ns裡面的所有資源都要有許可權。
點選檢視程式碼
點選檢視程式碼
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:
name: business-axer-admin-auth
rules:
- apiGroups:
- ""
resources: # 對pod的一些許可權。
- pods/attach
- pods/exec # exec pod
- pods/portforward # 設定pod的轉發
- pods/proxy
- secrets # secrets的許可權
- services/proxy
verbs:
- get
- list
- watch
- apiGroups:
- ""
resources:
- serviceaccounts # sa的許可權
verbs:
- impersonate
- apiGroups:
- ""
resources:
- pods
- pods/attach
- pods/exec
- pods/portforward
- pods/proxy
verbs:
- create
- delete
- deletecollection
- patch
- update
- apiGroups:
- ""
resources:
- configmaps
- endpoints
- persistentvolumeclaims
- replicationcontrollers
- replicationcontrollers/scale
- secrets
- serviceaccounts
- services
- services/proxy
verbs:
- create
- delete
- deletecollection
- patch
- update
- apiGroups:
- apps
resources:
- daemonsets
- deployments
- deployments/rollback
- deployments/scale
- replicasets
- replicasets/scale
- statefulsets
- statefulsets/scale
verbs:
- create
- delete
- deletecollection
- patch
- update
- apiGroups:
- autoscaling
resources:
- horizontalpodautoscalers
verbs:
- create
- delete
- deletecollection
- patch
- update
- apiGroups:
- batch
resources:
- cronjobs
- jobs
verbs:
- create
- delete
- deletecollection
- patch
- update
- apiGroups:
- extensions
resources:
- daemonsets
- deployments
- deployments/rollback
- deployments/scale
- ingresses
- networkpolicies
- replicasets
- replicasets/scale
- replicationcontrollers/scale
verbs:
- create
- delete
- deletecollection
- patch
- update
- apiGroups:
- policy
resources:
- poddisruptionbudgets
verbs:
- create
- delete
- deletecollection
- patch
- update
- apiGroups:
- networking.k8s.io
resources:
- ingresses
- networkpolicies
verbs:
- create
- delete
- deletecollection
- patch
- update
- apiGroups:
- metrics.k8s.io
resources:
- pods
verbs:
- get
- list
- watch
- apiGroups:
- ""
resources:
- configmaps
- endpoints
- persistentvolumeclaims
- pods
- replicationcontrollers
- replicationcontrollers/scale
- serviceaccounts
- services
verbs:
- get
- list
- watch
- apiGroups:
- ""
resources:
- bindings
- events
- limitranges
- pods/log
- pods/status
- replicationcontrollers/status
- resourcequotas
- resourcequotas/status
verbs:
- get
- list
- watch
- apiGroups:
- apps
resources:
- controllerrevisions
- daemonsets
- deployments
- deployments/scale
- replicasets
- replicasets/scale
- statefulsets
- statefulsets/scale
verbs:
- get
- list
- watch
- apiGroups:
- autoscaling
resources:
- horizontalpodautoscalers
verbs:
- get
- list
- watch
- apiGroups:
- batch
resources:
- cronjobs
- jobs
verbs:
- get
- list
- watch
- apiGroups:
- extensions
resources:
- daemonsets
- deployments
- deployments/scale
- ingresses
- networkpolicies
- replicasets
- replicasets/scale
- replicationcontrollers/scale
verbs:
- get
- list
- watch
- apiGroups:
- policy
resources:
- poddisruptionbudgets
verbs:
- get
- list
- watch
- apiGroups:
- networking.k8s.io
resources:
- ingresses
- networkpolicies
verbs:
- get
- list
- watch
- apiGroups:
- authorization.k8s.io
resources:
- localsubjectaccessreviews
verbs:
- create
- apiGroups:
- rbac.authorization.k8s.io
resources:
- rolebindings
- roles
verbs:
- create
- delete
- deletecollection
- get
- list
- patch
- update
- watch
這樣兩個許可權的ClusterRole就建立好了。其實就是定義許可權。有哪些許可權。
1.3 建立sa ServiceAccount
我選擇的是sa做角色,當然也可以選擇user,或者usergroup。就是K8s實現許可權劃分有很多方式。看大家的選擇需求了。
apiVersion: v1
kind: ServiceAccount
metadata:
name: business-axer-serviceaccount # sa的名稱。隨便取,當然你要能認識區分
namespace: business-auth # sa的ns。我這裡單獨的建了一個ns,就是為了做許可權劃分的ns。
1.4 建立ClusterRoleBinding
ClusterRoleBinding是用來繫結叢集許可權的。
也就是說把我上面定義的叢集許可權ClusterRole繫結給sa。這樣這個sa就有操作叢集的一些字眼的許可權了。
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRoleBinding # ClusterRoleBinding 用於繫結叢集許可權的
metadata:
name: business-axer:get # 名稱 ClusterRoleBinding 不受ns的限制,所以沒有ns
roleRef:
apiGroup: rbac.authorization.k8s.io
kind: ClusterRole # 上面定義的ClusterRole名稱
name: business-axer-get-auth
subjects:
- kind: ServiceAccount # 上面定義的sa名稱
name: business-axer-serviceaccount
namespace: business-auth
1.5 建立RoleBinding
這個RoleBinding就是繫結ns裡面的資源的許可權的。
也就是說我把上面定義的ClusterRole許可權繫結給sa。然後這個許可權只能在這個RoleBinding所在的ns裡面才有許可權。
想要授權給業務放哪個ns的許可權 就要在哪個ns裡面建立一個RoleBinding。
假如說一個業務放有10個ns的許可權,那麼久需要建立10個RoleBinding。
# 我這下面是給這個sa了兩個ns的所有許可權
# ai-platform-deploy和ai-platform-test名稱空間的所有許可權
# 如果需要別的ns的許可權那就定義多個RoleBinding。
# 當然這個RoleBinding必須要在ns裡面。
apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata:
name: business-axer:ai-platform-deploy
namespace: ai-platform-deploy
roleRef:
apiGroup: rbac.authorization.k8s.io
kind: ClusterRole
name: business-axer-admin-auth
subjects:
- kind: ServiceAccount
name: business-axer-serviceaccount
namespace: business-auth
---
apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata:
name: business-axer:ai-platform-test
namespace: ai-platform-test
roleRef:
apiGroup: rbac.authorization.k8s.io
kind: ClusterRole
name: business-axer-admin-auth
subjects:
- kind: ServiceAccount
name: business-axer-serviceaccount
namespace: business-auth
許可權和繫結都做完了,剩下的就是生成config檔案了
1.6 生成config檔案
我這裡選擇的是token的驗證方式。
我是寫了一個簡單的指令碼。
#!/bin/bash
sa_name="business-axer-serviceaccount" # 這個是sa的名稱
user="business-axer" # 這個是user,對於我使用token的驗證方式,這裡的user沒啥用,隨便寫
context_name="business-axer-ct" # 對於我使用token的驗證方式,這個也是可以隨便寫,
cp ./demo.config ./guest.config # 拷貝一份demo.config
# 這裡是獲取sa的secret名稱,每一個sa都會有。
secret_name=`kubectl get sa -n business-auth $sa_name -o go-template='{{range .secrets}}{{.name}}{{end}}'`
# 這裡是獲取secret的token
TOKEN=`kubectl -n business-auth get secret $secret_name -o go-template='{{.data.token}}'`
# 這下面是設定一些上下文
kubectl config set-credentials $user --token=`echo ${TOKEN} | base64 -d` --kubeconfig=./guest.config
kubectl config set-context $context_name --cluster=kubernetes --user=$user --kubeconfig=./guest.config
kubectl config use-context $context_name --kubeconfig=./guest.config
demo.config檔案
apiVersion: v1
clusters:
- cluster:
certificate-authority-data: LS0tLS1CRUdJTiBDRVJUSUZJQ0FURS0tLS0tCk1JSUCg== 這個是固定的,你檢視一下線上的,其實就是https安全驗證,ca證書
server: https://10.19.250.206:8443 # k8s叢集apiservice的埠
name: kubernetes # 叢集的名稱
kind: Config
最終的guest.config檔案,我的下面的除了token和ca我刪了,其他的都是正確的。
apiVersion: v1
clusters:
- cluster:
certificate-authority-data: LShRTl0tLS0tCg==
server: https://10.19.250.206:8443
name: kubernetes
contexts:
- context:
cluster: kubernetes
user: business-axer
name: business-axer-ct
current-context: business-axer-ct
kind: Config
preferences: {}
users:
- name: business-axer
user:
token: eyJhbGciOiJSUzI1NiIsImtpZC-iyX0M6m5nEXqC6w
解讀如下:
clusters記錄了 clusters(一個或多個 K8S 叢集)資訊:
name是這個 cluster(K8S 叢集)的名稱代號
server是這個 cluster(K8S 叢集)的訪問方式,一般為 IP+PORT
certificate-authority-data是證書資料,只有當 cluster(K8S 叢集)的連線方式是 https 時,為了安全起見需要證書資料
users記錄了訪問 cluster(K8S 叢集)的賬號資訊:
name是使用者賬號的名稱代號
user/token是使用者的 token 認證方式,token 不是使用者認證的唯一方式,其他還有賬號+密碼等。
contexts是上下文資訊,包括了 cluster(K8S 叢集)和訪問 cluster(K8S 叢集)的使用者賬號等資訊:
name是這個上下文的名稱代號
cluster是 cluster(K8S 叢集)的名稱代號
user是訪問 cluster(K8S 叢集)的使用者賬號代號
current-context記錄當前 kubectl 預設使用的上下文資訊
kind和apiVersion都是固定值,使用者不需要關心
preferences則是配置檔案的其他設定資訊,我沒有使用過,暫時不提。
1.7 config檔案放入業務方使用者的家目錄下面的.kube/config。許可權要644的。
多個業務放就按照上面的步驟建立就行,可以把業務放理解成sa。
二、配置jumpserver
其實就是在jumpserver上面建立系統使用者,然後把這個系統使用者繫結到使用者組。
那麼使用者組裡面的使用者登入k8s master1機器的時候就是他們自己的系統使用者了。
然後這個使用者執行kubectl 的時候 預設會去家目錄下面的.kube找config檔案。
config檔案又是我們生成的。
這樣就可以把使用者限制在ns裡面了。
歡迎大佬留言評論,有什麼不足的望各位大佬指出。