Kubernetes ---- API Server認證、配置文件、自定義用戶連接API Server

客戶端請求API Server過程

客戶端 --> API Server(識別用戶是否有通過api server執行操作的權限)
  api Server識別內容:
    user: username,uid
    group: 用戶組
    extra: 字段,提供額外信息

 

客戶端請求的API(Request Path):
例如客戶端對一個k8s集羣中的名爲myapp-deploy的deployment的資源發起請求,地址爲下,成功的話則可進行增刪改查;
  http://192.168.133.128:6443/apis/apps/v1/namespaces/default/deployments/myapp-deploy

  註釋:
    192.168.222.100: master地址
    6443: API server端口
    apis: 固定入口(除核心羣組(/api/v1/)外)
    apps: app組
    v1: 組版本
    namespaces: 名稱空間級別
    default: 名稱空間的名稱
    deployments: 訪問deployment資源
    myapp-deploy: deployment名稱

請求操作(action):
  http的方法請求:
    get
    post
    put
    delete
  k8s請求動作:
    增: create
    刪: delete,deletecollection(刪除一個集合)
    改: edit,patch
    查: get,list,watch(-w)

API Server是整個訪問請求進入的網關接口,請求過程中
  認證用於實現身份識別;
  授權用於實現權限檢查,檢查用戶是否擁有對資源執行各種k8s請求動作;
  准入控制機制用來進一步補充授權機制,創建、刪除、修改時需要;


k8s集羣有兩類認證時的認證賬號:
1. useraccount
2. serviceaccount

