Docker 系列二(操作鏡像).

来源:https://www.cnblogs.com/jmcui/archive/2018/07/22/9325945.html
-Advertisement-
Play Games

一、鏡像管理 1、拉取鏡像 -- Docker 鏡像倉庫地址 :一般是 功能變數名稱或者IP[:埠號]。預設地址是 Docker Hub -- 倉庫名 :兩段式名稱,即 用戶名/軟體名。對於Docker Hub,如果不給出用戶名,則預設為 library,也就是官方鏡像。 從下載過程中可以看到我們之前 提 ...


一、鏡像管理

    1、拉取鏡像

docker pull [選項] [Docker Registry 地址[:埠號]/]倉庫名[:標簽]

    -- Docker 鏡像倉庫地址 :一般是 功能變數名稱或者IP[:埠號]。預設地址是 Docker Hub
    -- 倉庫名 :兩段式名稱,即 用戶名/軟體名。對於Docker Hub,如果不給出用戶名,則預設為 library,也就是官方鏡像。

    從下載過程中可以看到我們之前 提及的分層存儲的概念,鏡像是由多層存儲所構成。下載也是一層一層的去下載,並非單一文件。

tips:Docker Hub 註冊的時候要FQ,否則那個註冊按鈕點擊不了~

    2、查看鏡像

docker image ls
docker images

    列表包含了 倉庫名、標簽、鏡像ID、創建時間 以及 所占用的空間。

    3、運行鏡像

docker run -it  --rm -d -p 8888:8080 tomcat:8.0
  -i:互動式操作
  -t:終端
  -rm:容器退出後隨之將其刪除,可以避免浪費空間
  -p :埠映射
  -d :容器在後臺運行

    指明瞭 -d 運行鏡像,會返回容器的 id;如果不指明 -d 運行鏡像,會列印出 catalina.out 的 日誌,在 [crtl +c] 後,容器即停止運行。

    至於容器啟動後,如果關閉容器進程,查看系統日誌等,會在下一篇文章中說明~ 

    4、刪除鏡像

docker image rm IMAGE_ID(不需要全部的id字元,足夠區分別的鏡像就可以了)
docker image rm 鏡像名(REPOSITORY:TAG)

tips:要註意鏡像和容器依賴的問題。如果用這個鏡像啟動的容器存在(即使容器沒有運行),那麼同樣不可以刪除這個鏡像,因為容器是以鏡像為基礎,再加一層容器存儲層,組成的多層結構去運行的。所以刪除 image 前要刪除 container 中的引用。

二、製作鏡像

    鏡像的定製實際上就是定製每一層所添加的配置、文件。我們通常把每一層修改、安裝、構建、操作的命令都寫入一個腳本,用這個腳本來構建、定製鏡像,這個腳本就是 Dockerfile。

    之前說過,鏡像是分層存儲的,Dockerfile 中每一個指令都會構建一層。鏡像構建時,一定要確保每一層只添加真正需要添加的東西,任何無關的東西都應該清理掉,避免鏡像的臃腫。

    現在我們來研究下 Dockerfile 的命令(不推薦使用的命令不做介紹),然後再用個 Demo 來說明:

FROM:制定基礎鏡像,鏡像的定製一定是以一個鏡像為基礎,在其上進行定製。FROM 是必備的命令,而且必須是第一條指令。FROM scratch 意味著你不以任何鏡像為基礎,接下來所寫的指令將作為鏡像第一層開始存在。

RUN:用來執行命令行命令的。有兩種格式:

-- shell 格式:RUN <命令>,就像直接在命令行中輸入的命令一樣。
-- exec 格式:RUN ["可執行文件", "參數1", "參數2"],這更像是函數調用中的格式。

WORKDIR:指定工作目錄,以後各層的當前目錄就被改為指定的目錄,如該目錄不存在,WORKDIR 會幫你建立目錄。

-- 格式:WORKDIR <工作目錄路徑>

USER:USER 指令和 WORKDIR 相似,都是改變環境狀態並影響以後的層。

