企業(yè)Docker實(shí)施面面觀
概述
當(dāng)下Docker容器化的架構(gòu)備受歡迎,越來(lái)越多的企業(yè)開始利用容器來(lái)構(gòu)建自己的基礎(chǔ)架構(gòu)。通常是自己建立了Docker注冊(cè)表,部署在服務(wù)器上安裝Docker,安裝Jenkins通過(guò)Docker插件Jenkins CI管道管理Docker容器。更大一點(diǎn)規(guī)模的則會(huì)使用K8S或者Swarm編排集群。對(duì)一個(gè)企業(yè)而言有開始嘗試使用容器到逐漸深入,擴(kuò)大規(guī)模要經(jīng)歷一系列的問(wèn)題和踩坑的過(guò)程,那么如何規(guī)范化、安全的實(shí)施容器化,如何盡量避免踩坑呢?本文蟲蟲給列出企業(yè)嘗試容器化架構(gòu)需要考慮的各方各面問(wèn)題,希望可以對(duì)大家有所幫助。
鏡像問(wèn)題
容器注冊(cè)表
Docker服務(wù)都需要一個(gè)注冊(cè)表(可不是我們常說(shuō)的windows注冊(cè)表),Docker注冊(cè)表是Docker鏡像的存儲(chǔ)和在線(Web)版本倉(cāng)庫(kù)(類似于代碼的github倉(cāng)庫(kù))。有很多公有云自有容器注冊(cè)表服務(wù),比如Docker官方的Docker Hub,很多公有云都提供自己Docker注冊(cè)表服務(wù):

除了這些公開的注冊(cè)表,基于安全、網(wǎng)絡(luò)訪問(wèn)速度、規(guī)范化等考慮企業(yè)維護(hù)一個(gè)自建的Docker注冊(cè)表(Docker私服)也是必須的。構(gòu)建Docker私服可以使用Docker官方的Distribution,它是Docker官方推出的Docker Registry 2開源產(chǎn)品,使用Golang開發(fā),極大提高了安全和性能。
知名的Git服務(wù)器端Gitlab也提供了Gitlab 容器注冊(cè)表,部署Gitlab企業(yè)可以直接考慮使用這個(gè)組件,實(shí)現(xiàn)統(tǒng)一管理和集成。當(dāng)然除了開源的,也可以使用商用的產(chǎn)品的比如Vmware開源的Harbor:

企業(yè)選擇容器注冊(cè)表需要考慮以下問(wèn)題:
- 注冊(cè)表是否能集成到企業(yè)內(nèi)部的身份統(tǒng)一系統(tǒng)(比如LDAP,Kerberos等)?
- 是否支持基于角色的訪問(wèn)控制(RBAC)?
- 統(tǒng)一身份認(rèn)證和授權(quán)對(duì)企業(yè)來(lái)說(shuō)是一個(gè)大問(wèn)題。雖然快速便宜的開放的注冊(cè)解決方案可以足夠開發(fā)環(huán)境的構(gòu)建。但是對(duì)企業(yè)線上環(huán)境,必須要考慮安全性、RBAC標(biāo)準(zhǔn)等。
- 是否有加速鏡像的方法?
- 鏡像是要有區(qū)別對(duì)待的。有些是快速、功能全,但是可能雜亂的的開發(fā)環(huán)境鏡像,他們不需要首要考慮正確性;而線上的鏡像則是要注重安全和性能和正確防護(hù)。企業(yè)要對(duì)這些鏡像分類,并且在注冊(cè)表中通過(guò)實(shí)例管理流程或用標(biāo)簽強(qiáng)制執(zhí)行。
- 是否與其他Artefact包管理架構(gòu)保持良好的一致性?

企業(yè)可能已經(jīng)有包文件庫(kù),內(nèi)部的Artefact存儲(chǔ)等(比如maven,npm,Gitlab等)。在理想的架構(gòu)中,容器注冊(cè)表應(yīng)該是它的一個(gè)功能。如果架構(gòu)上是分開的,那么久要考慮兩者的集成和管理開銷。
鏡像掃描

