1. 程式人生 > 實用技巧 >Kubernetes 如何只授予某一 Namespace 的訪問許可權

Kubernetes 如何只授予某一 Namespace 的訪問許可權

最近遇到一個問題,那就是需要給別人共享一下 Kubernetes 的某個資源的使用和訪問許可權,這個僅僅存在於某個 namespace 下,但是我又不能把管理員許可權全都給它,我想只給他授予這一個 Namespace 下的許可權,那應該怎麼辦呢?

比如我這邊是需要只想授予 postgresql 這個 Namespace 的許可權,這裡我就需要利用到 Kubernetes 裡面的 RBAC 機制來實現了,下面記錄了我的操作流程。

建立 Namespace

kubectl create namespace postgresql

首先沒有 Namespace 的話需要建立一個 Namespace,這裡我建立的是 postgresql,大家可以自行修改。

建立 ServiceAccount

接下來需要建立一個 ServiceAccount,yaml 如下:

apiVersion: v1kind: ServiceAccountmetadata:  name: postgresql  namespace: postgresql

建立 Role

然後還要建立一個 Role,來控制相應的許可權,yaml 如下:

kind: RoleapiVersion: rbac.authorization.k8s.io/v1beta1metadata:  name: postgresql  namespace: postgresqlrules:  - apiGroups: ["", "extensions", "apps"]
resources: ["*"] verbs: ["*"] - apiGroups: ["batch"] resources: - jobs - cronjobs verbs: ["*"]

這裡由於 Role 是 Namespace 級別的,所以只能在特定 Namespace 下生效,這裡我要讓授予本 Namespace 下的所有許可權,這裡 rules 就添加了所有的 API型別、資源型別和操作型別。

建立 RoleBinding

最後需要將 Role 和 ServiceAccount 繫結起來,yaml 如下:

kind: RoleBinding
apiVersion: rbac.authorization.k8s.io/v1beta1metadata: name: postgresql namespace: postgresqlsubjects: - kind: ServiceAccount name: postgresql namespace: postgresqlroleRef: apiGroup: rbac.authorization.k8s.io kind: Role name: postgresql

建立 kubeconfig 檔案

現在我們執行上述 yaml 檔案之後,ServiceAccount 其實就已經建立好了,它會對應一個 secret,我們來看下詳情,執行:

 kubectl get serviceaccount postgresql -n postgresql -o yaml

好,執行結果類似如下:

apiVersion: v1kind: ServiceAccountmetadata:  annotations:    kubectl.kubernetes.io/last-applied-configuration: |      {"apiVersion":"v1","kind":"ServiceAccount","metadata":{"annotations":{},"name":"postgresql","namespace":"postgresql"}}  creationTimestamp: "2020-07-30T16:10:38Z"  name: postgresql  namespace: postgresql  resourceVersion: "17800240"  selfLink: /api/v1/namespaces/postgresql/serviceaccounts/postgresql  uid: 6327db1f-6a93-4f1e-b988-31842989bbbcsecrets:- name: postgresql-token-v26k7

這裡它實際關聯了一個 secret,叫做 postgresql-token-v26k7,這裡面就隱藏了 ServiceAccount 的 token 和證書。

好,那麼我們就可以利用這個 secret 來製作 kubeconfig 檔案了,命令如下:

server=https://your-server:443name=postgresql-token-v26k7namespace=postgresql
ca=$(kubectl get secret/$name -n $namespace -o jsonpath='{.data.ca\.crt}')token=$(kubectl get secret/$name -n $namespace -o jsonpath='{.data.token}' | base64 --decode)
echo "apiVersion: v1kind: Configclusters:- name: test cluster: certificate-authority-data: ${ca} server: ${server}contexts:- name: test context: cluster: test user: postgresqlcurrent-context: testusers:- name: postgresql user: token: ${token}" > postgresql.kubeconfig

這裡我們需要指定三個變數:

•server:就是 Kubernetes Server API 的地址•name:就是 ServiceAccount 對應的 secret•namespace:就是當前操作的 Namespace

執行之後就會生成一個 portgresql.kubeconfig 檔案。

使用

那麼怎麼使用呢?很簡單,設定下環境變數切換下就好了。

export KUBECONFIG=postgresql.kubeconfig

這裡我們就將 KUBECONFIG 設定了下,這樣再執行 kubectl 就會讀取到當前的 kubeconfig 檔案,就會生效了。

這時候我們來測試下:

kubectl get nodes

執行結果如下:

Error from server (Forbidden): nodes is forbidden: User "system:serviceaccount:postgresql:postgresql" cannot list resource "nodes" in API group "" at the cluster scope

可以看到這裡就提示沒有列出節點的許可權了。

然後我們操作下 postgresql 下的許可權試試:

kubectl get svc -n postgresql

執行結果如下:

NAME                  TYPE        CLUSTER-IP     EXTERNAL-IP   PORT(S)    AGEpostgresql            ClusterIP   10.0.193.137   <none>        5432/TCP   9dpostgresql-headless   ClusterIP   None           <none>        5432/TCP   9dpostgresql-metrics    ClusterIP   10.0.60.88     <none>        9187/TCP   9dpostgresql-read       ClusterIP   10.0.236.184   <none>        5432/TCP   9d

這裡就可以看到對 postgresql 這個名稱空間的操作就成功了。

到此為止我們就成功實現了特定 Namespace 的限制,大功告成。