目錄
概述
1.kubernetes API訪問控制
2.認(rèn)證 Authentication
ServiceAccount令牌認(rèn)證
示例: 查看Pod 默認(rèn)ServiceAccount及Secret
概述:
1. kubernetes API 訪問控制
官方文檔:
https://kubernetes.io/zh/docs/reference/access-authn-authz/controlling-access/
kubernetes api分為:認(rèn)證、授權(quán)、準(zhǔn)入控制
-
用戶通過 kubectl、客戶端庫或者通過發(fā)送 REST 請求訪問 API。 用戶(自然人)和 Kubernetes 服務(wù)賬戶 都可以被授權(quán)進(jìn)行 API 訪問。 請求到達(dá) API 服務(wù)器后會(huì)經(jīng)過幾個(gè)階段,具體說明如圖:
首先看一下 Kubernetes API 請求的發(fā)起,請求的發(fā)起分為兩個(gè)部分:
- 第一個(gè)部分是人機(jī)交互的過程。 是大家非常熟悉的用 kubectl 對 apiserver 的一個(gè)請求過程 使用的是 Users Accounts普通賬戶;
- 第二個(gè)部分是 Pod 中的業(yè)務(wù)邏輯與 apiserver 之間的交互 使用的是Service Accounts 服務(wù)帳號(hào)。
- 當(dāng)我們的 apiserver 收到請求后,就會(huì)開啟訪問控制流程。這里面分為三個(gè)步驟:
- Authentication 認(rèn)證階段:判斷請求用戶是否為能夠訪問集群的合法用戶。如果用戶是個(gè)非法用戶,那 apiserver會(huì)返回一個(gè) 401 的狀態(tài)碼,并終止該請求;
- 如果用戶合法的話,我們的 apiserver 會(huì)進(jìn)入到訪問控制的第二階段 Authorization:授權(quán)階段。在該階段中apiserver 會(huì)判斷用戶是否有權(quán)限進(jìn)行請求中的操作。如果無權(quán)進(jìn)行操作,apiserver 會(huì)返回 403的狀態(tài)碼,并同樣終止該請求;
- 如果用戶有權(quán)進(jìn)行該操作的話,訪問控制會(huì)進(jìn)入到第三個(gè)階段:AdmissionControl。在該階段中 apiserver 的admission controller 會(huì)判斷請求是否是一個(gè)安全合規(guī)的請求。如果最終驗(yàn)證通過的話,訪問控制流程才會(huì)結(jié)束。
此時(shí)我們的請求將會(huì)轉(zhuǎn)換為一個(gè) Kubernetes objects 相應(yīng)的變更請求,最終持久化到 ETCD 中。
認(rèn)證(任意一種) -->授權(quán)(一般是rbac 和 node)–> 準(zhǔn)入控制(自己選擇)