-- USER <用戶名>

COPY:將從 <源路徑>(上下文路徑) 的文件/目錄複製到新的一層的鏡像內的 <目標路徑> (可以容器內的絕對路徑或者相對於 WORKDIR 的相對路徑)位置,源文件的各種元數據都會保留,比如讀、寫、執行許可權等。

-- COPY <源路徑> <目標路徑>
-- COPY ["<源路徑1>",... "<目標路徑>"]

CMD:用於指定預設的容器主進程的啟動命令的(執行目標鏡像中包含的軟體),只能出現一次,CMD 後面的命令可被運行時 [ docker run xxxx:1.0 參數 ] 中的參數取代。對於容器而言,其啟動程式就是容器應用進程,容器就是為了主進程而存在的,主進程退出,容器就失去了存在的意義,從而退出,其它輔助進程不是它需要關心的東西。

-- shell 格式:CMD <命令>
-- exec 格式:CMD ["可執行文件", "參數1", "參數2"...]
-- 參數列表格式:CMD ["參數1", "參數2"...]。在指定了 ENTRYPOINT 指令後,用 CMD 指定具體的參數。用來和 ENTRYPOINT 指令搭配使用

ENTRYPOINT:目的和 CMD 一樣,都是在指定容器啟動程式及參數,只能出現一次。主要有兩點不同,一是 ENTRYPOINT 可以在啟動時,為其之後的命令添加自定義的參數。二 就是與 CMD 的交互,當 Dockerfile 文件中指定了ENTRYPOINT 時,CMD 中的內容就變成了 ENTRYPOINT的參數。

-- shell 格式:ENTRYPOINT <命令>
-- exec 格式:ENTRYPOINT ["可執行文件", "參數1", "參數2"]

ENV:設置環境變數,無論是後面的其它指令,還是運行時的應用,都可以直接使用這裡定義的環境變數($KEY)

-- ENV <key> <value>
-- ENV <key1>=<value1> <key2>=<value2>...

ARG:和 ENV 的效果一樣,都是設置環境變數。所不同的是,ARG 所設置的構建環境的環境變數,在將來容器運行時是不會存在這些環境變數的。而且該值可以在構建命令 docker build 中用 --build-arg <參數名>=<值> 來覆蓋。

-- ARG <參數名>[=<預設值>]

VOLUME:指定某些目錄掛載為匿名捲,這樣在運行時如果用戶不指定掛載,其應用也可以正常運行,不會向容器存儲層寫入大量數據。

-- VOLUME ["<路徑1>", "<路徑2>"...]
-- VOLUME <路徑>

EXPOSE:聲明運行時容器提供服務埠,這隻是一個聲明,在運行時並不會因為這個聲明應用就會開啟這個埠的服務。主要是為了鏡像使用者在宿主開啟埠服務時,可以映射到容器的埠。

-- EXPOSE <埠1> [<埠2>...]

HEALTHCHECK:告訴 Docker 應該如何進行判斷容器的狀態是否正常,當在一個鏡像指定了 HEALTHCHECK 指令後,用其啟動容器,初始狀態會為 starting,在 HEALTHCHECK 指令檢查成功後變為 healthy,如果連續一定次數失敗,則會變為 unhealthy。

-- HEALTHCHECK [選項] CMD <命令>:設置檢查容器健康狀況的命令
    --interval=<間隔>:兩次健康檢查的間隔,預設為 30 秒;
    --timeout=<時長>:健康檢查命令運行超時時間,如果超過這個時間,本次健康檢查就被視為失敗,預設 30 秒;
    --retries=<次數>:當連續失敗指定次數後,則將容器狀態視為 unhealthy,預設 3 次。

-- HEALTHCHECK NONE:如果基礎鏡像有健康檢查指令,使用這行可以屏蔽掉其健康檢查指令

ONBUILD: 是一個特殊的指令,它後面跟的是其它指令,比如 RUN, COPY 等,而這些指令,在當前鏡像構建時並不會被執行。只有當以當前鏡像為基礎鏡像,去構建下一級鏡像的時候才會被執行。

