目標
定制kubectl可以操作k8s資源的權(quán)限,比如,對所有資源只能讀取,不能增刪改。
基本知識
kubernetes 本身支持 RBAC 權(quán)限校驗,現(xiàn)在的主流版本已經(jīng)默認支持,并默認開啟了。你也可以通過查看 apiserver 配置來看自己的k8s是否支持
我們要實現(xiàn)對 kubectl 權(quán)限管理,就得依賴 k8s 的 RBAC,我們知道,kubectl 默認情況下,是讀取 ~/.kube/config 文件作為配置,和 k8s 的 apiserver 通信的,所以,問題的關(guān)鍵之一就是,我們?nèi)绾紊蛇@個配置文件。
k8s的RBAC定義了4個資源對象:Role、ClusterRole;Rolebinding、ClusterRoleBinding,其中:
Role:定義權(quán)限的集合,需要注意,Role 是定義在 Namespace 下的。
ClusterRole:和 Role 類似,只不過,它是整個集群范圍使用的,沒有命名空間的束縛。
RoleBinding:它是為了把 Role 綁定到 Subject 上,讓 Subject 可以集成 Role 定義的所有權(quán)限。
ClusterRoleBinding:和 RoleBinding 差不多,只不過,它是將 ClusterRole 綁定到 Subject 上。
那么,Subject 是什么?Subject 其實可以理解為“用戶”,它有幾類,分別是:User、Group、ServiceAccount,我們直接通過源碼看 Subject 的定義(著重看注釋?。。。?/p>
// Subject contains a reference to the object or user identities a role binding applies to. This can either hold a direct API object reference,
// or a value for non-objects such as user and group names.
type Subject struct {
// Kind of object being referenced. Values defined by this API group are "User", "Group", and "ServiceAccount".
// If the Authorizer does not recognized the kind value, the Authorizer should report an error.
Kind string `json:"kind" protobuf:"bytes,1,opt,name=kind"`
// APIGroup holds the API group of the referenced subject.
// Defaults to "" for ServiceAccount subjects.
// Defaults to "rbac.authorization.k8s.io" for User and Group subjects.
// +optional
APIGroup string `json:"apiGroup,omitempty" protobuf:"bytes,2,opt.name=apiGroup"`
// Name of the object being referenced.
Name string `json:"name" protobuf:"bytes,3,opt,name=name"`
// Namespace of the referenced object. If the object kind is non-namespace, such as "User" or "Group", and this value is not empty
// the Authorizer should report an error.
// +optional
Namespace string `json:"namespace,omitempty" protobuf:"bytes,4,opt,name=namespace"`
}
那么,Subject 在哪里?我們要綁定 Role 或者 ClusterRole,就得配置 RoleBinding 或者 ClusterRoleBinding,所以,Subject 就在 RoleBinding 或者 ClusterRoleBinding 里。下面進行實操步驟。
實施
1、創(chuàng)建一個ClusterRole
定義只讀資源的操作。首先,創(chuàng)建文件 clusterrole-mytest-view.yaml,內(nèi)容如下:
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:
annotations:
rbac.authorization.kubernetes.io/autoupdate: "true"
name: mytest-view
rules:
- apiGroups:
- ""
resources:
- configmaps
- endpoints
- persistentvolumeclaims
- pods
- replicationcontrollers
- replicationcontrollers/scale
- serviceaccounts
- services
verbs:
- get
- list
- watch
- apiGroups:
- ""
resources:
- bindings
- events
- limitranges
- namespaces/status
- pods/log
- pods/exec
- pods/status
- replicationcontrollers/status
- resourcequotas
- resourcequotas/status
verbs:
- get
- list
- watch
- apiGroups:
- ""
resources:
- namespaces
verbs:
- get
- list
- watch
- apiGroups:
- ""
resources:
- pods/exec
verbs:
- create
- apiGroups:
- apps
resources:
- 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:
- networkpolicies
verbs:
- get
- list
- watch
2、創(chuàng)建 ServiceAccount
經(jīng)過這一步之后,其實就有了 Secret 資源,這是因為,創(chuàng)建 ServiceAccount 后,k8s 會自動創(chuàng)建 Secret 資源,而 Secret 資源,有我們需要的證書等信息
kubectl create ns mytest
kubectl create sa -n mytest user-guest
3、創(chuàng)建 ClusterRoleBinding,將 ClusterRole 的權(quán)限,綁定到 ServiceAccount
創(chuàng)建文件 clusterrolebinding-view.yml
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRoleBinding
metadata:
name: mytest:user-guest
roleRef:
apiGroup: rbac.authorization.k8s.io
kind: ClusterRole
name: mytest-view
subjects:
- kind: ServiceAccount
name: user-guest
namespace: mytest
執(zhí)行命令,創(chuàng)建資源
kubectl apply -f clusterrolebinding-view.yml
4、生成配置:guest.config
TOKEN=$(kubectl get sa -n mytest user-guest -o go-template='{{range .secrets}}{{.name}}{{end}}')
echo $TOKEN
CA_CERT=$(kubectl get secret -n mytest ${TOKEN} -o yaml | awk '/ca.crt:/{print $2}')
echo $CA_CERT
# 注意這里,需要改為你的apiserver的地址
API_SERVER="https://172.1.3.17:6443"
echo $API_SERVER
cat <<EOF > guest.config
apiVersion: v1
kind: Config
clusters:
- cluster:
certificate-authority-data: $CA_CERT
server: $API_SERVER
name: cluster
EOF
5、更新 guest.config 配置
SECRET=$(kubectl -n mytest get secret ${TOKEN} -o go-template='{{.data.token}}')
kubectl config set-credentials mytest-guest --token=`echo ${SECRET} | base64 -d` --kubeconfig=guest.config
kubectl config set-context default --cluster=cluster --user=mytest-guest --kubeconfig=guest.config
kubectl config use-context default --kubeconfig=guest.config
6、將 guest.config,重命名之后,放到 ~/.kube 目錄下即可。