kubernetes-認證、sa-11

回顧

​ 有狀態有存儲的就需要使用到sts控制器,比如一些常見的擴縮容問題,在K8s之上如果想要定義StatefulSet不建議直接使用StatefulSet,需要使用CordOS提供的第三方解決方案進行配置,配置方式:

底層存儲-->pv --> 無頭service ,只有基於這個無頭服務才能給每個pod分配一個唯一的持久的固定標識符
                sts -- pod   
                    volumeClaimTemplates 讓sts自動創建PVC關連pv,然後pod在掛載pvc, volumeMounts

理論來源: Kubernetes證書

系統安全說明

        對於Kubernetes來講,etcd存儲了當前整個集羣當中,每一個資源相關用戶定義的期望的狀態,以及當前在集羣之上的資源狀態,他們分別保存於資源的spec和status當中,當然也有個別資源沒有spec字段,比如像ConfigMap、Secret當中只有data,但是事實上也代表了spec,只不過其過於簡單,沒有使用spec來進行嵌套而已,如果說etcd宕機那麼整個集羣的所有狀態就丟失了,因此,我們必須要對etcd做高可用,而etcd本身是一個有狀態應用,如果它運行於Kubernetes上,那我們應該使用StatefulSet或者etcd的Operator來管理;
        整個集羣當中的所有狀態數據都必須保存在etcd中,k8s的kube-apiserver是整個etcd存儲集羣的唯一訪問入口,任何客戶端都不能直接寫etcd,用戶要想創建一個Pod資源也必須使用kubeadm這樣的工具與apiserver進行通信,將數據先提交給apiserver,然後再由api提交給etcd;
        對於Kubernetes來說,如果有用戶提交了所有關於Service的定義,都會被kube-proxy所捕獲,並讀取到本地轉換爲Iptables或者Ipvs規則,而Service的定義也需要通過APIServer進行獲取,它讀取完成並且創建相關規則以後這個創建的結果就結束了,這個結果就是當前狀態,也需要保存於etcd,它也需要經過APIServer保存於etcd當中,所以etcd就是一個通用鍵值存儲系統,但是在Kubernetes之上,它不允許隨意存取數據,所有能夠操作或使用數據的行爲,一定是在APIServer內部定義好了的;
        詳細創建過程: 當用戶創建一個pod資源, 該pod先被調度到集羣的任意一個 工作節點 之上, 然後通過 service內核中的 kubelet 調用docker將其運行, 調度器kube-sceduler守護進程也是APIServer的客戶端之一, 當有kubectl提交了一個新的Pod定義給APIServer, APIServer自己把etcd的watch機制通知給註冊監視相關資源的程序, 而kube-sceduler就像APIServer註冊監視了每一個沒有沒調度結果的相關信息,而kube-sceduler其實也是APIServer的客戶端,它需要通過APIServer完成Pod信息的查詢,甚至修改,比如把調度的結果保存給etcd當中,它不能夠直接操作etcd,而必須要經過APIServer;

字段 說明
kube-sceduler 負責只是調度它也只應該修改Pod上關於調度結果的字段
controller manager 負責更新當前狀態,並確保當前狀態一定要吻合於用戶期望的狀態的,
它負責修改status相關的信息
kubelet 負責創建Pod並負責更新Pod當前狀態信息
kube-proxy 負責創建\修改\更新Service相關的信息

        從這個角度來說,我們就沒有必要,kube-sceduler擁有controller manager、kube-proxy等相關的權限,還有如果kube-sceduler隨便連接到APIService上能隨便完成各種調度,那麼任何一個人使用kube-sceduler都可以完成集羣上的所有操作了,這就亂套了,安全性不言而喻,因此Kubernetes必須對運行其上的所有資源在訪問上構建出一個安全的訪問機制,或者說訪問控制模型來;