這是很重要的部分。當(dāng)鏡像上傳到自建容器注冊(cè)表時(shí),需要檢查它們是否符合標(biāo)準(zhǔn)。例如,檢查諸如此類的問(wèn)題:
- bash版本是否存在破殼漏洞?
- ssl庫(kù)是不是過(guò)時(shí)了?
- 該鏡像是否基于一個(gè)不安全或不可接受的基本鏡像(Base Image)?
- 是否存在有漏洞的或者過(guò)時(shí)庫(kù)(Strus 2)和工具?
- 等等
可以通過(guò)靜態(tài)鏡像分析來(lái)檢查這些問(wèn)題。我們需要注意的是,這些掃描可能不是十全十美的,可能會(huì)錯(cuò)過(guò)一些非常明顯漏洞,所以它也不是解決一切安全問(wèn)題的靈丹妙藥,而是一種必要的手段,特別非常適合用解決:
- 防止惡意攻擊者注入木馬?
- 在企業(yè)范圍了,統(tǒng)一規(guī)范標(biāo)準(zhǔn)?
- 快速發(fā)現(xiàn)和修補(bǔ)已知的和標(biāo)準(zhǔn)CVE漏洞?
這些問(wèn)題是組成了鏡像掃描評(píng)估的基礎(chǔ),當(dāng)然也需要考慮集成的成本。常見(jiàn)的鏡像掃描工具有Clair,Anchore,OpenSCAP,Dockerscan等。
鏡像構(gòu)建
如何構(gòu)建鏡像?企業(yè)要支持哪些構(gòu)建方法?如何將這些方組合在一起?
Dockerfiles最常用標(biāo)準(zhǔn)的方法之一,也可以使用S2I,Docker +Chef/Puppet/Ansible,甚至是手工方法構(gòu)建。
使用那種CM(配置管理,如果已經(jīng)使用的話)工具管理。
是否可以重復(fù)使用標(biāo)準(zhǔn)治理流程來(lái)和配置管理交互?
任何人都可以構(gòu)建鏡像嗎?
業(yè)界的經(jīng)驗(yàn)表明Dockerfile方法是一個(gè)使用廣泛而且通用的方法,而且具有大量的社區(qū)文檔和問(wèn)題反饋支持。嘗試更復(fù)雜的CM工具用來(lái)符合VM的公司標(biāo)準(zhǔn)的則通常有一定實(shí)施門檻。通過(guò)S2I或Chef/Puppet/Ansible方法則更加便捷,也能很好的實(shí)現(xiàn)代碼(playbook)重用。
鏡像完整
需要確保系統(tǒng)上運(yùn)行的鏡像在從構(gòu)建到運(yùn)行之間沒(méi)有被篡改過(guò)。
是否可以使用安全密鑰來(lái)對(duì)鏡像進(jìn)行簽名?
是否有可以重復(fù)使用的密鑰庫(kù)?
密鑰庫(kù)可以與選擇的工具集成嗎?
即使Docker流行了很多年,鏡像的完整性仍然是一個(gè)新興領(lǐng)域。很多的供應(yīng)商的對(duì)此還持觀望態(tài)度。 Docker 公司在這方面做了一些有益的工作,比如Notary(Docker開源簽名解決方案,已經(jīng)轉(zhuǎn)到CNCF基金會(huì)下)在Docker企業(yè)數(shù)據(jù)中心產(chǎn)品之外部署。
第三方鏡像
如果希望使用一鍵部署,那么供應(yīng)商的鏡像則可以直接使用。
是否擁有驗(yàn)證供應(yīng)商鏡像的管理流程?
我們不光需要知道鏡像是否安全,還需要知道誰(shuí)可以在必要時(shí)更新鏡像?
這些鏡像可被其他鏡像重用么?
這里有潛在的許可問(wèn)題。是否有辦法阻止其他項(xiàng)目/團(tuán)隊(duì)重用鏡像?
是否強(qiáng)制要求運(yùn)行于特定的環(huán)境(例如DMZ)?
Docker是否可以在這些環(huán)境中使用?
例如許多網(wǎng)絡(luò)級(jí)應(yīng)用程序運(yùn)行在網(wǎng)絡(luò)設(shè)備類似環(huán)境,并且需要認(rèn)證,所以,它必須與其他容器或項(xiàng)目工作環(huán)境隔離。是否有可能在這些環(huán)境中運(yùn)行鏡像,需要考慮。
SDLC

