自拍偷在线精品自拍偷,亚洲欧美中文日韩v在线观看不卡

Docker容器構(gòu)建優(yōu)秀實(shí)踐

安全 云安全
本文介紹我們給大家介紹了一套總結(jié)了業(yè)界實(shí)踐的容器的優(yōu)秀實(shí)踐。目的是讓容器構(gòu)建更加快速,更安全,也更具彈性。本文假設(shè)讀者有一定Docker和Kubernetes了解,但也可以單獨(dú)作為Docker容器構(gòu)建守則。

在容器和虛擬化廣泛流行的今天,如何構(gòu)建出一個(gè)安全、潔凈的容器是大家都關(guān)心的問題。和安全領(lǐng)域?qū)ο到y(tǒng)的要求一樣"只安裝必須的應(yīng)用"的最小化原則也是容器構(gòu)建的基本法則。一方面最小化的應(yīng)用可以減小鏡像的大小,節(jié)省上傳下載的時(shí)間,同時(shí)減少了容器中的應(yīng)用也就減少了可入侵點(diǎn),使容器更安全。本文介紹我們給大家介紹了一套總結(jié)了業(yè)界實(shí)踐的容器的優(yōu)秀實(shí)踐。目的是讓容器構(gòu)建更加快速,更安全,也更具彈性。本文假設(shè)讀者有一定Docker和Kubernetes了解,但也可以單獨(dú)作為Docker容器構(gòu)建守則。

一個(gè)容器一個(gè)應(yīng)用程序

當(dāng)開始使用容器時(shí),常見的一個(gè)誤區(qū)是把容器當(dāng)成虛擬機(jī)來(lái)使。這樣做往往會(huì)讓他們不能輕易滿足某些需求而非常痛苦,同時(shí)也背離了容器的最大優(yōu)勢(shì)點(diǎn)。很多初學(xué)者在群里問了很多為么:為什么Docker不能aaa?怎么實(shí)現(xiàn)Docker bbb?然后他需要的答案其實(shí)上只是需要一個(gè)虛擬。雖然現(xiàn)代容器已經(jīng)可以滿足這些需求,但是這會(huì)極大減弱容器模型的大多數(shù)優(yōu)點(diǎn)。以經(jīng)典的Apache/MySQL/PHP堆棧為例,你可能很想在一個(gè)容器中運(yùn)行所有組件。但是,最佳實(shí)踐是使用兩個(gè)或三個(gè)不同的容器:Apache容器,MySQL容器,和運(yùn)行PHP-FPM的php容器。

由于容器設(shè)計(jì)思想是容器和托管的應(yīng)用程序具有相同的生命周期,因此每個(gè)容器應(yīng)當(dāng)只包含一個(gè)應(yīng)用程序。當(dāng)容器啟動(dòng)時(shí),應(yīng)用程序隨之啟動(dòng),當(dāng)容器停止時(shí),應(yīng)用也會(huì)停止。

容器如果部署了多個(gè)應(yīng)用,則它們有可能具有不同的生命周期或處于不同的狀態(tài)。例如,一個(gè)正在運(yùn)行的容器,但其核心組件之一突然崩潰或無(wú)響應(yīng)。由于沒有額外的運(yùn)行狀況檢查,整個(gè)容器管理系統(tǒng)(Docker或Kubernetes)將無(wú)法判斷容器是否健康。在Kubernetes集群中,容器默認(rèn)是不會(huì)重啟的。

有些公共鏡像中可能會(huì)使用如下有一些的操作,但不遵循原則:

使用進(jìn)程管理系統(tǒng)(比如supervisor)來(lái)管理容器中的一個(gè)或多個(gè)應(yīng)用。使用bash腳本作為容器中的入口點(diǎn),并使其產(chǎn)生多個(gè)應(yīng)用程序作為后臺(tái)作業(yè)。

信號(hào)處理,PID 1和僵尸進(jìn)程