2. 認(rèn)證 Authentication
認(rèn)證有多種,可以啟動(dòng)一種或多種認(rèn)證方式,只要有一種認(rèn)證方式通過,就不再對其它方式認(rèn)證,通常啟動(dòng)X 509 Client Certs和Service Accout Tokens兩種認(rèn)證方式
- 常見的認(rèn)證:
- 引導(dǎo)令牌(Token) : 如:節(jié)點(diǎn)加入時(shí)認(rèn)證:kubelet
- 靜態(tài)令牌: 存儲(chǔ)于API Server進(jìn)程可直接加載到的文件中保存的令牌,該文件內(nèi)容會(huì)由API Server緩存于內(nèi)存中;
- 靜態(tài)密碼:存儲(chǔ)于API Server進(jìn)程可直接加載到的文件中保存的賬戶和密碼令牌,該文件內(nèi)容會(huì)由API Server緩存于內(nèi)存中;
- ServiceAccount令牌:
- OpenID Connect令牌:OIDC令牌,
- OAuth 2 webhook令牌
- 代理認(rèn)證等
訪問k8s的API Server的客戶端主要分為兩類:
kubectl :用戶家目錄中的 .kube/config 里面保存了客戶端訪問API Server的密鑰相關(guān)信息,這樣當(dāng)用kubectl訪問k8s時(shí),它就會(huì)自動(dòng)讀取該配置文件,向API Server發(fā)起認(rèn)證,然后完成操作請求,使用Users Accounts普通賬戶。
pod:Pod中的進(jìn)程需要訪問API Server,如果是人去訪問或編寫的腳本去訪問,這類訪問使用的賬號(hào)為:UserAccount;而Pod自身去連接API Server時(shí),使用的賬號(hào)是:ServiceAccount,生產(chǎn)中后者使用居多。
kubectl 向 apiserver發(fā)起的命令,采用的時(shí)http方式,其實(shí)就是對URL發(fā)起增刪改查的操作。
[root@k8s-master ~]# kubectl proxy --port=8888 &
[root@k8s-master ~]# curl http://localhost:8888/api/v1/namespaces/default
[root@k8s-master ~]# curl http://localhost:8888/apis/apps/v1/namespaces/default/deployments
- 以上兩種api的區(qū)別是:
api它是一個(gè)特殊鏈接,只有在核心v1群組中的對象才能使用。
apis 它是一般API訪問的入口固定格式名
ServiceAccount令牌認(rèn)證
K8S自動(dòng)為每個(gè)Pod注入一個(gè)ServiceAccount令牌,在每個(gè)名稱空間中,會(huì)自動(dòng)存在(由ServiceAccount準(zhǔn)入控制器負(fù)責(zé))一個(gè)ServiceAccount,將被該空間下的每個(gè)Pod共享使用。
認(rèn)證令牌保存于該空間下的一個(gè)Secret對象中,該對象中共有三個(gè)信息:
1.namespace
2.ca.crt
3.token資源定義格式:
apiVersion: v1 #ServiceAccount所屬的API群組及版本
kind: serviceAccount #資源類型標(biāo)識(shí)
metadata:
name <string> #資源名稱
namespace <string> # ServiceAccount是名稱空間級別的資源
automountServiceAccountToken <boolean> # 是否讓Pod自動(dòng)掛載API令牌
secrets <[]object> #以該SA運(yùn)行的Pod所要使用的Secret對象組成的列表
apiVersion <string> #引用的Secret對象所屬的API群組及版本,可省略
kind <string> #引用的資源的類型,這里是指Secret,可省略
name <string> #引用的Secret對象的名稱,通常僅給出該字段即可
namespace <string> #引用的Secret對象所屬的名稱空間
uid <string># 引用的Secret對象的標(biāo)識(shí)符;
imagePullSecrets <[]object> # 引用的用于下載Pod中容器鏡像的Secret對象列表 之前講到secret時(shí)提到過Pod掛載私有倉庫secret,實(shí)際使用不方便需要每個(gè)Pod單獨(dú)掛載,放到serviceaccount就不用每個(gè)Pod單獨(dú)掛載
name <string> #docker-registry類型的Secret資源的名稱
示例: 查看Pod 默認(rèn)ServiceAccount及Secret
[root@k8s-master ~]# kubectl get pod
NAME READY STATUS RESTARTS AGE
centos-deployment-66d8cd5f8b-9x47c 1/1 Running 1 41h
demodb-0 1/1 Running 0 17h
demodb-1 1/1 Running 0 16h
- 默認(rèn)情況下沒有指定ServiceAccount都會(huì)把默認(rèn)的ServiceAccount掛載到Pod
[root@k8s-master ~]# kubectl describe pod demodb-0
Annotations: <none>
...
Mounts:
/demodb/data from data (rw)
/var/run/secrets/kubernetes.io/serviceaccount from default-token-fsshk (ro) #默認(rèn)的ServiceAccount令牌
...
Volumes:
data:
Type: PersistentVolumeClaim (a reference to a PersistentVolumeClaim in the same namespace)
ClaimName: data-demodb-0
ReadOnly: false
default-token-fsshk: #默認(rèn)的ServiceAccount令牌 存儲(chǔ)卷
Type: Secret (a volume populated by a Secret)
SecretName: default-token-fsshk
Optional: false
QoS Class: BestEffort
Node-Selectors: <none>
Tolerations: node.kubernetes.io/not-ready:NoExecute op=Exists for 300s
node.kubernetes.io/unreachable:NoExecute op=Exists for 300s
Events: <none>
- 每個(gè)名稱空間下都自動(dòng)生成一個(gè)默認(rèn)的secret
[root@k8s-master ~]# kubectl get secret
NAME TYPE DATA AGE
default-token-fsshk kubernetes.io/service-account-token 3 51d
harbor-tom kubernetes.io/dockerconfigjson 1 11d
mysql-root-authn Opaque 2 11d
nginx-ssl-secret kubernetes.io/tls 2 11d
web-basic-authn kubenetes.io/basic-auth 2 11d
[root@k8s-master ~]# kubectl get secret -n kube-system
NAME TYPE DATA AGE
attachdetach-controller-token-bpprw kubernetes.io/service-account-token 3 51d
bootstrap-signer-token-69hd8 kubernetes.io/service-account-token 3 51d
bootstrap-token-hbjzpz bootstrap.kubernetes.io/token 5 14d
certificate-controller-token-26sn8 kubernetes.io/service-account-token 3 51d
clusterrole-aggregation-controller-token-hlb6c kubernetes.io/service-account-token 3 51d
coredns-token-k6swp kubernetes.io/service-account-token 3 51d
cronjob-controller-token-449ng kubernetes.io/service-account-token 3 51d
daemon-set-controller-token-qb22n kubernetes.io/service-account-token 3 51d
default-token-xjfpp kubernetes.io/service-account-token 3 51d
...
- 主要包含的3類信息 都是以加密方式顯示 1. namespace、2. ca.crt、3. token
[root@k8s-master ~]# kubectl describe secret default-token-xjfpp -n kube-system #查看secret 詳細(xì)信息
Name: default-token-xjfpp
Namespace: kube-system
Labels: <none>
Annotations: kubernetes.io/service-account.name: default
kubernetes.io/service-account.uid: a7cfad17-e87a-42dd-8f34-46181dd43b05
Type: kubernetes.io/service-account-token
Data
====
ca.crt: 1066 bytes
namespace: 11 bytes
token: eyJhbGciOiJSUzI1NiIsImtpZCI6Ijh4bkpFMkMxV0FtZmxPTmxsV3ZhY3lIRnZiRjlaUnhFSXdHSnRGc21adUUifQ.eyJpc3MiOiJrdWJlcm5ldGVzL3NlcnZpY2VhY2NvdW50Iiwia3ViZXJuZXRlcy5pby9zZXJ2aWNlYWNjb3VudC9uYW1lc3BhY2UiOiJrdWJlLXN5c3RlbSIsImt1YmVybmV0ZXMuaW8vc2VydmljZWFjY291bnQvc2VjcmV0Lm5hbWUiOiJkZWZhdWx0LXRva2VuLXhqZnBwIiwia3ViZXJuZXRlcy5pby9zZXJ2aWNlYWNjb3VudC9zZXJ2aWNlLWFjY291bnQubmFtZSI6ImRlZmF1bHQiLCJrdWJlcm5ldGVzLmlvL3NlcnZpY2VhY2NvdW50L3NlcnZpY2UtYWNjb3VudC51aWQiOiJhN2NmYWQxNy1lODdhLTQyZGQtOGYzNC00NjE4MWRkNDNiMDUiLCJzdWIiOiJzeXN0ZW06c2VydmljZWFjY291bnQ6a3ViZS1zeXN0ZW06ZGVmYXVsdCJ9.ifUAhcEjhmSszILrjPkbmKAKuo6nDBPrmQTjz6HjBXw85eTsu-D5CCjGwSaVj7X6xqK3GTwcv-r8518pSv92rfbN5cc9FdpknJGjtuigCrksap1gHcqZvco3BM7KFEaTFpCaxiVvzp6YBh4pVmm4zAJGieE8964m3SwZqXUmf3VP3LyVDrYnlISQXoXy5oEXODe8694H1vwU3wuRmkwLOCV5QthTxFpx5siM7_KFkcBuG-pt0lTbf6d15OXk-WY6J3qkdbmLrJFaofAo-1tas6Fp7ziQnIAkG_lTrbXPHD-rHJf9v1PobVIVvlEe5hKc_V1tE36SEwpIYHb61DfWRw
- Pod 默認(rèn)的掛載路徑 /var/run/secrets/kubernetes.io/serviceaccount
[root@k8s-master authfiles]# kubectl exec -it demodb-0 -- /bin/sh
/demodb/data # cd /var/run/secrets/kubernetes.io/serviceaccount
/run/secrets/kubernetes.io/serviceaccount # ls
ca.crt namespace token
/run/secrets/kubernetes.io/serviceaccount # cat namespace
/run/secrets/kubernetes.io/serviceaccount # cat ca.crt
-----BEGIN CERTIFICATE-----
MIIC5zCCAc+gAwIBAgIBADANBgkqhkiG9w0BAQsFADAVMRMwEQYDVQQDEwprdWJl
cm5ldGVzMB4XDTIxMDYyODE3NDIxMFoXDTMxMDYyNjE3NDIxMFowFTETMBEGA1UE
AxMKa3ViZXJuZXRlczCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAMwQ
mCJJ0GuIDdzZa8XAJIy7BRUGBT0oI0lVuWc3PD25whr1MBRyUru0u0n7mKVQTzbY
0G8USHzwSnX51OoMpU5YwHK6WGLgJ6gdCfjAY6v12e7y+rvjOKYns6ljUf2MnaIL
nrCy1/u56Lnh1wCH1XkLECP539MFamYkRGxeS9FZlFcgLvJp43VX9V4IWQeumHd9
1abKVei/41qbbvyDU7l4l7klUmLUTGDlYpf1GPU/Jaom4QLRaEt2csYcNZ8J3yaY
GvOloGM150Rsx4vL8DWOqZcUUg/uXujKg1MfWRrD9KvqK1QdP92IE+l6nXUKY34r
voDCmOcL8J0nPyjbyf0CAwEAAaNCMEAwDgYDVR0PAQH/BAQDAgKkMA8GA1UdEwEB
/wQFMAMBAf8wHQYDVR0OBBYEFOwi2wrUbuvVmbiV2rnnLtz0hsgcMA0GCSqGSIb3
DQEBCwUAA4IBAQBCFkEU4gyouDs4hG0pjdlrJRkDw1kKg1JV8m3CqcKUKmJBUT9H
9R8LaU2s/6yS5zX3VSdUNgF1V/hpjUJ6bSud9Xfnmbw8lHKUucUSIWU9a+TGTvkn
DqI8FcC8gKstUAwagxdRwj3KEy7HSAcbMXjKFSdAlQ2Qq7CG8vLXilurHhEEbrzq
unbuVjJ80gIWeeo23HkAbjOiTiSokN2AoGyGW9eS3bMLSJgMHzLtX80uWwS75jc3
2mMrYe59nzGIR2yY2zxkmmj6DOLoMQKyJlqPC2fGKyAv0N79QKAGl7JjbXzYvaV2
egWtCk0FHnfah9Fu+/P8pNtY8agSluneeHkL
-----END CERTIFICATE-----
/run/secrets/kubernetes.io/serviceaccount #
