docker筆記29-k8s認證及serviceaccount、RBAC
目前RBAC是k8s授權方式最常用的一種方式。
在k8s上,一個客戶端向apiserver發起請求,需要如下資訊:
1)username,uid, 2) group, 3) extra(額外資訊) 4) API 5) request path,例如: 6)HTTP request action,如get,post,put,delete, 7)Http request action,如 get,list,create,udate,patch,watch,proxy,redirect,delete,deletecollection 8) Rresource 9)Subresource 10)Namespace 11)API group
K8s可以支援多版本並存。
其實,我們用kubectl向apiserver發起的命令,都是http方式的。
k8s驗證分為useraccount和serviceaccount。
可以用代理:
[root@master ~]# kubectl proxy --port=8080 [root@master ~]# curl [root@master ~]# kubectl get deploy -n kube-system NAME DESIRED CURRENT UP-TO-DATE AVAILABLE AGE coredns 2 2 2 2 20d [root@master ~]# curl eployments
[root@master ~]# kubectl get svc NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE kubernetes ClusterIP 10.96.0.1 <none> 443/TCP 20d
[root@master ~]# kubectl describe svc kubernetes Name: kubernetes Namespace: default Labels: component=apiserver provider=kubernetes Annotations: <none> Selector: <none> Type: ClusterIP IP: 10.96.0.1 Port: https 443/TCP TargetPort: 6443/TCP Endpoints: 172.16.1.100:6443 Session Affinity: None Events: <none>
上面我們看到10.96.0.1是kubernetes apiserver的地址,從而實現了叢集外部透過10.96.0.1訪問叢集內部的pod,同時也實現了叢集內部的pod訪問叢集外部的應用的功能。
只要訪問apiserver,就必須實現認證。而認證資訊是儲存在pod中的。
[root@master ~]# kubectl explain pods.spec.serviceAccountName
[root@master manifests]# kubectl create serviceaccount mysa -o yaml --dry-run > mysa.yaml
[root@master manifests]# cat mysa.yaml apiVersion: v1 kind: ServiceAccount metadata: creationTimestamp: null name: mysa
上面我們可以看到,只要是kubectl create的,只要加上-o yaml,就可以匯出清單檔案,這樣我們以後就不用從頭到尾寫清單檔案了,而是隻要生產一個,然後改改就行了,這個很不錯。
另外kubectl get 也可以匯出yaml格式的,如下:
[root@master manifests]# kubectl get pods myapp-1 -o yaml --export apiVersion: v1 kind: Pod metadata: creationTimestamp: null generateName: myapp- labels: app: myapp-pod controller-revision-hash: myapp-8598dd746f statefulset.kubernetes.io/pod-name: myapp-1 ownerReferences: - apiVersion: apps/v1 blockOwnerDeletion: true controller: true kind: StatefulSet name: myapp uid: a98ebc48-c24f-11e8-bb35-005056a24ecb selfLink: /api/v1/namespaces/default/pods/myapp-1 spec: containers: - image: ikubernetes/myapp:v1 imagePullPolicy: IfNotPresent name: myapp ports: - containerPort: 80 name: web protocol: TCP resources: {} terminationMessagePath: /dev/termination-log terminationMessagePolicy: File volumeMounts: - mountPath: /usr/share/nginx/html name: myappdata - mountPath: /var/run/secrets/kubernetes.io/serviceaccount name: default-token-5r85r readOnly: true dnsPolicy: ClusterFirst hostname: myapp-1 nodeName: node2 priority: 0 restartPolicy: Always schedulerName: default-scheduler securityContext: {} serviceAccount: default serviceAccountName: default subdomain: myapp-svc terminationGracePeriodSeconds: 30 tolerations: - effect: NoExecute key: node.kubernetes.io/not-ready operator: Exists tolerationSeconds: 300 - effect: NoExecute key: node.kubernetes.io/unreachable operator: Exists tolerationSeconds: 300 volumes: - name: myappdata persistentVolumeClaim: claimName: myappdata-myapp-1 - name: default-token-5r85r secret: defaultMode: 420 secretName: default-token-5r85r status: phase: Pending qosClass: BestEffort
將上面的改改就成為我們新的配置清單了。
建立service account
[root@master manifests]# kubectl create serviceaccount admin serviceaccount/admin created
[root@master manifests]# kubectl get sa NAME SECRETS AGE admin 1 2s default 1 20d
[root@master manifests]# kubectl describe sa admin Name: admin Namespace: default Labels: <none> Annotations: <none> Image pull secrets: <none> Mountable secrets: admin-token-6jpc5 Tokens: admin-token-6jpc5 Events: <none>
[root@master manifests]# kubectl get secret NAME TYPE DATA AGE admin-token-6jpc5 kubernetes.io/service-account-token 3 57s
看到自動就會多一個token。
下面我們用配置清單把serviceaccount和pod繫結起來。
[root@master manifests]# cat pod-sa-demo.yaml apiVersion: v1 kind: Pod metadata: name: pod-sa-demo namespace: default labels: app: myapp tier: frontend annotations: zhixin.com/created-by: "cluster admin" spec: containers: - name: myapp image: ikubernetes/myapp:v1 ports: - name: http containerPort: 80 serviceAccountName: admin #這表示我們這個pod使用自定義的驗證資訊admin
[root@master manifests]# kubectl apply -f pod-sa-demo.yaml pod/pod-sa-demo created
建立useraccount
kubeconfig是客戶端連線apiserver時使用的認證格式的配置檔案。
[root@master manifests]# kubectl config view apiVersion: v1 clusters: - cluster: certificate-authority-data: REDACTED server: name: kubernetes contexts: - context: #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
證書存放位置:
[root@master manifests]# cd /etc/kubernetes/pki/ [root@master pki]# ls apiserver.crt apiserver.key ca.crt front-proxy-ca.crt front-proxy-client.key apiserver-etcd-client.crt apiserver-kubelet-client.crt ca.key front-proxy-ca.key sa.key apiserver-etcd-client.key apiserver-kubelet-client.key etcd front-proxy-client.crt sa.pub
例子:
1、做一個私鑰
[root@master pki]# cd /etc/kubernetes/pki [root@master pki]# (umask 077; openssl genrsa -out zhixin.key 2048) Generating RSA private key, 2048 bit long modulus ...........+++ ...........+++ e is 65537 (0x10001)
括號是子shell的意思。
2、基於私鑰生成一個證書
CN就是使用者的賬戶名字。
[root@master pki]# openssl req -new -key zhixin.key -out zhixin.csr -subj "/CN=zhixin"
-subj:替換或指定證書申請者的個人資訊
3、簽證書
[root@master pki]# openssl x509 -req -in zhixin.csr -CA ca.crt -CAkey ca.key -CAcreateserial -out zhixin.crt -days 365 Signature ok subject=/CN=zhixin Getting CA Private Key
-days:表示證書的過期時間
x509:生成x509格式證書
4、檢視證書內容
[root@master pki]# openssl x509 -in zhixin.crt -text -noout Certificate: Data: Version: 1 (0x0) Serial Number: ab:45:1b:b3:92:32:59:ae Signature Algorithm: sha256WithRSAEncryption Issuer: CN=kubernetes #證書籤署人 Validity #有效期限 Not Before: Sep 28 08:01:20 2018 GMT Not After : Sep 28 08:01:20 2019 GMT Subject: CN=zhixin #一會用這個賬戶登入k8s Subject Public Key Info: Public Key Algorithm: rsaEncryption Public-Key: (2048 bit) Modulus: 00:bf:e5:b1:80:1a:a6:d1:24:ca:b8:75:a1:71:08: d2:ba:43:ee:53:a1:10:b5:7a:83:e7:8b:06:65:c7: 8a:07:02:ca:cc:8f:5c:94:a9:7a:10:24:f6:41:a0: c6:fe:5f:21:59:21:e7:72:30:12:38:89:85:78:54: c1:15:c4:13:33:43:9c:94:c0:dc:99:e9:f0:44:7e: 35:66:cd:e0:d9:0c:82:dc:b3:73:ee:ea:47:9e:5e: e5:bf:0b:45:fb:a3:cf:59:67:ae:13:31:9c:dc:b6: 78:da:b2:7e:c0:7e:c2:30:c5:fd:ea:6f:94:fa:81: 19:9f:71:9c:cf:60:07:5b:fa:0d:c0:6f:2c:b4:e0: 42:d6:6d:d3:39:23:2b:f7:ad:cc:21:f8:df:89:ff: 6e:45:59:1f:5d:db:aa:fa:07:ef:fc:b3:7e:3d:b1: dd:3e:be:5e:43:de:8f:e2:ea:aa:ec:6c:48:df:2f: 2e:20:61:e3:5c:6a:37:3e:2b:32:e5:1a:ad:35:88: d6:d2:db:aa:26:5d:cb:67:0a:65:9e:d4:79:76:92: 9a:41:fb:df:db:85:1a:ea:5e:ff:bb:7b:2f:01:10: 9f:8e:9c:a1:fe:ae:ac:9d:43:02:40:01:f7:d6:da: bf:5a:99:ba:d0:bf:ea:53:1e:f5:51:06:9c:ac:6f: 32:43 Exponent: 65537 (0x10001) Signature Algorithm: sha256WithRSAEncryption 91:43:cd:36:ad:88:17:a1:81:9f:8f:ad:9b:c5:41:d7:de:aa: 6a:f0:3a:00:f2:d7:9b:0e:89:bc:51:73:cc:4f:10:85:13:70: aa:d1:67:f8:f3:a1:6b:83:ff:99:76:7f:14:a5:b4:82:fb:1b: fb:cf:d5:fc:b0:2f:ff:68:c4:b1:c0:ee:f9:6b:41:ea:0a:96: 2f:55:1d:d7:77:f8:70:a6:15:a4:b6:e7:6d:93:61:2e:ac:7a: 10:70:fa:f7:43:da:56:f2:d0:e9:6b:01:72:73:2d:65:ea:4d: c4:3b:46:2d:1b:ad:f8:1f:eb:71:88:35:51:2a:dc:3a:36:fe: 63:bb:28:ee:d2:a0:d4:e0:14:95:10:96:20:2e:f3:75:12:eb: 05:8e:34:a1:dc:74:19:a5:76:0f:f2:bd:f3:56:aa:c9:40:51: c7:bd:1f:1f:c1:ec:a5:98:c8:b8:1d:07:67:fa:1c:a0:a3:1f: d3:ba:cb:09:52:9a:e7:59:39:ce:c8:ef:01:c2:4b:98:ff:05: 12:bf:69:36:0e:a6:a9:f6:40:34:28:36:0d:1b:76:31:b4:96: 6e:09:33:8e:d5:0a:96:77:dd:41:b3:29:db:d5:5e:fa:05:f7: e7:90:5d:79:6d:a9:59:20:60:0f:fe:d5:b6:38:6c:1a:ee:51: 66:c3:9b:4b
5、把使用者賬戶資訊新增到k8s叢集中
[root@master pki]# kubectl config set-credentials zhixin --client-certificate=zhixin.crt --client-key=zhixin.key --embed-certs=true User "zhixin" set.
embed-certs:表示把使用者資訊隱藏起來。
5、設定context上下文,指定zhixin使用者訪問k8s的哪個叢集
[root@master pki]# kubectl config view apiVersion: v1 clusters: - cluster: certificate-authority-data: REDACTED server: 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 - name: zhixin user: client-certificate-data: REDACTED client-key-data: REDACTED
[root@master pki]# kubectl config set-context zhixin@kubernetes --cluster=kubernetes --user=zhixin Context "zhixin@kubernetes" created.
[root@master pki]# kubectl config view apiVersion: v1 clusters: - cluster: certificate-authority-data: REDACTED server: name: kubernetes contexts: - context: cluster: kubernetes user: kubernetes-admin name: kubernetes-admin@kubernetes - context: cluster: kubernetes user: zhixin name: zhixin@kubernetes current-context: kubernetes-admin@kubernetes kind: Config preferences: {} users: - name: kubernetes-admin user: client-certificate-data: REDACTED client-key-data: REDACTED - name: zhixin user: client-certificate-data: REDACTED client-key-data: REDACTED
上面看到contexts裡面有zhixin的名字了。
6、切換到zhixin使用者登入k8s
[root@master pki]# kubectl config use-context zhixin@kubernetes Switched to context "zhixin@kubernetes".
[root@master pki]# kubectl get pods No resources found. Error from server (Forbidden): pods is forbidden: User "zhixin" cannot list pods in the namespace "default"
上面看到get pods時報錯了,這是因為使用者zhixin@kubernetes沒有管理器許可權。
7、切回k8s管理員
[root@master pki]# kubectl config use-context kubernetes-admin@kubernetes Switched to context "kubernetes-admin@kubernetes".
8、設定新的k8s叢集
[root@master ~]# kubectl config set-cluster mycluster --kubeconfig=/tmp/test.conf --server=" Cluster "mycluster" set
.--kubeconfig:指定認證檔案位置,不指定的話預設就在~/.kube/config
--embed-certs=true 表示證書資訊被隱藏
大家看到,我們上面就建立了一個新的k8s叢集叫mycluster。
[root@master ~]# kubectl config view --kubeconfig=/tmp/test.conf apiVersion: v1 clusters: - cluster: certificate-authority-data: REDACTED server: name: mycluster contexts: [] current-context: "" kind: Config preferences: {} users: []
RBAC(基於角色的訪問控制)
rbac:role based ac,也就是我們把使用者加入角色裡面,這樣使用者就具有角色的許可權了。
在k8s中,一切皆物件。
Object_URL: /apis/<GROUP>/<VERSION>/namespaces/<NAMESPACE_NAME>/<KIND>[OJJECT_ID]
RBAC是透過rolebinding把user繫結到role上的。而role是基於namespace設定的,也就是這說這個user只能訪問指定namespace下的pod資源。
而如果把user透過clusterrolebind繫結到clusterrole上後,那麼這個user就突破了namespace的限制,而擁有了叢集級別的許可權,即這個使用者可以訪問這個叢集下所有namespace下的pod了。
但是,我們也可以用rolebinding去把user繫結到clusterrole。在上圖中,我們把user1透過rolebinding繫結到clusterrole上,但是我們知道rolebinding只限制在namespace中,所以user1也只限定在namespace中,而不是整個叢集中。
[root@master ~]# kubectl create role pods-reader --verb=get,list,watch --resource=pods 注意:想要授予所有許可權可以用*來表示
[root@master ~]# kubectl create role pods-reader --verb=get,list,watch --resource=pods --dry-run -o yaml apiVersion: rbac.authorization.k8s.io/v1 kind: Role metadata: creationTimestamp: null name: pods-reader rules: - apiGroups: - "" resources: - pods verbs: - get - list - watch
[root@master ~]# kubectl get role NAME AGE pods-reader 7s
[root@master ~]# kubectl describe role pods-reader Name: pods-reader Labels: <none> Annotations: <none> PolicyRule: Resources Non-Resource URLs Resource Names Verbs --------- ----------------- -------------- ----- pods [] [] [get list watch]
[root@master ~]# kubectl create rolebinding zhixin-read-pods --role=pods-reader --user=zhixin rolebinding.rbac.authorization.k8s.io/zhixin-read-pods created
[root@master ~]# kubectl create rolebinding zhixin-read-pods --role=pods-reader --user=zhixin -o yaml --dry-run apiVersion: rbac.authorization.k8s.io/v1 kind: RoleBinding metadata: creationTimestamp: null name: zhixin-read-pods roleRef: apiGroup: rbac.authorization.k8s.io kind: Role name: pods-reader subjects: #就是引用的使用者 - apiGroup: rbac.authorization.k8s.io kind: User name: zhixin
[root@master ~]# kubectl explain rolebinding
[root@master ~]# kubectl describe rolebinding zhixin-read-pods Name: zhixin-read-pods Labels: <none> Annotations: <none> Role: Kind: Role Name: pods-reader Subjects: Kind Name Namespace ---- ---- --------- User zhixin
[root@master ~]# kubectl config use-context zhixin@kubernetes Switched to context "zhixin@kubernetes".
[root@master ~]# kubectl get pods NAME READY STATUS RESTARTS AGE client 0/1 Error 0 18d filebeat-ds-bn7wf 0/1 InvalidImageName 0 4d filebeat-ds-vd287 0/1 InvalidImageName 0 3d liveness-httpget-pod 1/1 Running 7 11d myapp-0 1/1 Running 0 23h
上面我們看到先前我們建立的zhixin使用者是沒有get pods許可權的,但是我這回把它加入了pods-reader role,也就擁有了pods-reader role的許可權。
[root@master ~]# kubectl get pods -n kube-system No resources found. Error from server (Forbidden): pods is forbidden: User "zhixin" cannot list pods in the namespace "kube-system
但是,zhixin使用者就沒有訪問kube-system許可權,因為role就沒有訪問這個名稱空間的許可權,而只有訪問default名稱空間的許可權。
rolebinding只對namespace有效。
我們再切換回到管理員。
[root@master ~]# kubectl config use-context kubernetes-admin@kubernetes Switched to context "kubernetes-admin@kubernetes".
下面我們再定義一個clusterrole。
[root@master ~]# kubectl create clusterrole cluster-reader --verb=get,list,watch --resource=pods clusterrole.rbac.authorization.k8s.io/cluster-reader created
[root@master ~]# kubectl create clusterrole cluster-reader --verb=get,list,watch --resource=pods -o yaml --dry-run apiVersion: rbac.authorization.k8s.io/v1 kind: ClusterRole metadata: creationTimestamp: null name: cluster-reader rules: - apiGroups: - "" resources: - pods verbs: - get - list - watch
[root@master ~]# kubectl explain clusterrole
[root@master ~]# kubectl get rolebinding NAME AGE zhixin-read-pods 46m
[root@master ~]# kubectl delete rolebinding zhixin-read-pods rolebinding.rbac.authorization.k8s.io "zhixin-read-pods" deleted
下面我們測試把使用者zhixin加入clusterrole裡面:
[root@master ~]# kubectl create clusterrolebinding zhixin-read-all-pods --clusterrole=cluster-reader --user=zhixin clusterrolebinding.rbac.authorization.k8s.io/zhixin-read-all-pods created
[root@master ~]# kubectl get clusterrolebinding |grep read zhixin-read-all-pods 2m
[root@master ~]# kubectl describe clusterrolebinding zhixin-read-all-pods Name: zhixin-read-all-pods Labels: <none> Annotations: <none> Role: Kind: ClusterRole Name: cluster-reader Subjects: Kind Name Namespace ---- ---- --------- User zhixin
[root@master ~]# kubectl config use-context zhixin@kubernetes Switched to context "zhixin@kubernetes".
[root@master ~]# kubectl get pods NAME READY STATUS RESTARTS AGE client 0/1 Error 0 18d filebeat-ds-bn7wf 0/1 InvalidImageName 0 4d
[root@master ~]# kubectl get pods -n kube-system NAME READY STATUS RESTARTS AGE coredns-78fcdf6894-2l2cf 1/1 Running 17 21d coredns-78fcdf6894-dkkfq 1/1 Running 16 21d
可見,我們把使用者zhixin繫結到clusterrole後,這個 使用者對所有的名稱空間都有許可權了。因為cluserrolebinding是針對叢集的,而rolebinding是隻針對namespace的。
下面我們再測試一個,把使用者用rolebinding繫結到cluserrole裡面,看是什麼效果:
[root@master ~]# kubectl config use-context kubernetes-admin@kubernetes Switched to context "kubernetes-admin@kubernetes".
[root@master ~]# kubectl delete clusterrolebinding zhixin-read-all-pods clusterrolebinding.rbac.authorization.k8s.io "zhixin-read-all-pods" deleted
[root@master ~]# kubectl create rolebinding zhixin-read-pods --clusterrole=cluster-reader --user=zhixin rolebinding.rbac.authorization.k8s.io/zhixin-read-pods created
[root@master ~]# kubectl describe rolebinding zhixin-read-pods Name: zhixin-read-pods Labels: <none> Annotations: <none> Role: Kind: ClusterRole Name: cluster-read Subjects: Kind Name Namespace ---- ---- --------- User zhixin
[root@master ~]# kubectl config use-context zhixin@kubernetes Switched to context "zhixin@kubernetes".
[root@master ~]# kubectl get pods NAME READY STATUS RESTARTS AGE client 0/1 Error 0 18d filebeat-ds-bn7wf 0/1 InvalidImageName 0 4d filebeat-ds-vd287 0/1 InvalidImageName 0 3d liveness-httpget-pod 1/1 Running 7 11d
[root@master ~]# kubectl get pods -n kube-system No resources found. Error from server (Forbidden): pods is forbidden: User "zhixin" cannot list pods in the namespace "kube-system"
可以看出,clusterrole用rolebinding繫結後,會被降級到rolebinding所在的namespace裡面。
[root@master ~]# kubectl get clusterrole admin -o yaml resources: - pods - pods/attach - pods/exec - pods/portforward - pods/proxy verbs: - create - delete - deletecollection - get - list - patch - update - watch
[root@master ~]# kubectl create rolebinding default-nameespace-admin --clusterrole=adin --user=zhixin rolebinding.rbac.authorization.k8s.io/default-nameespace-admin created
這樣,我們就把zhixin設定為default名稱空間的管理員,而不是其他名稱空間的管理員。這就是用rolebinding繫結clusterrole的功能。
[root@master ~]# kubectl get clusterrolebinding cluster-admin -o yaml - apiGroup: rbac.authorization.k8s.io kind: Group name: system:masters
[root@master pki]# openssl x509 -in ./apiserver-kubelet-client.crt -text -noout Subject: O=system:masters, CN=kube-apiserver-kubelet-client
看到system:masters組具有管理員許可權
來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/28916011/viewspace-2215100/,如需轉載,請註明出處,否則將追究法律責任。
相關文章
- docker筆記30-k8s dashboard認證及分級授權Docker筆記K8S
- Kubernetes客戶端認證(二)—— 基於ServiceAccount的JWTToken認證客戶端JWT
- Kubernetes-16:一文詳解ServiceAccount及RBAC許可權控制
- 達夢DCA認證學習筆記及體會筆記
- CA認證服務筆記筆記
- K8S原來如此簡單(八)ServiceAccount+RBACK8S
- Docker 學習筆記(第一集:認識docker)Docker筆記
- 搭建docker registry (htpasswd 認證)Docker
- Laravel 使用者認證快速指南筆記Laravel筆記
- Laravel 認證原理及完全自定義認證Laravel
- 網路身份認證——Kerberos配置及認證ROS
- Docker Register部署與基本認證Docker
- 筆記:Docker筆記Docker
- Docker筆記Docker筆記
- docker 筆記Docker筆記
- Docker開啟TLS和CA認證DockerTLS
- RHCE7認證學習筆記34——配置ISCSI筆記
- RHCE7認證學習筆記35——配置ISCSI筆記
- docker 筆記3 dockerfile語法及最佳實踐Docker筆記
- 基於MongodbDB的使用者認證-運維筆記MongoDB運維筆記
- kafka SASL認證介紹及自定義SASL PLAIN認證功能KafkaAI
- os認證、口令檔案認證及兩個引數【轉】
- docker使用筆記Docker筆記
- docker 筆記4Docker筆記
- docker 筆記2Docker筆記
- Docker Stack 筆記Docker筆記
- docker筆記(一)Docker筆記
- RBAC支援公認的安全原則
- k8s 基於RBAC的認證、授權介紹和實踐K8S
- drf-jwt原始碼分析以及自定義token簽發認證、alc和rbacJWT原始碼
- RHCE7認證學習筆記34——DNS管理與配置筆記DNS
- RHCE7認證學習筆記38——Apache配置與管理筆記Apache
- RHCE7認證學習筆記19——計劃任務筆記
- RHCE7認證學習筆記32——網路埠安全筆記
- Docker的使用筆記Docker筆記
- Docker筆記之DockerfileDocker筆記
- Docker 學習筆記Docker筆記
- Docker 入門筆記Docker筆記