如何拉取k8s镜像_K8s 从懵圈到熟练 – 镜像拉取这件小事
順序上來說,私有鏡像自動(dòng)拉取會(huì)首先通過阿里云 Acr credential helper 組件,再經(jīng)過 K8s 集群的 API Server 和 kubelet 組件,最后到 docker 容器運(yùn)行時(shí)。但是我的敘述,會(huì)從后往前,從最基本的 docker 鏡像拉取說起。
鏡像拉取這件小事
為了討論方便,我們來設(shè)想一個(gè)場(chǎng)景。很多人會(huì)使用網(wǎng)盤來存放一些文件,像照片,文檔之類。當(dāng)我們存取文件的時(shí)候,我們需要給網(wǎng)盤提供賬戶密碼,這樣網(wǎng)盤服務(wù)就能驗(yàn)證我們的身份。這時(shí),我們是文件資源的所有者,而網(wǎng)盤則扮演著資源服務(wù)器的角色。賬戶密碼作為認(rèn)證方式,保證只有我們自己可以存取自己的文件。
這個(gè)場(chǎng)景足夠簡(jiǎn)單,但很快我們就遇到新需求:我們需要使用一個(gè)在線制作相冊(cè)的應(yīng)用。按正常的使用流程,我們需要把網(wǎng)盤的照片下載到本地,然后再把照片上傳到電子相冊(cè)。這個(gè)過程是比較很繁瑣的。我們能想到的優(yōu)化方法是,讓相冊(cè)應(yīng)用,直接訪問網(wǎng)盤來獲取我們的照片,而這需要我們把用戶名和密碼授權(quán)給相冊(cè)應(yīng)用使用。
這樣的授權(quán)方式,優(yōu)點(diǎn)顯而易見,但缺點(diǎn)也是很明顯的:我們把網(wǎng)盤的用戶名密碼給了相冊(cè)服務(wù),相冊(cè)服務(wù)就擁有了讀寫網(wǎng)盤的能力,從數(shù)據(jù)安全角度,這個(gè)是很可怕的。其實(shí)這是很多應(yīng)用都會(huì)遇到的一個(gè)一般性場(chǎng)景。私有鏡像拉取其實(shí)也是這個(gè)場(chǎng)景。這里的鏡像倉(cāng)庫(kù),就跟網(wǎng)盤一樣,是資源服務(wù)器,而容器集群則是三方服務(wù),它需要訪問鏡像倉(cāng)庫(kù)獲取鏡像。
理解 OAuth 2.0 協(xié)議
OAuth 協(xié)議是為了解決上述問題而設(shè)計(jì)的一種標(biāo)準(zhǔn)方案,我們的討論針對(duì) 2.0 版本。相比把賬戶密碼直接給三方應(yīng)用,此協(xié)議采用了一種間接的方式來達(dá)到同樣的目的。如下圖,這個(gè)協(xié)議包括六個(gè)步驟,分別是三方應(yīng)用獲取用戶授權(quán),三方應(yīng)用獲取臨時(shí) Token 以及三方應(yīng)用存取資源。
這六步理解起來不容易,主要是因?yàn)榘踩珔f(xié)議的設(shè)計(jì),需要考慮協(xié)議的易證明性,所以我們換一種方式來解釋這個(gè)協(xié)議。簡(jiǎn)單來說,這個(gè)協(xié)議其實(shí)就做了兩件事情:
- 在用戶授權(quán)的情況下,三方應(yīng)用獲取 token 所表示的臨時(shí)訪問權(quán)限;
- 然后三方應(yīng)用使用這個(gè) token 去獲取資源。
如果用網(wǎng)盤的例子來說明的話,那就是用戶授權(quán)網(wǎng)盤服務(wù)給相冊(cè)應(yīng)用創(chuàng)建臨時(shí) token,然后相冊(cè)應(yīng)用使用這個(gè) token 去網(wǎng)盤服務(wù)獲取用戶的照片。實(shí)際上 OAuth 2.0 各個(gè)變種的核心差別,在于第一件事情,就是用戶授權(quán)資源服務(wù)器的方式。
從上面的描述我們可以看到,資源服務(wù)器實(shí)際上扮演了鑒權(quán)和資源管理兩種角色,這兩者分開實(shí)現(xiàn)的話,協(xié)議流程會(huì)變成下圖這樣。
Docker 扮演的角色
大圖
鏡像倉(cāng)庫(kù) Registry 的實(shí)現(xiàn),目前使用“把賬戶密碼給三方應(yīng)用”的方式。即假設(shè)用戶對(duì) Docker 足夠信任,用戶直接將賬戶密碼交給 Docker,然后 Docker 使用賬戶密碼跟鑒權(quán)服務(wù)器申請(qǐng)臨時(shí) token。
理解 docker login
首先,我們?cè)诶∷接戌R像之前,要使用 docker login 命令來登錄鏡像倉(cāng)庫(kù)。這里的登錄其實(shí)并沒有和鏡像倉(cāng)庫(kù)建立什么會(huì)話之類的關(guān)系。登錄主要就做了三件事情:
- 第一件事情是跟用戶要賬戶密碼。
如下圖,當(dāng)執(zhí)行登錄命令,這個(gè)命會(huì)提示輸入賬戶密碼,這件事情對(duì)應(yīng)的是大圖的第一步。
- 第二件事情,docker 訪問鏡像倉(cāng)庫(kù)的 https 地址,并通過挑戰(zhàn) v2 接口來確認(rèn),接口是否會(huì)返回 Docker-Distribution-Api-Version 頭字段。
這件事情在協(xié)議圖中沒有對(duì)應(yīng)的步驟。它的作用跟 ping 差不多,只是確認(rèn)下 v2 鏡像倉(cāng)庫(kù)是否在線,以及版本是否匹配。
- 第三件事情,docker 使用用戶提供的賬戶密碼,訪問 Www-Authenticate 頭字段返回的鑒權(quán)服務(wù)器的地址 Bearer realm。
如果這個(gè)訪問成功,則鑒權(quán)服務(wù)器會(huì)返回 jwt 格式的 token 給 docker,然后 docker 會(huì)把賬戶密碼編碼并保存在用戶目錄的 .docker/docker.json 文件里。
下圖是我登錄倉(cāng)庫(kù)之后的 docker.json 文件。這個(gè)文件作為 docker 登錄倉(cāng)庫(kù)的唯一證據(jù),在后續(xù)鏡像倉(cāng)庫(kù)操作中,會(huì)被不斷的讀取并使用。其中關(guān)鍵信息 auth 就是賬戶密碼的 base64 編碼。
拉取鏡像是怎么回事
鏡像一般會(huì)包括兩部分內(nèi)容,一個(gè)是 manifests 文件,這個(gè)文件定義了鏡像的元數(shù)據(jù),另一個(gè)是鏡像層,是實(shí)際的鏡像分層文件。鏡像拉取基本上是圍繞這兩部分內(nèi)容展開。因?yàn)槲覀冞@篇文章的重點(diǎn)是權(quán)限問題,所以我們這里只以 manifests 文件拉取為例。
拉取 manifests 文件,基本上也會(huì)做三件事情:
- 首先,docker 直接訪問鏡像manifests的地址,以便獲取 Www-Authenticate 頭字段。這個(gè)字段包括鑒權(quán)服務(wù)器的地址 Bearer realm,鏡像服務(wù)地址 service,以及定義了鏡像和操作的 scope。
- 接著,docker 訪問上邊拿到的 Bearer realm 地址來鑒權(quán),以及在鑒權(quán)之后獲取一個(gè)臨時(shí)的 token。這對(duì)應(yīng)協(xié)議大圖使用賬戶密碼獲取臨時(shí) token 這一步,使用的賬戶密碼直接讀取自 docker.json 文件。
- 最后,使用上邊的 token,以 Authorization 頭字段的方式,來下載 manifests 文件。這對(duì)應(yīng)的是協(xié)議大圖下載鏡像這一步。當(dāng)然因?yàn)殓R像還有分層文件,所以實(shí)際 docker 還會(huì)用這個(gè)臨時(shí) token 多次下載文件才能完整鏡像下載。
K8s 實(shí)現(xiàn)的私有鏡像自動(dòng)拉取
基本功能
K8s 集群一般會(huì)管理多個(gè)節(jié)點(diǎn),每個(gè)節(jié)點(diǎn)都有自己的 docker 環(huán)境。如果讓用戶分別到集群節(jié)點(diǎn)上登錄鏡像倉(cāng)庫(kù),這顯然是很不方便的。為了解決這個(gè)問題,K8s 實(shí)現(xiàn)了自動(dòng)拉取鏡像的功能。這個(gè)功能的核心,是把 docker.json 內(nèi)容編碼,并以 Secret 的方式作為 Pod 定義的一部分傳給 Kubelet。
具體來說,步驟如下:
進(jìn)階方式
上邊的功能,一定程度上解決了集群節(jié)點(diǎn)登錄鏡像倉(cāng)庫(kù)不方便的問題。但是我們?cè)趧?chuàng)建 Pod 的時(shí)候,仍然需要給 Pod 指定 imagePullSecrets。K8s 通過變更準(zhǔn)入控制(Mutating Admission Control)進(jìn)一步優(yōu)化了上邊的基本功能。
進(jìn)一步優(yōu)化的內(nèi)容如下:
阿里云實(shí)現(xiàn)的 Acr credential helper
阿里云容器服務(wù)團(tuán)隊(duì),在 K8s 的基礎(chǔ)上實(shí)現(xiàn)了控制器 Acr credential helper。這個(gè)控制器可以讓同時(shí)使用阿里云 K8s 集群和容器鏡像服務(wù)產(chǎn)品的用戶,在不用配置自己賬戶密碼的情況下,自動(dòng)使用私有倉(cāng)庫(kù)中的容器鏡像。
具體來說,控制器會(huì)監(jiān)聽 acr-configuration 這個(gè) configmap 的變化,其主要關(guān)心 acr-registry 和 watch-namespace 這兩個(gè)配置。前一個(gè)配置指定為臨時(shí)賬戶授權(quán)的鏡像倉(cāng)庫(kù)地址,后一個(gè)配置管理可以自動(dòng)拉取鏡像的命名空間。當(dāng)控制器發(fā)現(xiàn)有命名空間需要被配置卻沒有被配置的時(shí)候,它會(huì)通過阿里云容器鏡像服務(wù)的 API,來獲取臨時(shí)賬戶和密碼。
有了臨時(shí)賬戶密碼,Acr credential helper 為命名空間創(chuàng)建對(duì)應(yīng)的 Secret 以及更改 default SA 來引用這個(gè) Secret。這樣,控制器和 K8s 集群本身的功能,一起自動(dòng)化了阿里云 K8s 集群拉取阿里云容器鏡像服務(wù)上的鏡像的全部流程。
總結(jié)
理解私有鏡像自動(dòng)拉取的實(shí)現(xiàn),有一個(gè)難點(diǎn)和一個(gè)重點(diǎn)。
- 難點(diǎn)是 OAuth 2.0 安全協(xié)議的原理,上文主要分析了為什么 OAuth 會(huì)這么設(shè)計(jì);
- 重點(diǎn)是集群控制器原理,因?yàn)檎麄€(gè)自動(dòng)化的過程,實(shí)際上是包括 Admission control 和 Acr credential helper 在內(nèi)的多個(gè)控制器協(xié)作的結(jié)果。
原文鏈接
本文為云棲社區(qū)原創(chuàng)內(nèi)容,未經(jīng)允許不得轉(zhuǎn)載。
總結(jié)
以上是生活随笔為你收集整理的如何拉取k8s镜像_K8s 从懵圈到熟练 – 镜像拉取这件小事的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: python人脸识别程序如何嵌入到app
- 下一篇: semantic ui中文文档_Vuet