連接api時的操作

        在k8s之上的API Server是整個集羣的網關,因此它的訪問控制功能都是在API Server上實現的, 當客戶端發起API Server調用時,API Server 內部要先進行用戶認證,然後執行用戶授權流程,即通過 “授權策略” 來決定一個API 調用是否合法,對合法用戶進行授權,並且隨後在用戶訪問時進行鑑權;
​        k8s是一個高度模塊化設計的工具,因此它的認證,授權,准入控制各自都通過插件的方式可以由用戶自定義選擇經由什麼樣的插件來完成何種控制邏輯, 由於k8s提供的是restFul風格的接口,它所有服務都通過http協議提供,由此認證信息只能經由http協議的認證首部進行傳遞(token),

  1. 認證:確認這個客戶端是否有權限允許操作API Server中的相關功能;
  2. 授權檢查: 檢查權限是否有這個權限,進行API Server之後資源調度(資源管理邏輯實現合理的權限指派)
  3. 准入控制: 有兩種操作
    1. 檢查其定義的資源是否合理;
    2. 檢查請求資源時的語法是否合乎規範,
      • 如果不合乎規範,如缺失就給它補齊,這種稱爲: 便易型准入控制
      • 不符合就拒絕,這種屬於合法性的一種准入控制器, 比如請求資源超過用戶最大的使用量 如CPU

在這裏插入圖片描述

認證說明

        對於kube-Apiserver來講,認證是一種功能,認證有多種認證機制,每一種機制都要一個認證插件, 可以選擇在kube-Apiserver啓動時,激活哪一個插件,來做認證插件, 甚至於還可以同時激活多個插件,都可以生效,授權、准入控制也一樣。但是隻有激活的才生效,未激活的不會生效,它的認證邏輯很特別,叫一票通過, 從1到N只 不管順序只要其中一個通過便算通過, 插件對於不認證的用戶不允許也不會拒絕;
        Kubernetes的授權的邏輯有點獨特,叫做許可授權, 如:當用戶進來只要API Server允許就允許, 沒有允許就繼續下一個插件檢查, 直到通過, 拒絕是默認值, 沒有顯示告知允許
        准入控制的插件也可以有多個,准入控制插件的邏輯有點獨特, 實現一票否決權, 只要其中有一個拒絕,那麼整個都算失敗, 要不就全部允許

認證插件