-- ONBUILD <其它指令>

tips:在指令格式上,一般推薦使用 exec 格式,這類格式在解析時會被解析為 JSON 數組,因此一定要使用雙引號 ",而不要使用單引號。

    簡單瞭解完這些命令後,讓我們來試著製作一個web工程的鏡像吧!為此,查了很多網上製作鏡像的教程,結果都不是很盡人意,很多竟然都是通過 docker commit  來製作的(不推薦使用 docker commit 來製作鏡像,會添加進很多編譯的文件,造成鏡像的臃腫),還有一些雖然是通過 Dockerfile 文件的方式來製作鏡像,但是 Dockerfile 的語法卻不是很規範(比如將多個 Linux 命令寫在多行,造成 鏡像無謂的分層,因為Dockerfile 一條命令就是一層結構)。

    所以就自己著手寫一個 Dockerfile 文件吧!第一次自己琢磨著寫鏡像,有點小激動,連晚飯都忘記吃了...思路是這樣的,首先先寫一個基礎環境鏡像,基於 centos 伺服器,安裝好 jdk 環境和 Tomcat;然後基於這個基礎環境鏡像構建web鏡像 — 將 war 包拷貝進 webapps 目錄,啟動 Tomcat。

    基礎鏡像文件 Dockerfile:

FROM centos
#1、指定工作目錄
WORKDIR /usr/local
#2、指定版本信息
ENV JAVA=jdk-8u181-linux-x64 TOMCAT=apache-tomcat-8.0.53
#3、創建目錄,多個命令儘量在一個Dockerfile 命令中完成,避免構建多層,做好清理工作
RUN mkdir java \
   && mkdir tomcat \
   && cd java \
   && yum -y install wget \
   && wget -q -O jdk-linux.rpm --no-check-certificate --no-cookies --header "Cookie: oraclelicense=accept-securebackup-cookie" http://download.oracle.com/otn-pub/java/jdk/8u181-b13/96a7b8442fe848ef90c96a2fad6ed6d1/${JAVA}.rpm \
   && rpm -ivh jdk-linux.rpm \
   && rm -rf jdk-linux.rpm \
   && cd ../tomcat \
   && wget -q http://apache.claz.org/tomcat/tomcat-8/v8.0.53/bin/${TOMCAT}.tar.gz \
   && tar -zxv -f ${TOMCAT}.tar.gz \
   && rm -rf ${TOMCAT}.tar.gz \
   && rm -rf ${TOMCAT}/webapps/ROOT \
   && yum -y remove wget;
#4、把上下文目錄中的 war 複製進來
ONBUILD COPY *.war ./tomcat/${TOMCAT}/webapps/
#5、啟動容器
ONBUILD ENTRYPOINT ["/usr/local/tomcat/apache-tomcat-8.0.53/bin/catalina.sh","run"]
#6、基礎環境構建完畢
CMD ["sh","-c","echo Environment construction completed"]

     然後運行構建鏡像,註意docker build 最後面的那個點,表示的是鏡像的上下文目錄,COPY 命令的上下文目錄指的就是這個。

    這個鏡像製作的,額,差強人意吧,竟然有600多兆。不過,最開放我思維的是那兩個 ONBUILD 命令,就像上文提到的 ONBUILD 命令本次鏡像不會被執行,只有以這個鏡像為基礎鏡像的時候才會被執行。所以,大家想想看,有了這個基礎鏡像後,我們將打好的 war 包放在上下文目錄,然後就可以運行起來任意的 web 工程啦!

    接下來,來看看 web 鏡像是怎麼製作出來的吧!已經進展到了這一步,你會發現出奇的簡單~

FROM myenv:1.0

     是的,你沒有看錯,整個 Dockerfile 就只要這行命令就夠了,然後構建的時候,會幫你把 war 包放進 webapps 目錄(ONBUILD 的效果),接著構建運行起來吧~

#構建(--no-cache=true 表示不使用鏡像緩存)
docker build -t myweb .
#運行
docker run -p 7575:8080 myweb

    哈哈,折騰了一個周末,終於成功了!小激動小激動~~ 寫的兩個鏡像已經上傳到了 Docker hub,喜歡的點個推薦吧!

    Dockerfile 的一些書寫建議:

1、使用 Dockerfile 構建鏡像時最好是將 Dockerfile 放置在一個新建的空目錄下。然後將構建鏡像所需要的文件添加到該目錄中。

2、應該保證在一個容器只運行一個進程。將多個應用解耦到不同容器中,保證容器的橫向擴展和復用。例如 web 應用應該包含三個容器:web應用、資料庫、緩存。

3、FROM:推薦使用 Alpine 鏡像,因為它被嚴格控制並保持最小尺寸(目前小於 5 MB),但它仍然是一個完整的 Linux 發行版。

4、多行命令用反斜杠 \ 分割成多行,增加可讀性。

5、不要使用 RUN apt-get upgrade 或 dist-upgrade,因為許多基礎鏡像中的「必須」包不會在一個非特權容器中升級。

6、永遠將 RUN apt-get update 和 apt-get install 組合成一條 RUN 聲明,將 apt-get update 放在一條單獨的 RUN 聲明中會導致緩存問題以及後續的 apt-get install 失敗。

7、應該避免使用 sudo,因為它不可預期的 TTY 和信號轉發行為可能造成的問題比它能解決的問題還多。

 

Docker hub 地址:https://hub.docker.com/u/jmcui/

參考資料:《Docker — 從入門到實踐》

 


您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • 第一步下載Python3.7.0 剛開始我是在windows上下載之後 傳到FTP伺服器上的 後來發現使用以下命令可以更快捷地下載到伺服器 * wget https://www.python.org/ftp/python/3.7.0/Python-3.7.0.tgz wget 是一個從網路上自動下載 ...
  • ls 2* 顯示以2開頭的文件,名字位數不限 ls 2?? 顯示3位的文件 重定向(將所查文件置於文件中) > 和 >> cat 一次性顯示內容, cat 加多個文件可以同時查看多個文件內容 more + 文件名 分屏顯示內容 cd ./A 或 cd A/ 跳到當前路徑的A文件夾下 cd .. 當前 ...
  • Linux常用精簡命令實訓 一、文件操作 1.1 在家目錄下創建testDir目錄,隨後進入testDir,分別採用相對路徑和絕對路徑兩種方式,再進入到目錄/home。 1.2 在家目錄下,創建目錄testDir/java/docs和目錄testDir/shell/docs 1.3 在家目錄下,目錄 ...
  • 1.先新建一個文件夾,裡面分別鍵六個名為COMSIS、FWLIB、HARDWARE、MDK、OBJ、USER的空文件夾 2.創建好文件夾就可以往裡面添加文件啦,這三個文件夾放置如圖所示的文件,其餘三個文件夾HARDWARE、MDK、OBJ分別用於存放工程創建時的文件 3.開始創建工程啦,找到如圖所示 ...
  • wc 命令 使用說明 wc 命令還是很是簡單的,通過 man 命令,可以見到可以選擇的選項: wc option file 並且 wc 命令支持 管道操作 其中較為常用的命令選項 -c 字元的個數 -l 文件的行數 -w 單詞的個數 小例子: Man 手冊,具體內容很簡短,有時間大家還是多閱讀英文手 ...
  • 按ESC鍵回到命令模式,輸入:w保存即可,或者輸入:wq!保存文件並退出。 以下是保存命令: :w 保存文件但不退出vi 。 :w file 將修改另外保存到file中,不退出vi 。 :w! 強制保存,不推出vi。 拓展: vi/vim 的使用 基本上 vi/vim 共分為三種模式,分別是命令模式 ...
  • 基於Red Hat Enterprise Linux 7.5 1、ifconfig ifconfig用於獲取和配置網路介面的網路參數,格式為“ifconfig [網路設備] [參數]” 參數: add addr/prefixlen:給網路設備添加一個IPv6地址 del add/prefixlen: ...
  • 環境: CentOS6.9_64位 步驟1 虛擬機此時處在關機模式,開機後在下圖界面4秒倒計時結束前,按 步驟2 此時會進入下圖所示界面,接著按一下 步驟3 此時會進入下圖所示的界面,選擇第2項,接著按一下 步驟4 此時會進入下圖所示的界面,此時可以輸入字元,請輸入 ,輸入完畢之後按一下 鍵 1 也 ...