Linux信號(hào)是控制容器內(nèi)進(jìn)程生命周期的主要方法。為了與前一條最佳實(shí)踐保持一致,為了將應(yīng)用程序的生命周期和容器關(guān)連,請(qǐng)確保應(yīng)用程序能夠正確處理Linux信號(hào)。其中最重要的一個(gè)Linux信號(hào)是SIGTERM,因?yàn)樗脕?lái)終止進(jìn)程。應(yīng)用可能還會(huì)收到SIGKILL信號(hào),用于非正常地終止進(jìn)程,或者SIGINT信號(hào),用于接受,鍵入的Ctrl + C指令。

進(jìn)程標(biāo)識(shí)符(PID)是Linux內(nèi)核為每個(gè)進(jìn)程提供的唯一標(biāo)識(shí)符。 PID具有名稱空間,容器具有自己的一組PID,這些PID會(huì)被映射到宿主機(jī)系統(tǒng)的PID。Linux內(nèi)核啟動(dòng)時(shí)會(huì)創(chuàng)建第一個(gè)進(jìn)程具有PID1。用來(lái)init系統(tǒng)用來(lái)管理其他進(jìn)程,比如systemd或SysV。同樣,容器中啟動(dòng)的第一個(gè)進(jìn)程也是PID1。Docker和Kubernetes使用信號(hào)與容器內(nèi)的進(jìn)程進(jìn)行通信。Docker和Kubernetes都只能向容器內(nèi)具有PID 1的進(jìn)程發(fā)送信號(hào)。

在容器環(huán)境中,需要考慮兩個(gè)PIDs和Linux信號(hào)的問題。

Linux內(nèi)核如何處理信號(hào)?

Linux內(nèi)核處理PID 1的進(jìn)程方式與對(duì)其他進(jìn)程不同。PID1,不會(huì)自動(dòng)注冊(cè)信號(hào)量SIGTERM,所以SIGTERM或SIGINT默認(rèn)對(duì)PID 1無(wú)效。默認(rèn)必須使用SIGKILL信號(hào)來(lái)殺掉進(jìn)程,無(wú)法優(yōu)雅的關(guān)閉進(jìn)程,可能會(huì)導(dǎo)致錯(cuò)誤,監(jiān)視數(shù)據(jù)寫入中斷(對(duì)于數(shù)據(jù)存儲(chǔ))以及一些不必要的告警。

典型的初始化系統(tǒng)如何處理孤立進(jìn)程?

典型的初始化系統(tǒng)(例如systemd)也用被用來(lái)刪除(捕獲)孤立的僵尸進(jìn)程。僵尸進(jìn)程(其父進(jìn)程已死亡的進(jìn)程)將會(huì)被附加到具有PID 1的進(jìn)程下,被其捕獲關(guān)閉。但是在容器中,需要映射到容器PID 1的進(jìn)程來(lái)處理。如果該進(jìn)程無(wú)法正確處理,則可能會(huì)出現(xiàn)內(nèi)存不足或其他資源不足的風(fēng)險(xiǎn)。

面對(duì)這些問題有幾種常見的解決方案:

1. 以PID 1運(yùn)行并注冊(cè)信號(hào)處理程序

該方案用來(lái)解決第一個(gè)問題。如果應(yīng)用以受控方式生成子進(jìn)程(通常是這種情況)是有效的,可以避免第二個(gè)問題。最簡(jiǎn)單方法是在Dockerfile中使用CMD和/或ENTRYPOINT指令啟動(dòng)你的進(jìn)程。例如,下面的Dockerfile中,nginx是第一個(gè)也是唯一要啟動(dòng)的進(jìn)程。

  1. FROM debian:9  
  2. RUN apt-get update && \  
  3. apt-get install -y nginx  
  4. EXPOSE 80  
  5. CMD [ "nginx", "-g", "daemon off;" ] 

注意:Nginx進(jìn)程注冊(cè)其自己的信號(hào)處理程序。使用此解決方案,在許多情況下,你必須在應(yīng)用程序代碼中執(zhí)行相同的操作。

