Docker知識總結

1 安裝docker

docker是cs架構,安裝docker默認會安裝服務端和客戶端,通過docker version查看版本和安裝信息。docker有很多平臺的版本,雲服務器最常用的是linux版本,個人學習也可以安裝windows和macOS的桌面版。docker version就是docker客戶端發給服務端的一條命令

 ~/ docker version
Client: Docker Engine - Community
 Cloud integration  0.1.18
 Version:           19.03.13
 API version:       1.40
 Go version:        go1.13.15
 Git commit:        4484c46d9d
 Built:             Wed Sep 16 16:58:31 2020
 OS/Arch:           darwin/amd64
 Experimental:      false

Server: Docker Engine - Community
 Engine:
  Version:          19.03.13
  API version:      1.40 (minimum version 1.12)
  Go version:       go1.13.15
  Git commit:       4484c46d9d
  Built:            Wed Sep 16 17:07:04 2020
  OS/Arch:          linux/amd64
  Experimental:     false
 containerd:
  Version:          v1.3.7
  GitCommit:        8fba4e9a7d01810a393d5d25a3621dc101981175
 runc:
  Version:          1.0.0-rc10
  GitCommit:        dc9208a3303feef5b3839f4323d9beb36df0a9dd
 docker-init:
  Version:          0.18.0
  GitCommit:        fec3683

2 docker基本概念

2.1 Docker是容器化平臺

Docker是提供應用打包,部署與運行應用的容器化平臺。在docker上運行的應用程序,面向Docker-Engine(docker引擎)。docker引擎依賴於(面向)基礎物理機的資源(物理機,虛擬機)。可以看出docker引擎和我們Java的JVM虛擬機非常像

2.2 Docker體系結構

Docker引擎包含底層的docker服務器Server,也稱爲docker-daemon(Docker守護進程),中間是RestApi層(Http協議),Client(Docker-cli)通過API和Server進行通信。所以對於運維工程師來說,可以在本地安裝docker-cli,操作多臺安裝了docker-daemon的服務器,進行通信

2.3 容器與鏡像

鏡像: 鏡像是文件,是隻讀的,提供了運行程序完整的軟硬件資源,是應用程序的"集裝箱"

容器: 是鏡像的實例,由Docker負責創建,容器之間彼此隔離。彼此擁有自己的文件系統,容器的底層鏡像都是一個linux系統

可以類比爲,我們安裝系統,首先需要系統鏡像文件來安裝啓動盤,鏡像文件對安裝的系統有一定的要求,安裝到某臺電腦之後,該電腦就有了該安裝鏡像文件的一個‘實例’。鏡像文件是隻讀的,這裏的鏡像文件和‘實例’,就可以類比爲docker的鏡像個容器

Docker命令執行流程

3 docker常用命令

  • docker pull 鏡像名<:tags> - 從遠程倉庫抽取鏡像

遠程鏡像倉庫地址 hub.docker.com,可以查看遠程倉庫存在哪些鏡像支持。不帶版本號,默認下載latest版本

  • docker images - 查看本地鏡像

  • docker run 鏡像名<:tags> - 創建容器,啓動應用

如果執行docker run時,鏡像在本地鏡像倉庫不存在,那麼默認會先執行docker pull從遠程倉庫拉去鏡像到本地鏡像倉庫

  • docker ps - 查看正在運行中的鏡像

  • docker rm <-f> 容器id - 刪除容器

-f強制刪除

  • docker rmi <-f> 鏡像名:<tags> - 刪除鏡像

-f強制刪除

3.1 快速安裝tomcat

3.1.1 尋找鏡像

先到docker中央倉庫尋找tomcat的官方鏡像,點擊鏡像會有各種版本tag,用來描述該鏡像的基本組件信息。例如‘9.0.39-jdk11-adoptopenjdk-hotspot’表示的就是該tomcat基礎環境是基於hotspot虛擬機jdk11版本,tomcat版本爲9.0.39。點擊該版本tag,我們可以看到該鏡像的詳細構建信息。後續會詳細解釋各個命令,從而能夠看懂這個文件

