<kbd id="afajh"><form id="afajh"></form></kbd>
<strong id="afajh"><dl id="afajh"></dl></strong>
    <del id="afajh"><form id="afajh"></form></del>
        1. <th id="afajh"><progress id="afajh"></progress></th>
          <b id="afajh"><abbr id="afajh"></abbr></b>
          <th id="afajh"><progress id="afajh"></progress></th>

          如何在不重建鏡像的情況下修改容器

          共 4878字,需瀏覽 10分鐘

           ·

          2020-09-30 12:52

          現(xiàn)在我們使用容器非常頻繁,偶爾有一些需求需要更改容器鏡像中的一些行為,也許是一個(gè)很小的變化,一般我們能想到的就是重新構(gòu)建鏡像,但是這個(gè)我們就需要重新構(gòu)建發(fā)布鏡像了,除了構(gòu)建鏡像這種方式之外其實(shí)還有其他方式可以來(lái)實(shí)現(xiàn)這個(gè)需求。

          初始化容器

          Init Containers 是為了給 Pod 中定義的主容器提供附加功能的。它們?cè)谥魅萜髦皥?zhí)行,可以使用不同的容器鏡像,如果出現(xiàn)任何故障,它們將阻止主容器的啟動(dòng),所有的日志都可以很容易查看到,故障排除也相當(dāng)簡(jiǎn)單,它們就像在 Pod 中定義的任何其他容器一樣。這種方法在數(shù)據(jù)庫(kù)等服務(wù)中比較常用,可以根據(jù)配置參數(shù)對(duì)它們進(jìn)行初始化和配置。

          下面的例子使用一個(gè) emptyDir 來(lái)存儲(chǔ)由初始化容器初始化的數(shù)據(jù)。在這個(gè)示例,它只是一個(gè)簡(jiǎn)單的 echo 命令,在實(shí)際的生產(chǎn)環(huán)境中,可能是一個(gè)腳本,做一些更復(fù)雜的事情。

          apiVersion:?apps/v1
          kind:?Deployment
          metadata:
          ??labels:
          ????app:?nginx
          ??name:?nginx-init
          spec:
          ??selector:
          ????matchLabels:
          ??????app:?nginx
          ??template:
          ????metadata:
          ??????labels:
          ????????app:?nginx
          ????spec:
          ??????initContainers:
          ????????-?name:?prepare-webpage
          ??????????image:?busybox:1.28
          ??????????command:?["sh",?"-c"]
          ??????????args:?[
          ??????????????"set?-x;
          ??????????????echo?'

          Page?prepared?by?an?init?container

          '?>?/web/index.html;
          ??????????????echo?'Init?finished?successfully'
          ??????????????"
          ,
          ????????????]
          ??????????volumeMounts:
          ????????????-?mountPath:?/web
          ??????????????name:?web
          ??????containers:
          ????????-?image:?nginx:1.19
          ??????????name:?nginx
          ??????????volumeMounts:
          ????????????-?mountPath:?/usr/share/nginx/html/
          ??????????????name:?web
          ??????????ports:
          ????????????-?containerPort:?80
          ??????????????name:?http
          ??????volumes:
          ????????-?name:?web
          ??????????emptyDir:?{}

          PostStart Hook

          post-start hook 可用于在主容器啟動(dòng)后執(zhí)行一些操作,它可以是在與容器相同的上下文中執(zhí)行的腳本,也可以是針對(duì)定義的端點(diǎn)執(zhí)行的 HTTP 請(qǐng)求,但是,不能保證回調(diào)會(huì)在容器入口點(diǎn)(ENTRYPOINT)之前執(zhí)行。在大多數(shù)情況下,它可能是一個(gè) shell 腳本,Pod一直保持在ContainerCreating 狀態(tài),直到這個(gè)腳本結(jié)束。由于沒(méi)有可用的日志,所以調(diào)試起來(lái)可能很棘手。這個(gè)方法最大的特點(diǎn)是,當(dāng)主容器中的服務(wù)啟動(dòng)時(shí),腳本就會(huì)被執(zhí)行,并且可以用來(lái)與服務(wù)進(jìn)行交互,通過(guò)適當(dāng)?shù)?readinessProbe 配置,這可以提供一種很好的方式,在允許任何請(qǐng)求之前初始化應(yīng)用程序。在下面的例子中,一個(gè)啟動(dòng)后的鉤子會(huì)執(zhí)行 echo 命令,但同樣這可以是任何使用容器文件系統(tǒng)上可用的同一組文件來(lái)執(zhí)行某種初始化的東西。

          apiVersion:?apps/v1
          kind:?Deployment
          metadata:
          ??labels:
          ????app:?nginx
          ??name:?nginx-hook
          spec:
          ??selector:
          ????matchLabels:
          ??????app:?nginx
          ??template:
          ????metadata:
          ??????labels:
          ????????app:?nginx
          ????spec:
          ??????containers:
          ????????-?image:?nginx:1.19
          ??????????name:?nginx
          ??????????ports:
          ????????????-?containerPort:?80
          ??????????????name:?http
          ??????????lifecycle:
          ????????????postStart:
          ??????????????exec:
          ????????????????command:
          ??????????????????[
          ????????????????????"sh",
          ????????????????????"-c",
          ????????????????????"sleep?5;set?-x;?echo?'

          Page?prepared?by?a?PostStart?hook

          '?>?/usr/share/nginx/html/index.html"
          ,
          ??????????????????]

          Sidecar 容器

          這種方法利用了 Pod 的概念 - 多個(gè)容器同時(shí)運(yùn)行、共享 IPC 和網(wǎng)絡(luò)命名空間。在 Kubernetes 生態(tài)系統(tǒng)中,它已經(jīng)被 Istio、Consul Connect 等項(xiàng)目廣泛使用。這里的假設(shè)是所有容器同時(shí)運(yùn)行,這使得使用 sidecar 容器來(lái)修改主容器的行為變得有點(diǎn)棘手。但這是可行的,它可以用來(lái)與正在運(yùn)行的應(yīng)用程序或服務(wù)進(jìn)行交互。我在 Jenkins Helm Chart 中使用了這個(gè)功能,其中有一個(gè) sidecar 容器負(fù)責(zé)讀取 ConfigMap 對(duì)象和 Configuration-as-Code 配置項(xiàng)。

          在下面示例中同樣只是使用 echo 這個(gè)命令,不過(guò)需要注意的是,因?yàn)?sidecar 容器必須遵循 restartPolicy 設(shè)置,所以這個(gè)容器在完成動(dòng)作后還必須處于運(yùn)行狀態(tài),示例中我們使用的是一個(gè)簡(jiǎn)單的 while 無(wú)限循環(huán),在實(shí)際環(huán)境中,往往會(huì)是一個(gè)小的守護(hù)進(jìn)程,像服務(wù)一樣一直運(yùn)行。

          apiVersion:?apps/v1
          kind:?Deployment
          metadata:
          ??labels:
          ????app:?nginx
          ??name:?nginx-sidecar
          spec:
          ??selector:
          ????matchLabels:
          ??????app:?nginx
          ??template:
          ????metadata:
          ??????labels:
          ????????app:?nginx
          ????spec:
          ??????containers:
          ????????-?image:?nginx:1.19
          ??????????name:?nginx
          ??????????volumeMounts:
          ????????????-?mountPath:?/usr/share/nginx/html/
          ??????????????name:?web
          ??????????ports:
          ????????????-?containerPort:?80
          ??????????????name:?http
          ????????-?name:?prepare-webpage
          ??????????image:?busybox:1.28
          ??????????command:?["sh",?"-c"]
          ??????????args:?[
          ??????????????"set?-x;
          ??????????????echo?'

          Page?prepared?by?a?sidecar?container

          '?>?/web/index.html;
          ??????????????while?:;do?sleep?9999;done
          ??????????????"
          ,
          ????????????]
          ??????????volumeMounts:
          ????????????-?mountPath:?/web
          ??????????????name:?web
          ??????volumes:
          ????????-?name:?web
          ??????????emptyDir:?{}

          EntryPoint

          最后一種方法使用相同的容器鏡像,與 PostStart Hook 類似,只是它在主應(yīng)用程序或服務(wù)之前運(yùn)行。我們?cè)谌萜麋R像中都定義一個(gè)ENTRYPOINT 命令,我們可以利用它來(lái)執(zhí)行一些腳本,這種方式經(jīng)常被很多官方鏡像所使用,在這種方法中,我們只需要預(yù)置自己的腳本來(lái)修改主容器的行為。在實(shí)際生產(chǎn)環(huán)境中,其實(shí)我們可以提供一個(gè)修改后的原始入口點(diǎn)文件。

          這個(gè)方法相對(duì)復(fù)雜一點(diǎn),需要?jiǎng)?chuàng)建一個(gè) ConfigMap,其中包含一個(gè)腳本內(nèi)容,在主入口點(diǎn)之前執(zhí)行。如下所示我們修改 nginx 入口點(diǎn)的腳本,然后嵌入到下面的 ConfigMap 中。

          apiVersion:?v1
          kind:?ConfigMap
          metadata:
          ??name:?scripts
          data:
          ??prestart-script.sh:?|-
          ????#!/usr/bin/env?bash
          ????echo?'

          Page?prepared?by?a?script?executed?before?entrypoint?container

          '
          ?>?/usr/share/nginx/html/index.html
          ????#?這是?"ENTRYPOINT?CMD?"從主容器鏡像定義中提取出來(lái)的
          ????exec?/docker-entrypoint.sh?nginx?-g?"daemon?off;"?

          有一點(diǎn)非常重要,就是最后一行與 exec,它執(zhí)行的是原始的入口點(diǎn)腳本,必須與 Dockerfile 中定義的腳本完全匹配,在這種情況下,它需要額外的參數(shù),這些參數(shù)是在 CMD 中定義的。現(xiàn)在讓我們定義一下 Deployment 資源對(duì)象。

          apiVersion:?apps/v1
          kind:?Deployment
          metadata:
          ??labels:
          ????app:?nginx
          ??name:?nginx-script
          spec:
          ??selector:
          ????matchLabels:
          ??????app:?nginx
          ??template:
          ????metadata:
          ??????labels:
          ????????app:?nginx
          ????spec:
          ??????containers:
          ????????-?image:?nginx:1.19
          ??????????name:?nginx
          ??????????command:?["bash",?"-c",?"/scripts/prestart-script.sh"]
          ??????????ports:
          ????????????-?containerPort:?80
          ??????????????name:?http
          ??????????volumeMounts:
          ????????????-?mountPath:?/scripts
          ??????????????name:?scripts
          ??????volumes:
          ????????-?name:?scripts
          ??????????configMap:
          ????????????name:?scripts
          ????????????defaultMode:?0755?#?<-?這個(gè)很重要

          我們用命令覆蓋入口點(diǎn),我們還必須確保我們的腳本是以適當(dāng)?shù)臋?quán)限掛載的(因此需要定義 defaultMode)。

          總結(jié)

          現(xiàn)在我們來(lái)總結(jié)下上面幾種方式的差異。

          容器講究的是可重用性,很多時(shí)候做一些小的調(diào)整,不需要重新構(gòu)建整個(gè)容器的鏡像,這樣發(fā)布和維護(hù)就會(huì)輕松很多。

          作者:Tomasz Cholewa,原文鏈接:https://cloudowski.com/articles/how-to-modify-containers-wihtout-rebuilding/




          K8S進(jìn)階訓(xùn)練營(yíng),點(diǎn)擊下方圖片了解詳情


          瀏覽 66
          點(diǎn)贊
          評(píng)論
          收藏
          分享

          手機(jī)掃一掃分享

          分享
          舉報(bào)
          評(píng)論
          圖片
          表情
          推薦
          點(diǎn)贊
          評(píng)論
          收藏
          分享

          手機(jī)掃一掃分享

          分享
          舉報(bào)
          <kbd id="afajh"><form id="afajh"></form></kbd>
          <strong id="afajh"><dl id="afajh"></dl></strong>
            <del id="afajh"><form id="afajh"></form></del>
                1. <th id="afajh"><progress id="afajh"></progress></th>
                  <b id="afajh"><abbr id="afajh"></abbr></b>
                  <th id="afajh"><progress id="afajh"></progress></th>
                  久久十八禁 | 中文字幕久久成人 | 亚洲男人天堂2025 | 女人一级A片色黄情免费 | 免费黄色视频网站在线观看 |