kubernetes-身份與權限認證(十四)
Kubernetes的安全框架
https://kubernetes.io/docs/reference/access-authn-authz/rbac/
?訪問K8S集群的資源需要過三關:認證、鑒權、準入控制
?普通用戶若要安全訪問集群API Server,往往需要證書、Token或者用戶名+密碼;Pod訪問,需要ServiceAccount
?K8S安全控制框架主要由下面3個階段進行控制,每一個階段都支持插件方式,通過API Server配置來啟用插件。
1.Authentication
2.Authorization
3.Admission Control
三種客戶端身份認證:
?HTTPS 證書認證:基於CA證書簽名的數字證書認證
?HTTP Token認證:通過一個Token來識別用戶
?HTTP Base認證:用戶名+密碼的方式認證
授權:RBAC(Role-Based Access Control,基於角色的訪問控制):負責完成授權(Authorization)工作。
準入控制:AdminssionControl實際上是一個準入控制器插件列表,發送到APIServer的請求都需要經過這個列表中的每個準入控制器插件的檢查,檢查不通過,則拒絕請求。
使用RBAC授權
RBAC(Role-Based Access Control,基於角色的訪問控制),允許通過Kubernetes API動態配置策略。
角色
?Role:授權特定命名空間的訪問權限
?ClusterRole:授權所有命名空間的訪問權限
角色綁定
?RoleBinding:將角色綁定到主體(即subject)
?ClusterRoleBinding:將集群角色綁定到主體
主體(subject)
?User:用戶
?Group:用戶組
?ServiceAccount:服務賬號
使用RBAC授權對pod讀取權限示例
創建角色
[root@k8s-master1 ~]# vim role-demo.yaml kind: Role apiVersion: rbac.authorization.k8s.io/v1 metadata: namespace: developent name: pod-reader rules: - apiGroups: [""] resources: ["pods"] verbs: ["get", "watch", "list"] [root@k8s-master1 ~]# kubectl apply -f role-demo.yaml role.rbac.authorization.k8s.io/pod-reader created [root@k8s-master1 ~]# kubectl get role -n developent NAME AGE pod-reader 50s
創建角色綁定
[root@k8s-master1 ~]# vim rolebinding-demo.yaml kind: RoleBinding apiVersion: rbac.authorization.k8s.io/v1 metadata: name: dev-read-pods namespace: developent subjects: - kind: User name: jane apiGroup: rbac.authorization.k8s.io roleRef: kind: Role name: pod-reader apiGroup: rbac.authorization.k8s.io [root@k8s-master1 ~]# kubectl get rolebinding -n developent NAME AGE dev-read-pods 3s [root@k8s-master1 ~]# kubectl describe rolebinding dev-read-pods -n developent Name: dev-read-pods Labels: <none> Annotations: kubectl.kubernetes.io/last-applied-configuration: {"apiVersion":"rbac.authorization.k8s.io/v1","kind":"RoleBinding","metadata":{"annotations":{},"name":"dev-read-pods","namespace":"develop... Role: Kind: Role Name: pod-reader Subjects: Kind Name Namespace ---- ---- --------- User jane
基於證書配置客戶端身份認證
創建證書
[root@k8s-master1 ~]# vim jane-csr.json { "CN": "jane", "hosts": [], "key": { "algo": "rsa", "size": 2048 }, "names": [ { "C": "CN", "L": "BeiJing", "ST": "BeiJing" } ] } [root@k8s-master1 ~]# cfssl gencert -ca=/opt/kubernetes/ssl/ca.pem -ca-key=/opt/kubernetes/ssl/ca-key.pem -config=/opt/kubernetes/ssl/ca-config.json -profile=kubernetes jane-csr.json | cfssljson -bare jane
創建kubeconfig文件
kubectl config set-cluster kubernetes --certificate-authority=/opt/kubernetes/ssl/ca.pem --embed-certs=true --server=https://192.168.0.130:6443 \ --kubeconfig=jane-kubeconfig kubectl config set-credentials jane --client-key=jane-key.pem --client-certificate=jane.pem --embed-certs=true --kubeconfig=jane-kubeconfig kubectl config set-context default --cluster=kubernetes --user=jane --kubeconfig=jane-kubeconfig kubectl config use-context default --kubeconfig=jane-kubeconfig
測試僅對developent命名空間查看pod權限
[root@k8s-master1 ~]# kubectl get pod -n developent NAME READY STATUS RESTARTS AGE nginx-7cdbd8cdc9-5dd7x 1/1 Running 0 16s nginx-7cdbd8cdc9-dthp7 1/1 Running 0 16s nginx-7cdbd8cdc9-lwzjf 1/1 Running 0 16s [root@k8s-master1 ~]# kubectl --kubeconfig=jane-kubeconfig get pod -n developent NAME READY STATUS RESTARTS AGE nginx-7cdbd8cdc9-5dd7x 1/1 Running 0 2m13s nginx-7cdbd8cdc9-dthp7 1/1 Running 0 2m13s nginx-7cdbd8cdc9-lwzjf 1/1 Running 0 2m13s [root@k8s-master1 ~]# kubectl --kubeconfig=jane-kubeconfig get pod Error from server (Forbidden): pods is forbidden: User "jane" cannot list resource "pods" in API group "" in the namespace "default"
使用RBAC授權UI權限示例
serviceAccount
當創建 pod 的時候,如果沒有指定一個 service account,系統會自動在與該pod 相同的 namespace 下為其指派一個default service account。而pod和apiserver之間進行通信的賬號,稱為serviceAccountName。如下:
[root@k8s-master1 ~]# kubectl get pod
NAME READY STATUS RESTARTS AGE
nfs-client-provisioner-f69cd5cf-rfbdb 1/1 Running 0 4h31m
web-0 1/1 Running 0 4h16m
web-1 1/1 Running 0 4h16m
[root@k8s-master1 ~]# kubectl get pod/web-0 -o yaml |grep "serviceAccountName"
serviceAccountName: default
[root@k8s-master1 ~]# kubectl describe pod web-0
Name: web-0
Namespace: default
. . . . .
Volumes:
www:
Type: PersistentVolumeClaim (a reference to a PersistentVolumeClaim in the same namespace)
ClaimName: www-web-0
ReadOnly: false
default-token-7vs6s:
Type: Secret (a volume populated by a Secret)
SecretName: default-token-7vs6s
Optional: false
從上面可以看到每個Pod無論定義與否都會有個存儲卷,這個存儲卷為default-token-*** token令牌,這就是pod和serviceaccount認證信息。通過secret進行定義,由於認證信息屬於敏感信息,所以需要保存在secret資源當中,並以存儲卷的方式掛載到Pod當中。從而讓Pod內運行的應用通過對應的secret中的信息來連接apiserver,並完成認證。每個 namespace 中都有一個默認的叫做 default 的 service account 資源。進行查看名稱空間內的secret,也可以看到對應的default-token。讓當前名稱空間中所有的pod在連接apiserver時可以使用的預制認證信息,從而保證pod之間的通信。
[root@k8s-master1 ~]# kubectl get sa
NAME SECRETS AGE
default 1 9d
nfs-client-provisioner 1 4h37m
[root@k8s-master1 ~]# kubectl get secret
NAME TYPE DATA AGE
default-token-7vs6s kubernetes.io/service-account-token 3 9d
nfs-client-provisioner-token-glqhl kubernetes.io/service-account-token 3 4h38m
registry-pull-secret kubernetes.io/dockerconfigjson 1 8d
而默認的service account 僅僅只能獲取當前Pod自身的相關屬性,無法觀察到其他名稱空間Pod的相關屬性信息。如果想要擴展Pod,假設有一個Pod需要用於管理其他Pod或者是其他資源對象,是無法通過自身的名稱空間的serviceaccount進行獲取其他Pod的相關屬性信息的,此時就需要進行手動創建一個serviceaccount,並在創建Pod時進行定義。那麽serviceaccount該如何進行定義呢???實際上,service accout也屬於一個k8s資源。如下查看service account的定義方式:
[root@k8s-master1 ~]# kubectl explain sa
service account的創建
[root@k8s-master1 ~]# kubectl create sa devsa -o yaml -n developent --dry-run #不執行查看定義方式
apiVersion: v1
kind: ServiceAccount
metadata:
creationTimestamp: null
name: devsa
namespace: developent
[root@k8s-master1 ~]# kubectl create sa devsa -o yaml -n developent --dry-run > sa.yaml #導出yaml文件
[root@k8s-master1 ~]# kubectl apply -f sa.yaml #創建
serviceaccount/devsa created
[root@k8s-master1 ~]# kubectl get sa -n developent #查看
NAME SECRETS AGE
default 1 5m46s
devsa 1 28s
[root@k8s-master1 ~]# kubectl get sa devsa -n developent -o yaml
apiVersion: v1
kind: ServiceAccount
metadata:
annotations:
kubectl.kubernetes.io/last-applied-configuration: |
{"apiVersion":"v1","kind":"ServiceAccount","metadata":{"annotations":{},"creationTimestamp":null,"name":"devsa","namespace":"developent"}}
creationTimestamp: "2018-12-28T07:01:01Z"
name: devsa
namespace: developent
resourceVersion: "780489"
selfLink: /api/v1/namespaces/developent/serviceaccounts/devsa
uid: 56125cdc-0a6e-11e9-b58a-000c298a2b5f
secrets:
- name: devsa-token-krgp7
創建角色綁定
[root@k8s-master1 ~]# vim sa-rolebinding-demo.yaml kind: RoleBinding apiVersion: rbac.authorization.k8s.io/v1 metadata: name: sa-read-pods namespace: developent subjects: - kind: ServiceAccount name: devsa roleRef: kind: Role name: pod-reader apiGroup: rbac.authorization.k8s.io [root@k8s-master1 ~]# kubectl apply -f sa-rolebinding-demo.yaml rolebinding.rbac.authorization.k8s.io/sa-read-pods created
獲取token
[root@k8s-master1 ~]# kubectl get secret -n developent NAME TYPE DATA AGE default-token-2zhxk kubernetes.io/service-account-token 3 148m devsa-token-pktnh kubernetes.io/service-account-token 3 2m20s [root@k8s-master1 ~]# kubectl describe secret devsa-token-pktnh -n developent Name: devsa-token-pktnh Namespace: developent Labels: <none> Annotations: kubernetes.io/service-account.name: devsa kubernetes.io/service-account.uid: f69d0ff3-0a81-11e9-b58a-000c298a2b5f Type: kubernetes.io/service-account-token Data ==== ca.crt: 1359 bytes namespace: 10 bytes token: eyJhbGciOiJSUzI1NiIsImtpZCI6IiJ9.eyJpc3MiOiJrdWJlcm5ldGVzL3NlcnZpY2VhY2NvdW50Iiwia3ViZXJuZXRlcy5pby9zZXJ2aWNlYWNjb3VudC9uYW1lc3BhY2UiOiJkZXZlbG9wZW50Iiwia3ViZXJuZXRlcy5pby9zZXJ2aWNlYWNjb3VudC9zZWNyZXQubmFtZSI6ImRldnNhLXRva2VuLXBrdG5oIiwia3ViZXJuZXRlcy5pby9zZXJ2aWNlYWNjb3VudC9zZXJ2aWNlLWFjY291bnQubmFtZSI6ImRldnNhIiwia3ViZXJuZXRlcy5pby9zZXJ2aWNlYWNjb3VudC9zZXJ2aWNlLWFjY291bnQudWlkIjoiZjY5ZDBmZjMtMGE4MS0xMWU5LWI1OGEtMDAwYzI5OGEyYjVmIiwic3ViIjoic3lzdGVtOnNlcnZpY2VhY2NvdW50OmRldmVsb3BlbnQ6ZGV2c2EifQ.tkA8I8zHF0yjAS4aitd2NhltvASCx8KTug_cdAs3ImYe-5QkxgeO9VTck6L5F6SlMewg8keMYQ9hhgE89aQC4Vs1t89U_ftZ8lo725SrNxIBqhucPUHpvBWfc4OWc96p7PGYNH59AnudXVIKEXuYZyL-KLoQeAjddPRrYXPqUtBpxpQStLWe6qvl-hXY2yj-FyMXAbYRH516ZCMGetRJbYjla7JAPdPt9nAqZoJe00NvOUfw0xXVp_8H7tcvp0tQbQ5GE06zuCRHMfDV9RWj6XUoXKvKirk1yd2nSNJdygTp-1q5JGKxYY2a_tuq2NSCurNBI28Rpj7dV7eIkehkTw
訪問dashboard,僅對developent命名空間讀取pod的權限
kubernetes-身份與權限認證(十四)