K8s之認證,授權及准入控制
阿新 • • 發佈:2020-07-13
第1章 訪問認證的概述
1.1 概念的引入
API Server作為Kubernetes集群系統的閘道器,是訪問及管理資源物件的唯一人口, 餘下所有需要訪問叢集資源的元件,包括kube-controller-manager、kube- scheduler 、 kubelet和kube-proxy等叢集基礎元件、CoreDNS等叢集的附加元件以及此前使用的kubectl 命令等都要經由此閘道器進行叢集訪問和管理。這些客戶端均要經由API Server訪問或改變叢集狀態並 完成資料儲存,並由它對每一次的訪問請求進行合法性檢驗,包括使用者身份鑑別、操作許可權 驗證以及操作是否符合全域性規範的約束等。所有檢查均正常完成且物件配置資訊合法性檢驗 無誤之後才能訪問或存人資料於後端儲存系統etcd中
第2章 ServiceAccount
2.1 概述
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 開啟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/
2.2 檢視相關資訊
當建立pod的時候,如果沒有指定一個service account,系統會自動在與該pod相同的namespace下為其指派一個default service account。 而pod和apiserver之間進行通訊的賬號,稱為serviceAccountName。如下: [root@master ~]# kubectl get pods NAME READY STATUS RESTARTS AGE filebeat-ds-hxgdx 1/1 Running 1 34d filebeat-ds-s466l 1/1 Running 2 34d myapp-0 1/1 Running 0 3h myapp-1 1/1 Running 0 3h myapp-2 1/1 Running 0 4h myapp-3 1/1 Running 0 4h pod-vol-demo 2/2 Running 0 2d redis-5b5d6fbbbd-q8ppz 1/1 Running 1 2d [root@master ~]# kubectl get pods/myapp-0 -o yaml |grep "serviceAccountName" serviceAccountName: default [root@k8s-master ~]# kubectl describe pods myapp-0 Name: myapp-0 Namespace: default ...... Volumes: ...... default-token-j5pf5: Type: Secret (a volume populated by a Secret) SecretName: default-token-j5pf5 Optional: false 從上面可以看到每個Pod無論定義與否都會有個儲存卷,這個儲存卷為default-token-*** token令牌, 這就是pod和serviceaccount認證資訊。通過secret進行定義,由於認證資訊屬於敏感資訊,所以需要儲存在secret資源當中, 並以儲存卷的方式掛載到Pod當中。從而讓Pod內執行的應用通過對應的secret中的資訊來連線apiserver,並完成認證。 每個namespace中都有一個預設的叫做default的service account資源。進行檢視名稱空間內的secret也可以看到對應的default-token。 讓當前名稱空間中所有的pod在連線apiserver時可以使用的預製認證資訊,從而保證pod之間的通訊。
2.3 service account定義的方式
[root@master ~]# kubectl explain sa
KIND: ServiceAccount
VERSION: v1
FIELDS:
apiVersion <string>
automountServiceAccountToken <boolean>
imagePullSecrets <[]Object>
kind <string>
metadata <Object>
secrets <[]Object>
2.4 service account的建立
[root@master mainfests]# kubectl create serviceaccount mysa -o yaml --dry-run #不執行檢視定義方式
apiVersion: v1
kind: ServiceAccount
metadata:
creationTimestamp: null
name: mysa
[root@master mainfests]# kubectl create serviceaccount mysa -o yaml --dry-run > serviceaccount.yaml #直接匯出為yaml定義檔案,可以節省敲鍵盤的時間
[root@master mainfests]# kubectl apply -f serviceaccount.yaml
serviceaccount/mysa created
[root@master mainfests]# kubectl get serviceaccount/mysa -o yaml
apiVersion: v1
kind: ServiceAccount
metadata:
annotations:
kubectl.kubernetes.io/last-applied-configuration: |
{"apiVersion":"v1","kind":"ServiceAccount","metadata":{"annotations":{},"creationTimestamp":null,"name":"mysa","namespace":"default"}}
creationTimestamp: 2018-10-11T08:12:25Z
name: mysa
namespace: default
resourceVersion: "432865"
selfLink: /api/v1/namespaces/default/serviceaccounts/mysa
uid: 62fc7782-cd2d-11e8-801a-000c2972dc1f
secrets:
- name: mysa-token-h2mgk
看到有一個token已經被自動建立,並被service account引用。設定非預設的service account
只需要在pod的spec.serviceAccountName欄位中將name設定為您想要用的service account名字即可。
在pod建立之初service account就必須已經存在,否則建立將被拒絕。需要注意的是不能更新已建立的pod的service account
2.5 serviceaccount的自定義使用
這裡在default名稱空間建立了一個sa為admin,可以看到已經自動生成了一個Tokens:admin-token-7k5nr
[root@master mainfests]# kubectl create serviceaccount admin
serviceaccount/admin created
[root@master mainfests]# kubectl get sa
NAME SECRETS AGE
admin 1 3s
default 1 50d
[root@master mainfests]# kubectl describe sa/admin
Name: admin
Namespace: default
Labels: <none>
Annotations: <none>
Image pull secrets: <none>
Mountable secrets: admin-token-7k5nr
Tokens: admin-token-7k5nr
Events: <none>
[root@master mainfests]# kubectl get secret
NAME TYPE DATA AGE
admin-token-7k5nr kubernetes.io/service-account-token 3 31s
default-token-j5pf5 kubernetes.io/service-account-token 3 50d
mysecret Opaque 2 1d
tomcat-ingress-secret kubernetes.io/tls 2 10d
[root@master mainfests]# vim pod-sa-demo.yaml #Pod中引用新建的serviceaccount
apiVersion: v1
kind: Pod
metadata:
name: pod-sa-demo
namespace: default
labels:
app: myapp
tier: frontend
spec:
containers:
- name: myapp
image: ikubernetes/myapp:v1
ports:
- name: http
containerPort: 80
serviceAccountName: admin
[root@master mainfests]# kubectl apply -f pod-sa-demo.yaml
pod/pod-sa-demo created
[root@master mainfests]# kubectl describe pods pod-sa-demo
......
Volumes:
admin-token-7k5nr:
Type: Secret (a volume populated by a Secret)
SecretName: admin-token-7k5nr
Optional: false
在K8S叢集當中,每一個使用者對資源的訪問都是需要通過apiserver進行通訊認證才能進行訪問的,那麼在此機制當中,對資源的訪問可以是token,也可以是通過配置檔案的方式進行儲存和使用認證資訊,可以通過kubectl config進行檢視配置,如下:
[root@master mainfests]# kubectl config view
apiVersion: v1
clusters: #叢集列表
- cluster:
certificate-authority-data: REDACTED
server: https://192.168.56.11: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
在上面的配置檔案當中,定義了叢集、上下文以及使用者。其中Config也是K8S的標準資源之一,在該配置檔案當中定義了一個叢集列表,指定的叢集可以有多個;
使用者列表也可以有多個,指明叢集中的使用者;而在上下文列表當中,是進行定義可以使用哪個使用者對哪個叢集進行訪問,以及當前使用的上下文是什麼。
如圖:定義了使用者kubernetes-admin可以對kubernetes該叢集的訪問,使用者kubernetes-user1對Clluster1叢集的訪問
上圖解析:
1. kubectl config中定義了有哪些叢集和哪些使用者(都是以列表的形式)
2. contexts就是定義哪個使用者去訪問哪個叢集(從kubectl config中選出來)
3. contexts可以是多個的(一個contexts用來包含一個賬號和一個叢集),所以用的列表的形式
4. current-context: kubernetes-admin@kubernetes 就是表示從眾多的contexts選出一個當前使用的contexts