一、前言
- 在前一篇文章中,我們介紹了如何使用kubectl proxy與API服務器進行互動
- 本文介紹如何在一個pod內部與API服務器進行互動,因此在pod內部因為沒有kubectl命令,所以與API服務器互動需要關注三件事情:
- 確定API服務器的位置
- 確保是與API服務器進行互動,而不是一個冒名者
- 通過服務器的認證,否則將不能查看任何內容以及進行任何操作
二、創建pod
- 下面我們準備創建pod,創建pod之前我們需要構建一個容器,該容器有如下的特點:
- 該容器什么也不做(在它僅有的容器內部運行一個sleep命令)
- 該容器帶有curl命令工具(Docker Hub中的tutum/curl鏡像有,下面我們直接使用這個鏡像)
- 有了上面的規則之后,使用下面名為curl.yaml的檔案創建pod:

apiVersion: v1
kind: Pod
metadata:
name: curl
spec:
containers:
- name: main
image: tutum/curl
command: ["sleep", "9999999"]
- 在完成pod的創建后,在容器中啟動一個shell:

- 下面我們開始與API服務器進行互動了
三、發現API服務器地址
- 與API服務器互動之前,需要先獲取API服務器的IP地址和埠
- 因為一個名為kubernetes的服務在默認的命名空間被自動暴露,并被配置為指向API服務器,所以可以通過下面的命令查看所有服務清單,查看這個服務

- 每個服務都被配置了對應的環境變數,在容器內查詢即可獲取API服務器的IP地址和埠

- 備注:我們之前介紹過DNS,每個服務都可以獲得一個DNS入口,所以可以不去查詢環境變數,直接將curl指向https://kubernetes, 公平地講,如果我們不知道服務在哪個埠是可用的,既可以查詢環境變數,也可以查看DNS SRV記錄來得到實際的埠號
- 上圖展示的環境變數說明API服務器監聽HTTPS協議默認的443埠,所以嘗試通過HTTPS協議來訪問服務器

- curl -k選項說明:
- 上圖顯示了我們沒有權限,驗證未通過
- 我們可以使用在前一篇文章中介紹過的curl的-k選項跳過服務器證書檢查環節,來檢測服務是否存在并且是否正常作業
- -k選項不是長久之計,下面我們會介紹如何與API服務器之間進行驗證
- 在真實的應用中,永遠不要跳過檢查服務器證書的環節,這 樣做會導致你的應用驗證憑證暴露給采用中間人攻擊方式的攻擊者,
四、驗證服務器身份(ca.crt檔案)
- 在之前介紹Secret文章中提到過,有一個名為defalut-token-xyz的Secret被自動創建,并掛載到每個容器的/var/run/secrets/kubernetes.io/serviceaccount目錄下,可以查看一下Secret的內容,如下所示:
![]()
- Secret有三個入口(因此在Secret卷中有三個檔案)
驗證并信任服務器
- 我們先來看一下ca.crt檔案,該檔案中包含了CA的證書,用來對Kubernetes API服務器證書進行簽名
- 為了驗證正在互動的API服務器,我們需要檢查服務器的證書是否是由CA簽發,可以使用-cacert選項來指定CA證書,并重新訪問API服務器,如下所示:
- 上圖顯示:“Unauthorized”(可能看到一個比“Unauthorized”更長的錯誤描述)表示curl信任了API服務器是安全的,但是API服務器還沒有確認curl的身份,curl此時沒有權限訪問API服務器,授權在下面介紹
- 為了不必每次運行curl時都指定--cacert選項,我們可以設定一個環境變數CURL_CA_BUNDLE來簡化操作,如下所示:
- 上面客戶端(curl)現在信任API服務器,但API服務器并不確認訪問者的身份,所以沒有授權允許訪問
五、獲得API服務器授權(token檔案)
- 我們需要獲得API服務器的授權,以便可以讀取并進一步修改或洗掉部署在集群中的API物件
- 為了獲得授權,我們需要認證的憑證,幸運的是,憑證可以使用之前提到的default-token Secret來產生,同時憑證被存放在secret卷的token檔案中,可以使用憑證來訪問API服務器
- 第一步,將憑證掛載到環境變數中:
![]()
- 然后使用下面的命令向API服務器發送請求:

- 我們通過發送請求的HTTP頭中的Authorization欄位向API服務器傳遞了憑證,API服務器識別確認憑證并回傳正確的回應
關倍訓于角色的訪問控制(RBAC)
- 如果我們正在使用一個帶有RBAC機制的Kubernetes集群,服務賬戶可能不會被授權訪問API服務器(或只有部分授權),我們會在后面相關文章中詳細了解服務賬戶和RBAC機制
- 目前最簡單的方式就是運行下面的命令查詢API服務器,從而繞過RBAC方式,
- 這個命令賦予了所有服務賬戶(也可以說所有的pod)的集群管理 員權限,允許它們執行任何需要的操作,很明顯這是一個危險的操作, 永遠都不應該在生產的集群中執行,對于測驗來說是沒有問題的,
六、測驗:獲取當前運行pod所在的命名空間(namespace檔案)
- 前面curl與API服務器之間都相互認證了,現在可以來探索集群中所有的資源
- 現在我們測驗一下,列出集群中所有的pod,但是我們需要知道運行curl的pod屬于哪個命名空間:
- 在介紹Downward API時,我們了解了如何使用Downward API的方式將命名空間的屬性傳遞到pod,如果你注意觀察的話,或許注意到secret卷中也包含了一個叫作命名空間的檔案,這個檔案包含了當前運行pod所在的命名空間,所以我們可以讀取這個檔案來獲得命名空間資訊,而不是通過環境變數明確地傳遞資訊到pod
- 我們將該檔案設定到NS環境變數中,然后進行訪問,列出所有的pod,如下所示:

七、總結
- 我們將掛載在secret卷目錄下的3個檔案都使用了一遍,并最終演示羅列出與當前pod運行在同一個命名空間下的所有pod的清單
- 使用同樣的方式不僅可以使用GET請求,還可以使用PUT或者PATCH來檢索和修改其 他API物件
八、簡要說明pod如何與Kubernetes互動
- 簡單說明一下在pod中運行的應用如何正確訪問Kubernetes的 API:
- 應用應該驗證API服務器的證書是否是證書機構所簽發,這個證書是在ca.crt檔案中
- 應用應該將它在token檔案中持有的憑證通過Authorization標頭來獲得API服務器的授權
- 當對pod所在命名空間的API物件進行CRUD操作時,應該使用namespace檔案來傳遞命名空間資訊到API服務器
- 定義:CRUD代表創建、讀取、修改和洗掉操作,與之對應的HTTP方法分別是POST、GET、PATCH/PUT以及DELETE
- 與API服務器通信相關的pod的三個方面如下圖所示:

轉載請註明出處,本文鏈接:https://www.uj5u.com/qita/248549.html
標籤:其他
上一篇:網路增大


