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 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 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. Book of Shaders 02 - 矩阵:二维仿射变换练习

    0x00 一些废话 如果要深入学习 CG (Computer Graphics,计算机图形学),必然要学习相关的数学知识.CG 涉及到多个不同的领域,根据所研究领域的不同,也会涉及到不同的数学分支.但 ...

  2. netty之handler write

    转载自:https://blog.csdn.net/FishSeeker/article/details/78447684 实验过,例如channle的handler里有很多个outhandler,在 ...

  3. 使用spring mvc拦截器 会话失效处理

    import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import ...

  4. minium-微信小程序自动化框架-python,官方文档

    minium文档 个人将其部署到了自己的服务器上,如有需要可以访问共同学习这个minium 用python来实现小程序自动化测试... 文档地址 http://49.232.203.244:3000/ ...

  5. python语言概述

    python语言的发展 python语言诞生于1990年,由Guide van Rossum设计并领导开发. python语言是开源项目的优秀代表,其解释器的全部代码都是开源的. 编写Hello程序 ...

  6. golang开发:select多路选择

    select 是 Golang 中的一个控制结构,语法上类似于switch 语句,只不过select是用于 goroutine 间通信的 ,每个 case 必须是一个通信操作,要么是发送要么是接收,s ...

  7. hadoop分布式格式化时出现异常java.net.unknownhostexception

    当搭建好分布式集群后,准备使用命令格式化时 hdfs namenode format 在日志的最后一行出现 java.net.unknownhostexception的异常,通常是你的主机名没有配置好 ...

  8. 在Linux系统下搭建和配置一个minio文件服务器(一)

    1.minio文件服务器的介绍 Minio 是一个基于Go语言的对象存储服务.它实现了大部分亚马逊S3云存储服务接口,可以看做是是S3的开源版本,非常适合于存储大容量非结构化的数据,例如图片.视频.日 ...

  9. WPF启动流程-自己手写Main函数

    WPF一般默认提供一个MainWindow窗体,并在App.Xaml中使用StartupUri标记启动该窗体.以下通过手写实现WPF的启动. 首先先介绍一下VS默认提供的App.Xaml的结构,如下图 ...

  10. AngularJS 路由和模板实例及路由地址简化方法

    最近一同事在学习AngularJS,在路由与模板的学习过程中遇到了一些问题,于是今天给她写了个例子,顺便分享出来给那些正在学习AngularJS的小伙伴们. 话说这AngularJs 开发项目非常的爽 ...