W3Cschool
恭喜您成為首批注冊(cè)用戶
獲得88經(jīng)驗(yàn)值獎(jiǎng)勵(lì)
容器鏡像(Image)所承載的是封裝了應(yīng)用程序及其所有軟件依賴的二進(jìn)制數(shù)據(jù)。 容器鏡像是可執(zhí)行的軟件包,可以單獨(dú)運(yùn)行;該軟件包對(duì)所處的運(yùn)行時(shí)環(huán)境具有 良定(Well Defined)的假定。
你通常會(huì)創(chuàng)建應(yīng)用的容器鏡像并將其推送到某倉(cāng)庫(kù)(Registry),然后在 Pod 中引用它。
本頁(yè)概要介紹容器鏡像的概念。
容器鏡像通常會(huì)被賦予 ?pause
?、?example/mycontainer
? 或者 ?kube-apiserver
? 這類的名稱。 鏡像名稱也可以包含所在倉(cāng)庫(kù)的主機(jī)名。例如:?fictional.registry.example/imagename
?。 還可以包含倉(cāng)庫(kù)的端口號(hào),例如:?fictional.registry.example:10443/imagename
?。
如果你不指定倉(cāng)庫(kù)的主機(jī)名,Kubernetes 認(rèn)為你在使用 Docker 公共倉(cāng)庫(kù)。
在鏡像名稱之后,你可以添加一個(gè)標(biāo)簽(Tag)(與使用 ?docker
?或 ?podman
?等命令時(shí)的方式相同)。 使用標(biāo)簽?zāi)茏屇惚孀R(shí)同一鏡像序列中的不同版本。
鏡像標(biāo)簽可以包含小寫字母、大寫字母、數(shù)字、下劃線(?_
?)、句點(diǎn)(?.
?)和連字符(?-
?)。 關(guān)于在鏡像標(biāo)簽中何處可以使用分隔字符(?_
?、?-
? 和 ?.
?)還有一些額外的規(guī)則。 如果你不指定標(biāo)簽,Kubernetes 認(rèn)為你想使用標(biāo)簽 ?latest
?。
當(dāng)你最初創(chuàng)建一個(gè) Deployment、 StatefulSet、Pod 或者其他包含 Pod 模板的對(duì)象時(shí),如果沒有顯式設(shè)定的話,Pod 中所有容器的默認(rèn)鏡像 拉取策略是 ?IfNotPresent
?。這一策略會(huì)使得 kubelet 在鏡像已經(jīng)存在的情況下直接略過(guò)拉取鏡像的操作。
容器的 ?imagePullPolicy
?和鏡像的標(biāo)簽會(huì)影響 kubelet 嘗試?yán)。ㄏ螺d)指定的鏡像。
以下列表包含了 ?imagePullPolicy
?可以設(shè)置的值,以及這些值的效果:
只要能夠可靠地訪問(wèn)鏡像倉(cāng)庫(kù),底層鏡像提供者的緩存語(yǔ)義甚至可以使 imagePullPolicy: Always 高效。 你的容器運(yùn)行時(shí)可以注意到節(jié)點(diǎn)上已經(jīng)存在的鏡像層,這樣就不需要再次下載。
在生產(chǎn)環(huán)境中部署容器時(shí),你應(yīng)該避免使用 ?:latest
? 標(biāo)簽,因?yàn)檫@使得正在運(yùn)行的鏡像的版本難以追蹤,并且難以正確地回滾。
相反,應(yīng)指定一個(gè)有意義的標(biāo)簽,如 ?v1.42.0
?。
為了確保 Pod 總是使用相同版本的容器鏡像,你可以指定鏡像的摘要; 將 ?<image-name>:<tag>
? 替換為 ?<image-name>@<digest>
?,例如 ?image@sha256:45b23dee08af5e43a7fea6c4cf9c25ccf269ee113168c19722f87876677c5cb2
?。
當(dāng)使用鏡像標(biāo)簽時(shí),如果鏡像倉(cāng)庫(kù)修改了代碼所對(duì)應(yīng)的鏡像標(biāo)簽,可能會(huì)出現(xiàn)新舊代碼混雜在 Pod 中運(yùn)行的情況。 鏡像摘要唯一標(biāo)識(shí)了鏡像的特定版本,因此 Kubernetes 每次啟動(dòng)具有指定鏡像名稱和摘要的容器時(shí),都會(huì)運(yùn)行相同的代碼。 通過(guò)摘要指定鏡像可固定你運(yùn)行的代碼,這樣鏡像倉(cāng)庫(kù)的變化就不會(huì)導(dǎo)致版本的混雜。
有一些第三方的準(zhǔn)入控制器 在創(chuàng)建 Pod(和 Pod 模板)時(shí)產(chǎn)生變更,這樣運(yùn)行的工作負(fù)載就是根據(jù)鏡像摘要,而不是標(biāo)簽來(lái)定義的。 無(wú)論鏡像倉(cāng)庫(kù)上的標(biāo)簽發(fā)生什么變化,你都想確保你所有的工作負(fù)載都運(yùn)行相同的代碼,那么指定鏡像摘要會(huì)很有用。
當(dāng)你(或控制器)向 API 服務(wù)器提交一個(gè)新的 Pod 時(shí),你的集群會(huì)在滿足特定條件時(shí)設(shè)置 ?imagePullPolicy
?字段:
imagePullPolicy
?字段,并且容器鏡像的標(biāo)簽是 ?:latest
?, ?imagePullPolicy
?會(huì)自動(dòng)設(shè)置為 ?Always
?。imagePullPolicy
?字段,并且沒有指定容器鏡像的標(biāo)簽, ?imagePullPolicy
?會(huì)自動(dòng)設(shè)置為 ?Always
?。imagePullPolicy
?字段,并且為容器鏡像指定了非 ?:latest
? 的標(biāo)簽, ?imagePullPolicy
?就會(huì)自動(dòng)設(shè)置為 ?IfNotPresent
?。容器的 ?imagePullPolicy
?的值總是在對(duì)象初次 創(chuàng)建 時(shí)設(shè)置的,如果后來(lái)鏡像的標(biāo)簽發(fā)生變化,則不會(huì)更新。
例如,如果你用一個(gè) 非 ?:latest
? 的鏡像標(biāo)簽創(chuàng)建一個(gè) Deployment, 并在隨后更新該 Deployment 的鏡像標(biāo)簽為 ?:latest
?,則 ?imagePullPolicy
?字段 不會(huì) 變成 ?Always
?。 你必須手動(dòng)更改已經(jīng)創(chuàng)建的資源的拉取策略。
如果你想總是強(qiáng)制執(zhí)行拉取,你可以使用下述的一中方式:
imagePullPolicy
?為 ?Always
?。imagePullPolicy
?,并使用 ?:latest
? 作為鏡像標(biāo)簽; 當(dāng)你提交 Pod 時(shí),Kubernetes 會(huì)將策略設(shè)置為 ?Always
?。imagePullPolicy
?和鏡像的標(biāo)簽; 當(dāng)你提交 Pod 時(shí),Kubernetes 會(huì)將策略設(shè)置為 ?Always
?。當(dāng) kubelet 使用容器運(yùn)行時(shí)創(chuàng)建 Pod 時(shí),容器可能因?yàn)?nbsp;?ImagePullBackOff
?導(dǎo)致狀態(tài)為 Waiting。
?ImagePullBackOff
?狀態(tài)意味著容器無(wú)法啟動(dòng), 因?yàn)?nbsp;Kubernetes 無(wú)法拉取容器鏡像(原因包括無(wú)效的鏡像名稱,或從私有倉(cāng)庫(kù)拉取而沒有 ?imagePullSecret
?)。 ?BackOff
?部分表示 Kubernetes 將繼續(xù)嘗試?yán)$R像,并增加回退延遲。
Kubernetes 會(huì)增加每次嘗試之間的延遲,直到達(dá)到編譯限制,即 300 秒(5 分鐘)。
除了提供二進(jìn)制的鏡像之外,容器倉(cāng)庫(kù)也可以提供 容器鏡像索引。 鏡像索引可以根據(jù)特定于體系結(jié)構(gòu)版本的容器指向鏡像的多個(gè) 鏡像清單。 這背后的理念是讓你可以為鏡像命名(例如:?pause
?、?example/mycontainer
?、?kube-apiserver
?) 的同時(shí),允許不同的系統(tǒng)基于它們所使用的機(jī)器體系結(jié)構(gòu)取回正確的二進(jìn)制鏡像。
Kubernetes 自身通常在命名容器鏡像時(shí)添加后綴 ?-$(ARCH)
?。 為了向前兼容,請(qǐng)?jiān)谏奢^老的鏡像時(shí)也提供后綴。 這里的理念是為某鏡像(如 ?pause
?)生成針對(duì)所有平臺(tái)都適用的清單時(shí), 生成 ?pause-amd64
? 這類鏡像,以便較老的配置文件或者將鏡像后綴影編碼到其中的 YAML 文件也能兼容。
從私有倉(cāng)庫(kù)讀取鏡像時(shí)可能需要密鑰。 憑證可以用以下方式提供:
設(shè)置憑據(jù)的具體說(shuō)明取決于你選擇使用的容器運(yùn)行時(shí)和倉(cāng)庫(kù)。
Kubernetes 默認(rèn)僅支持 Docker 配置中的 ?
auths
?和 ?HttpHeaders
?部分, 不支持 Docker 憑據(jù)輔助程序(?credHelpers
?或 ?credsStore
?)。
對(duì)于 ?config.json
? 的解釋在原始 Docker 實(shí)現(xiàn)和 Kubernetes 的解釋之間有所不同。 在 Docker 中,?auths
?鍵只能指定根 URL ,而 Kubernetes 允許 glob URLs 以及 前綴匹配的路徑。這意味著,像這樣的 ?config.json
? 是有效的:
{
"auths": {
"*my-registry.io/images": {
"auth": "…"
}
}
}
使用以下語(yǔ)法匹配根 URL (?*my-registry.io
?):
pattern:
{ term }
term:
'*' 匹配任何無(wú)分隔符字符序列
'?' 匹配任意單個(gè)非分隔符
'[' [ '^' ] 字符范圍
字符集(必須非空)
c 匹配字符 c (c 不為 '*','?','\\','[')
'\\' c 匹配字符 c
字符范圍:
c 匹配字符 c (c 不為 '\\','?','-',']')
'\\' c 匹配字符 c
lo '-' hi 匹配字符范圍在 lo 到 hi 之間字符
現(xiàn)在鏡像拉取操作會(huì)將每種有效模式的憑據(jù)都傳遞給 CRI 容器運(yùn)行時(shí)。例如下面的容器鏡像名稱會(huì)匹配成功:
my-registry.io/images
?my-registry.io/images/my-image
?my-registry.io/images/another-image
?sub.my-registry.io/images/my-image
?a.sub.my-registry.io/images/my-image
?kubelet 為每個(gè)找到的憑證的鏡像按順序拉取。 這意味著在 ?config.json
? 中可能有多項(xiàng):
{
"auths": {
"my-registry.io/images": {
"auth": "…"
},
"my-registry.io/images/subpath": {
"auth": "…"
}
}
}
如果一個(gè)容器指定了要拉取的鏡像 ?my-registry.io/images/subpath/my-image
?, 并且其中一個(gè)失敗,kubelet 將嘗試從另一個(gè)身份驗(yàn)證源下載鏡像。
該方法適用于你能夠控制節(jié)點(diǎn)配置的場(chǎng)合。 如果你的云供應(yīng)商負(fù)責(zé)管理節(jié)點(diǎn)并自動(dòng)置換節(jié)點(diǎn),這一方案無(wú)法可靠地工作。
默認(rèn)情況下,?kubelet
?會(huì)嘗試從指定的倉(cāng)庫(kù)拉取每個(gè)鏡像。 但是,如果容器屬性 ?imagePullPolicy
?設(shè)置為 ?IfNotPresent
?或者 ?Never
?, 則會(huì)優(yōu)先使用(對(duì)應(yīng) ?IfNotPresent
?)或者一定使用(對(duì)應(yīng) ?Never
?)本地鏡像。
如果你希望使用提前拉取鏡像的方法代替?zhèn)}庫(kù)認(rèn)證,就必須保證集群中所有節(jié)點(diǎn)提前拉取的鏡像是相同的。
這一方案可以用來(lái)提前載入指定的鏡像以提高速度,或者作為向私有倉(cāng)庫(kù)執(zhí)行身份認(rèn)證的一種替代方案。
所有的 Pod 都可以使用節(jié)點(diǎn)上提前拉取的鏡像。
運(yùn)行使用私有倉(cāng)庫(kù)中鏡像的容器時(shí),建議使用這種方法。
Kubernetes 支持在 Pod 中設(shè)置容器鏡像倉(cāng)庫(kù)的密鑰。
你需要知道用于向倉(cāng)庫(kù)進(jìn)行身份驗(yàn)證的用戶名、密碼和客戶端電子郵件地址,以及它的主機(jī)名。 運(yùn)行以下命令,注意替換適當(dāng)?shù)拇髮懼担?/p>
kubectl create secret docker-registry <name> --docker-server=DOCKER_REGISTRY_SERVER --docker-username=DOCKER_USER --docker-password=DOCKER_PASSWORD --docker-email=DOCKER_EMAIL
如果你已經(jīng)有 Docker 憑據(jù)文件,則可以將憑據(jù)文件導(dǎo)入為 Kubernetes Secret, 而不是執(zhí)行上面的命令。
如果你在使用多個(gè)私有容器倉(cāng)庫(kù),這種技術(shù)將特別有用。 原因是 ?kubectl create secret docker-registry
? 創(chuàng)建的是僅適用于某個(gè)私有倉(cāng)庫(kù)的 Secret。
Pod 只能引用位于自身所在名字空間中的 Secret,因此需要針對(duì)每個(gè)名字空間 重復(fù)執(zhí)行上述過(guò)程。
現(xiàn)在,在創(chuàng)建 Pod 時(shí),可以在 Pod 定義中增加 ?imagePullSecrets
?部分來(lái)引用該 Secret。
例如:
cat <<EOF > pod.yaml
apiVersion: v1
kind: Pod
metadata:
name: foo
namespace: awesomeapps
spec:
containers:
- name: foo
image: janedoe/awesomeapp:v1
imagePullSecrets:
- name: myregistrykey
EOF
cat <<EOF >> ./kustomization.yaml
resources:
- pod.yaml
EOF
你需要對(duì)使用私有倉(cāng)庫(kù)的每個(gè) Pod 執(zhí)行以上操作。 不過(guò),設(shè)置該字段的過(guò)程也可以通過(guò)為 服務(wù)賬號(hào) 資源設(shè)置 ?imagePullSecrets
?來(lái)自動(dòng)完成。
你也可以將此方法與節(jié)點(diǎn)級(jí)別的 ?.docker/config.json
? 配置結(jié)合使用。 來(lái)自不同來(lái)源的憑據(jù)會(huì)被合并。
配置私有倉(cāng)庫(kù)有多種方案,以下是一些常用場(chǎng)景和建議的解決方案。
如果你需要訪問(wèn)多個(gè)倉(cāng)庫(kù),可以為每個(gè)倉(cāng)庫(kù)創(chuàng)建一個(gè) Secret。 ?kubelet
?將所有 ?imagePullSecrets
?合并為一個(gè)虛擬的 ?.docker/config.json
? 文件。
Copyright©2021 w3cschool編程獅|閩ICP備15016281號(hào)-3|閩公網(wǎng)安備35020302033924號(hào)
違法和不良信息舉報(bào)電話:173-0602-2364|舉報(bào)郵箱:jubao@eeedong.com
掃描二維碼
下載編程獅App
編程獅公眾號(hào)
聯(lián)系方式:
更多建議: