目錄
- 通過DOCKER OVERLAY2目錄名查找容器名和容器ID
- DOCKER入門
- Docker基礎
- docker簡介
- 基本概念
- 利用DockerFile定制鏡像
- Dockerfile指令詳解
- 保存鏡像
- 總結
通過DOCKER OVERLAY2目錄名查找容器名和容器ID
有時候經常會有個別容器占用磁盤空間特別大,這個時候就需要通過docker overlay2 目錄名查找對應容器名:
1.首先進入到 /var/lib/docker/overlay2 目錄下,查看誰占用的較多
du -s ./* | sort -rn | more
2、查出所占用的大文件
3、再通過目錄名查找容器名
?docker ps -q | xargs docker inspect --format '{{.State.Pid}}, {{.Id}}, {{.Name}}, {{.GraphDriver.Data.WorkDir}}' | grep bff25099a59b0fc8addd06f9223872f2904256f0432b3c3c47b58faef167115f
輸出依次為,進程pid、容器ID、容器名、存儲work路徑,即可確定是哪個容器。
DOCKER入門
Docker基礎
docker保姆級教程
https://github.com/yeasy/docker_practice/blob/master/SUMMARY.md
Docker系統有兩個程序
docker服務端和docker客戶端。
其中docker服務端是一個服務進程,管理著所有的容器。
docker客戶端則扮演著docker服務端的遠程控制器,可以用來控制docker的服務端進程。
大部分情況下,docker服務端和客戶端運行在一臺機器上。
常用命令
// 查看docker版本信息
docker version
// 搜索可用的鏡像
docker search mysql
//拉取鏡像-默認是拉取的最新版本
docker pull mysql
//拉取鏡像-特定版本拉取(版本號一定要是官方放出的版本號,否則是查找不到的)
docker pull mysql:8.0.22
// 列舉本機所有鏡像
docker images -a
// 列出鏡像結果,并且只包含鏡像ID和倉庫名
docker images --format "{{.ID}}: {{.Repository}}"
// 刪除鏡像('xxx'可以為鏡像id或鏡像REPOSITORY)
docker rmi xxx
// 保存對容器的修改(如安裝了ping)
參見https://www.docker.org.cn/book/docker/docer-save-changes-10.html
查看被修改的容器 :docker ps -l
提交指定容器保存為新的鏡像: docker commit <container id> <new image name>
// 查看容器詳細信息
docker inspect xxx
// 查看所有容器
docker ps -a
[or]
docker container ls -a
// 查看運行中的容器
docker ps
// 刪除指定容器(Docker 會發送 SIGKILL 信號給容器。 加-f是刪除處于運行中的容器)
docker rm -f xxx
// 查看docker容器日志
docker logs xxx
// 新建并啟動容器
docker run
// docker run命令實用參數舉例
-d 讓docker處于后臺運行
-P 容器內部端口隨機映射到主機的端口
-p 容器內部端口綁定到主機指定的端口(使用:docker run -d -p <主機端口>:<容器端口> ...)
--name 給容器起別名(使用:docker run -d -P --name <容器別名> <鏡像>)
-it 進入交互式終端(這是兩個參數,一個是 -i 交互式操作,一個是 -t 終端。通常還會在鏡像名后跟一個命令,如我們希望有個交互式 Shell,因此在鏡像后會跟一個 bash)
--rm 這個參數是說容器退出后隨之將其刪除。
-v 添加數據卷(-v /my/own/datadir:/var/lib/mysql /my/own/datadir是主機的數據庫路徑 /var/lib/mysql是容器中的數據庫路徑)
// 查看指定容器的啟動命令
docker ps -a --no-trunc | grep xxx
[or]
在docker inspect的Path參數也可見
// 查看容器端口綁定情況
docker port xxx
// 查看docker網絡
docker network ls
// 創建網絡
docker network create -d bridge test-net
(說明:-d用于指定docker網絡類型,分為bridge、overlay)
// 連接容器(運行一個容器并連接到新建的 test-net 網絡)
docker run -itd --name test1 --network test-net ubuntu /bin/bash
docker run -itd --name test2 --network test-net ubuntu /bin/bash
(而后,test1、test2容器間便可以互相ping通了)
// 進入容器后,若發現有的命令不支持,如:ping www.baidu.com,提示:`bash: ping: command not found`
// 這時就需要手動安裝對應命令了。但執行apt-get install ping時,又提示:`E: Unable to locate package ping`
// 解決方式:先執行apt-get update,再執行apt-get install ping即可
// 構建鏡像
docker build -t xxx .
拓展
redis-shake是一個用于做redis數據遷移的工具,并提供一定程度的數據清洗能力。
參見:https://github.com/alibaba/RedisShake/blob/v3/README_zh.md
docker簡介
參考:https://docs.kilvn.com/docker_practice/introduction/why.html
Docker 技術比虛擬機技術更為輕便、快捷。
傳統虛擬機技術是虛擬出一套硬件后,在其上運行一個完整操作系統,在該系統上再運行所需應用進程;
而容器內的應用進程直接運行于宿主的內核,容器內沒有自己的內核,而且也沒有進行硬件虛擬。因此容器要比傳統虛擬機更為輕便。
** Q:docker優勢 ** 1、更高效的利用系統資源 由于容器不需要進行硬件虛擬以及運行完整操作系統等額外開銷,Docker 對系統資源的利用率更高。 無論是應用執行速度、內存損耗或者文件存儲速度,都要比傳統虛擬機技術更高效。 因此,相比虛擬機技術,一個相同配置的主機,往往可以運行更多數量的應用。 2、更快速的啟動時間 Docker容器應用,由于直接運行于宿主內核,無需啟動完整的操作系統, 因此可以做到秒級、甚至毫秒級的啟動時間。大大的節約了開發、測試、部署的時間。 3、一致的運行環境 開發過程中一個常見的問題是環境一致性問題。 由于開發環境、測試環境、生產環境不一致,導致有些 bug 并未在開發過程中被發現。 而 Docker 的鏡像提供了除內核外完整的運行時環境,確保了應用運行環境一致性, 從而不會再出現 “這段代碼在我機器上沒問題啊” 這類問題。 4、持續交付和部署 對開發和運維(DevOps)人員來說,最希望的就是一次創建或配置,可以在任意地方正常運行。 使用 Docker 可以通過定制應用鏡像來實現持續集成、持續交付、部署。 開發人員可以通過 Dockerfile 來進行鏡像構建,并結合 持續集成(Continuous Integration) 系統進行集成測試, 而運維人員則可以直接在生產環境中快速部署該鏡像,甚至結合 持續部署(Continuous Delivery/Deployment) 系統進行自動部署。 5、更輕松的遷移 由于 Docker 確保了執行環境的一致性,使得應用的遷移更加容易。 因此用戶可以很輕易的將在一個平臺上運行的應用,遷移到另一個平臺上,而不用擔心運行環境的變化導致應用無法正常運行的情況。 6、更輕松的擴展和維護 Docker 使用的分層存儲以及鏡像的技術,使得應用重復部分的復用更為容易, 也使得應用的維護更新更加簡單,基于基礎鏡像進一步擴展鏡像也變得非常簡單。
基本概念
鏡像
操作系統分為內核和用戶空間。
對于 Linux 而言,內核啟動后,會掛載 root 文件系統為其提供用戶空間支持。
而 Docker 鏡像(Image),就相當于是一個 root 文件系統。比如官方鏡像 ubuntu:14.04 就包含了完整的一套 Ubuntu 14.04 最小系統的 root 文件系統。
Docker 鏡像是一個特殊的文件系統,除了提供容器運行時所需的程序、庫、資源、配置等文件外,還包含了一些為運行時準備的一些配置參數(如匿名卷、環境變量、用戶等)。鏡像不包含任何動態數據,其內容在構建之后也不會被改變。
注意,當我們運行一個容器的時候(如果不使用卷,也沒綁定宿主機目錄的話),我們做的任何文件修改都會被記錄于容器存儲層里。而 Docker 提供了一個 docker commit 命令,可以將容器的存儲層保存下來成為鏡像。
換句話說,就是在原有鏡像的基礎上,再疊加上容器的存儲層,并構成新的鏡像。以后我們運行這個新鏡像的時候,就會擁有原有容器最后的文件變化。
// docker commit 的語法格式為:
docker commit [選項] <容器ID或容器名> [<倉庫名>[:<標簽>]]
// 舉例
$ docker commit \
--author "Tao Wang <[email protected]>" \
--message "修改了默認網頁" \
webserver \
nginx:v2
// 查看鏡像的歷史版本提交信息
docker history nginx:v2
需慎用 docker commit去生成鏡像,其生成的鏡像被稱為黑箱鏡像。換句話說,就是除了制作鏡像的人知道執行過什么命令、怎么生成的鏡像,別人根本無從得知,這種黑箱鏡像的維護工作是非常痛苦的。
回顧之前提及的鏡像所使用的分層存儲的概念,除當前層外,之前的每一層都是不會發生改變的,換句話說,任何修改的結果僅僅是在當前層進行標記、添加、修改,而不會改動上一層。如果使用 docker commit 制作鏡像,以及后期修改的話,每一次修改都會讓鏡像更加臃腫一次,所刪除的上一層的東西并不會丟失,會一直如影隨形的跟著這個鏡像,即使根本無法訪問到™。這會讓鏡像更加臃腫。
鏡像的定制行為應該使用 Dockerfile 來完成。
容器
鏡像(Image)和容器(Container)的關系,就像是面向對象程序設計中的類和實例一樣。
鏡像是靜態的定義,容器是鏡像運行時的實體。容器可以被創建、啟動、停止、刪除、暫停等。
容器的實質是進程,但與直接在宿主執行的進程不同,容器進程運行于屬于自己的獨立的 命名空間。因此容器可以擁有自己的 root 文件系統、自己的網絡配置、自己的進程空間,甚至自己的用戶 ID 空間。容器內的進程是運行在一個隔離的環境里,使用起來,就好像是在一個獨立于宿主的系統下操作一樣。這種特性使得容器封裝的應用比直接在宿主運行更加安全。
每一個容器運行時,是以鏡像為基礎層,在其上創建一個當前容器的存儲層,我們可以稱這個為容器運行時讀寫而準備的存儲層為容器存儲層。
容器存儲層的生存周期和容器一樣,容器消亡時,容器存儲層也隨之消亡。因此,任何保存于容器存儲層的信息都會隨容器刪除而丟失。
按照 Docker 最佳實踐的要求,容器不應該向其存儲層內寫入任何數據,容器存儲層要保持無狀態化。所有的文件寫入操作,都應該使用 數據卷(Volume)、或者綁定宿主目錄,在這些位置的讀寫會跳過容器存儲層,直接對宿主(或網絡存儲)發生讀寫,其性能和穩定性更高。
數據卷的生存周期獨立于容器,容器消亡,數據卷不會消亡。因此,使用數據卷后,容器可以隨意刪除、重新 run,數據卻不會丟失。
當利用 docker run 來創建容器時,Docker 在后臺運行的標準操作包括:
- 檢查本地是否存在指定的鏡像,不存在就從公有倉庫下載
- 利用鏡像創建并啟動一個容器
- 分配一個文件系統,并在只讀的鏡像層外面掛載一層可讀寫層
- 從宿主主機配置的網橋接口中橋接一個虛擬接口到容器中去
- 從地址池配置一個 ip 地址給容器
- 執行用戶指定的應用程序
- 執行完畢后容器被終止
倉庫
一個 Docker Registry 中可以包含多個倉庫(Repository);每個倉庫可以包含多個標簽(Tag);每個標簽對應一個鏡像。
通常,一個倉庫會包含同一個軟件不同版本的鏡像,而標簽就常用于對應該軟件的各個版本。我們可以通過 <倉庫名>:<標簽> 的格式來指定具體是這個軟件哪個版本的鏡像。如果不給出標簽,將以 latest 作為默認標簽。
倉庫名經常以 兩段式路徑 形式出現,比如 jwilder/nginx-proxy,前者往往意味著 Docker Registry 多用戶環境下的用戶名,后者則往往是對應的軟件名。
注冊服務器(Registry)是管理倉庫(Repository)的具體服務器,倉庫是集中存放鏡像的地方。
利用DockerFile定制鏡像
參見:https://docs.kilvn.com/docker_practice/image/build.html
從之前的 docker commit 的學習中,我們可以了解到:鏡像的定制實際上就是定制每一層所添加的配置、文件。
如果我們可以把每一層修改、安裝、構建、操作的命令都寫入一個腳本,用這個腳本來構建、定制鏡像,那么之前提及的無法重復的問題、鏡像構建透明性的問題、體積的問題就都會解決。這個腳本就是 Dockerfile。
Dockerfile 是一個文本文件,其內包含了一條條的指令(Instruction),每一條指令構建一層。
在docker build 命令最后有一個 . 表示當前目錄,其實這是在指定上下文路徑。
當構建的時候,用戶會指定構建鏡像上下文的路徑,docker build 命令得知這個路徑后,會將路徑下的所有內容打包,然后上傳給 Docker 引擎。這樣 Docker 引擎收到這個上下文包后,展開就會獲得構建鏡像所需的一切文件。
一般來說,應該會將 Dockerfile 置于一個空目錄下,或者項目根目錄下。如果該目錄下沒有所需文件,那么應該把所需文件復制一份過來。如果目錄下有些東西確實不希望構建時傳給 Docker 引擎,那么可以用 .gitignore 一樣的語法寫一個 .dockerignore,該文件是用于剔除不需要作為上下文傳遞給 Docker 引擎的。
在默認情況下,如果不額外指定 Dockerfile 的話,會將上下文目錄下的名為 Dockerfile 的文件作為 Dockerfile。
這只是默認行為,實際上 Dockerfile 的文件名并不要求必須為 Dockerfile,而且并不要求必須位于上下文目錄中,比如可以用 -f …/Dockerfile.php 參數指定某個文件作為 Dockerfile。
常規構建方法
docker build -t xxx .
其它構建方法
1.直接用 Git repo 進行構建
docker build 還支持從 URL 構建,比如可以直接從 Git repo 中構建:
docker build https://github.com/twang2218/gitlab-ce-zh.git#:8.14
說明:這行命令指定了構建所需的 Git repo,并且指定默認的 master 分支,構建目錄為 /8.14/,然后 Docker 就會自己去 git clone 這個項目、切換到指定分支、并進入到指定目錄后開始構建。
2.用給定的 tar 壓縮包構建
docker build http://server/context.tar.gz
如果所給出的 URL 不是個 Git repo,而是個 tar 壓縮包,那么 Docker 引擎會下載這個包,并自動解壓縮,以其作為上下文,開始構建。
3.從標準輸入中讀取 Dockerfile 進行構建
4.從標準輸入中讀取上下文壓縮包進行構建
Dockerfile指令詳解
// Dockerfile指令詳解
- FROM 指定基礎鏡像
所謂定制鏡像,那一定是以一個鏡像為基礎,在其上進行定制。而 FROM 就是指定基礎鏡像。
因此一個 Dockerfile 中 FROM 是必備的指令,并且必須是第一條指令。
(Docker 還存在一個特殊的鏡像,名為 scratch。這個鏡像是虛擬的概念,并不實際存在,它表示一個空白的鏡像。因此直接 FROM scratch 會讓鏡像體積更加小巧。
如果以 scratch 為基礎鏡像的話,意味著你不以任何鏡像為基礎,接下來所寫的指令將作為鏡像第一層開始存在。)
- RUN 執行命令
其格式有兩種:
1. shell 格式:RUN <命令>
2. exec 格式:RUN ["可執行文件", "參數1", "參數2"]
每一個 RUN 都是啟動一個容器、執行命令、然后提交存儲層文件變更。
對于有多個命令的情況,建議將命令間用‘&&'連接,避免多層構建鏡像。正確示例:
RUN buildDeps='gcc libc6-dev make' \
&& apt-get update \
&& apt-get install -y $buildDeps
- COPY 復制文件
格式:
COPY <源路徑>... <目標路徑>
COPY ["<源路徑1>",... "<目標路徑>"]
COPY 指令將從構建上下文目錄中 <源路徑> 的文件/目錄復制到新的一層的鏡像內的 <目標路徑> 位置。
比如:
COPY package.json /usr/src/app/
COPY hom* /mydir/
<源路徑> 可以是多個,甚至可以是通配符
<目標路徑> 可以是容器內的絕對路徑,也可以是相對于工作目錄的相對路徑(工作目錄可以用 WORKDIR 指令來指定)。
目標路徑不需要事先創建,如果目錄不存在會在復制文件前先行創建缺失目錄。
- ADD 更高級的復制文件
ADD 指令和 COPY 的格式和性質基本一致,但也有所不同。
比如 <源路徑> 可以是一個 URL,這種情況下,Docker 引擎會試圖去下載這個鏈接的文件放到 <目標路徑> 去。
下載后的文件權限自動設置為 600,如果這并不是想要的權限,那么還需要增加額外的一層 RUN 進行權限調整;
另外,如果下載的是個壓縮包,需要解壓縮,也一樣還需要額外的一層 RUN 指令進行解壓縮。
所以不如直接使用 RUN 指令,然后使用 wget 或者 curl 工具下載,處理權限、解壓縮、然后清理無用文件更合理。
因此,這個功能其實并不實用,而且不推薦使用。
如果 <源路徑> 為一個 tar 壓縮文件的話,壓縮格式為 gzip, bzip2 以及 xz 的情況下,ADD 指令將會自動解壓縮這個壓縮文件到 <目標路徑> 去。
在 Docker 官方的最佳實踐文檔中要求,盡可能的使用 COPY,因為 COPY 的語義很明確,就是復制文件而已,而 ADD 則包含了更復雜的功能,其行為也不一定很清晰。
另外需要注意的是,ADD 指令會令鏡像構建緩存失效,從而可能會令鏡像構建變得比較緩慢。
- CMD 容器啟動命令
CMD 指令的格式和 RUN 相似,也是兩種格式:
shell 格式:CMD <命令>
exec 格式:CMD ["可執行文件", "參數1", "參數2"...]
Docker不是虛擬機,容器就是進程。既然是進程,那么在啟動容器的時候,需要指定所運行的程序及參數。
CMD 指令就是用于指定默認的容器主進程的啟動命令的。
在指令格式上,一般推薦使用 exec 格式,這類格式在解析時會被解析為 JSON 數組,因此一定要使用雙引號 ",而不要使用單引號。
如果使用 shell 格式的話,實際的命令會被包裝為 sh -c 的參數的形式進行執行。比如:
CMD echo $HOME
在實際執行中,會將其變更為:
CMD [ "sh", "-c", "echo $HOME" ]
提到 CMD 就不得不提容器中應用在前臺執行和后臺執行的問題。
容器中的應用都應該以前臺執行,而不是像虛擬機、物理機里面那樣,用 upstart/systemd 去啟動后臺服務,容器內沒有后臺服務的概念。
對于容器而言,其啟動程序就是容器應用進程,容器就是為了主進程而存在的,主進程退出,容器就失去了存在的意義,從而退出,其它輔助進程不是它需要關心的東西。
舉例:
CMD service nginx start
使用 service nginx start 命令,是希望以后臺守護進程形式啟動 nginx 服務。
而剛才說了 CMD service nginx start 會被理解為 CMD [ "sh", "-c", "service nginx start"],因此主進程實際上是 sh。
那么當 service nginx start 命令結束后,sh 也就結束了,sh 作為主進程退出了,自然就會令容器退出。
正確的做法是直接執行 nginx 可執行文件,并且要求以前臺形式運行。比如:
CMD ["nginx", "-g", "daemon off;"]
- ENTRYPOINT 入口點
ENTRYPOINT 的目的和 CMD 一樣,都是在指定容器啟動程序及參數。ENTRYPOINT 在運行時也可以替代,不過比 CMD 要略顯繁瑣,需要通過 docker run 的參數 --entrypoint 來指定。
當指定了 ENTRYPOINT 后,CMD 的含義就發生了改變,不再是直接的運行其命令,而是將 CMD 的內容作為參數傳給 ENTRYPOINT 指令,換句話說實際執行時,將變為:
<ENTRYPOINT> "<CMD>"
其使用場景及好處參見:https://docs.kilvn.com/docker_practice/image/dockerfile/entrypoint.html
- ENV 設置環境變量
格式有兩種:
ENV <key> <value>
ENV <key1>=<value1> <key2>=<value2>...
這個指令很簡單,就是設置環境變量而已。
環境變量可以使用的地方很多,很強大。通過環境變量,我們可以讓一份 Dockerfile 制作更多的鏡像,只需使用不同的環境變量即可。
- VOLUME 定義匿名卷
格式為:
VOLUME ["<路徑1>", "<路徑2>"...]
VOLUME <路徑>
之前我們說過,容器運行時應該盡量保持容器存儲層不發生寫操作,對于數據庫類需要保存動態數據的應用,其數據庫文件應該保存于卷(volume)中。
為了防止運行時用戶忘記將動態文件所保存目錄掛載為卷,在 Dockerfile 中,我們可以事先指定某些目錄掛載為匿名卷,
這樣在運行時如果用戶不指定掛載,其應用也可以正常運行,不會向容器存儲層寫入大量數據。
VOLUME /data 這里的 /data 目錄就會在運行時自動掛載為匿名卷,任何向 /data 中寫入的信息都不會記錄進容器存儲層,
從而保證了容器存儲層的無狀態化。當然,運行時可以覆蓋這個掛載設置。比如:
docker run -d -v mydata:/data xxxx
在這行命令中,就使用了 mydata 這個命名卷掛載到了 /data 這個位置,替代了 Dockerfile 中定義的匿名卷的掛載配置。
- EXPOSE 聲明端口
格式為 EXPOSE <端口1> [<端口2>...]
指令是聲明運行時容器提供服務端口,這只是一個聲明,在運行時并不會因為這個聲明應用就會開啟這個端口的服務。
在 Dockerfile 中寫入這樣的聲明有兩個好處:
一個是幫助鏡像使用者理解這個鏡像服務的守護端口,以方便配置映射;
另一個用處則是在運行時使用隨機端口映射時,也就是 docker run -P 時,會自動隨機映射 EXPOSE 的端口。
- WORKDIR 指定工作目錄
格式為 WORKDIR <工作目錄路徑>
使用 WORKDIR 指令可以來指定工作目錄(或者稱為當前目錄),以后各層的當前目錄就被改為指定的目錄,如該目錄不存在,WORKDIR 會幫你建立目錄。
- USER 指定當前用戶
格式:USER <用戶名>
USER 指令和 WORKDIR 相似,都是改變環境狀態并影響以后的層。
WORKDIR 是改變工作目錄,
USER 則是改變之后層的執行 RUN, CMD 以及 ENTRYPOINT 這類命令的身份。
- HEALTHCHECK 健康檢查
格式:
HEALTHCHECK [選項] CMD <命令>:設置檢查容器健康狀況的命令
HEALTHCHECK NONE:如果基礎鏡像有健康檢查指令,使用這行可以屏蔽掉其健康檢查指令
HEALTHCHECK 指令是告訴 Docker 應該如何進行判斷容器的狀態是否正常,這是 Docker 1.12 引入的新指令。
自 1.12 之后,Docker 提供了 HEALTHCHECK 指令,通過該指令指定一行命令,用這行命令來判斷容器主進程的服務狀態是否還正常,從而比較真實的反應容器實際狀態。
背景:
在沒有 HEALTHCHECK 指令前,Docker 引擎只可以通過容器內主進程是否退出來判斷容器是否狀態異常。
很多情況下這沒問題,但是如果程序進入死鎖狀態,或者死循環狀態,應用進程并不退出,但是該容器已經無法提供服務了。
在 1.12 以前,Docker 不會檢測到容器的這種狀態,從而不會重新調度,導致可能會有部分容器已經無法提供服務了卻還在接受用戶請求。
當在一個鏡像指定了 HEALTHCHECK 指令后,用其啟動容器,初始狀態會為 starting,在 HEALTHCHECK 指令檢查成功后變為 healthy,如果連續一定次數失敗,則會變為 unhealthy。
HEALTHCHECK 支持下列選項:
--interval=<間隔>:兩次健康檢查的間隔,默認為 30 秒;
--timeout=<時長>:健康檢查命令運行超時時間,如果超過這個時間,本次健康檢查就被視為失敗,默認 30 秒;
--retries=<次數>:當連續失敗指定次數后,則將容器狀態視為 unhealthy,默認 3 次。
和 CMD, ENTRYPOINT 一樣,HEALTHCHECK 只可以出現一次,如果寫了多個,只有最后一個生效。
在 HEALTHCHECK [選項] CMD 后面的命令,格式和 ENTRYPOINT 一樣,分為 shell 格式,和 exec 格式。
命令的返回值決定了該次健康檢查的成功與否:0:成功;1:失敗
舉例:
假設我們有個鏡像是個最簡單的 Web 服務,我們希望增加健康檢查來判斷其 Web 服務是否在正常工作,我們可以用 curl 來幫助判斷,其 Dockerfile 的 HEALTHCHECK 可以這么寫:
FROM nginx
RUN apt-get update \
&& apt-get install -y curl \
&& rm -rf /var/lib/apt/lists/*
HEALTHCHECK --interval=5s --timeout=3s \
CMD curl -fs http://localhost/ || exit 1
這里我們設置了每 5 秒檢查一次(這里為了試驗所以間隔非常短,實際應該相對較長),
如果健康檢查命令超過 3 秒沒響應就視為失敗,并且使用 curl -fs http://localhost/ || exit 1 作為健康檢查命令。
- ONBUILD 為他人做嫁衣裳
參見:https://docs.kilvn.com/docker_practice/image/dockerfile/onbuild.html
保存鏡像
使用 docker save 命令可以將鏡像保存為歸檔文件。
保存鏡像為鏡像存儲文件的命令:
docker save mynginx | gzip > mynginx-latest.tar.gz
加載鏡像存儲文件到本地鏡像庫的命令:
docker load -i mynginx-latest.tar.gz
如果我們結合這兩個命令以及 ssh 甚至 pv 的話,利用 Linux 強大的管道,我們可以寫一個命令完成從一個機器將鏡像遷移到另一個機器,并且帶進度條的功能:
docker save <鏡像名> | bzip2 | pv | ssh <用戶名>@<主機名> 'cat | docker load'
導出容器快照到本地的命令:
docker export myubuntu > myubuntu.tar
導入容器快照到本地鏡像庫的命令:
cat myubuntu.tar | docker import - myubuntu:v1.0
鏡像存儲文件與容器快照文件的區別:
這兩者的區別在于容器快照文件將丟棄所有的歷史記錄和元數據信息(即僅保存容器當時的快照狀態),而鏡像存儲文件將保存完整記錄,體積也要大。此外,從容器快照文件導入時可以重新指定標簽等元數據信息。
總結
以上為個人經驗,希望能給大家一個參考,也希望大家多多支持。