Kubernetes支持很多種認證插件,如

  1. Client Certificates(客戶端證書認證: 類似就是公私密鑰認證的
  2. Passwd:用戶名和密碼認證,通過base64編碼之後通過header傳輸
  3. Plain Tokens(令牌): 隨機字符,稱之爲令牌,沒有用戶名;
  4. Bootstrap Tokens(引導令牌,引導集羣啓動,或者加入集羣使用的令牌)
  5. JWT Tokens(JSON的web Token,基於HTTP協議攜帶json格式的令牌)

kubectl proxy

  1. 獲取 api 資源類型

    1. 通過kubectl proxy命令,在本地監聽某個端口
    2. 然後就能在通過本地的curl 命令地址:端口 反向代理至apiserver
    # 監聽 proxy    
    ~]# kubectl proxy --port=1999
    	Starting to serve on 127.0.0.1:1999
    
    # 列出當前系統上所有namespace所有資源
    ~]# curl http://127.0.0.1:1999/api/v1/namespaces
      # 對象類: pod, Service...  同一類型對象下所有叫集合
        {
            "kind": "NamespaceList",  # 資源類型
            "apiVersion": "v1",
            "metadata": {
                "selfLink": "/api/v1/namespaces",
            },
            "items": [
                {
                    "metadata": {
                        "name": "default",
                        "selfLink": "/api/v1/namespaces/default",
                        "uid": "93b7a2c6-a62f-40dd-830d-caca91104047"
                    }
                },
                {
                    "metadata": {
                        "name": "kube-node-lease",
                        "selfLink": "/api/v1/namespaces/kube-node-lease",
                        "uid": "99cf5fac-605d-4095-97f9-e7f48fe50d7f"
                    }
                },
                {
                    "metadata": {
                        "name": "kube-public",
                        "selfLink": "/api/v1/namespaces/kube-public",
                        "uid": "93e98efe-b0e6-4e56-ae50-5cb41e898c89"
                    }
                },
                {
                    "metadata": {
                        "name": "kube-system",
                        "selfLink": "/api/v1/namespaces/kube-system",
                        "uid": "9832f8fa-b476-496b-b465-6d97a0e97537"
                    }
                }
            ]
        }
    
  2. 獲取某個特定的API信息

    • /api/v1: 一種特殊的路徑, 只有核心羣組纔有這樣訪問邏輯
    • /apis: 只要不是核心羣組,都必須要起始與/apis
    # 獲取全部的 deployments 所有的對象
    ~]#  curl http://127.0.0.1:1999/apis/apps/v1/namespaces/kube-system/deployments
      "kind": "DeploymentList",
      "apiVersion": "apps/v1",
      "metadata": {
        "selfLink": "/apis/apps/v1/namespaces/kube-system/deployments",
        "resourceVersion": "454268"
      },
    
  3. 只訪問某單個資源

    ~]#  curl http://127.0.0.1:1999/apis/apps/v1/namespaces/kube-system/deployments/coredns
      "kind": "Deployment",
      "apiVersion": "apps/v1",
      "metadata": {
        "name": "coredns", ....
       }
    
  4. 訪問請求方式

    1. http request: get, port, put, delete
    2. API request: get, list, create, update, patch, edit, watch, redirect, delete, deletecollection(刪除一組)
    3. Resource
    4. Subresource
    5. Namespace
    6. API Group
  5. 訪問請求總結

    ​ API Server是整個訪問請求進入的網關接口,請求過程當中認證用於實現身份識別,而授權實現權限檢查,而准入控制機制進一步補充了授權機制,它也一樣有多個插件來實現,一般而言只在 創建刪除修改或做代理 操作時做補充

k8s認證

在Kubernetes之上認證是雙向的,也就是說kubectl接入APIServer時,雙方要互相認證

  1. kubectl會把自己的證書提交給APIServer並請求APIServer的證書;
  2. 此時kubectl是客戶端證書APIServer是服務端證書,他們互相做雙向認證;
  3. kubectl還需要檢查證書是否由自己認可信任的機制頒發,該證書持有者所聲明的身份要與證書中的身份保持一致,證書還需要在有效期內,一旦條件不滿足,認證就失敗;
  4. 集羣需要很多證書,但是一般Kubernetes集羣所有的證書都不會使用一樣的,認證通過之後還需要知道這個認證是誰來認證的,如果這個證書頒發給某一個用戶了,那麼這個證書裏面的subject裏面的CN就是哪個用戶,很顯然,每個用戶都需要不同的證書,來進行用戶身份判斷,這樣才能做到分用戶或分客戶端進行不同的授權;

​        Kubernetes對於權限的檢查,還需要知道哪個用戶的哪個權限,按上面的例子來說用戶就是subject裏面的CN,所以我們創建的每一個證書的CN的名字還要和Kubernetes內建的用戶名一致,subject裏面還有一個字段叫做owner,O是用戶所屬的部門,O就相當於用戶的組,CN是用戶名,所以我們就可以在Kubernetes上利用Auth Policies對一個組授權,加入到這個組中的所有用戶都有同一個權限,所以必要的時候多個用戶要擁有通一個權限就可以在同一個組的方式來實現權限控制;

用戶類型

  1. Useraccount: 用戶客戶端操作的用戶;
    • 對於客戶端用戶來說,只需要擁有該 API Server的證書並且認證通過,那麼該客戶端就能擁有該證書用戶的權限。
  2. 服務帳號: 讓pod連接server時使用的帳號, 程序作爲一個守護進程需要連入APIServer認證並獲得相關授權時,它就需要附帶着用戶身份;
    • 服務帳號是在 k8s 系統上存在的帳號,它是k8s之上的一個標準資源,它通過secrets保存着這個用戶帳號要接入APIServer時的密碼,作爲一個secrets資源存在。