FROM adoptopenjdk:11-jdk-hotspot

ENV CATALINA_HOME /usr/local/tomcat
ENV PATH $CATALINA_HOME/bin:$PATH
RUN mkdir -p "$CATALINA_HOME"
WORKDIR $CATALINA_HOME

# let "Tomcat Native" live somewhere isolated
ENV TOMCAT_NATIVE_LIBDIR $CATALINA_HOME/native-jni-lib
ENV LD_LIBRARY_PATH ${LD_LIBRARY_PATH:+$LD_LIBRARY_PATH:}$TOMCAT_NATIVE_LIBDIR

# see https://www.apache.org/dist/tomcat/tomcat-$TOMCAT_MAJOR/KEYS
# see also "update.sh" (https://github.com/docker-library/tomcat/blob/master/update.sh)
ENV GPG_KEYS 05AB33110949707C93A279E3D3EFE6B686867BA6 07E48665A34DCAFAE522E5E6266191C37C037D42 47309207D818FFD8DCD3F83F1931D684307A10A5 541FBE7D8F78B25E055DDEE13C370389288584E7 61B832AC2F1C5A90F0F9B00A1C506407564C17A3 79F7026C690BAA50B92CD8B66A3AD3F4F22C4FED 9BA44C2621385CB966EBA586F72C284D731FABEE A27677289986DB50844682F8ACB77FC2E86E29AC A9C5DF4D22E99998D9875A5110C01C5A2F6059E7 DCFD35E0BF8CA7344752DE8B6FB21E8933C60243 F3A04C595DB5B6A5F1ECA43E3B7BBB100D811BBE F7DA48BB64BCB84ECBA7EE6935CD23C10D498E23

ENV TOMCAT_MAJOR 9
ENV TOMCAT_VERSION 9.0.39
ENV TOMCAT_SHA512 307ca646bac267e529fb0862278f7133fe80813f0af64a44aed949f4c7a9a98aeb9bd7f08b087645b40c6fefdd3a7fe519e4858a3dbf0a19c38c53704f92b575