有時(shí)可能需要準(zhǔn)備容器中的環(huán)境以使進(jìn)程正常運(yùn)行。在這種情況下,最佳實(shí)踐是讓容器在啟動(dòng)時(shí)運(yùn)行shell初始化腳本。該Shell腳本的用來(lái)配置所需的環(huán)境并啟動(dòng)主要進(jìn)程。但是,如果采用這種方法,則shell腳本擁有PID 1,這就是為什么必須使用內(nèi)置exec命令從shell腳本啟動(dòng)進(jìn)程的原因。exec命令將腳本替換為所需的程序,進(jìn)程將繼承PID 1。

2. 在Kubernetes中啟用進(jìn)程名稱空間共享

為Pod啟用進(jìn)程名稱空間共享時(shí),Kubernetes對(duì)該P(yáng)od中的所有容器使用單個(gè)進(jìn)程名稱空間。 Kubernetes Pod基礎(chǔ)容器成為PID 1,并自動(dòng)捕獲孤立的進(jìn)程。

3. 使用專門的初始化系統(tǒng)

就像在更經(jīng)典的Linux環(huán)境中一樣,也可以使用init系統(tǒng)來(lái)解決這些問題。但是,如果用于這個(gè)目的,普通的初始化系統(tǒng)(例如systemd或SysV)太復(fù)雜且太重,建議使用專門的容器創(chuàng)建的初始化系統(tǒng)(例如tini)。

如果使用容器專用的初始化系統(tǒng),則初始化進(jìn)程具有PID 1,并執(zhí)行以下操作:

  • 注冊(cè)正確的信號(hào)處理程序。
  • 確保信號(hào)對(duì)你的應(yīng)用程序有效。
  • 捕獲所有僵尸進(jìn)程。

可以通過使用docker run命令的--init選項(xiàng)在Docker中使用此解決方案。要在Kubernetes中使用,則必須在容器鏡像中先安裝init系統(tǒng),并將其用作容器的入口。

優(yōu)化Docker構(gòu)建緩存

Docker的構(gòu)建緩存可以極大的加速容器鏡像的構(gòu)建。在容器系統(tǒng)中鏡像是逐層構(gòu)建的,在Dockerfile中,每條指令都會(huì)在鏡像中創(chuàng)建一個(gè)層。在構(gòu)建期間,如果可能,Docker會(huì)嘗試重用先前構(gòu)建中一層,盡可能跳過其底層來(lái)減少構(gòu)建消耗成本的步驟。Docker只有在所有先前的構(gòu)建步驟都使用它的情況下,才能使用其構(gòu)建緩存。盡管這種做法通常使構(gòu)建更快,但需要考慮一些情況。

例如,要充分利用Docker構(gòu)建緩存,必須將需要經(jīng)常更改的構(gòu)建步驟放在Dockerfile的后面。如果將它們放在前面,則Docker無(wú)法將其構(gòu)建緩存用于其他更改頻率較低的構(gòu)建步驟。通常為源代碼的每個(gè)新版本構(gòu)建一個(gè)新的Docker鏡像,所以應(yīng)盡可能在Dockerfile的后面將源代碼添加到鏡像。如下圖,你可以看到,如果要更改了STEP 1,則Docker只能重用FROM FROM debian:9步驟中的層。但是,如果更改STEP 3,則Docker可以將這些層重新用于STEP 1和STEP 2。

圖中藍(lán)色表示可以重用的層,紅色表示必須重建的層。層的重用原則導(dǎo)致另一個(gè)后果,如果構(gòu)建步驟依賴于存儲(chǔ)在本地文件系統(tǒng)上的任何類型的緩存,則該緩存必須在同一構(gòu)建步驟中生成。如果未生成此緩存,則可能會(huì)使用來(lái)自先前構(gòu)建的過期的緩存來(lái)執(zhí)行的構(gòu)建步驟。通過apt或yum等程序包管理器中最常有這個(gè)問題,必須在一個(gè)RUN命令中同時(shí)安裝所有必須要的庫(kù)。如果更改下面Dockerfile中的第二個(gè)RUN步驟,則不會(huì)重新運(yùn)行apt-get update命令,從而導(dǎo)致過期的apt緩存。

  1. FROM debian:9  
  2. RUN apt-get update  
  3. RUN apt-get install -y nginx 

而是,在單個(gè)RUN步驟中合并兩個(gè)命令:

  1. FROM debian:9  
  2. RUN apt-get update && \  
  3. apt-get install -y nginx 