啓用證書

APIServer內建了很多認證授權與准入控制插件,最終APIServer啓用與否取決在傳遞的參數選項

  1. Client Certificates:--client-ca-file=SOMEFILE啓用證書認證;
  2. Static Token File:靜態令牌認證,簡單的明文令牌認證
    • --token-auth-file=SOMEFILE啓用靜態令牌認證;
  3. Bootstrap Tokens:Bootstrap的令牌文件也需要指定,定義方式
    • kube-apiserver使用: --experimental-bootstrap-token-auth選項;
    • kube-controller-manager使用: "--controllers=*,tokencleaner"選項;
  4. ServiceAccount Tokens:
    1. 承載令牌進行數字前面的PEM格式的密鑰: --service-account-key-file;
    2. 缺省使用APIServer的TLS私鑰,--service-account-lookup是否吊銷刪除的令牌;

通信方式

kubectl有哪些客戶些需要與API Server通信

  1. 集羣內部的POD

        pod與api server 通信使用的是集羣內的工作地址,通過一個專用於集羣內的地址: kubectl get svc查看 指向的是節點地址 Endpoints: 192.168.2.220:6443 而 server 引用到集羣內部從而使的pod就能直接請求API Server上的服務了 IP: 10.96.0.1

master ~]# kubectl get svc
NAME         TYPE        CLUSTER-IP   EXTERNAL-IP   PORT(S)   AGE
kubernetes   ClusterIP   10.96.0.1    <none>        443/TCP   4d

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:         192.168.2.220:6443
Session Affinity:  None
Events:            <none>

# api Server必須要認證後才能進行通信
  1. 集羣外部的客戶端: 每次訪問api server時都使用自己api server所監聽的節點地址
            任意版本kubectl客戶端只需要配置好連接方式,就連接至master上的api server的監聽地址

kubeconfig簡介

選項 說明
users 用戶帳號及其認證信息列表
clusters 目標集羣列表
contexts 以哪個user接入哪個clustere的連接組合
curren-context 當前使用的context,當前上下文,它可以進行切換
用戶@上下文
]# kubectl config view
# 或 ~]# cat .kube/config ,  與kubectl config view結果是一樣的
apiVersion: v1
clusters:    # 集羣列表,當有多個集羣時,可以同時定義多個集羣名稱
- cluster:   # 集羣配置的標識,因爲可以有多個所有得有所區分
    certificate-authority-data: DATA+OMITTED  # 集羣的CA證書,APIServer所信任的CA的證書
    server: https://192.168.2.220:6443        # 集羣Server地址
  name: kubernetes           #  集羣名稱
contexts:
- context:     # 上下文列表
    cluster: kubernetes      # 這個上下文接入的cluster
    user: kubernetes-admin   # 這個上下文使用的user
  name: kubernetes-admin@kubernetes
current-context: kubernetes-admin@kubernetes   # 當前上下文
kind: Config
preferences: {}
users:                          # 用戶列表,  當有多個集羣,可以定義多個用戶
- name: kubernetes-admin        # 定義一個users,名爲kubernetes-admin
  user:    # 該user的信息
    client-certificate-data: REDACTED   # 公鑰
    client-key-data: REDACTED			# 私鑰

# 客戶端只需要拿着證書,那麼就能夠認證成功,而Kubernetes所信任的CA就在我們的/etc/kubernetes/pki裏面他們分別是ca.crt和ca.key,那麼我們就自己生成一個私鑰,手動用這個ca去簽署得到一個證書,那拿着這個客戶端簽署的證書就可以直接接入kube-apiserver,CN代表用戶名,能夠認證通過,對應的這個獲得了哪些權限它就能擁有哪些權限,而且這個用戶名不需要在Kubernetes之上存在,系統上有一個組叫做masters,這是一個管理員組,如果創建一個用戶加入這個組,那麼該用戶就是管理員;