一周排行
    -Advertisement-
    Play Games
  • 示例項目結構 在 Visual Studio 中創建一個 WinForms 應用程式後,項目結構如下所示: MyWinFormsApp/ │ ├───Properties/ │ └───Settings.settings │ ├───bin/ │ ├───Debug/ │ └───Release/ ...
  • [STAThread] 特性用於需要與 COM 組件交互的應用程式,尤其是依賴單線程模型(如 Windows Forms 應用程式)的組件。在 STA 模式下,線程擁有自己的消息迴圈,這對於處理用戶界面和某些 COM 組件是必要的。 [STAThread] static void Main(stri ...
  • 在WinForm中使用全局異常捕獲處理 在WinForm應用程式中,全局異常捕獲是確保程式穩定性的關鍵。通過在Program類的Main方法中設置全局異常處理,可以有效地捕獲並處理未預見的異常,從而避免程式崩潰。 註冊全局異常事件 [STAThread] static void Main() { / ...
  • 前言 給大家推薦一款開源的 Winform 控制項庫,可以幫助我們開發更加美觀、漂亮的 WinForm 界面。 項目介紹 SunnyUI.NET 是一個基於 .NET Framework 4.0+、.NET 6、.NET 7 和 .NET 8 的 WinForm 開源控制項庫,同時也提供了工具類庫、擴展 ...
  • 說明 該文章是屬於OverallAuth2.0系列文章,每周更新一篇該系列文章(從0到1完成系統開發)。 該系統文章,我會儘量說的非常詳細,做到不管新手、老手都能看懂。 說明:OverallAuth2.0 是一個簡單、易懂、功能強大的許可權+可視化流程管理系統。 有興趣的朋友,請關註我吧(*^▽^*) ...
  • 一、下載安裝 1.下載git 必須先下載並安裝git,再TortoiseGit下載安裝 git安裝參考教程:https://blog.csdn.net/mukes/article/details/115693833 2.TortoiseGit下載與安裝 TortoiseGit,Git客戶端,32/6 ...
  • 前言 在項目開發過程中,理解數據結構和演算法如同掌握蓋房子的秘訣。演算法不僅能幫助我們編寫高效、優質的代碼,還能解決項目中遇到的各種難題。 給大家推薦一個支持C#的開源免費、新手友好的數據結構與演算法入門教程:Hello演算法。 項目介紹 《Hello Algo》是一本開源免費、新手友好的數據結構與演算法入門 ...
  • 1.生成單個Proto.bat內容 @rem Copyright 2016, Google Inc. @rem All rights reserved. @rem @rem Redistribution and use in source and binary forms, with or with ...
  • 一:背景 1. 講故事 前段時間有位朋友找到我,說他的窗體程式在客戶這邊出現了卡死,讓我幫忙看下怎麼回事?dump也生成了,既然有dump了那就上 windbg 分析吧。 二:WinDbg 分析 1. 為什麼會卡死 窗體程式的卡死,入口門檻很低,後續往下分析就不一定了,不管怎麼說先用 !clrsta ...
  • 前言 人工智慧時代,人臉識別技術已成為安全驗證、身份識別和用戶交互的關鍵工具。 給大家推薦一款.NET 開源提供了強大的人臉識別 API,工具不僅易於集成,還具備高效處理能力。 本文將介紹一款如何利用這些API,為我們的項目添加智能識別的亮點。 項目介紹 GitHub 上擁有 1.2k 星標的 C# ...