如果企業(yè)已經(jīng)實(shí)施了軟件開發(fā)生命周期(SDLC)流程,那么就要考慮Docker和它適應(yīng)的問(wèn)題:
- 如何處理補(bǔ)丁?
- 如何識(shí)別哪些鏡像需要更新?
- 如何更新它們?
- 如何通知團(tuán)隊(duì)更新?
- 如果他們不及時(shí)更新,如何強(qiáng)制他們更新?
該問(wèn)題與上面已經(jīng)提到的鏡像掃描方案密切相關(guān)。可能需要在某些時(shí)候考慮將其與現(xiàn)有SDLC流程集成。
密碼管理
在實(shí)施中數(shù)據(jù)庫(kù)密碼等信息需要傳遞到容器中。可以通過(guò)構(gòu)建時(shí)(不建議)或運(yùn)行時(shí)來(lái)完成該項(xiàng)工作。
如何在容器內(nèi)管理密碼?
是否對(duì)密碼信息的使用進(jìn)行了審核/跟蹤并確保安全?
和鏡像簽名一樣,密碼管理也是一個(gè)仍在快速變化的新興領(lǐng)域。業(yè)界有OpenShift/Origin與Hashicorp Vault等現(xiàn)有集成解決方案。Docker Swarm等核心組件中也有對(duì)密碼管理的支持,Kubernetes 1.7加強(qiáng)了其密碼安全功能。
基礎(chǔ)鏡像
如果在企業(yè)中運(yùn)行Docker,則可能需要在公司范圍內(nèi)強(qiáng)制使用基礎(chǔ)鏡像:
- 該基本鏡像應(yīng)該包含哪些內(nèi)容?
- 應(yīng)該使用哪種標(biāo)準(zhǔn)工具?
- 誰(shuí)負(fù)責(zé)管理集成鏡像?
- 需要提前準(zhǔn)備好很多關(guān)于基本鏡像的問(wèn)題。另外開發(fā)人員非常注重鏡像的精簡(jiǎn)。
安全和審計(jì)
root權(quán)限
默認(rèn)情況下,訪問(wèn)docker命令(特別是訪問(wèn)Docker UNIX套接字)需要機(jī)器root權(quán)限。對(duì)于生產(chǎn)環(huán)境中的來(lái)說(shuō),這是不可能接受的。需要回答以下問(wèn)題:
- 誰(shuí)(組)有權(quán)能夠運(yùn)行docker命令?
- 怎么管理這些有運(yùn)行權(quán)限的人員?
- 如何控制可運(yùn)行的內(nèi)容?
這些都有解決方案,但它們相對(duì)較新,通常是其他更大解決方案的一部分。
例如,OpenShift具有強(qiáng)大的RBAC控制功能,但需要購(gòu)買整個(gè)平臺(tái)。Twistlock和Aquasec這樣的容器安全工具提供了一種管理這些工具的方法,可以考慮集成他們。
運(yùn)行時(shí)監(jiān)控
企業(yè)可能希望能夠確定線上容器運(yùn)行情況。
如何知道線上運(yùn)行了哪些容器?
這些運(yùn)行中的容器,怎樣容器注冊(cè)表?怎么關(guān)聯(lián)的,怎么在容器注冊(cè)表中管理的?
啟動(dòng)以后,容器都更改過(guò)哪些關(guān)鍵性的文件?
同樣,這還有其他一些問(wèn)題,這些構(gòu)成Docker基礎(chǔ)運(yùn)行策略。在這方面另一個(gè)經(jīng)常被供應(yīng)商提起的功能是異常檢測(cè)。安全解決方案提供了諸如花哨的機(jī)器學(xué)習(xí)的解決方案,聲稱可以通過(guò)學(xué)習(xí)容器該做什么,并對(duì)可能的異常活動(dòng)發(fā)出告警。例如連接到與應(yīng)用程序無(wú)關(guān)的外部應(yīng)用程序的端口。雖然聽(tīng)起來(lái)不錯(cuò),但是需要考慮一下如何運(yùn)維他們。一般來(lái)說(shuō)可能會(huì)有大量的誤報(bào),需要大量調(diào)整和回歸驗(yàn)證的,是否有人力和資金來(lái)維持運(yùn)維,是問(wèn)題的關(guān)鍵。
審計(jì)
當(dāng)發(fā)生問(wèn)題后,我們需要知道發(fā)生了什么。在物理和虛擬機(jī)的架構(gòu)體系中,有很多安全措施來(lái)協(xié)助故障調(diào)查。而Docker容器的體系下,有可能是一個(gè)沒(méi)有"黑匣子記錄"的。
能馬上查詢出誰(shuí)在運(yùn)行容器嗎?
能馬上查詢出誰(shuí)構(gòu)建了了容器嗎?
要?jiǎng)h除容器時(shí),能快速確定該容器的作用嗎?
要?jiǎng)h除容器時(shí),能確定改容器可能做了什么嗎?
在這個(gè)問(wèn)題上,我們可能希望強(qiáng)制使用特定的日志系統(tǒng)解決方案,以確保有關(guān)系統(tǒng)活動(dòng)的信息在容器實(shí)例中保持不變。Sysdig的Falco(目前已經(jīng)轉(zhuǎn)到CNCF基金會(huì)下)是容器安全監(jiān)控和審計(jì)領(lǐng)域一個(gè)有趣,很有前途的工具。