Kubernetes證書

整個Kubernetes之上要使用的證書有以下組件:
        etcd:etcd保存着整個Kubernetes集羣之上的資源,所以etcd也一定不能非授權訪問,它的認證方式和APIServer的方式一樣,默認使用證書認證,etcd是服務端,APIServer是etcd的客戶端,爲了保證etcd不被非授權訪問,要做一個專門的CA,讓etcd各節點之間通信要使用一個證書,自己做個CA證書,只用於節點之間通信,這叫做節點證書,還需要爲每一個節點發送一個Server端證書,而後再給APIServer發生一個Client證書,APIServer與etcd通信也需要拿着Client證書纔可以;

對於集羣組件連接到APIServer也需要證書:
        這個時候還需要一套CA,然後給各組件通信到APIServer各一套證書,因爲上面說過不同組件實現不同功能,組件也不能非授權訪問,Kubernetes是沒有用戶這麼一說的,用戶的區別主要是以證書裏面的信息來區分的,比如說CN就是用戶名,所以每個組件的證書我們應該使用不一樣的,而不能使用同一個證書,因爲Kubernetes組件到APIServer是雙向認證的,也就是說APIServer到組件也需要證書,也就是說APIServer->組件,組件->APIServer一套,每個組件兩套證書,好在這個APIServer->組件的證書會自己生成;

證書說明:

  • 各節點證書:server端證書,
  • apiserver: client證書
  • apiserver與etcd通信: client證書

授權配置管理

​        至於切換上下文,設置users設置contexts等都可以使用命令行的方式來定義,其主要配置是/etc/kubernetes/admin.conf,

語法kubectl config command [option]

參數 說明
set-cluster 添加集羣
set-context 添加一個上下文
set-credentials 添加用戶信息
set 添加集羣、添加用戶、添加上下文
use-context 指定當前使用的上下文
view 查看當前配置

ApiServer

​        ApiServer定義了當前資源可以使用哪些資源類型,如Pod、StatefulSet等,如果認爲K8s自建的存儲方案不夠用,需自定義有如下方案

  1. 通過ApiServer直接修改go源代碼;

  2. 自建ApiServer,自已寫一個程序,將這個程序引入新的資源類型,以Pod方式運行在k8s之上,這種叫自定義資源類型,類型Operator控制器,此處我們只寫定ApiServer,而k8s爲了開發者更方便開發ApiServer擴展接口,包含了如下組件:

  3. kube-aggregator:用於反代,

  4. kube-apiserver: 默認資源,

  5. extension–apiserver:自定義資源反代

  所以當我們需要自定義Apiserver時只需要配置kube-aggregator,然後將默認資源反代給kube-apiserver,自定義資源反代給extension--apiserver,所以kube-aggregator到extension--apiserver還需要一套證書;

APIServer證書: ~]# cat /etc/kubernetes/manifests/kube-apiserver.yaml

k8s證書示例

自建證書

--kubeconfig:指定要配置的配置文件;
--embed-certs:證書和私鑰打包存放;
--username:指定用戶名,在此處無實際意義,因爲用戶主要是靠證書的CN來區分的,但是這裏最好和證書裏面的CN一致;

# 創建一個私鑰
]# openssl genrsa -out lzx.key 4096

# 爲證書生成一個證書籤署請求,並且使用kubernetes的CA來簽署, CN代表用戶名, 0組織表示組
]# openssl req -new -key lzx.key -out lzx.csr -subj "/CN=xiong/O=kubernetes"