刪除不必要的工具

為了保護(hù)你的應(yīng)用免受攻擊者的侵害,請(qǐng)嘗試通過刪除所有不必要的工具來(lái)減少應(yīng)用的攻擊面。例如,刪除諸如netcat之類的實(shí)用程序,因?yàn)榭梢杂胣ecat隨便就能構(gòu)建一個(gè)反向shell。如果容器中不安裝netcat,則攻擊者無(wú)法這樣簡(jiǎn)單利用。

即使沒有容器化,此最佳實(shí)踐也適用于任何工作負(fù)載。區(qū)別在于,與經(jīng)典虛擬機(jī)或裸機(jī)服務(wù)器相比,使用容器實(shí)現(xiàn)起來(lái)要容易得多。

其中一些工具可能對(duì)于調(diào)試有用。例如,如果你將此最佳實(shí)踐推得足夠遠(yuǎn),那么詳盡的日志,跟蹤,概要分析和應(yīng)用程序性能管理系統(tǒng)將成為必不可少的。實(shí)際上,你不再可以依賴本地調(diào)試工具,因?yàn)樗鼈兺ǔ>哂泻芨叩奶貦?quán)。

文件系統(tǒng)內(nèi)容

鏡像中應(yīng)盡可能少的保留內(nèi)容。如果可以將應(yīng)用程序編譯為單個(gè)靜態(tài)鏈接的二進(jìn)制文件,則將該二進(jìn)制文件添加到暫存鏡像中將使獲得最終鏡像,該鏡像僅包含一個(gè)應(yīng)用程序,無(wú)其他內(nèi)容。通過減少鏡像中打包的工具數(shù)量,可以減少潛在的可在容器中執(zhí)行的操作。

文件系統(tǒng)安全

鏡像中沒有工具是不夠的。必須防止?jié)撛诘墓粽甙惭b工具。可以在此處組合使用兩種方法:

首先,避免以root用戶身份在容器內(nèi)運(yùn)行。該方法提供了第一層安全性,并且可以防止攻擊者使用嵌入在鏡像中的包管理器(如apt-get或apk)修改root擁有的文件。為了使用該方法,必須禁用或卸載sudo命令。

以只讀模式啟動(dòng)容器,可以通過使用docker run命令中的--read-only標(biāo)志或使用Kubernetes中的readOnlyRootFilesystem選項(xiàng)來(lái)執(zhí)行此操作??梢允褂肞odSecurityPolicy在Kubernetes中強(qiáng)制執(zhí)行此操作。

注意:如果應(yīng)用需要將臨時(shí)數(shù)據(jù)寫入磁盤,也可以使用readOnlyRootFilesystem選項(xiàng),只需為臨時(shí)文件添加emptyDir卷。Kubernetes中不支持emptyDir卷上的掛載,所以不能在啟用noexec標(biāo)志的情況下掛載該卷。

最小化鏡像

生成較小的鏡像具有諸如更快的上載和下載時(shí)間等優(yōu)點(diǎn),這對(duì)于Kubernetes中pod的冷啟動(dòng)時(shí)間尤為重要:鏡像越小,節(jié)點(diǎn)下載就越快。但是,構(gòu)建小型鏡像很難,因?yàn)榭赡軙?huì)在無(wú)意中給最終鏡像引入了構(gòu)建依賴項(xiàng)或未優(yōu)化的鏡像層。

使用最小的基礎(chǔ)鏡像

基礎(chǔ)鏡像是Dockerfile中FROM指令中所引用的鏡像。Dockerfile中的所有指令均基于該鏡像構(gòu)建?;A(chǔ)鏡像越小,生成的鏡像就越小,下載和加載就越快。例如,alpine:3.7鏡像比centos:7鏡像就小好幾十M。

我們甚至還可使用 scratch基礎(chǔ)鏡像,這是一個(gè)空鏡像,可以在其上構(gòu)建自己的運(yùn)行時(shí)環(huán)境。如果需要運(yùn)行的應(yīng)用程序是靜態(tài)鏈接的二進(jìn)制文件,使用暫存基礎(chǔ)鏡像非常容易:

  1. FROM scratch  
  2. COPY mybinary /mybinary  
  3. CMD [ "/mybinary" ] 