運(yùn)維
日志
應(yīng)用程序日志記錄是企業(yè)關(guān)注的問(wèn)題之一:
- 容器是否記錄了操作所需的內(nèi)容?
- 日志是否遵循企業(yè)日志標(biāo)準(zhǔn)?
- 日志記錄在什么地方?
容器的日志可能與傳統(tǒng)機(jī)器部署有著非常不同的模式。日志存儲(chǔ)空間可能要支持橫向擴(kuò)展,可能需要增加存儲(chǔ)等。
容器編排
為了讓容器可以迅速隨著業(yè)務(wù)擴(kuò)展和變更迭代,就需要編排系統(tǒng)來(lái)統(tǒng)一管理。
選擇的編排架構(gòu)是否和Docker基礎(chǔ)架構(gòu)的其他部分可以很好的適應(yīng)?
是想使用一個(gè)與主流架構(gòu)相悖的編排架構(gòu),還是追隨主流呢?
Kubernetes目前看來(lái)是贏得編排系統(tǒng)的市場(chǎng)。選擇非Kubenetes的架構(gòu)可能需要找出充分的理由。

操作系統(tǒng)
企業(yè)線上操作系統(tǒng)遠(yuǎn)落后于最新的版本和最通用的版本。
線上的標(biāo)準(zhǔn)操作系統(tǒng)是否能夠支持Docker所有最新功能?
例如,一些編排系統(tǒng)和Docker本身需要的內(nèi)核版本或軟件包可能比所能支持的新很多,這可能是一個(gè)非常棘手的問(wèn)題。
系統(tǒng)軟件包管理默認(rèn)支持的Docker版本是多少?

Docker版本之間可能會(huì)存在明顯差異(比如,1.10是一個(gè)很大的差異),我們需要關(guān)注這些差異的細(xì)節(jié)。發(fā)行版提供的Docker(或者說(shuō)'Moby'版本)之間也存在差異,這個(gè)影響很大。比如,RedHat的二進(jìn)制docker包請(qǐng)求的順序RedHat的注冊(cè)表排在Docker Hub之前。
開發(fā)
開發(fā)環(huán)境
開發(fā)人員往往會(huì)要求系統(tǒng)管理權(quán)限。如何控制他們權(quán)限?
一個(gè)比較好的做法是可以為開發(fā)人員提供一個(gè)VM,讓他們?cè)诒镜剡M(jìn)行Docker構(gòu)建,或者只運(yùn)行docker客戶端,而將Docker服務(wù)端運(yùn)行在統(tǒng)一服務(wù)器上。
他們的客戶端是否與部署環(huán)境保持一致?
如果他們的桌面上使用的是docker-compose,他們可能會(huì)很反感在UAT和生產(chǎn)中切換到Kubernetes pod。
CI/CD
Jenkins是最受歡迎的CI工具,但是還有其他流行的替代方案,例如TeamCity,Gitlab CI等
Docker引入很多開發(fā)人員渴望使用的插件。其中很多都沒(méi)有考慮到安全性,甚至可能與其他插件存在兼容性的問(wèn)題。
你CI/CD插件的策略是什么?
你準(zhǔn)備好開啟一大堆新良莠不齊的插件了嗎?
CI流程是否適合短暫Jenkins實(shí)例以及持久的,受支持的實(shí)例?