# 使用CA簽署證書
]# openssl x509 -req -in lzx.csr -CA /etc/kubernetes/pki/ca.crt -CAkey /etc/kubernetes/pki/ca.key  -CAcreateserial -out lzx.crt -days 3650

]# mkdir /etc/kubernetes/lzx
]# mv lzx.* /etc/kubernetes/lzx/

]# openssl x509 -in lzx.crt -text -noout
    Certificate:
        Signature Algorithm: sha256WithRSAEncryption
            Issuer: CN=kubernetes
            Subject: CN=xiong

使用證書

  1. 配置用戶信息, 直接這麼配置就是保存在 /etc/k8s/admin.conf中

    ]# kubectl config set-credentials xiong --client-certificate=/etc/kubernetes/lzx/lzx.crt  --client-key=/etc/kubernetes/lzx/lzx.key  --embed-certs=true
    
    ]# kubectl config view
    users:
    - name: kubernetes-admin
      user:
        client-certificate-data: REDACTED
        client-key-data: REDACTED
    - name: xiong     # 自定義的用戶
      user:
        client-certificate-data: REDACTED
        client-key-data: REDACTED
    
  2. 將user和cluster組合起來形成一個context, 組成一個上下文

# server 集羣不動 還是使用 kubernetes的
]# kubectl config set-context xiong-k8s --cluster=kubernetes --user=xiong
Context "xiong-k8s" created.

]# kubectl config view
apiVersion: v1
clusters:
- cluster:
    certificate-authority-data: DATA+OMITTED
    server: https://192.168.2.220:6443
  name: kubernetes
contexts:
- context:
    cluster: kubernetes
    user: kubernetes-admin
  name: kubernetes-admin@kubernetes
- context:
    cluster: kubernetes
    user: xiong
  name: xiong-k8s
  1. 切換用戶
]# kubectl config use-context xiong-k8s

]# kubectl config view
current-context: xiong-k8s
  1. 測試
]# kubectl get svc
Error from server (Forbidden): services is forbidden: User "xiong" cannot list resource "services" in API group "" in the namespace "default"

# 刪除用戶 
kubectl config unset users.username   # 相當於 delete user username

# 刪除下上文  kubectl config set-context xiong-k8s
kubectl config unset contexts.name    # 如  unset contexts.xiong-k8s

配置文件

# 創建一個新的kubeconfig文件, 配置 集羣
]# kubectl config set-cluster xiong-cluster --server=https://192.168.2.220:6443 --certificate-authority=/etc/kubernetes/lzx/lzx.crt --embed-certs=true --kubeconfig=/etc/kubernetes/lzx.conf

# 設定用戶配置信息, 配置 用戶
]# kubectl config set-credentials xiong --client-certificate=/etc/kubernetes/lzx/lzx.crt --client-key=/etc/kubernetes/lzx/lzx.key --username=xiong --kubeconfig=/etc/kubernetes/lzx.conf --embed-certs=true

# 將user和cluster組合起來形成一個context, 組成一個上下文
]# kubectl config set-context context-xiong --cluster=kubernetes --user=xiong --kubeconfig=/etc/kubernetes/lzx.conf 

# 指定默認使用的context  
]# kubectl config use-context --kubeconfig=/etc/kubernetes/lzx.conf  context-xiong 
Switched to context "context-xiong".

# 測試使用該配置連接Kubernetes集羣
]# kubectl get pods --kubeconfig=/etc/kubernetes/lzx.conf  # 權限被拒絕
error: no configuration has been provided, try setting KUBERNETES_MASTER environment variable

# 系統k8s上下文: 

最終還是切換回原先版本:

]# kubectl config use-context kubernetes-admin@kubernetes
# 在次訪問,就沒有環境變量問題了

serviceaccount

牢記:認證不代表權限, 權限需要有授權

Kubernetes之上的認證用戶有兩種

  1. 常規用戶: UserAccount,
  2. ServiceAccount

