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的镜像个容器

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/users@tomcat.apache.org/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 stop和docker kill会对处在运行状态的容器执行die事件,让其回到停止运行的状态。kill会杀掉容器进程,而stop只会停止容器,不会杀死进程。区别:重新docker start该容器,被kill掉的容器会令启进程,stop掉的容器会恢复进程
  • docker restart会把当前容器die,再start再restart重新回到运行状态
  • 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 darope@163.com  # 常用来表示该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命令可以通过外界传参,组合使用会有意想不到的结果

Docker知识总结的更多相关文章

  1. Docker知识-1

    [编者的话]本文用图文并茂的方式介绍了容器.镜像的区别和Docker每个命令后面的技术细节,能够很好的帮助读者深入理解Docker. 这篇文章希望能够帮助读者深入理解Docker的命令,还有容器(co ...

  2. Docker知识进阶与容器编排技术

    目录 1 使用Dockerfile定制redis镜像 1.1 环境准备 1.2 编写Dockerfile文件 1.3 通过Dockerfile构建镜像 1.4 通过镜像运行容器 1.5 官方镜像替代我 ...

  3. 认识大明星——轻量级容器docker知识树点亮

    docker是一个轻量级容器,属于操作系统层面的虚拟化技术,封装了文件系统(AUFS)以及网络互联,进程隔离等特性. 传统虚拟化架构: docker虚拟化架构: 可以看出,docker是没有Guest ...

  4. docker知识复习

    1.镜像基于内容寻址 基于内容寻址的实现,使用了两个目录:/var/lib/docker/image和/var/lib/docker/overlay, 后面的这个根据存储驱动的名称不同,而目录名不同. ...

  5. Docker 使用Docker知识简易部署一个LNMP平台

    1.自定义网络 docker network create lnmp 2.创建Mysql数据库容器(这里我们首先得创建一个mysql-vol数据卷) docker volume create mysq ...

  6. 讲给测试人员的docker知识

    docker对测试来说有什么用 docker类似于Windows系统的虚拟机,对于测试来说docker意味着一种新的测试环境部署方式,由于其镜像分层的设置,我们可以在一台物理机上同过docker的方式 ...

  7. Docker 核心知识回顾

    Docker 核心知识回顾 最近公司为了提高项目治理能力.提升开发效率,将之前的CICD项目扩展成devops进行项目管理.开发人员需要对自己的负责的项目进行流水线的部署,包括写Dockerfile ...

  8. 使用Docker在本地搭建Hadoop分布式集群

    学习Hadoop集群环境搭建是Hadoop入门必经之路.搭建分布式集群通常有两个办法: 要么找多台机器来部署(常常找不到机器) 或者在本地开多个虚拟机(开销很大,对宿主机器性能要求高,光是安装多个虚拟 ...

  9. 容器化-Docker实战

    导读:本文系统性介绍Docker安装.Docker组件.Docker命令.Dockerfile语法和Docker应用,通过上述介绍使我们已经对docker基本操作有一定了解. 一.前言 本文将系统性的 ...

随机推荐

  1. yum 安装提示公钥安装失败,Public key for .x86_64.rpm is not instal 手动导入公钥方案

    Linux 中yum 安装google-chrome-stable时,报错如下,提示公钥安装失败,原因是 GPG公钥获取失败,无法连接获取到 https://dl-ssl.google.com/lin ...

  2. k8s架构分析(二)

    master节点 k8s的集群由master和node组成,节点上运行着若干k8s服务. master节点之上运行着的后台服务有kube-apiserver .kube-scheduler.kube- ...

  3. kolla部署openstack多节点高可用并对接ceph后端存储(17)

    部署节点执行: 安装基础包和docker yum install python-devel libffi-devel gcc openssl-devel git python-pip -y 升级一下 ...

  4. AtomicInteger原理&源码分析

    转自https://www.cnblogs.com/rever/p/8215743.html 深入解析Java AtomicInteger原子类型 在进行并发编程的时候我们需要确保程序在被多个线程并发 ...

  5. 说说我对 WSGI 的理解

    先说下 WSGI 的表面意思,Web Server Gateway Interface 的缩写,即 Web 服务器网关接口. 之前不知道 WSGI 意思的伙伴,看了上面的解释后,我估计也还是不清楚,所 ...

  6. Mac使用Charles给iPhone抓包流程

    目录 需求 步骤 1. Mac打开共享Wifi 2. iPhone连接刚刚的WIFI 3. 找到Mac的局域网ip 4. 配置代理 需求 有时候手机接口出问题了,不知道从哪里下手,Charles就是非 ...

  7. 01.vue数据绑定

    Vue特点 渐进式: 渐进, 可以理解成一步一步的. 在使用Vue的时候, 我们不需要把整个Vue框架的东西都用上, 可以一步一步的根据需要慢慢的替换之前的代码. 自底向上逐层应用: 由底层开始, 把 ...

  8. 【Java并发编程】面试常考的ThreadLocal,超详细源码学习

    目录 ThreadLocal是啥?用来干啥? ThreadLocal的简单使用 ThreadLocal的实现思路? ThreadLocal常见方法源码分析 ThreadLocal.set(T valu ...

  9. 消息队列MQ面试专题(rabbitmq)

    正文: 1.什么是 rabbitmq 采用 AMQP 高级消息队列协议的一种消息队列技术,最大的特点就是消费并不需要确保提供方存在,实现了服务之间的高度解耦 2.为什么要使用 rabbitmq 在分布 ...

  10. 【Python】数字与运算符

    数据类型与运算符 数字 / 浮点除 // 整数除 ** 乘方 多种混合类型运算数的运算会把整数转换为浮点数 除了 int 和 float,Python也支持其他类型的数字,例如 Decimal 或者 ...