基礎(chǔ)設(shè)施
共享存儲(chǔ)
Docker的核心是使用獨(dú)立于運(yùn)行容器的卷,其中存儲(chǔ)持久數(shù)據(jù)。
共享存儲(chǔ)容易配置嗎?
NFS服務(wù)有其局限性,但已經(jīng)成熟,并且在大型組織中通常得到很好的支持。
共享存儲(chǔ)支持是否可以滿足業(yè)務(wù)增加的需求?
是否需要跨部署位置提供共享存儲(chǔ)?
你可能擁有多個(gè)數(shù)據(jù)中心和/或云提供商。所有這些地點(diǎn)是否可以互相交互?他們需要交互嗎?
網(wǎng)絡(luò)
企業(yè)通常擁有自己喜歡的軟件定義網(wǎng)絡(luò)(SDN)解決方案,如Nuage,或新的方案比如Calico。
你是否有規(guī)定的SDN解決方案?
它如何與你選擇的解決方案相互作用?
SDN交互是否可能會(huì)導(dǎo)致出現(xiàn)問(wèn)題?
aPaaS
擁有像OpenShift或Tutum Cloud這樣的aPaaS可以通過(guò)集中化支持Docker運(yùn)行的上下文來(lái)解決上述許多問(wèn)題。
你是否考慮過(guò)使用aPaaS?
云供應(yīng)商
如果你使用的是亞馬遜或谷歌,阿里云等云提供商:
如何在云供應(yīng)商上提供鏡像和運(yùn)行容器?
是否希望將Docker解決方案與云供應(yīng)商的產(chǎn)品聯(lián)系起來(lái),或者讓他們與云供應(yīng)商無(wú)關(guān)?
解決方案選擇時(shí)要注意的事項(xiàng)
有兩種方法可以選擇。一種方法是使用單個(gè)供應(yīng)商的整體統(tǒng)一架構(gòu)。還有一種方法是使用多個(gè)供應(yīng)商的各個(gè)優(yōu)勢(shì)產(chǎn)品,然后拼湊集成為一個(gè)企業(yè)方案。
方法一的,好處是:
- 統(tǒng)一管理,統(tǒng)一認(rèn)證。
- 減少集成工作量和開銷。
- 交付更快。
- 可以享受來(lái)自供應(yīng)商的更大承諾和關(guān)注。
- 可能對(duì)產(chǎn)品方向的影響
- 更易于管理。
單一供應(yīng)商解決方案通常要求按照節(jié)點(diǎn)付款,可能導(dǎo)致成本費(fèi)用很高,而且后續(xù)更換需要承受巨大損失,也會(huì)限制內(nèi)部的架構(gòu)。
拼湊集成方案的好處有:
- 可以更具企業(yè)需求,用不同的速率提供更靈活的解決方案
- 集眾家之長(zhǎng),可以讓你少踩坑,少犯錯(cuò)誤,有問(wèn)題可以隨時(shí)調(diào)整更換工具。
- 從從長(zhǎng)遠(yuǎn)來(lái)看更加批恩一便宜,而且不會(huì)被 "鎖定"到某家供應(yīng)商上,不仰人鼻息,被人敲詐,吊死在一棵樹上。
結(jié)論
企業(yè)Docker架構(gòu)和部署復(fù)雜而多變。制定一個(gè)統(tǒng)一的,具有成本效益,安全,完整,靈活的,可以快速交付且無(wú)需鎖定的戰(zhàn)略是當(dāng)下企業(yè)容器化臨的挑戰(zhàn)之一。本文列出了企業(yè)Docker實(shí)施各個(gè)方面需要注意的問(wèn)題總結(jié),供大家參考。