云計算
作者 | 聲東 阿里云售后技術專家
創(chuàng)新互聯(lián)建站長期為千余家客戶提供的網(wǎng)站建設服務,團隊從業(yè)經(jīng)驗10年,關注不同地域、不同群體,并針對不同對象提供差異化的產(chǎn)品和服務;打造開放共贏平臺,與合作伙伴共同營造健康的互聯(lián)網(wǎng)生態(tài)環(huán)境。為臨夏州企業(yè)提供專業(yè)的網(wǎng)站建設、成都網(wǎng)站設計,臨夏州網(wǎng)站改版等技術服務。擁有10余年豐富建站經(jīng)驗和眾多成功案例,為您定制開發(fā)。導讀:相比 K8s 集群的其他功能,私有鏡像的自動拉取,看起來可能是比較簡單的。而鏡像拉取失敗,大多數(shù)情況下都和權限有關。所以,在處理相關問題的時候,我們往往會輕松的說:這問題很簡單,肯定是權限問題。但實際的情況是,我們經(jīng)常為一個問題,花了多個人的時間卻找不到原因。這主要還是我們對鏡像拉取,特別是私有鏡像自動拉取的原理理解不深。這篇文章,作者將帶領大家討論下相關原理。
順序上來說,私有鏡像自動拉取會首先通過阿里云 Acr credential helper 組件,再經(jīng)過 K8s 集群的 API Server 和 kubelet 組件,最后到 docker 容器運行時。但是我的敘述,會從后往前,從最基本的 docker 鏡像拉取說起。
鏡像拉取這件小事為了討論方便,我們來設想一個場景。很多人會使用網(wǎng)盤來存放一些文件,像照片,文檔之類。當我們存取文件的時候,我們需要給網(wǎng)盤提供賬戶密碼,這樣網(wǎng)盤服務就能驗證我們的身份。這時,我們是文件資源的所有者,而網(wǎng)盤則扮演著資源服務器的角色。賬戶密碼作為認證方式,保證只有我們自己可以存取自己的文件。
這個場景足夠簡單,但很快我們就遇到新需求:我們需要使用一個在線制作相冊的應用。按正常的使用流程,我們需要把網(wǎng)盤的照片下載到本地,然后再把照片上傳到電子相冊。這個過程是比較很繁瑣的。我們能想到的優(yōu)化方法是,讓相冊應用,直接訪問網(wǎng)盤來獲取我們的照片,而這需要我們把用戶名和密碼授權給相冊應用使用。
這樣的授權方式,優(yōu)點顯而易見,但缺點也是很明顯的:我們把網(wǎng)盤的用戶名密碼給了相冊服務,相冊服務就擁有了讀寫網(wǎng)盤的能力,從數(shù)據(jù)安全角度,這個是很可怕的。其實這是很多應用都會遇到的一個一般性場景。私有鏡像拉取其實也是這個場景。這里的鏡像倉庫,就跟網(wǎng)盤一樣,是資源服務器,而容器集群則是三方服務,它需要訪問鏡像倉庫獲取鏡像。
理解 OAuth 2.0 協(xié)議OAuth 協(xié)議是為了解決上述問題而設計的一種標準方案,我們的討論針對 2.0 版本。相比把賬戶密碼直接給三方應用,此協(xié)議采用了一種間接的方式來達到同樣的目的。如下圖,這個協(xié)議包括六個步驟,分別是三方應用獲取用戶授權,三方應用獲取臨時 Token 以及三方應用存取資源。
這六步理解起來不容易,主要是因為安全協(xié)議的設計,需要考慮協(xié)議的易證明性,所以我們換一種方式來解釋這個協(xié)議。簡單來說,這個協(xié)議其實就做了兩件事情:
在用戶授權的情況下,三方應用獲取 token 所表示的臨時訪問權限; 然后三方應用使用這個 token 去獲取資源。如果用網(wǎng)盤的例子來說明的話,那就是用戶授權網(wǎng)盤服務給相冊應用創(chuàng)建臨時 token,然后相冊應用使用這個 token 去網(wǎng)盤服務獲取用戶的照片。實際上 OAuth 2.0 各個變種的核心差別,在于第一件事情,就是用戶授權資源服務器的方式。
最簡單的一種,適用于三方應用本身就擁有被訪問資源控制權限的情況。這種情況下,三方應用只需要用自己的賬戶密碼登錄資源服務器并申請臨時 token 即可; 當用戶對三方應用足夠信任的情況下,用戶直接把賬戶密碼給三方應用,三方應用使用賬戶密碼向資源服務器申請臨時 token; 用戶通過資源服務器提供的接口,登錄資源服務器并授權資源服務器給三方應用發(fā)放 token; 完整實現(xiàn) OAuth 2.0 協(xié)議,也是最安全的。三方應用首先獲取以驗證碼表示的用戶授權,然后用此驗證碼從資源服務器換取臨時 token,最后使用 token 存取資源。從上面的描述我們可以看到,資源服務器實際上扮演了鑒權和資源管理兩種角色,這兩者分開實現(xiàn)的話,協(xié)議流程會變成下圖這樣。
Docker 扮演的角色 大圖鏡像倉庫 Registry 的實現(xiàn),目前使用“把賬戶密碼給三方應用”的方式。即假設用戶對 Docker 足夠信任,用戶直接將賬戶密碼交給 Docker,然后 Docker 使用賬戶密碼跟鑒權服務器申請臨時 token。
理解 docker login首先,我們在拉取私有鏡像之前,要使用 docker login 命令來登錄鏡像倉庫。這里的登錄其實并沒有和鏡像倉庫建立什么會話之類的關系。登錄主要就做了三件事情:
第一件事情是跟用戶要賬戶密碼。如下圖,當執(zhí)行登錄命令,這個命會提示輸入賬戶密碼,這件事情對應的是大圖的第一步。
第二件事情,docker 訪問鏡像倉庫的 https 地址,并通過挑戰(zhàn) v2 接口來確認,接口是否會返回 Docker-Distribution-Api-Version 頭字段。這件事情在協(xié)議圖中沒有對應的步驟。它的作用跟 ping 差不多,只是確認下 v2 鏡像倉庫是否在線,以及版本是否匹配。
第三件事情,docker 使用用戶提供的賬戶密碼,訪問 Www-Authenticate 頭字段返回的鑒權服務器的地址 Bearer realm。如果這個訪問成功,則鑒權服務器會返回 jwt 格式的 token 給 docker,然后 docker 會把賬戶密碼編碼并保存在用戶目錄的 .docker/docker.json 文件里。
下圖是我登錄倉庫之后的 docker.json 文件。這個文件作為 docker 登錄倉庫的唯一證據(jù),在后續(xù)鏡像倉庫操作中,會被不斷的讀取并使用。其中關鍵信息 auth 就是賬戶密碼的 base64 編碼。
拉取鏡像是怎么回事鏡像一般會包括兩部分內(nèi)容,一個是 manifests 文件,這個文件定義了鏡像的元數(shù)據(jù),另一個是鏡像層,是實際的鏡像分層文件。鏡像拉取基本上是圍繞這兩部分內(nèi)容展開。因為我們這篇文章的重點是權限問題,所以我們這里只以 manifests 文件拉取為例。
拉取 manifests 文件,基本上也會做三件事情:
首先,docker 直接訪問鏡像manifests的地址,以便獲取 Www-Authenticate 頭字段。這個字段包括鑒權服務器的地址 Bearer realm,鏡像服務地址 service,以及定義了鏡像和操作的 scope。 接著,docker 訪問上邊拿到的 Bearer realm 地址來鑒權,以及在鑒權之后獲取一個臨時的 token。這對應協(xié)議大圖使用賬戶密碼獲取臨時 token 這一步,使用的賬戶密碼直接讀取自 docker.json 文件。 最后,使用上邊的 token,以 Authorization 頭字段的方式,來下載 manifests 文件。這對應的是協(xié)議大圖下載鏡像這一步。當然因為鏡像還有分層文件,所以實際 docker 還會用這個臨時 token 多次下載文件才能完整鏡像下載。 K8s 實現(xiàn)的私有鏡像自動拉取 基本功能K8s 集群一般會管理多個節(jié)點,每個節(jié)點都有自己的 docker 環(huán)境。如果讓用戶分別到集群節(jié)點上登錄鏡像倉庫,這顯然是很不方便的。為了解決這個問題,K8s 實現(xiàn)了自動拉取鏡像的功能。這個功能的核心,是把 docker.json 內(nèi)容編碼,并以 Secret 的方式作為 Pod 定義的一部分傳給 Kubelet。
具體來說,步驟如下:
創(chuàng)建 secret。這個 secret 的 .dockerconfigjson 數(shù)據(jù)項包括了一份 base64 編碼的 docker.json 文件; 創(chuàng)建 pod,且 pod 編排中 imagePullSecrets 指向第一步創(chuàng)建的 secret; Kubelet 作為集群控制器,監(jiān)控著集群的變化。當它發(fā)現(xiàn)新的 pod 被創(chuàng)建,就會通過 API Server 獲取 pod 的定義,這包括 imagePullSecrets 引用的 secret; Kubelet 調用 docker 創(chuàng)建容器且把 .dockerconfigjson 傳給 docker; 最后 docker 使用解碼出來的賬戶密碼拉取鏡像,這和上一節(jié)的方法一致。 進階方式上邊的功能,一定程度上解決了集群節(jié)點登錄鏡像倉庫不方便的問題。但是我們在創(chuàng)建 Pod 的時候,仍然需要給 Pod 指定 imagePullSecrets。K8s 通過變更準入控制(Mutating Admission Control)進一步優(yōu)化了上邊的基本功能。
進一步優(yōu)化的內(nèi)容如下:
在第一步創(chuàng)建 secret 之后,添加 default service account 對 imagePullSecrets 的引用; Pod 默認使用 default service account,而 service account 變更準入控制器會在 default service account 引用 imagePullSecrets 的情況下,添加 imagePullSecrets 配置到 pod 的編排里。 阿里云實現(xiàn)的 Acr credential helper阿里云容器服務團隊,在 K8s 的基礎上實現(xiàn)了控制器 Acr credential helper。這個控制器可以讓同時使用阿里云 K8s 集群和容器鏡像服務產(chǎn)品的用戶,在不用配置自己賬戶密碼的情況下,自動使用私有倉庫中的容器鏡像。
具體來說,控制器會監(jiān)聽 acr-configuration 這個 configmap 的變化,其主要關心 acr-registry 和 watch-namespace 這兩個配置。前一個配置指定為臨時賬戶授權的鏡像倉庫地址,后一個配置管理可以自動拉取鏡像的命名空間。當控制器發(fā)現(xiàn)有命名空間需要被配置卻沒有被配置的時候,它會通過阿里云容器鏡像服務的 API,來獲取臨時賬戶和密碼。
有了臨時賬戶密碼,Acr credential helper 為命名空間創(chuàng)建對應的 Secret 以及更改 default SA 來引用這個 Secret。這樣,控制器和 K8s 集群本身的功能,一起自動化了阿里云 K8s 集群拉取阿里云容器鏡像服務上的鏡像的全部流程。
總結理解私有鏡像自動拉取的實現(xiàn),有一個難點和一個重點。
難點是 OAuth 2.0 安全協(xié)議的原理,上文主要分析了為什么 OAuth 會這么設計; 重點是集群控制器原理,因為整個自動化的過程,實際上是包括 Admission control 和 Acr credential helper 在內(nèi)的多個控制器協(xié)作的結果。**“ 阿里巴巴云×××icloudnative×××erverless、容器、Service Mesh等技術領域、聚焦云原生流行技術趨勢、云原生大規(guī)模的落地實踐,做最懂云原生開發(fā)×××
分享題目:K8s從懵圈到熟練–鏡像拉取這件小事
網(wǎng)址分享:http://www.rwnh.cn/article38/cjddsp.html
成都網(wǎng)站建設公司_創(chuàng)新互聯(lián),為您提供云服務器、做網(wǎng)站、虛擬主機、網(wǎng)站建設、關鍵詞優(yōu)化、靜態(tài)網(wǎng)站
聲明:本網(wǎng)站發(fā)布的內(nèi)容(圖片、視頻和文字)以用戶投稿、用戶轉載內(nèi)容為主,如果涉及侵權請盡快告知,我們將會在第一時間刪除。文章觀點不代表本網(wǎng)站立場,如需處理請聯(lián)系客服。電話:028-86922220;郵箱:631063699@qq.com。內(nèi)容未經(jīng)允許不得轉載,或轉載時需注明來源: 創(chuàng)新互聯(lián)