1. 程式人生 > >kubernetes-身份與權限認證(十四)

kubernetes-身份與權限認證(十四)

tmg describe apiserver null ply http bar ati ldm

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-身份與權限認證(十四)