打docker镜像_从安全到镜像流水线,Docker 最佳实践与反模式一览
作者 | Timothy Mugayi
譯者 | 彎月,責編 | 夕顏
封圖 | CSDN付費下載自視覺中國
出品 | CSDN(ID:CSDNnews)
在使用Docker的大部分時間里,我們并不關心其內(nèi)部的工作原理。僅憑啟動一個Docker容器并且讓應用程序運行良好,并不能說明你已經(jīng)實現(xiàn)了一個良好的解決方案。有時,由于時間限制,我們只能復制粘貼Docker鏡像,卻沒能真正理解實現(xiàn)細節(jié)以及如何構建Docker鏡像的細微差別。
在本文中,我們將探討Docker的最佳實踐和反模式。反模式是人們對于反復出現(xiàn)的問題的一般解決方案,這些方案沒有效率,甚至會完全抵消Docker技術棧帶來的好處。
下面我們來看看我們的哪些做法不可取。
我們需要的標簽
標簽是必不可少的,我們需要通過標簽傳達有關Docker鏡像的信息。你可以將標簽視為Docker鏡像ID的別稱。Git標簽負責標記特定的提交,而Docker標簽與之類似,可以給不同時間點上的Docker鏡像添加版本。忘記打標簽是小事,但會帶來一些弊端,具體來講,如果未指定標記,則默認鏡像將被標記為latest。
FROM your_image_name:latest如果你頻繁執(zhí)行該操作,那么很有可能鏡像不是最新的,可能指向的是舊版本。因此,請使用適當?shù)臉撕灢⒆袷啬硞€版本控制標準,例如語義版本控制。這樣,Docker鏡像使用者才能確保Docker鏡像的兼容性并時刻保持最新,還可以有計劃地使用正確的版本。
還有一個情況應該避免。你可以利用最新的默認標簽(如FROM python3:latest),從Docker鏡像倉庫中提取最新的鏡像。乍一看,這種做法似乎是個好主意,但卻有一些意想不到的副作用:每個最新的請求可能都會派生出與以前的構建完全不同的Docker鏡像。弄明白Docker鏡像損壞的原因?qū)兊煤芾щy,因為鏡像本應該是不可變的。因此,我強力建議使用特定的標簽來標記鏡像(例如:python3:1.0.1)。這種方法可以確保你的Dockerfile保持不變。
在同一個容器中運行多個服務
雖然你可以在同一個容器中運行多個服務,但我并不建議你這么做,原因有兩個。在使用Docker服務時,我們應該努力維持責任單一性。最佳做法是,組成應用程序的每個服務都應在各自的容器中運行,請務必將每項獨立的功能都打包到單獨的獨立容器鏡像中。
將多個服務添加到一個Docker鏡像的做法似乎很誘人,但是你不應該將容器鏡像視為虛擬機。一個容器包含多個服務,可能會導致你的應用程序很難水平擴展。Docker容器核心概念是,它們都是瞬態(tài)的,專為分發(fā)而設計,這對于現(xiàn)代Web應用程序來說很理想,因為它的瞬態(tài)特性、擴展和并發(fā)會非常容易。添加多個服務會增加管理分發(fā)的難度。
另外,單個容器上的多個服務還會加大管理安全性的難度。龐大的鏡像可能會降低CI/CD的速度,你需要小心。
使用LABEL對鏡像進行分類
這并不能說是反模式,但我認為值得一提。我在處理各種Docker鏡像時注意到了一件事:有時這些鏡像的創(chuàng)建者沒有使用LABEL maintainer標簽。這個標簽可在事件中設置鏡像的Author字段,當出現(xiàn)問題或需要澄清時,這個標簽可以方便大家了解該與何人內(nèi)部聯(lián)系;如果鏡像是公開共享的,也可以知道該與哪個外部的人聯(lián)系。
這絕不是唯一可以使用的標簽。你可以根據(jù)需要定義各種標簽,來對鏡像進行分類,定義許可信息,也可以定義標簽來幫助自動化。
除了maintainer,還可以使用多行標簽:
# Set one or more individual labelsLABEL com.example.version="0.0.1-beta"LABEL vendor1="RBTSB Incorporated"LABEL vendor2=TIPTAPCODE IncorporatedLABEL com.example.release-date="202-04-02"LABEL com.example.version.production="0.0.1"Docker 1.10之前的單行標簽會創(chuàng)建新的docker層,如果你使用的是最新版的Docker,則不必擔心創(chuàng)建額外的層。
LABEL vendor=ACME Incorporated com.example.is-beta= com.example.is-production="" com.example.version="0.0.1-beta" com.example.release-date="2015-02-12"我們應該將盡可能多的元數(shù)據(jù)添加到不可變的Docker鏡像,以方便追蹤,提高可見性和可維護性。
避免構建依賴特定環(huán)境的鏡像
在構建Docker鏡像時,我們應始終牢記不變性。最好不要使用帶有dev、test、staging和production的鏡像,因為這會破壞單一來源的原則。另一個問題是,如果在不同環(huán)境上驗證或調(diào)試,則這種做法無法保證鏡像的相似。
為什么要使用非Root容器?
在默認情況下,Docker容器以root身份運行。以root用戶身份運行的Docker容器可以完全控制主機系統(tǒng)。然而,出于安全考慮,我并不推薦這種做法。使用非root運行的Docker容器鏡像可以多一層保護,在生產(chǎn)環(huán)境中通常建議使用非root容器。但是,由于這些容器由非root用戶運行,因此無法執(zhí)行需要特殊權限的任務。如果需要利用USER指令指定非root用戶(如以下示例所示),則需要進行一些上下文切換。
FROM python:3.6-slim-busterLABEL maintainer="Timothy Mugayi "RUN apt-get update && apt-get install -y --no-install-recommends wget && rm -rf /var/lib/apt/lists/*# Dumb initRUN wget -O /usr/local/bin/dumb-init https://github.com/Yelp/dumb-init/releases/download/v1.2.0/dumb-init_1.2.0_amd64RUN chmod +x /usr/local/bin/dumb-initRUN pip install --upgrade pipWORKDIR /usr/src/appCOPY requirements.txt .RUN pip install -r requirements.txtCOPY helloworld.py .USER 1001ENTRYPOINT ["/usr/local/bin/dumb-init總結
以上是生活随笔為你收集整理的打docker镜像_从安全到镜像流水线,Docker 最佳实践与反模式一览的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: html多级折叠菜单表单,JS实战篇之收
- 下一篇: php document.getel,j