第一章、前言
每一個用戶對API資源進行操作都需要通經過以下三個步驟:
第一步:對客戶端訪問進行認證操作,確認是否具有訪問k8s權限
token(共享秘鑰)
SSL(雙向SSL認證)
....
通過任何一個認證即表示認證通過,進入下一步
第二步:授權檢查,確認是否對資源具有相關的權限
ABAC(基於屬性的訪問控制)
RBAC(基於角色的訪問控制)
NODE(基於節點的訪問控制)
WEB HOOK(自定義HTTP回調方法的訪問控制)
第三步:准入控制(對操作資源相關聯的其他資源是否有權限操作)
Kubernetes只對以下的API請求屬性進行檢查:
user - username,uid group - user group "extra"- 額外信息 API - API資源的對象 Request path - 請求資源的路徑(k8s使用resultful風格接口的API) http://Node_IPaddr:6443/apis/apps/v1/namespaces/namespaces_name/resource_name/
HTTP 請求動作 - HTTP verbs get,post,put,和delete用於非資源請求 HTTP 請求動作映射到 API資源操作- get,list,create,update,patch,watch,proxy,redirect,delete,和deletecollection用於請求resource Resource -被訪問(僅用於resource 請求)的resource 的ID或名字- *對於使用resource 的請求get,update,patch,和delete,必須提供resource 名稱。 Subresource - 正在訪問的subresource (僅用於請求resource ) Namespace - 正在訪問對象的命名空間(僅針對命名空間的請求資源) API group - 正在訪問的API組(僅用於請求資源)。空字符串指定核心API組。
什么是serviceaccount
Service account是為了方便Pod里面的進程調用Kubernetes API或其他外部服務而設計的。它與User account不同 1.User account是為人設計的,而service account則是為Pod中的進程調用Kubernetes API而設計; 2.User account是跨namespace的,而service account則是僅局限它所在的namespace; 3.每個namespace都會自動創建一個default service account 4.Token controller檢測service account的創建,並為它們創建secret 5.開啟ServiceAccount Admission Controller后 1.每個Pod在創建后都會自動設置spec.serviceAccount為default(除非指定了其他ServiceAccout) 2.驗證Pod引用的service account已經存在,否則拒絕創建 3.如果Pod沒有指定ImagePullSecrets,則把service account的ImagePullSecrets加到Pod中 4.每個container啟動后都會掛載該service account的token和ca.crt到/var/run/secrets/kubernetes.io/serviceaccount/
驗證:
[root@k8s-master01 ~]# kubectl create namespace qiangungun #創建一個名稱空間 namespace "qiangungun" created [root@k8s-master01 ~]# kubectl get sa -n qiangungun #名稱空間創建完成后會自動創建一個sa NAME SECRETS AGE default 1 11s [root@k8s-master01 ~]# kubectl get secret -n qiangungun #同時也會自動創建一個secret NAME TYPE DATA AGE default-token-5jtz2 kubernetes.io/service-account-token 3 19s
在創建的名稱空間中新建一個pod
[root@k8s-master01 pod-example]# cat pod_demo.yaml kind: Pod apiVersion: v1 metadata: name: task-pv-pod namespace: qiangungun spec: containers: - name: nginx image: ikubernetes/myapp:v1 ports: - containerPort: 80 name: www
查看pod信息
[root@k8s-master01 pod-example]# kubectl apply -f pod_demo.yaml pod "task-pv-pod" created [root@k8s-master01 pod-example]# kubectl get pod -n qiangungun NAME READY STATUS RESTARTS AGE task-pv-pod 1/1 Running 0 13s [root@k8s-master01 pod-example]# kubectl get pod task-pv-pod -o yaml -n qiangungun ...... volumeMounts: - mountPath: /var/run/secrets/kubernetes.io/serviceaccount name: default-token-5jtz2 ...... volumes: #掛載sa的secret - name: default-token-5jtz2 secret: defaultMode: 420 secretName: default-token-5jtz2 ......
#名稱空間新建的pod如果不指定sa,會自動掛載當前名稱空間中默認的sa(default)
第二章、創建serviceaccount(以下簡稱sa)
[root@k8s-master01 ~]# kubectl create serviceaccount admin #創建一個sa 名稱為admin serviceaccount "admin" created [root@k8s-master01 ~]# kubectl get sa NAME SECRETS AGE admin 1 6s default 1 28d [root@k8s-master01 ~]# kubectl describe sa admin #查看名稱為admin的sa的信息,系統會自動創建一個token信息 Name: admin Namespace: default Labels: <none> Annotations: <none> Image pull secrets: <none> Mountable secrets: admin-token-rxtrc Tokens: admin-token-rxtrc Events: <none> [root@k8s-master01 ~]# kubectl get secret #會自動創建一個secret(admin-token-rxtrc),用於當前sa連接至當前API server時使用的認證信息 NAME TYPE DATA AGE admin-token-rxtrc kubernetes.io/service-account-token 3 1m default-token-tcwjz kubernetes.io/service-account-token 3 28d myapp-ingress-secret kubernetes.io/tls 2 6h mysql-passwd Opaque 1 17d tomcat-ingress-secret kubernetes.io/tls 2 7h
創建一個pod應用剛剛創建的sa
[root@k8s-master01 service_account]# cat deploy-demon.yaml apiVersion: v1 kind: Pod metadata: name: sa-demo labels: app: myapp release: canary spec: containers: - name: myapp image: ikubernetes/myapp:v2 ports: - name: httpd containerPort: 80 serviceAccountName: admin #此處指令為指定sa的名稱 [root@k8s-master01 service_account]# kubectl apply -f deploy-demon.yaml pod "sa-demo" created [root@k8s-master01 service_account]# kubectl describe pod sa-demo ...... Mounts: /var/run/secrets/kubernetes.io/serviceaccount from admin-token-rxtrc (ro) #pod會自動掛載自己sa的證書 ......
Volumes:
admin-token-rxtrc:
Type: Secret (a volume populated by a Secret)
SecretName: admin-token-rxtrc
......
集群交互的時候少不了的是身份認證,使用 kubeconfig(即證書) 和 token 兩種認證方式是最簡單也最通用的認證方式,下面我使用kubeconfing來進行認證
使用kubeconfig文件來組織關於集群,用戶,名稱空間和身份驗證機制的信息。使用 kubectl命令行工具對kubeconfig文件來查找選擇群集並與群集的API服務器進行通信所需的信息。
默認情況下 kubectl使用的配置文件名稱是在$HOME/.kube目錄下 config文件,可以通過設置環境變量KUBECONFIG或者--kubeconfig指定其他的配置文件
查看系統的kubeconfig
[root@k8s-master01 ~]# kubectl config view apiVersion: v1 clusters: #集群列表 - cluster: certificate-authority-data: REDACTED #認證集群的方式 server: https://172.16.150.212:6443 #訪問服務的APIserver的路徑
name: kubernetes #集群的名稱 contexts: #上下文列表 - context: cluster: kubernetes #訪問kubernetes這個集群 user: kubernetes-admin #使用 kubernetes-admin賬號 name: kubernetes-admin@kubernetes #給定一個名稱 current-context: kubernetes-admin@kubernetes #當前上下文,表示使用哪個賬號訪問哪個集群 kind: Config preferences: {} users: #用戶列表 - name: kubernetes-admin #用戶名稱 user: client-certificate-data: REDACTED #客戶端證書,用於與apiserver進行認證 client-key-data: REDACTED #客戶端私鑰
[root@k8s-master01 ~]# kubectl get svc NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE kubernetes ClusterIP 10.96.0.1 <none> 443/TCP 29d my-nginx NodePort 10.104.13.148 <none> 80:32008/TCP 18h myapp ClusterIP 10.102.229.150 <none> 80/TCP 19h tomcat ClusterIP 10.106.222.72 <none> 8080/TCP,8009/TCP 19h [root@k8s-master01 ~]# 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.150.212:6443 #可以看到此處svc后端的Endpoint是當前節點的IP地址,通過svc的IP地址進行映射,以確保cluster中的pod可以通過該sa與集群內api進行通訊,僅僅是身份認證 Session Affinity: ClientIP Events: <none>
查看kubeconfig命令行配置幫助
[root@k8s-master01 ~]# kubectl config --help Modify kubeconfig files using subcommands like "kubectl config set current-context my-context" The loading order follows these rules: 1. If the --kubeconfig flag is set, then only that file is loaded. The flag may only be set once and no merging takes place. 2. If $KUBECONFIG environment variable is set, then it is used a list of paths (normal path delimitting rules for your system). These paths are merged. When a value is modified, it is modified in the file that defines the stanza. When a value is created, it is created in the first file that exists. If no files in the chain exist, then it creates the last file in the list. 3. Otherwise, ${HOME}/.kube/config is used and no merging takes place. Available Commands: current-context 顯示 current_context delete-cluster 刪除 kubeconfig 文件中指定的集群 delete-context 刪除 kubeconfig 文件中指定的 context get-clusters 顯示 kubeconfig 文件中定義的集群 get-contexts 描述一個或多個 contexts rename-context Renames a context from the kubeconfig file. set 設置 kubeconfig 文件中的一個單個值 set-cluster 設置 kubeconfig 文件中的一個集群條目 set-context 設置 kubeconfig 文件中的一個 context 條目 set-credentials 設置 kubeconfig 文件中的一個用戶條目 unset 取消設置 kubeconfig 文件中的一個單個值 use-context 設置 kubeconfig 文件中的當前上下文 view 顯示合並的 kubeconfig 配置或一個指定的 kubeconfig 文件 Usage: kubectl config SUBCOMMAND [options] Use "kubectl <command> --help" for more information about a given command. Use "kubectl options" for a list of global command-line options (applies to all commands).
第三章、創建一個cluster用戶及context
使用當前系統的ca證書認證一個私有證書
[root@k8s-master01 ~]# cd /etc/kubernetes/pki/ [root@k8s-master01 pki]# (umask 077;openssl genrsa -out qiangungun.key 2048) Generating RSA private key, 2048 bit long modulus .........................+++ ..........................................................+++ e is 65537 (0x10001) [root@k8s-master01 pki]# openssl req -new -key qiangungun.key -out qiangungun.csr -subj "/CN=qiangungun" #qiangungun是后面我們創建的用戶名稱,需要保持一致 [root@k8s-master01 pki]# openssl x509 -req -in qiangungun.csr -CA ca.crt -CAkey ca.key -CAcreateserial -out qiangungun.crt -days 3650 Signature ok subject=/CN=qiangungun Getting CA Private Key
查看證書內容
[root@k8s-master01 pki]# openssl x509 -in qiangungun.crt -text -noout Certificate: Data: Version: 1 (0x0) Serial Number: b6:06:cb:30:86:e3:fe:84 Signature Algorithm: sha256WithRSAEncryption Issuer: CN=kubernetes #由誰簽署的 Validity #證書的有效時間 Not Before: Nov 27 15:09:41 2018 GMT Not After : Nov 24 15:09:41 2028 GMT Subject: CN=qiangungun #證書使用的用戶 Subject Public Key Info: Public Key Algorithm: rsaEncryption Public-Key: (2048 ......
創建一個當前集群用戶
[root@k8s-master01 pki]# kubectl config set-credentials qiangungun --client-certificate=./qiangungun.crt --client-key=./qiangungun.key --embed-certs=true #--embed-certs表示是否隱藏證書路徑及名稱,默認不隱藏 User "qiangungun" set. [root@k8s-master01 pki]# kubectl config view apiVersion: v1 clusters: - cluster: certificate-authority-data: REDACTED server: https://172.16.150.212: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
- name: qiangungun #我們新建的用戶 user: client-certificate-data: REDACTED client-key-data: REDACTED
為qiangungun用戶創建一個context
[root@k8s-master01 pki]# kubectl config set-context qiangungun@kubernetes --cluster=kubernetes --user=qiangungun Context "qiangungun@kubernetes" created. [root@k8s-master01 pki]# kubectl config view apiVersion: v1 clusters: - cluster: certificate-authority-data: REDACTED server: https://172.16.150.212:6443
name: kubernetes contexts: - context: cluster: kubernetes user: kubernetes-admin name: kubernetes-admin@kubernetes - context: #新創建的context cluster: kubernetes user: qiangungun name: qiangungun@kubernetes current-context: kubernetes-admin@kubernetes kind: Config preferences: {} users: - name: kubernetes-admin user: client-certificate-data: REDACTED client-key-data: REDACTED- name: qiangungun user: client-certificate-data: REDACTED client-key-data: REDACTED
切換serviceaccount
[root@k8s-master01 pki]# kubectl config use-context qiangungun@kubernetes Switched to context "qiangungun@kubernetes". [root@k8s-master01 pki]# kubectl get pod Error from server (Forbidden): pods is forbidden: User "qiangungun" cannot list pods in the namespace "default"
自定義一個cluster
[root@k8s-master01 pki]# kubectl config set-cluster mycluster --kubeconfig=/tmp/test.conf --server="https://172.16.150.212:6443" --certificate-authority=/etc/kubernetes/pki/ca.crt --embed-certs=true Cluster "mycluster" set. [root@k8s-master01 pki]# kubectl config view --kubeconfig=/tmp/test.conf apiVersion: v1 clusters: - cluster: certificate-authority-data: REDACTED server: https://172.16.150.212:6443
name: mycluster contexts: [] current-context: "" kind: Config preferences: {} users: []
