構建私有映象
文章目錄
Docker file定製映象
-
映象的定製實際上就是定製每一層所新增的配置,檔案。我們可以把每一層修改,安裝,構建,操作的命令都寫入一個指令碼,這個指令碼就是Dockerfile。
-
Dockerfile是一個文字檔案,其內包含了一條條的指令,每一條指令構建一層,因此每一條指令的內容就是該層應該如何構建。
構建nginx映象
以官方nginx映象為例,使用Dockerfile來定製映象。
- 在一個空白的目錄中,建立一個文字檔案,並將檔案命名為Dockerfile:
mkdir mynginx
cd mynginx
touch Dockerfile
- 在Dockerfile檔案中寫入以下內容:
FROM nginx
RUN echo '<h1>Hello Docker!</h1>' > /usr/share/nginx/html/index.html
- 使用docker build命令建立映象
docker build -t mynginx:1.0 .
- 執行docker run命令,既可以執行構建好的mynginx映象,通過瀏覽器 http://ip:8080 即可訪問nginx服務
docker run -d -p 8080:80 mynginx:1.0
Dockerfile構建命令
FROM 指定基礎映象
所謂定製映象,一定是以一個映象為基礎,在其上進行定製。基礎映象是必須指定的,而FROM指令就是指定基礎映象,因此一個Dockerfile中FROM是必需的,並且一定是第一條指令。 在Docker Hub上有許多高質量的官方映象,如nginx,redis,mysql,tomcat,centos,ubuntu等,可以在其中找到一個符合我們要求的映象為基礎映象進行定製。
除了選擇現有的映象為基礎外,Docker還存在一個特殊的映象,名為scratch。這個映象是虛擬的概念,並不實際存在,它表示一個空白的映象。
如果以scratch映象為基礎映象的話,意味著不以任何映象為基礎,接下來所寫的指令將作為映象的第一層開始存在。 對於Linux下靜態編譯程式來說,並不需要有作業系統提供執行時支援,所需的一切庫都已經在可執行檔案裡了,因此直接使用FROM scratch會讓映象的體積更小。使用Go語言開發的應用很多會使用這種方式來製作映象,這也是為什麼有人認為Go特別適合容器微服務架構語言的原因之一。
RUN 執行命令
RUN指令是用來執行命令列命令的,由於命令列的強大能力,RUN指令在定製映象時是最常用的指令之一。其格式有兩種: shell格式:RUN <命令>
RUN echo '<h1>Hello Docker!</h1>' > /usr/share/nginx/html/index.html
exec格式:RUN [“可執行檔案”,“引數1”, “引數2” ]
RUN tar -xzf redis.tar.gz -C /usr/src/redis--strip-components=1
RUN make -C /usr/src/redis
RUN make -C /usr/src/redis install
COPY 複製檔案
格式:
- COPY <原始檔> …<目標路徑>
- COPY ["<原始檔1>",…“目標路徑”]
COPY指令將從構建上下文目錄中<原始檔>的檔案/目錄複製到新的一層映象的<目標路徑>位置,如:
COPY package.json /usr/src/app
<原始檔>可以是多個,甚至可以是萬用字元,如:
COPY hom* /mydir/
COPY hom?.txt /mydir/
ADD 檔案複製
ADD指令和COPY指令的格式和性質基本一致,但是ADD在COPY的基礎上增加了一些功能。比如<原始檔>可以是一個URL,這種情況下,Docker引擎會試圖下載這個連結的檔案放到<目標路徑>去。 在Docker官方的Dockerfile最佳實踐文件中要求,儘可能的使用COPY,因為COPY的語義很明確,就是複製檔案而已,而ADD則包含了更復雜的功能,其行為也不一定清晰。最適合使用ADD的場合,就是需要自動解壓縮的場合。因此在COPY和ADD指令的選擇的時候,可以遵循這樣的原則,所有檔案的複製均使用COPY指令,僅在需要自動解壓縮的場合使用ADD。
CMD 容器啟動命令
CMD指令的格式和RUN相似,也是兩種格式: shell格式:CMD <命令> exec格式:CMD [“可執行檔案”,“引數1”, “引數2” ] 引數列表格式:CMD [“引數1”, “引數2” ],在指定ENTRYPOINT指令後,用CMD指定具體的引數
Docker不是虛擬機器,容器就是程式。既然是程式,那麼在啟動容器的時候,需要指定所執行的程式及引數,CMD指令就是用於指定預設的容器主程式啟動命令的。
ENTRYPOINT 入口點
ENTRYPOINT的目的和CMD一樣,都是在指定容器啟動程式及引數。ENTRYPOINT在執行的時也可以替代,不過比CMD要略顯繁瑣,需要通過docker run的引數–entrypoint來指定。 當指定了ENTRYPOINT後,CMD的含義就發生了改變,不再是直接的執行其命令,而是將CMD的內容作為引數傳給ENTYRYPOINT指令。
ENV 設定環境變數
格式有兩種:
- ENV
- ENV = =
這個指令很簡單,就是設定環境變數而已,後面的其他指令都可以使用這裡定義的環境變數。
ENV VERSION=1.0 DEBUG=on
$VERSION # 使用前面定義的環境變數VERSION
ARG 構建引數
格式:ARG <引數名> [=<預設值>] 構建引數和ENV的效果一樣,都是設定環境變數。所不同的是,ARG所設定的構建環境的環境變數,在之後容器執行時是不會存在這些環境變數的,但是不要因此就使用ARG儲存密碼之類的資訊,因為docker history還是可以看到所有值的。 Dockerfile中的ARG指令是定義引數名稱,以及定義其預設值,該預設值可以在構建命令docker build 中用–build-arg <引數名>=<值>來覆蓋。
VOLUME 定義匿名卷
格式為:
- VOLUME ["<路徑1>","<路徑2>"…]
- VOLUME <路徑>
容器執行時應該儘量保持容器儲存層不發生寫操作,對於資料庫類需要儲存動態資料的應用,其資料檔案應該儲存於卷(volume)中,為了防止執行時使用者忘記將動態檔案所儲存的目錄掛載為卷,在Dockerfile中可以事先指定某些目錄掛載為匿名卷,這樣在執行時如果使用者不指定掛載,其應用也可以正常執行,不會向容器儲存層寫入大量資料。
VOLUME /data
這裡的 /data 目錄就會在執行時自動掛載為匿名卷,任何向 /data 中寫入的資訊都不會記錄到容器儲存層,從而保證了容器儲存層的無狀態化,當然執行時也可以覆蓋這個掛載設定,如:
docker run -d -v mydata:/data xxxx
在這行命令中,就使用了mydata這個命令卷掛載到了 /data 這個位置,替代了Dockerfile中定義的匿名卷的掛載位置。
EXPOSE 宣告埠
格式為 EXPOSE <埠> [<埠>…] EXPOSE指令時宣告執行時容器提供的服務埠,這只是一個宣告,在執行時並不會因為這個宣告應用就會開啟這個埠的服務。 在Dockerfile中寫入這樣的宣告有兩個好處:
- 是幫助映象使用者理解這個映象服務的守護埠,以方便配置對映
- 在執行時使用隨機埠對映時,也就是 docker run -P 時,會自動隨機對映EXPOSE的埠
WORKDIR指定工作目錄
格式為 WORKDIR <工作目錄路徑> 使用WORKDIR指令可以用來指定工作目錄(或者稱為當前目錄),以後各層的當前目錄就被改為指定目錄,如該目錄不存在,則會自動建立。 初學者可能遇到的錯誤是將Dockerfile當shell指令碼來寫,這種錯誤的理解還可能會導致下面的錯誤:
RUN cd /app
RUN echo "hello" > world.txt
如果將這個Dockerfile構建成映象執行後,會發現找不到 /app/world.txt 檔案。 在shell中,連續兩行是同一個程式執行環境,因此前一個命令修改的狀態,會直接影響後一個命令。而在Dockerfile中,這兩行RUN命令執行的環境根本不同,是兩個完全不同的容器。 每一個RUN都是啟動一個容器,執行命令,然後提交儲存層檔案變更。 第一個 RUN cd /app 的執行僅僅是當前程式的工作目錄變更,一個記憶體上的變化而已,其結果不會造成任何檔案變更。而到第二層的時候,啟動的是一個全新的容器,跟第一層的容器完全沒關係,自然不可能繼承前一層構建過程中的記憶體變化。 因此,如果需要改變以後的各層的工作目錄,那麼就應該使用WORKDIR指令。
USRE 指定當前使用者
格式為 USER <使用者名稱> USER指令和WORKDIR指令都是改變環境狀態並影響以後的層。WORKDIR是改變工作目錄,USER是改變之後層的執行RUN,CMD以及ENTRYPOINT這類命令的身份。 USER只是幫助切換指定使用者,如果使用者不存在,則無法切換。
RUN groupadd -r redis && useradd -r -g redis redis
USER redis
RUN ["redis-server"]
HEALTHCHECK 健康檢查
格式:
- HEALTHCHECK [選項] CMD <命令> ,設定檢查容器健康狀況的指令
- HEALTHCHECK NONE ,如果基礎映象有健康檢查指令,可以遮蔽掉其健康檢查指令
HEALTHCHECK指令告訴Docker應該如何判斷容器的狀態是否正常,這是Docker 1.12引入的新指令。通過該指令指定一行命令,用這行命令來判斷容器主程式的服務狀態是否正常,從而比較真實的反應容器實際狀態。 一個映象指定了HEALTHCHECK指令後,其容器啟動,初始狀態會為starting,在執行健康檢查成功後變為healthy,如果連續一定次數失敗,則會變為unhealthy。 HEALTHCHECK支援下列選項:
- –interval=<間隔>,兩次健康檢查的間隔,預設為30秒
- –timeout=<時長>,健康檢查命令超時時間,如果超過這個時間,本次健康檢查就被視為失敗,預設30秒
- –retries=<次數>,當連續失敗指定次數後,則將容器狀態視為unhealthy,預設3次
為了幫助健康檢查,健康檢查命令的輸出(包括stdout以及stderr)都會被儲存於健康檢查狀態裡,可以用docker inspect 來檢視。
相關文章
- Kunbernetes-基於Nexus構建私有映象倉庫
- docker構建映象Docker
- DockerFile構建映象Docker
- [Dockerfile構建映象]Docker
- Docker私有映象Docker
- 基於ubuntu映象構建redis映象UbuntuRedis
- docker構建supervisor映象Docker
- 使用Packer構建映象
- Packer構建openStack映象
- StarRocks 容器映象構建
- Docker 構建 kubectl 映象Docker
- Docker映象構建(五)Docker
- Docker映象構建原理解析(不裝docker也能構建映象)Docker
- docker 構建自己的映象Docker
- JAVA專案映象構建Java
- Docker 映象構建之 DockerfileDocker
- OCI 與容器映象構建
- 使用dockerfile構建nginx映象DockerNginx
- 基於VMWare構建私有云2019
- 自動化構建映象:Packer
- Docker 構建多平臺映象Docker
- Docker構建多平臺映象Docker
- 筆記:使用Dockerfile構建映象筆記Docker
- Docker 構建PHP 映象環境DockerPHP
- Docker 映象分階段構建Docker
- Docker 分階段構建映象Docker
- windows系統用docker構造映象上傳私有倉庫WindowsDocker
- 構建映象的幾個小技巧
- 使用 ansible-bender 構建容器映象
- 構建更小的容器映象的技巧
- 私有建構函式的物件建立例項函式物件
- harbor私有映象安裝和使用
- docker映象構建libreoffice轉換檔案Docker
- 構建 Docker 映象的 N 個小技巧Docker
- 視訊私有云實戰:基於Docker構建點播私有云平臺Docker
- apisix閘道器-構建docker映象構建及外掛化開發APIDocker
- 不用安裝docker也能構建docker映象Docker
- HamsterBear 構建可啟動的映象(更新中)