RUN set -eux; \
	\
	savedAptMark="$(apt-mark showmanual)"; \
	apt-get update; \
	apt-get install -y --no-install-recommends \
		gnupg dirmngr \
		wget ca-certificates \
	; \
	\
	ddist() { \
		local f="$1"; shift; \
		local distFile="$1"; shift; \
		local mvnFile="${1:-}"; \
		local success=; \
		local distUrl=; \
		for distUrl in \
# https://issues.apache.org/jira/browse/INFRA-8753?focusedCommentId=14735394#comment-14735394
			"https://www.apache.org/dyn/closer.cgi?action=download&filename=$distFile" \
# if the version is outdated (or we're grabbing the .asc file), we might have to pull from the dist/archive :/
			"https://www-us.apache.org/dist/$distFile" \
			"https://www.apache.org/dist/$distFile" \
			"https://archive.apache.org/dist/$distFile" \
# if all else fails, let's try Maven (https://www.mail-archive.com/[email protected]/msg134940.html; https://mvnrepository.com/artifact/org.apache.tomcat/tomcat; https://repo1.maven.org/maven2/org/apache/tomcat/tomcat/)
			${mvnFile:+"https://repo1.maven.org/maven2/org/apache/tomcat/tomcat/$mvnFile"} \
		; do \
			if wget -O "$f" "$distUrl" && [ -s "$f" ]; then \
				success=1; \
				break; \
			fi; \
		done; \
		[ -n "$success" ]; \
	}; \
	\
	ddist 'tomcat.tar.gz' "tomcat/tomcat-$TOMCAT_MAJOR/v$TOMCAT_VERSION/bin/apache-tomcat-$TOMCAT_VERSION.tar.gz" "$TOMCAT_VERSION/tomcat-$TOMCAT_VERSION.tar.gz"; \
	echo "$TOMCAT_SHA512 *tomcat.tar.gz" | sha512sum --strict --check -; \
	ddist 'tomcat.tar.gz.asc' "tomcat/tomcat-$TOMCAT_MAJOR/v$TOMCAT_VERSION/bin/apache-tomcat-$TOMCAT_VERSION.tar.gz.asc" "$TOMCAT_VERSION/tomcat-$TOMCAT_VERSION.tar.gz.asc"; \
	export GNUPGHOME="$(mktemp -d)"; \
	for key in $GPG_KEYS; do \
		gpg --batch --keyserver ha.pool.sks-keyservers.net --recv-keys "$key"; \
	done; \
	gpg --batch --verify tomcat.tar.gz.asc tomcat.tar.gz; \
	tar -xf tomcat.tar.gz --strip-components=1; \
	rm bin/*.bat; \
	rm tomcat.tar.gz*; \
	command -v gpgconf && gpgconf --kill all || :; \
	rm -rf "$GNUPGHOME"; \
	\
# https://tomcat.apache.org/tomcat-9.0-doc/security-howto.html#Default_web_applications
	mv webapps webapps.dist; \
	mkdir webapps; \
# we don't delete them completely because they're frankly a pain to get back for users who do want them, and they're generally tiny (~7MB)
	\
	nativeBuildDir="$(mktemp -d)"; \
	tar -xf bin/tomcat-native.tar.gz -C "$nativeBuildDir" --strip-components=1; \
	apt-get install -y --no-install-recommends \
		dpkg-dev \
		gcc \
		libapr1-dev \
		libssl-dev \
		make \
	; \
	( \
		export CATALINA_HOME="$PWD"; \
		cd "$nativeBuildDir/native"; \
		gnuArch="$(dpkg-architecture --query DEB_BUILD_GNU_TYPE)"; \
		aprConfig="$(command -v apr-1-config)"; \
		./configure \
			--build="$gnuArch" \
			--libdir="$TOMCAT_NATIVE_LIBDIR" \
			--prefix="$CATALINA_HOME" \
			--with-apr="$aprConfig" \
			--with-java-home="$JAVA_HOME" \
			--with-ssl=yes; \
		make -j "$(nproc)"; \
		make install; \
	); \
	rm -rf "$nativeBuildDir"; \
	rm bin/tomcat-native.tar.gz; \
	\
# reset apt-mark's "manual" list so that "purge --auto-remove" will remove all build dependencies
	apt-mark auto '.*' > /dev/null; \
	[ -z "$savedAptMark" ] || apt-mark manual $savedAptMark > /dev/null; \
	find "$TOMCAT_NATIVE_LIBDIR" -type f -executable -exec ldd '{}' ';' \
		| awk '/=>/ { print $(NF-1) }' \
		| sort -u \
		| xargs -r dpkg-query --search \
		| cut -d: -f1 \
		| sort -u \
		| xargs -r apt-mark manual \
	; \
	apt-get purge -y --auto-remove -o APT::AutoRemove::RecommendsImportant=false; \
	rm -rf /var/lib/apt/lists/*; \
	\
# sh removes env vars it doesn't support (ones with periods)
# https://github.com/docker-library/tomcat/issues/77
	find ./bin/ -name '*.sh' -exec sed -ri 's|^#!/bin/sh$|#!/usr/bin/env bash|' '{}' +; \
	\
# fix permissions (especially for running as non-root)
# https://github.com/docker-library/tomcat/issues/35
	chmod -R +rX .; \
	chmod 777 logs temp work

# verify Tomcat Native is working properly
RUN set -e \
	&& nativeLines="$(catalina.sh configtest 2>&1)" \
	&& nativeLines="$(echo "$nativeLines" | grep 'Apache Tomcat Native')" \
	&& nativeLines="$(echo "$nativeLines" | sort -u)" \
	&& if ! echo "$nativeLines" | grep -E 'INFO: Loaded( APR based)? Apache Tomcat Native library' >&2; then \
		echo >&2 "$nativeLines"; \
		exit 1; \
	fi

EXPOSE 8080
CMD ["catalina.sh", "run"]

3.1.2 拉取鏡像到本地

docker pull tomcat # 不帶版本號,默認下載latest版本

docker pull tomcat:9.0.39-jdk11-adoptopenjdk-hotspot # 下載指定版本tag的tomcat。版本號參見上文

docker images # 查看本地下載了哪些鏡像

3.1.3 運行鏡像,啓動容器

docker run tomcat # 默認方式啓動,端口號默認爲8080,默認以交互方式啓動

此時,tomcat雖然在8080端口運行起來了,但是此時只是docker容器暴露了8080,宿主機的端口並沒有暴露出去,外部訪問不了該tomcat。docker提供了端口映射,用來綁定宿主機和容器的端口,從而解決這個問題。這種方式隔離了底層的實現,比如我們把tomcat的web服務換成其他的,但是綁定的還是宿主機的原來端口,外部用戶無感知

docker run -p 8000:8080 tomcat #表示宿主機的8000映射容器的8080

netstat -tulpn # 查看服務端口號佔用情況,此時外部可以訪問8000端口映射的tomcat服務

此時tomcat是以前臺交互的方式啓動的,後臺掛起的方式啓動如下,增加-d參數。

docker run -p 8000:8080 -d tomcat #tomcat後臺方式啓動

3.1.4 停止容器

方法1

docker stop xxx # xxx爲容器id

docker rm xxx # xxx爲容器id

方法2

docker rm -f xxx # xxx爲容器id,線上環境還是建議使用方法1,不要強殺

3.1.5 移除鏡像

docker rmi xxx # xxx爲鏡像id

如果有基於該鏡像運行的容器,需要先停止容器,再刪除鏡像。或者執行下面命令:

docker rmi -f xxx # xxx爲鏡像id,生產環境不建議使用

4 容器內部結構

dockerhub上關於鏡像的詳細信息,對鏡像的組成做了比較詳細的解釋。找到鏡像的版本tag,點進去,看dockerfile詳細描述文件

通過tomcat鏡像來看,一個tomcat鏡像的最底層都包含一個linux基礎鏡像(mini),一個jdk鏡像,一個tomcat鏡像。層數以來順序爲tomcat以來於jdk,jdk依賴於linux。

4.1 進入容器

  • 格式:docker exec [-it] 容器id 命令

exec 在對應容器中執行命令

-it 採用交互方式執行命令

docker exec -it xxx sh # xxx爲容器id

cat /proc/version # 查看容器內置的底層mini操作系統

java -version # 查看在mini基礎操作系統上安裝的jdk版本信息。創建容器後,Java環境變量無需我們關心,已經配置好了

exit # 退回到宿主機

4.2 docker容器和鏡像存放在宿主機的位置

docker容器和鏡像默認存放在宿主機的/var/lib/docker目錄下。容器存在在該目錄下的containers下,鏡像存在在該目錄下的images目錄下。除非特殊需要,不建議修改docker默認存放的地址/var/lib/docker

4.3 容器生命週期流程圖

橢圓表示容器所處在的狀態,矩形表示容器變化產生的事件

  • docker run產生兩個事件,創建容器,啓動容器,至此容器處於運行狀態
  • docker create只是創建容器,此時容器處在停止運行狀態,需要docker start來觸發讓容器處在運行狀態
  • docker stopdocker kill會對處在運行狀態的容器執行die事件,讓其回到停止運行的狀態。kill會殺掉容器進程,而stop只會停止容器,不會殺死進程。區別:重新docker start該容器,被kill掉的容器會令啓進程,stop掉的容器會恢復進程
  • docker restart會把當前容器die,再startrestart重新回到運行狀態
  • docker pause會暫停容器,讓其不再對位提供服務,容器處在不可用狀態,可以用docker unpause恢復到運行狀態(不常用)
  • oom當容器遇到未知異常,比如oom容器會die,其會根據docker配置的重啓策略,決定是否回到運行態
  • docker rm當容器不需要了,我們可以通過該命令觸發destory移除容器

容器生命週期流程圖

docker ps只會列出正在運行的容器,要想看到所有容器,使用docker ps -a

create狀態是stop狀態的一種表現,實際也是stop狀態。exited退出狀態,是在docker stop後的一種狀態,也是stop的一種表現

up狀態是runing狀態的一種表現,表示已上線,運行中

5 Dockerfile構建鏡像

Dockerfile是一個包含用於組合鏡像的命令的文本文檔(本身是一個腳本)

Docker通過讀取Dockerfile中的指令,按步自動生成鏡像

docker build命令用來解析執行dockerfile文件,生成鏡像。docker build -tag 機構+鏡像名稱<:Tags> dockerfile文件所在目錄(推薦用相對路徑)

5.1 dockerfile部署tomcat web案例

通過dockerfile構建自定義鏡像

FROM tomcat:latest #指定基準鏡像
MAINTAINER darope.163.com # 指定維護人或者維護機構信息
WORKDIR /usr/local/tomcat/webapps # 指定工作目錄,工作目錄指的是進入容器後,默認進入的目錄,不存在則自動創建
# dockerfile需要和docker-web放在同級文件夾中,拷貝到容器中的路徑,基於工作目錄,移動的目錄不存在則自動創建
ADD docker-web ./docker-web # 拷貝文件docker-web,到該鏡像的指定目錄下。

在我們項目根目錄執行:docker build -tag myweb:1.0 .

  • dockerfile文件放在項目根目錄下
  • -t 參數後指定機構,應用名稱。 . 表示dockerfile文件就在當前文件夾下,相對路徑
 ~/test/ docker build --tag myweb:1.0 .
Sending build context to Docker daemon  3.584kB
Step 1/4 : FROM tomcat:latest
 ---> 891fcd9c5b3a
Step 2/4 : MAINTAINER darope.163.com
 ---> Running in fa753d5d868c
Removing intermediate container fa753d5d868c
 ---> fc43dedb3ad5
Step 3/4 : WORKDIR /usr/local/tomcat/webapps
 ---> Running in 98d448195ab1
Removing intermediate container 98d448195ab1
 ---> c876f3ed91ef
Step 4/4 : ADD docker-web ./docker-web
 ---> bf912fc6c119
Successfully built bf912fc6c119
Successfully tagged myweb:1.0
 ~/test/ docker images
REPOSITORY          TAG                 IMAGE ID            CREATED             SIZE
myweb               1.0                 bf912fc6c119        57 seconds ago      647MB
tomcat              latest              891fcd9c5b3a        8 days ago          647MB
 ~/test/ ls
Dockerfile docker-web
 ~/test/ docker run -p 8000:8080 -d bf912fc6c119
26c97c083e429ab30aa25aec3ad2ebe92a3dfbf62b891820a60237625125b1eb
 ~/test/ docker ps
CONTAINER ID        IMAGE               COMMAND             CREATED             STATUS              PORTS                    NAMES
26c97c083e42        bf912fc6c119        "catalina.sh run"   5 seconds ago       Up 5 seconds        0.0.0.0:8000->8080/tcp   loving_pasteur
 ~/test/ docker exec -it 26c97c083e42 sh
# pwd
/usr/local/tomcat/webapps
# ls
docker-web
# cd docker-web
# ls
index.html
#

訪問127.0.0.1:8000/docker-web/index.html可以看到'hello',成功部署

5.2 鏡像分層(layer)的概念

在我們dockerfile文件中,每一行指令build過程中都對應一個分層,所以,在能完成我們的構建要求的情況下,命令行數越簡潔,越少行數越好。

上文中,構建的dockerfile爲四條命令,對應的構建鏡像爲4層

FROM tomcat:latest 
MAINTAINER darope.163.com 
WORKDIR /usr/local/tomcat/webapps 
ADD docker-web ./docker-web
 ~/test/ docker build --tag myweb:1.0 .
Sending build context to Docker daemon  3.584kB
Step 1/4 : FROM tomcat:latest
 ---> 891fcd9c5b3a
Step 2/4 : MAINTAINER darope.163.com
 ---> Running in fa753d5d868c
Removing intermediate container fa753d5d868c
 ---> fc43dedb3ad5
Step 3/4 : WORKDIR /usr/local/tomcat/webapps
 ---> Running in 98d448195ab1
Removing intermediate container 98d448195ab1
 ---> c876f3ed91ef
Step 4/4 : ADD docker-web ./docker-web
 ---> bf912fc6c119
Successfully built bf912fc6c119
Successfully tagged myweb:1.0

構建過程中,每一層會產生一個臨時只讀容器id,臨時容器只會用於鏡像的構建。例如上面的每一層的 ---> 891fcd9c5b3a。臨時容器相當於每一層,對當前系統做一份快照。整個過程類似於千層餅。

在以後構建其他應用的時候,如果該應用有相同的快照,不會重新拉去,而是使用系統已經形成的快照。系統沒有的快照再形成新的快照保存到系統中。從而達到快速構建,不重複構建,節省系統資源的效果。

5.3 dockerfile命令

5.3.1 基礎指令

  • 1、FROM - 基於基準鏡像
FROM centos  #製作基準鏡像(基於centos:lastest)

FROM scratch   #不依賴任何基準鏡像base image

FROM tomcat: 9.0.22-jdk8-openjdk

儘量使用官方提供的Base Image,防止其他第三方鏡像存在漏洞和後門。

  • 2、LABEL & MAINTAINER - 說明信息
MAINTAINER [email protected]  # 常用來表示該docker鏡像是哪個個人或者機構維護的

# 常用來描述構建過程中關鍵信息,只是描述,不會影響任何構建功能。爲程序維護帶來便利。類似於Java中的註釋
LABEL version = "1.0"   

LABEL description = "hahaha"
  • 3、WORKDIR - 設置工作目錄
WORKDIR /usr/local
WORKDIR /usr/local/newdir #不存在該目錄會自動創建

和linux中的cd命令非常相似,儘量使用絕對路徑

  • 4、ADD & COPY - 複製文件
ADD hello / #將hello文件複製到容器的根路徑下
ADD test.tar.gz / #添加到根目錄並解壓
ADD 除了複製,還具備添加遠程文件功能。實際項目中很少使用

ADD 複製並且解壓,COPY單純複製。大多數情況可以互相替換

  • 5、ENV - 設置環境常量
ENV JAVA_HOME /usr/local/openjdk8 #用環境常量JAVA_HOME指代/usr/local/openjdk8
RUN ${JAVA_HOME}/bin/java -jar test.jar #用${JAVA_HOME}標識,獲取環境常量JAVA_HOME

儘量使用環境常量,可提高程序維護性

  • 6、EXPOSE - 暴露容器端口

將容器內部端口暴露給物理機,從而可以使得物理機端口和暴露給物理機的容器端口做映射

EXPOSE 8080
docker run -p 8000:8080 tomcat

5.3.2 dockerfile中的執行指令

RUN & CMD & ENTRYPOINT

三個執行命令本質是執行時機不同

RUN  : 在Build構建時執行命令
ENTRYPOINT : 容器啓動時執行的命令
CMD : 容器啓動後執行默認的命令或參數

RUN : 是在構建鏡像過程中(docker build),對鏡像內部的文件及資源做相應調整。一旦鏡像被創建成功,鏡像就是隻讀的,不允許再修改

ENTRYPOINT和CMD是在容器創建時(docker run)對容器內執行的命令

  • 1、RUN-構建時運行

RUN命令有兩種運行格式,一種是shell命令格式,一種是Exec命令格式

如果不清楚該用哪種方式,推薦使用Exec方式執行命令,參考官方鏡像的構建

RUN yum install -y vim  #Shell 命令格式
RUN ["yum","install","-y","vim"] #Exec命令格式

Shell運行方式

使用Shell執行時,當前shell是父進程,生成一個子shell進程

在子shell中執行腳本。腳本執行完畢,退出子shell,回到當前shell。

Exec運行方式

使用Exec方式,會用Exec進程替換當前進程,並且保持PID不變

執行完畢,直接退出,並不會退回之前的進程環境

  • 2、ENTRYPOINT啓動命令

Dockerfile中只有最後一個ENTRYPOINT會被執行

ENTRYPOINT(入口點)用於在容器啓動時執行命令
ENTRYPOINT ["ps"] #推薦使用Exec格式
  • 3、CMD默認命令

CMD用於設置默認執行的命令,如Dockerfile中出現多個CMD,則只有最後一個被執行。如容器啓動時附加指令,則CMD被忽略

CMD ["ps" , "-ef"] #推薦使用Exec格式

ENTRYPOINT和CMD的區別:兩者非常相似,區別在於,ENTRYPOINT一定會被執行,且只會執行dockerfile中最後一個ENTRYPOINT。而CMD不一定會被執行,如果容器啓動時附加了命令,則CMD命令會被覆蓋,如果容器啓動時沒有附加命令,則CMD也是隻會dockerfile中的最後一個CMD命令

編寫測試Dockerfile文件

 ~/ cd opt/docker_run
 ~/opt/docker_run/ ls
Dockerfile
 ~/opt/docker_run/ cat Dockerfile
FROM centos
RUN ["echo", "image building..."]
CMD ["echo","container start..."]
 ~/opt/docker_run/

構建鏡像測試

 ~/opt/docker_run/ docker build --tag docker_run .
Sending build context to Docker daemon  2.048kB
Step 1/3 : FROM centos
 ---> 0d120b6ccaa8
Step 2/3 : RUN ["echo", "image building..."]
 ---> Running in 7490a32995d4
image building...
Removing intermediate container 7490a32995d4
 ---> 31c5d825a261
Step 3/3 : CMD ["echo","container start..."]
 ---> Running in c6d25a6895aa
Removing intermediate container c6d25a6895aa
 ---> ed5e36a3fcbd
Successfully built ed5e36a3fcbd
Successfully tagged docker_run:latest
 ~/opt/docker_run/

可以觀察到,RUN命令在構建過程中已經執行打印了image building....。而CMD命令是在容器啓動的時候纔會運行,所在在構建過程中並沒有執行打印。通過該鏡像啓動容器,可以看到CMD命令的打印內容。

 ~/opt/docker_run/ docker run docker_run
container start...
 ~/opt/docker_run/

在我們運行容器的時候,如果增加了命令,那麼默認的最後CMD命令,不會被執行。

 ~/opt/docker_run/ docker run docker_run ls
bin
dev
etc
home
lib
lib64
lost+found
media
mnt
opt
proc
root
run
sbin
srv
sys
tmp
usr
var
 ~/opt/docker_run/

如果我們把Dockerfile中的CMD換作ENTRYPOINT,無論運行容器加不加指令,ENTRYPOINT都會執行,這裏不再演示。

  • 4、CMD和ENTRYPOINT組合使用

例如我們把Dockerfile更改如下,再構建運行容器

FROM centos
RUN ["echo", "image building..."]
ENTRYPOINT ["ps"]
CMD ["-ef"]

可以看到

 ~/opt/docker_run/ docker run docker_run
UID        PID  PPID  C STIME TTY          TIME CMD
root         1     0  0 16:16 ?        00:00:00 ps -ef
 ~/opt/docker_run/

運行時傳參,覆蓋CMD命令後

 ~/opt/docker_run/ docker run docker_run -aux
USER       PID %CPU %MEM    VSZ   RSS TTY      STAT START   TIME COMMAND
root         1  0.0  0.1  47508  3556 ?        Rs   16:19   0:00 ps -aux
 ~/opt/docker_run/

CMD命令可以通過外界傳參,組合使用會有意想不到的結果

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章