​        在創建SA資源時,指定用戶的認證信息需要靠secrets來提供,這個secrets可以不非得是tls帳號密碼,因爲我們證書和私鑰都在secrets當中,如果需要定義爲tls類型,可以用於ssl通信而不是用於認證,因此這裏的SA不能使用secret創建時的tls類型,而是應該使用generic類型的證書,我們在創建SA時可以不用自行定義secrets,在創建時k8s會自動生成一個secerts,其保存了相關用戶的認證信息,
​        每一個ServiceAccount的定義方式很簡單,簡稱爲SA,在創建SA資源的時候我們可以指定metadata.name來指定該SA的名稱,metadata.namespace來指定該ServiceAccount所屬的namespace,當前用戶的認證信息是什麼則需要靠secrets來提供,這個secrets可以不用非得是tls帳號密碼,因爲我們的證書和私鑰在secrets當中,如果要定義爲tls類型的,那是用於ssl通信的,而不是用於認證的,而認證不代表權限,權限需要有授權

認證信息說明

]# 查看某一個pod的詳細信息, kubectl describe pods PODNAME
Volumes:
  default-token-cbkjx:
    Type:        Secret (a volume populated by a Secret)
    SecretName:  default-token-cbkjx
    Optional:    false
    
# 通過secret定義,並以存儲卷的方式關連到pod,從而讓pod內的應用通過對應的secret保存的認證信息來連接API Server並完成認證

]# kubectl get secrets 
NAME                  TYPE                                  DATA   AGE
default-token-cbkjx   kubernetes.io/service-account-token   3      4d3h

]# kubectl describe secrets default-token-cbkjx 
Name:         default-token-cbkjx
Namespace:    default
Labels:       <none>
Annotations:  kubernetes.io/service-account.name: default
              kubernetes.io/service-account.uid: 4b1cf2dc-b8c6-45fa-8b6d-46b9d746e037

Type:  kubernetes.io/service-account-token

Data
====
ca.crt:     1025 bytes
namespace:  7 bytes
token:      xxxxx

其它pod認證

]# kubectl get pods -n ingress-nginx 
NAME                                        READY   STATUS    RESTARTS   AGE
nginx-ingress-controller-67754f4878-fr8cz   1/1     Running   0          35m

]# kubectl describe pods -n ingress-nginx nginx-ingress-controller-67754f4878-fr8cz 
Volumes:
  nginx-ingress-serviceaccount-token-lh6vj:
    Type:        Secret (a volume populated by a Secret)
    SecretName:  nginx-ingress-serviceaccount-token-lh6vj
    Optional:    false
    
]#  kubectl get secrets -n ingress-nginx 
NAME                            TYPE                                  DATA   AGE
nginx-ingress-serviceaccount-token-lh6vj   kubernetes.io/service-account-token   3      37m

]# kubectl describe secrets -n ingress-nginx nginx-ingress-serviceaccount-token-lh6vj 
Name:         nginx-ingress-serviceaccount-token-lh6vj
Namespace:    ingress-nginx
Labels:       <none>
Annotations:  kubernetes.io/service-account.name: nginx-ingress-serviceaccount
              kubernetes.io/service-account.uid: 3fba317a-efc3-499d-8dc9-b692f50df714

Type:  kubernetes.io/service-account-token

Data
====
token:      xxxxxxx
ca.crt:     1025 bytes
namespace:  13 bytes

sa-示例

