[TOC]html
Kubernetes 區分用戶帳戶和服務帳戶的概念主要基於如下緣由:node
- 用戶帳戶是針對人而言的。 服務帳戶是針對運行在pod中的進程而言的。
- 用戶帳戶是全局性的。 其名稱在集羣各namespace中都是全局惟一的,將來的用戶資源不會作namespace隔離, 服務帳戶是namespace隔離的。
- 一般狀況下,集羣的用戶帳戶可能會從企業數據庫進行同步,其建立須要特殊權限,而且涉及到複雜的業務流程。 服務帳戶建立的目的是爲了更輕量,容許集羣用戶爲了具體的任務建立服務帳戶 (即權限最小化原則)。
- 對人員和服務帳戶審計所考慮的因素可能不一樣。
- 針對複雜系統的配置可能包含系統組件相關的各類服務帳戶的定義。 由於服務帳戶能夠定製化地建立,而且有namespace級別的名稱,這種配置是很輕量的。
UserAccount經常使用於複雜業務邏輯管控,做用於系統全局,獨立於K8s以外 ServiceAccount僅用於實現某些特定操做任務,隸屬於名稱空間,由API Server管理
客戶端 → API Server → 認證插件 → 受權插件 → 准入控制插件 → 寫入成功nginx
須要注意:認證受權過程只存在HTTPS形式的API中。也就是說,若是客戶端使用HTTP鏈接到kube-apiserver,是不會進行認證受權的。因此說,能夠這麼設置,在集羣內部組件間通訊使用HTTP集羣, 外部就使用HTTPS,這樣既增長了安全性,也不至於太複雜。 |
Node,基於Pod資源的目標調度節點來實現對kubelet的訪問控制shell
ABAC,基於屬性的訪問控制,attribute-based access control數據庫
RBAC,基於角色的訪問控制,role-based access controlapi
Webhook,基於HTTP回調機制經過外部REST服務檢查確認用戶受權的訪問控制安全
AlwaysDeny,老是拒絕,僅用於測試服務器
AlwaysAllow,老是容許app
啓用API Server時 --authorization-mode定義要啓用的受權機制,多個選項以逗號分隔frontend
在對象持久化存儲etcd前,強制執行對象的語義驗證等功能 讀取資源信息的請求不會通過准入控制器檢查
Service Account 資源通常由用戶名和相關的Secret對象組成 用於讓Pod對象內的容器進程訪問其餘服務時提供身份認證信息,這些其餘服務包括:API 調度器 Pod控制器 節點控制器 私有Registry服務等 |
每一個Pod都會自動關聯一個存儲卷,掛載至 /var/run/secrets/kubernetes.io/serviceaccount
[root@master ~]# kubectl exec nginx-554b9c67f9-r5852 ls /var/run/secrets/kubernetes.io/serviceaccount ca.crt # 這是API Server的CA公鑰證書,用於Pod中的Process對API Server的服務端數字證書進行校驗時使用的 namespace token # token保存了Service Account的認證token 容器中進程使用它向API Server發起鏈接請求
每一個Pod對象都只有一個服務賬戶,若建立時未明確指定,會自動附加當前名稱空間中默認服務賬戶default |
#測試 [root@master ~]# kubectl create serviceaccount admin -o yaml --dry-run #幹跑 apiVersion: v1 kind: ServiceAccount metadata: creationTimestamp: null name: admin kubectl create serviceaccount admin #查看以建立的service賬號 [root@master ~]# kubectl get sa NAME SECRETS AGE admin 1 6s default 1 24d #查看詳細信息 kubectl describe sa admin ##簡潔輸出 kubectl get pods myapp-0 -o yaml --export
pod使用上述建立的ServiceAccount
apiVersion: v1 kind: Pod metadata: name: pod-sa-demo namespace: default labels: app: myapp tier: frontend annotations: leiyan.com/reatedby: "cluster admin" spec: containers: - name: myapp image: ikubernetes/myapp:v1 ports: - name: http containerPort: 80 serviceAccountName: admin
包括kubectl、kubelet、kube-controller-manager等在內的API Server的各種客戶端均可以使用kubeconfig配置文件提供接入多個集羣的相關配置信息
包括API Server的URL及認證信息,且可設置不一樣的上下文,並在各環境之間快速切換
/etc/kubernetes/admin.conf
即爲kubeconfig
格式的配置文件
查看當前正在使用的配置文件, 上下文是集羣和用戶的配對 |
[root@master ~]# kubectl config view apiVersion: v1 clusters: - cluster: certificate-authority-data: DATA+OMITTED server: https://10.0.0.50:6443 name: kubernetes contexts: - context: cluster: kubernetes user: kubernetes-admin name: kubernetes-admin@kubernetes current-context: kubernetes-admin@kubernetes kind: Config preferences: {} users: - name: kubernetes-admin user: client-certificate-data: REDACTED client-key-data: REDACTED
kubeconfig配置文件可經過kubectl config命令進行設定
kubectl config view,打印文件內容 kubectl config set-cluster,設置clusters段 kubectl config set-credentials,設置users段 kubectl config set-context,設置contexts段 kubectl config set-use-context,設置current-context段
爲賬號kube-user1建立私鑰及證書文件,保存於/etc/kubernetes/pki目錄中 #須要在master節點以root用戶執行
cd /etc/kubernetes/pki (umask 077; openssl genrsa -out kube-user1.key 2048) openssl req -new -key kube-user1.key -out kube-user1.csr -subj "/CN=kube-user1/O=kubeusers" # 其中 CN是用戶名,O是用戶組 openssl x509 -req -in kube-user1.csr -CA ca.crt -CAkey ca.key -CAcreateserial -out kube-user1.crt -days 3650 openssl x509 -in kube-user1.crt -text -noout # 驗證證書(可選)
以默認管理員 kubernetes-admin@kubernetes爲新用戶kube-user1設定配置文件,默認保存於 .kube/config 也可以使用 --kubeconfig指定自定義路徑
2.1 配置集羣信息,存在可省略此步驟
kubectl config set-cluster kubernetes-new --embed-certs=true --certificate-authority=/etc/kubernetes/pki/ca.crt --server="https://10.0.0.50:6443"
2.2 配置客戶端證書及密鑰,用戶名組名會自動提取
kubectl config set-credentials kube-user1 --embed-certs=true --client-certificate=/etc/kubernetes/pki/kube-user1.crt --client-key=/etc/kubernetes/pki/kube-user1.key
2.3 配置context,組合cluster和credentials
kubectl config set-context kube-user1@kubernetes-new --cluster=kubernetes-new --user=kube-user1
2.4 指定當前上下文
kubectl config use-context kube-user1@kubernetes-new
2.5 測試
[root@master pki]# kubectl get pods Error from server (Forbidden): pods is forbidden: User "kube-user1" cannot list resource "pods" in API group "" in the namespace "default" #切換回來 kubectl config use-context kubernetes-admin@kubernetes [root@master pki]# kubectl get pods NAME READY STATUS RESTARTS AGE nginx-554b9c67f9-r5852 1/1 Running 0 89m pod-cm-1 1/1 Running 0 6d pod-cm-2 1/1 Running 0 6d pod-hostpath-demo 1/1 Terminating 0 7d21h
在RBAC API中,一個角色包含了一套表示一組權限的規則。 權限以純粹的累加形式累積(沒有」否認」的規則)。 角色能夠由命名空間(namespace)內的Role
對象定義,而整個Kubernetes集羣範圍內有效的角色則經過ClusterRole
對象實現。
一個Role對象只能用於授予對某一單一命名空間中資源的訪問權限。 如下示例描述了」default」命名空間中的一個Role對象的定義,用於授予對pod的讀訪問權限: |
[root@master manifests]# cat role-demo.yaml apiVersion: rbac.authorization.k8s.io/v1 kind: Role metadata: name: pods-reader namespace: default rules: - apiGroups: - "" resources: - pods verbs: - get - list - watch
[root@master manifests]# kubectl apply -f role-demo.yaml role.rbac.authorization.k8s.io/pods-reader created
將role和user綁定, 並驗證已經生效, 能夠get到pod資源
# 將kube-user1和pods-reader綁定 [root@master manifests]# kubectl create rolebinding kube-user1-read-pods --role=pods-reader --user=kube-user1 rolebinding.rbac.authorization.k8s.io/kube-user1-read-pods created # 切換用戶到kube-user1 [root@master manifests]# kubectl config use-context kube-user1@kubernetes Switched to context "kube-user1@kubernetes". # 測試能夠get到pod信息 [root@master manifests]# kubectl get pod NAME READY STATUS RESTARTS AGE myapp-0 1/1 Running 0 5d4h myapp-1 1/1 Running 0 5d4h myapp-2 1/1 Running 0 5d4h myapp-3 1/1 Running 0 5d4h
ClusterRole對象能夠授予與Role對象相同的權限,但因爲它們屬於集羣範圍對象, 也可使用它們授予對如下幾種資源的訪問權限: |
建立ClusterRole
[root@master manifests]# cat cluster-role-demo.yaml apiVersion: rbac.authorization.k8s.io/v1 kind: ClusterRole metadata: name: cluster-role rules: - apiGroups: - "" resources: - pods verbs: - get - list - watch
[root@master manifests]# kubectl apply -f cluster-role-demo.yaml clusterrole.rbac.authorization.k8s.io/cluster-role created
將ClusterRole
和User
綁定, 並驗證權限是否生效
[root@master manifests]# cat clusterrolebinding-demo.yaml apiVersion: rbac.authorization.k8s.io/v1beta1 kind: ClusterRoleBinding metadata: name: user1-read-all-pods roleRef: apiGroup: rbac.authorization.k8s.io kind: ClusterRole name: cluster-reader subjects: - apiGroup: rbac.authorization.k8s.io kind: User name: kube-user1
[root@master manifests]# kubectl apply -f clusterrolebinding-demo.yaml clusterrolebinding.rbac.authorization.k8s.io/user1-read-all-pods created
驗證權限
# 切換用戶到kube-user1 [root@master manifests]# kubectl config use-context kube-user1@kubernetes Switched to context "kube-user1@kubernetes". # 成功獲取到默認namespace的pod信息 [root@master manifests]# kubectl get pod NAME READY STATUS RESTARTS AGE myapp-0 1/1 Running 0 5d4h myapp-1 1/1 Running 0 5d4h myapp-2 1/1 Running 0 5d4h myapp-3 1/1 Running 0 5d4h # 成功獲取到其餘namespace的pod信息 [root@master manifests]# kubectl get pod -n ingress-nginx NAME READY STATUS RESTARTS AGE nginx-ingress-controller-7995bd9c47-crpwt 1/1 Running 0 12d
角色綁定將一個角色中定義的各類權限授予一個或者一組用戶。 角色綁定包含了一組相關主體(即subject, 包括用戶——User、用戶組——Group、或者服務帳戶——Service Account)以及對被授予角色的引用。 在命名空間中能夠經過RoleBinding
對象授予權限,而集羣範圍的權限授予則經過ClusterRoleBinding
對象完成。
RoleBinding能夠引用在同一命名空間內定義的Role對象。 下面示例中定義的RoleBinding對象在」default」命名空間中將」pod-reader」角色授予用戶」kube-user1」。 這一受權將容許用戶」kube-user1」從」default」命名空間中讀取pod。 |
RoleBinding對象也能夠引用一個ClusterRole對象用於在RoleBinding所在的命名空間內授予用戶對所引用的ClusterRole中 定義的命名空間資源的訪問權限。這一點容許管理員在整個集羣範圍內首先定義一組通用的角色,而後再在不一樣的命名空間中複用這些角色。 |
[root@master manifests]# cat rolebinding-clusterrole.yaml apiVersion: rbac.authorization.k8s.io/v1 kind: RoleBinding metadata: name: user1-read-pods namespace: default roleRef: apiGroup: rbac.authorization.k8s.io kind: ClusterRole name: cluster-reader subjects: - apiGroup: rbac.authorization.k8s.io kind: User name: kube-user1 [root@master manifests]# kubectl apply -f rolebinding-clusterrole.yaml rolebinding.rbac.authorization.k8s.io/user1-read-pods created
這時候發現只能獲取到RoleBinding
設置的namespace
中的pod
了
[root@master ~]# kubectl config use-context kube-user1@kubernetes Switched to context "kube-user1@kubernetes". [root@master ~]# kubectl get pod NAME READY STATUS RESTARTS AGE myapp-0 1/1 Running 0 5d4h myapp-1 1/1 Running 0 5d4h myapp-2 1/1 Running 0 5d4h myapp-3 1/1 Running 0 5d4h [root@master ~]# kubectl get pod -n ingress-nginx Error from server (Forbidden): pods is forbidden: User "kube-user1" cannot list resource "pods" in API group "" in the namespace "ingress-nginx"
最後將ClusterRole
和User
經過ClusterRoleBinding
綁定到一塊兒
容許用戶kube-user1讀取全部namespace的pod信息
apiVersion: rbac.authorization.k8s.io/v1beta1 kind: ClusterRoleBinding metadata: name: user1-read-all-pods roleRef: apiGroup: rbac.authorization.k8s.io kind: ClusterRole name: cluster-reader subjects: - apiGroup: rbac.authorization.k8s.io kind: User name: kube-user1
[root@master manifests]# kubectl apply -f clusterrolebinding-demo.yaml clusterrolebinding.rbac.authorization.k8s.io/user1-read-all-pods created
[root@master manifests]# kubectl config use-context kube-user1@kubernetes Switched to context "kube-user1@kubernetes". [root@master manifests]# kubectl get pod NAME READY STATUS RESTARTS AGE myapp-0 1/1 Running 0 5d7h myapp-1 1/1 Running 0 5d7h myapp-2 1/1 Running 0 5d7h myapp-3 1/1 Running 0 5d7h [root@master manifests]# kubectl get pod -n ingress-nginx NAME READY STATUS RESTARTS AGE nginx-ingress-controller-7995bd9c47-crpwt 1/1 Running 0 13d