GoogleContainerTools的Distroless項(xiàng)目提供了多種語(yǔ)言(Java,Python(3),Golang,Node.js,dotnet)的基礎(chǔ)鏡像。鏡像僅包含語(yǔ)言的運(yùn)行時(shí),剔除了Linux發(fā)行版的很多工具,例如Shell,應(yīng)用包管理器等,下面項(xiàng)目的一個(gè)Golang的列子:

減少鏡像無(wú)效刪減

要減小鏡像的大小,需要嚴(yán)格遵守只安裝必須的應(yīng)用的原則??赡苡袝r(shí)候需要臨時(shí)安裝一些工具的軟件包,使用后在后面的步驟中再刪除。但是,這種方法也是有問題的。因?yàn)镈ockerfile的每條指令都會(huì)創(chuàng)建一個(gè)鏡像層,創(chuàng)建后,再在稍后的步驟中刪除的方法,實(shí)際不能減少鏡像的大小。(數(shù)據(jù)還在,只是被隱藏在底層而已)。比如:

錯(cuò)誤Dockerfile:

  1. FROM debian:9  
  2. RUN apt-get update && \  
  3. apt-get install -y \  
  4. [buildpackage]  
  5. RUN [build my app]  
  6. RUN apt-get autoremove --purge \  
  7. -y [buildpackage] && \  
  8. apt-get -y clean && \  
  9. rm -rf /var/lib/apt/lists/* 

正確Dockerfile:

  1. FROM debian:9  
  2. RUN apt-get update && \  
  3. apt-get install -y \  
  4. [buildpackage] && \  
  5. [build my app] && \  
  6. apt-get autoremove --purge \  
  7. -y [buildpackage] && \  
  8. apt-get -y clean && \  
  9. rm -rf /var/lib/apt/lists/* 

在錯(cuò)誤版本Dockerfile中,[buildpackage]和/var/lib/ap /lists/*中的文件仍然存在于與第一個(gè)RUN相對(duì)應(yīng)的鏡像層中。該層是鏡像的一部分,盡管里面的數(shù)據(jù)在最終鏡像中不可訪問,但也會(huì)和其他鏡像層一起上傳和下載。

在正確版本Dockerfile中,所有操作都在構(gòu)建的應(yīng)用程序的同一層中完成。 /var/lib/apt/lists/*中的[buildpackage]和文件在最終鏡像中不會(huì)存在,真正起到了刪除的效果。

減少鏡像無(wú)效刪除的另一種方法是使用多階段構(gòu)建(Docker 17.05中引入)。多階段構(gòu)建允許在第一個(gè)"構(gòu)建"容器中構(gòu)建應(yīng)用程序,并在使用相同Dockerfile的同時(shí)在另一個(gè)容器中使用結(jié)果。

在下面的Dockerfile中,hello二進(jìn)制文件內(nèi)置在第一個(gè)容器中,并注入了第二個(gè)容器。因?yàn)榈诙€(gè)容器是從頭開始的,所以生成的鏡像僅包含hello二進(jìn)制文件,而不包含構(gòu)建期間所需的源文件和目標(biāo)文件。但是,二進(jìn)制文件是必須靜態(tài)鏈接才能正常工作。

  1. FROM golang:1.10 as builder  
  2. WORKDIR /tmp/go  
  3. COPY hello.go ./  
  4. RUN CGO_ENABLED=0 go build -a -ldflags '-s' -o hel
  5. lo  
  6. FROM scratch  
  7. CMD [ "/hello" ]  
  8. COPY --from=builder /tmp/go/hello /hello 

嘗試創(chuàng)建具有公共鏡像層的鏡像

如果必須下載Docker鏡像,則Docker首先檢查鏡像中是否已經(jīng)包含某些層。如果你具有這些鏡像層,就不會(huì)下載。如果以前下載的其他鏡像與當(dāng)前下載的鏡像具有相同的基礎(chǔ)鏡像,則當(dāng)前鏡像的下載數(shù)據(jù)量會(huì)少很多。

在企業(yè)內(nèi)部,可以為開發(fā)人員提供一組通用的標(biāo)準(zhǔn)基礎(chǔ)鏡像來(lái)減少必要的下載。系統(tǒng)只會(huì)下載每個(gè)基礎(chǔ)鏡像一次,初始下載后,只需要使每個(gè)鏡像中不同的鏡像層,鏡像的共同層越多,下載速度就越快。如下圖中紅色框的基礎(chǔ)鏡像就只需下載一次。

容器注冊(cè)表進(jìn)行漏洞掃描

對(duì)服務(wù)器和虛擬機(jī),軟件漏洞掃描是常用的一個(gè)安全手段,通過集中式軟件掃描系統(tǒng),列出了每臺(tái)主機(jī)上安裝的軟件包和存在的漏洞源,并及時(shí)通知管理員修補(bǔ)漏洞,比如蟲蟲之前的文章中介紹過的Flan Scan系統(tǒng)。

由于容器原則上是不可變的,所以不建議對(duì)存在漏洞的情況下對(duì)其進(jìn)行漏洞修補(bǔ)。最佳實(shí)踐是對(duì)其重建鏡像,打包補(bǔ)丁程序,然后重新部署。與服務(wù)器相比,容器的生命周期要短得多,身份標(biāo)識(shí)的定義要好得多。因此,使用類似的集中檢測(cè)容器中漏洞的一種不好的方法。

為了解決這個(gè)問題,可以在托管鏡像的容器注冊(cè)表(Container Registry)中進(jìn)行漏洞掃描。這樣就可以在發(fā)現(xiàn)容器鏡像中的漏洞。將鏡像上傳到注冊(cè)表時(shí)或漏洞庫(kù)更新時(shí),就會(huì)進(jìn)行掃描,或者啟動(dòng)計(jì)劃任務(wù)定期掃描。

檢測(cè)到漏洞后,可以使用腳本來(lái)觸發(fā)自動(dòng)漏洞修補(bǔ)過程。最好是結(jié)合版本管理(比如Gitlab)CI/CD管道來(lái)持續(xù)進(jìn)行鏡像構(gòu)建來(lái)進(jìn)行漏洞修補(bǔ)。一般步驟如下:

  • 將鏡像存儲(chǔ)在容器注冊(cè)表中并啟用漏洞掃描。
  • 配置一個(gè)作業(yè),該作業(yè)定期從容器注冊(cè)表中獲取新漏洞,并在需要時(shí)觸發(fā)鏡像重建。
  • 構(gòu)建新鏡像后,通過持續(xù)部署系統(tǒng)CD來(lái)將鏡像部署到驗(yàn)證環(huán)境中。
  • 手動(dòng)檢查驗(yàn)證是否正常。
  • 如果未發(fā)現(xiàn)問題,請(qǐng)手動(dòng)推送灰度部署到生產(chǎn)環(huán)境。

正確標(biāo)記鏡像

Docker鏡像通常由兩個(gè)部分標(biāo)識(shí):它們的名稱和標(biāo)簽。例如,對(duì)于centos:8.0.1鏡像,centos是名稱,而8.0.1是標(biāo)簽。如果在Docker命令中未提供最新標(biāo)簽,則默認(rèn)使用最新標(biāo)簽。名稱和標(biāo)簽對(duì)在任何給定時(shí)間都是應(yīng)該唯一的。但是,可以根據(jù)需要將標(biāo)簽重新分配給其他鏡像。構(gòu)建鏡像時(shí),需要正確標(biāo)記,遵循統(tǒng)一一致標(biāo)記策略。

容器鏡像是一種打包和發(fā)布軟件的方法。標(biāo)記鏡像可讓用戶識(shí)別軟件的特定版本進(jìn)行下載。因此,將容器鏡像上的標(biāo)記系統(tǒng)關(guān)系到軟件的發(fā)布策略。

使用語(yǔ)義版本標(biāo)記

發(fā)行軟件的常用方法是使用語(yǔ)義化版本號(hào)規(guī)范(The Semantic Versioning Specification)版本號(hào)來(lái)"標(biāo)記"(如git tag命令中的)特定版本的源代碼。語(yǔ)義化版本號(hào)規(guī)范是為了改善各種軟件版本號(hào)格式混亂,語(yǔ)義不明的現(xiàn)狀由semver.org提出的一種處理版本號(hào)的規(guī)整方法。在該規(guī)范中軟件版本號(hào)由三部分構(gòu)成:X.Y.Z,其中:

  • X是主要版本,有向下不兼容的修改或者顛覆性的更新時(shí)增加。
  • Y是次要版本,有向下兼容的修改或者添加兼容性的新功能時(shí)增加1。
  • Z是補(bǔ)丁程序版本,僅僅是打一些兼容性補(bǔ)丁,做一些兼容性修復(fù)時(shí)增加。
  • 次要版本號(hào)或補(bǔ)丁程序版本號(hào)中的每個(gè)增量都必須是向后兼容的更改。

如果該系統(tǒng)或類似系統(tǒng),請(qǐng)按照以下策略標(biāo)記鏡像:

  • 最新標(biāo)簽始終指的是最新(可能穩(wěn)定)的鏡像。創(chuàng)建新鏡像后,該標(biāo)簽即被移動(dòng)。
  • X.Y.Z標(biāo)簽是指軟件的特定版本。請(qǐng)不要將其移動(dòng)到其他鏡像。
  • X.Y標(biāo)記是指軟件X.Y次要分支的最新修補(bǔ)程序版本。當(dāng)發(fā)布新的補(bǔ)丁程序版本時(shí),它將被移動(dòng)。
  • X標(biāo)記是指X主要分支的最新次要版本的最新補(bǔ)丁程序版本。當(dāng)發(fā)布新的修補(bǔ)程序版本或新的次要版本時(shí),它將移動(dòng)。

使用此策略可以使用戶靈活地選擇他們要使用的軟件版本。他們可以選擇特定的X.Y.Z版本,并確保鏡像永不更改,或者可以通過選擇不太具體的標(biāo)簽來(lái)自動(dòng)獲取更新。

用Git提交哈希標(biāo)記

如果你用持續(xù)交付系統(tǒng)并且經(jīng)常發(fā)布軟件,則可能不能使用語(yǔ)義版本控制規(guī)范中描述的版本號(hào)。在這種情況下,處理版本號(hào)的常用方法是使用Git commit SHA-1哈希(或它的簡(jiǎn)短版本)作為版本號(hào)。根據(jù)設(shè)計(jì)原理,Git的提交哈希是不可變的,并引用到軟件的特定版本。

可以將git提交哈希用作軟件的版本號(hào),也可以用作軟件特定版本構(gòu)建的Docker鏡像的標(biāo)記。這樣可以使Docker鏡像具有可追溯性,在這種情況下image標(biāo)記是不可變的,因此可以立即知道給定容器中正在運(yùn)行哪個(gè)特定版本的軟件。在持續(xù)交付管道中,自動(dòng)更新用于部署的版本號(hào)。

權(quán)衡公共鏡像的使用

Docker的一大優(yōu)點(diǎn)是可用于各種軟件的大量公共可用鏡像。這些鏡像使你可以快速入門。但是,在為線上環(huán)境設(shè)計(jì)容器策略時(shí),可能會(huì)遇到一些限制,使得公共提供的鏡像無(wú)法滿足要求。以下是可能導(dǎo)致無(wú)法使用公共鏡像的一些限制示例:

  • 精確控制鏡像內(nèi)部的內(nèi)容。
  • 不想依賴外部存儲(chǔ)庫(kù)。
  • 想嚴(yán)格控制生產(chǎn)環(huán)境中的漏洞。
  • 每個(gè)鏡像都需要相同的基礎(chǔ)操作系統(tǒng)。

對(duì)所有這些限制的對(duì)策都是相同的,并且但是有很高的代價(jià),那就是必須構(gòu)建自己的鏡像。對(duì)于數(shù)量有限的鏡像,可以自己構(gòu),但是當(dāng)數(shù)目有增長(zhǎng)的時(shí)。為了有機(jī)會(huì)大規(guī)模管理這樣的系統(tǒng),可以考慮使用以下方法:

  • 以可靠的方式自動(dòng)生成鏡像,即使對(duì)于很少生成的鏡像也是如此。
  • 解決鏡像漏洞,可以在容器注冊(cè)表中漏洞掃描。企業(yè)中不同團(tuán)隊(duì)創(chuàng)建的鏡像執(zhí)行內(nèi)部標(biāo)準(zhǔn)的方法。有幾種工具可用來(lái)幫助在生成和部署的鏡像上實(shí)施策略:
  • container-diff:可以分析鏡像的內(nèi)容,甚至可以比較兩個(gè)鏡像之間的鏡像。
  • container-structure-test:可以測(cè)試鏡像的內(nèi)容是否符合定義一組規(guī)則。
  • Grafeas:是一種工件元數(shù)據(jù)API,可以在其中存儲(chǔ)有關(guān)鏡像的元數(shù)據(jù),以便以后檢查這些鏡像是否符合你的策略。
  • Kubernetes具有準(zhǔn)入控制器,在Kubernetes中部署工作負(fù)載之前,可以使用該準(zhǔn)入控制器檢查許多先決條件。
  • Kubernetes還具有Pod安全策略,可用于在群集中強(qiáng)制使用安全選項(xiàng)。
  • 也能采用一種混合系統(tǒng):使用諸如Debian或Alpine之類的公共鏡像作為基礎(chǔ)鏡像,然后基于該鏡像構(gòu)建其他鏡像。或者可能想將公共鏡像用于某些非關(guān)鍵鏡像,并為其他情況構(gòu)建自己的鏡像。

關(guān)于軟件可

在Docker鏡像中包含第三方庫(kù)和軟件包之前,請(qǐng)確保相應(yīng)的許可允許這樣做。第三方許可證可能還會(huì)對(duì)重新分發(fā)施加限制,當(dāng)將Docker鏡像發(fā)布到公共注冊(cè)表時(shí),這些限制就適用。

總結(jié)

本文中介紹了容器構(gòu)建過程中應(yīng)該遵循的一些基本的原則,通過這些原則可以確保構(gòu)建的容器安全、精煉,可收縮,可控,當(dāng)然這些條款也只是建議性質(zhì)的,在滿足需求的基礎(chǔ)上請(qǐng)盡量遵循。其中涉及的一些方法僅供參考,你也可以在遵守基本原則情況下使用更適合自己的解決方法。

 

責(zé)任編輯:趙寧寧 來(lái)源: 蟲蟲搜奇
相關(guān)推薦

2022-07-25 14:24:53

Docker容器安全

2020-11-23 18:39:54

容器Kubernetes架構(gòu)

2022-08-01 07:27:36

JavaDocker容器

2021-06-08 10:26:10

云計(jì)算云計(jì)算產(chǎn)業(yè)云應(yīng)用

2021-02-21 09:33:19

Docker容器安全 應(yīng)用程序

2020-03-24 14:45:17

程序員技能開發(fā)者

2022-04-20 12:08:17

容器安全漏洞網(wǎng)絡(luò)安全

2023-01-13 16:34:08

2021-05-08 16:11:08

Java開發(fā)代碼

2020-12-16 08:23:06

DevOps容器安全容器

2019-04-26 07:56:40

容器秘密安全

2022-08-24 08:16:33

容器安全容器

2022-05-13 14:28:03

云原生權(quán)限云原生

2021-02-25 09:00:00

架構(gòu)開發(fā)運(yùn)維

2021-03-16 10:30:44

云計(jì)算云計(jì)算產(chǎn)業(yè)云應(yīng)用

2022-10-09 08:08:02

人工智能機(jī)器學(xué)習(xí)平臺(tái)

2020-07-24 10:36:17

云計(jì)算云平臺(tái)數(shù)據(jù)

2022-05-27 05:42:34

容器云安全

2019-05-21 10:45:44

Docker架構(gòu)容器

2023-09-14 09:31:21

Docker容器
點(diǎn)贊
收藏

51CTO技術(shù)棧公眾號(hào)