牢記, 認證不代表權限, 權限需要有授權

  1. 創建serviceaccount

    # serviceAccount不帶權限, 通過RBAC可以增加權限
    
    ]# kubectl create serviceaccount mysa
    
  2. 查看詳細頁

    ]# kubectl describe serviceaccounts mysa
    Name:                mysa
    Namespace:           default
    Labels:              <none>
    Annotations:         <none>
    Image pull secrets:  <none>
    Mountable secrets:   mysa-token-tddm9
    Tokens:              mysa-token-tddm9
    Events:              <none>
    
    # 通過 -o yaml可以查看創建yaml內容
    ]# kubectl get serviceaccounts mysa -o yaml
    apiVersion: v1
    kind: ServiceAccount
    metadata:
      creationTimestamp: "2020-05-11T07:16:16Z"
      name: mysa
      namespace: default
      resourceVersion: "859176"
      selfLink: /api/v1/namespaces/default/serviceaccounts/mysa
      uid: 5d361efd-18aa-4c42-9dc6-cc71b08bcee7
    secrets:
    - name: mysa-token-tddm9
    
  3. 查看secrets

    ]# kubectl get secrets 
    	# k8s自動生成token,用於讓sa連接至當前系統api 認證信息,認證不表達權限, 權限需要有授權
    	
    NAME                  TYPE                                  DATA   AGE
    mysa-token-tddm9      kubernetes.io/service-account-token   3      3m4s
    
  4. 認證詳情

    ]# kubectl describe secrets mysa-token-tddm9 
    Name:         mysa-token-tddm9
    Namespace:    default
    Labels:       <none>
    Annotations:  kubernetes.io/service-account.name: mysa
                  kubernetes.io/service-account.uid: 5d361efd-18aa-4c42-9dc6-cc71b08bcee7
    
    Type:  kubernetes.io/service-account-token
    
    Data
    ====
    ca.crt:     1025 bytes
    namespace:  7 bytes
    token:      token內容
    
  5. pod使用自定義sa

    # 1、創建一個sa,
    ~]# kubectl describe sa podsa
    
    ~]# kubectl describe sa podsa 
    Name:                podsa
    Namespace:           default
    Tokens:              podsa-token-nfbns
    
    # 2、定義pod
    ]#   cat pod_sa.yaml 
    apiVersion: v1
    kind: Pod
    metadata:
      name: pod-sa
      labels:
        name: pod-sa
    spec:
      containers:
      - name: pod-sa
        image: ikubernetes/myapp:v1
        imagePullPolicy: IfNotPresent
        ports:
        - name: http
          containerPort: 80
        readinessProbe:
          failureThreshold: 5
          initialDelaySeconds: 3
          tcpSocket:
            port: http
      serviceAccountName: podsa   # 只需要指定sa,認證不代表權限, 權限需要有授權
      
    ]#  kubectl describe pod pod-sa
    Name:         pod-sa
    Namespace:    default
    Containers:
      pod-sa:
        Mounts:
          /var/run/secrets/kubernetes.io/serviceaccount from podsa-token-nfbns (ro)
    Volumes:
      podsa-token-nfbns:
        Type:        Secret (a volume populated by a Secret)
        SecretName:  podsa-token-nfbns
        Optional:    false
    

資源清單提供給api server時,api server告訴 kubenet, 創建並運行Pod, pod中的容器依賴於私有register,部分私有register就需要提供用戶帳號密碼了

爲pod獲取私有register的兩種方式:

  1. 在pod上直接使用imagesecrtePull字段指定能認證完成的sercret對象
  2. 在pod上自定義一個sa, 附加一個Image pull secrets對象

授權

   ]#  kubectl describe pod pod-sa
   Name:         pod-sa
   Namespace:    default
   Containers:
     pod-sa:
       Mounts:
         /var/run/secrets/kubernetes.io/serviceaccount from podsa-token-nfbns (ro)
   Volumes:
     podsa-token-nfbns:
       Type:        Secret (a volume populated by a Secret)
       SecretName:  podsa-token-nfbns
       Optional:    false

        資源清單提供給api server時,api server告訴 kubenet, 創建並運行Pod, pod中的容器依賴於私有register,部分私有register就需要提供用戶帳號密碼了

爲pod獲取私有register的兩種方式:

  1. 在pod上直接使用imagesecrtePull字段指定能認證完成的sercret對象
  2. 在pod上自定義一個sa, 附加一個Image pull secrets對象
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章