訪問API Server的客戶端分爲以下兩類:
  1. 集羣之外的客戶端訪問節點地址進行通信;
  2. 集羣內部的Pod等,使用API Server在集羣內的地址(kubectl get svc(kubernetes這個svc),將集羣外部地址引入到集羣內部供內部組件使用;

  # 經過查看某一個Pod的詳細信息發現Pod會自動擁有一個Volumes,這個Volumes的名稱叫做"default-token-ppzsj"也就是令牌,這就是Pod連接API Server的認證信息,通過secret來定義,並以存儲卷的方式關聯到Pod上,
使Pod內的運行的應用通過對應的secret中保存的認證信息連接API Server來完成認證的;

$ kubectl describe pod deploy-demo-854b57c687-f7txr
....
Volumes:
default-token-ppzsj:
Type: Secret (a volume populated by a Secret)
SecretName: default-token-ppzsj
Optional: false
QoS Class: BestEffort
Node-Selectors: <none>
Tolerations: node.kubernetes.io/not-ready:NoExecute for 300s
node.kubernetes.io/unreachable:NoExecute for 300s
....

# 經查,發現每個名稱空間下都會有一個默認的secret(default-token-ppzsj)

$ kubectl get secret
NAME             TYPE               DATA   AGE
default-token-ppzsj kubernetes.io/service-account-token 3   26d

創建Pod與API Server通信的serviceaccount(與權限無關,僅認證):

# 首先查看系統上已有的serviceaccount;
$ kubectl get serviceaccount
NAME     SECRETS    AGE
default     1       26d

# 直接使用create創建一個名爲admin的sa;
$ kubectl create sa admin

# 再次查詢,發現創建成功;
$ kubectl get sa
NAME   SECRETS   AGE
admin     1      84s
default   1      26d

# 查看sa的詳細信息,發現了名爲"admin-token-pfp5j"的secret;
$ kubectl describe sa admin
Name: admin
Namespace: default
Labels: <none>
Annotations: <none>
Image pull secrets: <none>
Mountable secrets: admin-token-pfp5j
Tokens: admin-token-pfp5j
Events: <none>

# 查看secret,發現剛創建的sa自動創建了一個"admin-token-pfp5j"secret;
$ kubectl get secret
NAME               TYPE               DATA   AGE
admin-token-pfp5j kubernetes.io/service-account-token    3   2m32s
default-token-ppzsj kubernetes.io/service-account-token   3   26d

# 創建Pod使用新創建的sa;
$ vim pod-sa.yaml
apiVersion: v1
kind: Pod
metadata:
  name: pod-sa
  namespace: default
spec:
  containers:
  - name: sa-container
    image: ikubernetes/myapp:v1
    imagePullPolicy: IfNotPresent
    ports:
    - name: http
      containerPort: 80
  # 自定義serviceaccount的名稱
  serviceAccountName: admin

$ kubectl apply -f pod-sa.yaml

# 查看詳細信息發現默認自帶的volumes中的名稱變爲了"admin-token-pfp5j"也就是我們剛創建sa後,集羣自動幫我們創建的secret;
$ kubectl describe pods pod-sa
....
Volumes:
admin-token-pfp5j:
Type: Secret (a volume populated by a Secret)
SecretName: admin-token-pfp5j
Optional: false
QoS Class: BestEffort
Node-Selectors: <none>
Tolerations: node.kubernetes.io/not-ready:NoExecute for 300s
node.kubernetes.io/unreachable:NoExecute for 300s
....

 

配置文件連接API Server:
  API Server的客戶端在認證時,如果我們要基於配置文件來保存客戶端的認證信息,就要配置個配置文件,k8s集羣中的所有組件,除API Server外都需要連接至API Server,都需要被API Server認證
每一個組件爲了能夠連入正確的集羣,提供正確的賬號、證書、私鑰等認證信息,需要將這些信息保存爲配置文件(kubeconfig),也就是API Server的客戶端連入API Server時使用的認證格式的配置文件;

# 查看配置
$ kubectl config view
apiVersion: v1
clusters:
- cluster:
certificate-authority-data: DATA+OMITTED
server: https://192.168.133.128: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

註釋:
  clusters: 集羣列表,可以包含多個集羣
  certificate-authority-data: 認證方式
  server: API Server路徑
  name: 集羣名稱
  users: 用戶列表
  name: 用戶賬號名
  client-certificate-data: 客戶端證書
  client-key-data: 客戶端私鑰
  contexts: 上下文列表,一個上下文用來指明哪個賬號管理哪個集羣;
  cluster: 訪問哪個集羣
  user: 使用哪個用戶
  name: 給上下文取名
  current-context: 當前上下文,當前使用哪個賬號管理哪個集羣;

由於客戶端連入API Server要做雙向認證,所以可以去"/etc/kubernetes/pki"目錄下找到各種key、ca;

 

創建新賬號來連接API Server

# cd /etc/kubernetes/pki
# (umask 077; openssl genrsa -out kfree.key 2048)
# openssl req -new -key kfree.key -out kfree.csr -subj "/CN=kfree"
# openssl x509 -req -in kfree.csr -CA ./ca.crt -CAkey ./ca.key -CAcreateserial -out kfree.crt -days 365
# su - kubeadm
$ kubectl config set-credentials kfree --client-certificate=/etc/kubernetes/pki/kfree.crt --client-key=/etc/kubernetes/pki/kfree.key
$ kubectl config set-context kfree@kubernetes --cluster=kubernetes --user=kfree
$ kubectl config view
apiVersion: v1
clusters:
- cluster:
certificate-authority-data: DATA+OMITTED
server: https://192.168.133.128:6443
name: kubernetes
contexts:
- context:
cluster: kubernetes
user: kfree
name: kfree@kubernetes
- context:
cluster: kubernetes
user: kubernetes-admin
name: kubernetes-admin@kubernetes
current-context: kubernetes-admin@kubernetes
kind: Config
preferences: {}
users:
- name: kfree
user:
client-certificate: /etc/kubernetes/pki/kfree.crt
client-key: /etc/kubernetes/pki/kfree.key
- name: kubernetes-admin
user:
client-certificate-data: REDACTED
client-key-data: REDACTED
$ kubectl config use
-context kfree@kubernetes # 因爲我們只處理了認證,沒有授予權限,所以沒有權限的; $ kubectl get pods Error from server (Forbidden): pods is forbidden: User "kfree" cannot list resource "pods" in API group "" in the namespace "default"

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章