Docke--Dockerfile指令介绍
Dockerfile 构建镜像常用指令
Dockerfile 是一个文本文件,其内包含了一条条的指定(Instruction),每一条指令构建一层,因此每一条指定的内容,就是描述该层应当如何构建。
通过使用build 命令,根据Dockerfile的描述来构建镜像
通过源代码的方式
通过标准输入流的方式
通过源代码的路径:
Dockerfile需要放置在项目的跟目录位置
在构建的时候,Dockerfile client会把整个context打包发送到Docker Server端,然后由server端负责build镜像,在构建成功后,会删除context目录
docker build -t {镜像名字} {项目的路径可以是相对路径}
通过标准输入流:
通过标准输入流的方式获取Dockerfile的内容
client不会打包上传context目录,因此对于一些ADD、COPY等涉及host本地文件复制的操作不能够支持
docker build -t {镜像名字} - < Dockerfile路径
已nginx 示例:
[root@server ~]# mkdir myNginx #创建一个存放Dockerfile的目录
[root@server ~]# cd myNginx
[root@server myNginx]# vim Dockerfile #编辑Dockerfile
FROM nginx
RUN echo '<h1>Hello, My Dockerfile Nginx!</h1>' > /usr/share/nginx/html/index.html
这个Dockerfile很简单,就两行。涉及到两条指令,FROM 和RUN。
FROM 指定基础镜像
所谓的定制镜像,必须是以一个镜像为基础,在其上进行定制。一个 Dockerfile 中的 FROM 是必备的指定,并且必须是第一条指令。
FROM {bash镜像}
RUN 执行命令
RUN 指令是用来执行命令行命令的,一个Dockerfile可以包含多个 RUN,按照定义顺序执行。
RUN 支持两种运行格式:
- shell 格式:RUN <cmd>,这个会当做/bin/sh -c “cmd” 运行,就像直接在命令行中输入的命令一样。比如上面的:
RUN echo '<h1>Hello, My Dockerfile Nginx!</h1>' > /usr/share/nginx/html/index.html
exec 格式:RUN ["可执行文件", "参数1", "参数2", ...],Docker 把它当做json的顺序来解析,必须使用双引号,且可执行文件必须是完整路径。
RUN 就像Shell脚本一样可以执行命令,但是也不建议一个命令对应一个RUN,像下面这样的写法
FROM centos
RUN yum install -y gcc make cmake
RUN wget -O redis.tar.gz "http://download.redis.io/releases/redis-3.2.5.tar.gz"
RUN mkdir -p /usr/src/redis
RUN tar xf redis.tar.gz -C /usr/src/redis --stript-components=
RUN cd /usr/src/redis
RUN make
RUN make install
因为Dockerfile 中的每一个指令都会建立一层,RUN 也不例外,每一个RUN 的行为,就和我们手工创建景象的过程一样,新建一层,上面的这种写法创建了7层,这样会产生非常臃肿、非常多层的镜像,不仅仅增加了构建部署的时间,也容易出错。上面的Dockerfile正确写法应该如下:
FROM centos
RUN yum install -y gcc make cmake \
&& wget -O redis.tar.gz "http://download.redis.io/releases/redi s-3.2.5.tar.gz" \
&& mkdir -p /usr/src/redis \
&& tar xf redis.tar.gz -C /usr/src/redis --stript-components= \
&& cd /usr/src/redis \
&& make \
&& make install
首先,之前所有的命令只有一个目的,就是编译、安装redis 可执行文件。因此没有必要建立很多层,这只是一层的事情。因此 只需要使用一个RUN 指令,使用&& 将各个所需命令串联起来。将前面的7层简化为1层。
COPY 复制文件
格式:
- COPY <源路径> ... <目标路径>
- COPY ["<源路径1>", ... "<目标路径>"]
和 RUN 指令一样,也有两种格式,一种类似于命令行,一种类似于函数调用。
COPY 指令将从构建上下文目录中 <源路径> 的文件/目录复制到新的一层的镜像内的 <目标路径> 位置。例如:
[root@server ~]# mkdir myCentos #创建一个文件夹
[root@server ~]# cd myCentos/
[root@server myCentos]# echo "hello world" >> file.txt #准备测试文件
[root@server myCentos]# mkdir dir #准备测试目录
[root@server myCentos]# touch dir/test{..}.txt #准备测试目录里面的文件
[root@server myCentos]# vim Dockerfile #编辑Dockerfile
FROM centos
COPY file.txt /mydir/
COPY dir /mydir/
[root@server myCentos]# ls #查看宿主主机的当前的测试文件
dir Dockerfile file.txt
[root@server myCentos]# ls dir/ #查看宿主机的当前的测试文件
test1.txt test2.txt test3.txt test4.txt test5.txt
[root@server myCentos]# docker build -t mycentos:v1 . #构建一个叫mycentos,标签为v1的镜像
Sending build context to Docker daemon .144kB
Step / : FROM centos
---> 1e1148e4cc2c
Step / : COPY file.txt /mydir/
---> 16250be2483b
Step / : COPY dir /mydir/dir
---> 2296f62ff0b3
Successfully built 2296f62ff0b3
Successfully tagged mycentos:v1
[root@server myCentos]# docker run -it --rm --name myC mycentos:v1 /bin/bash #启动一个容器,使用上面创建的镜像,进去并执行shell命令
[root@cc87d839493f /]# ls mydir/ #查看容器内的mydir文件夹
dir file.txt
[root@cc87d839493f /]# ls mydir/dir/ #查看容器内mydir文件夹下面的dir文件夹的文件
test1.txt test2.txt test3.txt test4.txt test5.txt
从上面示例可以看出, <目标路径> 可以是容器内的相对路径,如果该路径不存在,会自动在复制文件前创建缺失目录,且<目标路径>也可以是相对路径(工作目录可以用WORKDIR 指令来指定)
如果是拷贝目录, 那么在 目标地址 也必须写上 拷贝的目录的名称 。否则是将该目录下的所文件拷贝到目标路径
还需注意一点,使用COPY指令,源文件的各种元数据都会保留,比如读、写、执行权限、文件变更时间等。这个特性对于镜像定制很有用。特别是构建相关的文件都在使用Git进行管理的时候。
ADD 更高级的复制文件
ADD 指令和COPY 的格式和性质基本一致。但是在 COPY 基础上增加了一些功能。
比如 <源路径> 可能是一个 URL,这种情况下,会自动去下载这个链接的文件到 <目标路径>里,下载完成的文件权限自动设置为 600,如果不是想要的权限,那么可以通过 RUN 进行权限调整。
如果 <源路径> 为一个 tar 压缩文件的话,或者压缩格式为 gzip,bzip以及xz 的情况下,ADD 指令会自动解压缩这个压缩文件到 <目标路径>去。
示例
[root@server ~]# mkdir myCentos1 && cd myCentos1 #创建构建编写Dockerfile的目录并进入
[root@server myCentos1]# wget http://nginx.org/download/nginx-1.14.2.tar.gz #方便测试,先准备一个nginx1.14-2版本的
[root@server myCentos1]# vim Dockerfile #编写Dockerfile
FROM centos
ADD http://nginx.org/download/nginx-1.12.2.tar.gz /nginx/
ADD nginx-1.14.2.tar.gz /nginx/
[root@server myCentos1]# ls #编写完成查看当前目录下的文件
Dockerfile nginx-1.14..tar.gz [root@server myCentos1]# docker build -t mycentos:v2 . #开始构建一个名字叫mycentos:v2的镜像
Sending build context to Docker daemon .018MB
Step / : FROM centos
---> 1e1148e4cc2c
Step / : ADD http://nginx.org/download/nginx-1.12.2.tar.gz /nginx/
Downloading [==================================================>] .7kB/.7kB
---> a1c9717e9a03
Step / : ADD nginx-1.14..tar.gz /nginx/
---> 068c9e89ae0e
Successfully built 068c9e89ae0e
Successfully tagged mycentos:v2
[root@server myCentos1]# docker run -it --rm --name myC mycentos:v2 /bin/bash #进入容器,并执行/bin/bash命令
[root@197da52295fa /]# ls /nginx/ #查看nginx目录
nginx-1.12..tar.gz nginx-1.14.
从上面示例可以看出,ADD指令,如果我们跟的是一个URL的文件,那么会自动下载并放到 <目标路径>,如果跟的是一个压缩文件,那么会自动解压到 <目标路径>
注意:如果我们只是单纯的想复制一个文件或者一个压缩包,那么建议还是使用COPY,如果需要像上面这样用到下载,或解压缩,采用ADD
CMD 容器启动命令
容器不是虚拟机,容器就是进程,既然是进程,那么在启动容器的时候,需要指定所运行的程序及参数。CMD 指令就是用于指定容器默认的主进程启动命令的。
CMD 指令有三种格式:
- shell 格式: CMD <命令>
- exec 格式:CMD ["可执行文件","参数1","参数2", ...]
- 参数列表格式:CMD ["参数1","参数2",...] , 这个时候CMD作为 ENTRYPOINT的参数。
在指令格式上,一般推荐使用exec 格式,这类格式在解析时会被解析为JSON数组,因此一定要使用双引号 “” ,而不要使用单引号。
如果使用shell 格式的话,实际的命令会被包装为 sh -c 的参数的形式进行执行。比如:
CMD echo $HOME
在实际执行中,会将其变更为:
CMD ["sh", "-c", "echo $HOME"]
在运行时可以指定新的命令来替代镜像设置中的这个默认命令,比如,centos镜像默认的 CMD 是 /bin/bash, 如果我们直接 docker run -it centos 的时候,会直接进入 bash。我们也可以在运行时指定别的命令,如 docker run -it centos cat /etc/passwd 。这就是用 cat /etc/passwd命令替换了默认的 /bin/bash 命令了。
前台执行和后台执行的问题:
Docker 不是虚拟机,容器中的应用都应该以前台执行,而不是像虚拟机、物理机里面那样,用 start / systemctl 去启动后台服务,容器内没有后台服务的概念。
比如:如果我们将CMD 写成这样:
CMD service nginx start
然后会发现容器执行后就立刻退出了,甚至在容器内使用systemctl 命令结果却发现根本执行不了。这就是因为没有搞明白前台、后台的概念,没有区分容器和虚拟机的差异,依旧在以传统虚拟机的角度去理解容器
对于容器而言,其启动程序就是容器应用进程,容器就是为了主进程而存在的,主进程退出,容器就失去了存在的意义,从而退出,其它辅助进程不是它需要关心的东西。
而使用 service nginx start 命令,则是希望 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 的格式和 RUN 指令格式一样,分为 exec 格式 和shell格式。
ENTRYPOINT 的目的和 CMD 一样,都是在指定容器启动程序及参数。ENTRYPOINT 在运行时也可以替代,不过比CMD要繁琐,需要通过 docker run 的参数 --entrypoint 来指定。
当指定了 ENTRYPOINT 后,CMD 的含义就发生了改变,不再是直接运行其命令,而是将 CMD 的内容作为参数传给 ENTRYPOINT 指令,换句话说实际执行时,将变为:
ENTRYPOINT "<CMD>"
那么问题来了? 有了CMD ,为什么还要有ENTRYPOINT呢? 这种 ENTRYPOINT "<CMD>" 有什么好处呢?
场景一:让镜像变成命令一样使用
假设我们需要一个得知自己当前公网IP的镜像,那么可以使用CMD来实现:
[root@server myCentos2]# cat Dockerfile #查看Dockerfile文件内容
FROM centos
CMD ["curl", "-s", "https://ip.cn"]
[root@server myCentos2]# docker build -t mycentos:v3 . #创建一个镜像
[root@server myCentos2]# docker run mycentos:v3 #启动一个容器
当前 IP: 116.24.66.227 来自: 广东省深圳市 电信
这样看起来是可以当做命令来使用,不过命令一般有参数,CMD 中实质的命令是 curl, 如果希望显示HTTP头信息,就需要加上 -i 参数。
[root@server myCentos2]# docker run mycentos:v3 -i
docker: Error response from daemon: OCI runtime create failed: container_linux.go:: starting container process caused "exec: \"-i\": executable file not found in $PATH": unknown.
这里可以看到可执行文件找不到的报错, executable file not found。上面说过,跟在镜像名后面的是 command, 运行时会替换 CMD 的默认值,因此这里的 -i 替换了原来的 CMD,而不是添加在原来的 curl -s https://ip.cn 后面,而 -i 根本不是命令,所以找不到。
那么如果我们希望加入 -i 参数,我们就必须重新完整的输入这个命令:
[root@server myCentos2]# docker run mycentos:v3 curl -i https://ip.cn
显然这不是好的解决办法,而是用 ENTRYPOINT 就可以解决这个问题:
[root@server myCentos2]# cat Dockerfile #查看修改后的Dockerfile
FROM centos
ENTRYPOINT ["curl", "-s", "https://ip.cn"]
[root@server myCentos2]# docker build -t mycentos:v4 . #再次生成一个新的镜像
[root@server myCentos2]# docker run mycentos:v4 #测试不加参数启动镜像
当前 IP: 116.24.66.227 来自: 广东省深圳市 电信
[root@server myCentos2]# docker run mycentos:v4 -i #测试加上参数启动镜像
HTTP/1.1 OK
Date: Wed, Jan :: GMT
Content-Type: text/html; charset=UTF-
Transfer-Encoding: chunked
Connection: keep-alive
Set-Cookie: __cfduid=d67dbccf782da9ec6788bf87a78993a701547040189; expires=Thu, -Jan- :: GMT; path=/; domain=.ip.cn; HttpOnly
Expect-CT: max-age=, report-uri="https://report-uri.cloudflare.com/cdn-cgi/beacon/expect-ct"
Server: cloudflare
CF-RAY: 49673780decb961f-SJC 当前 IP: 116.24.66.227 来自: 广东省深圳市 电信
从上面可以看出,不加-i 参数可以运行成功, 加上-i参数也可以运行成功,且达到了curl -i 的效果。这是因为当存在 ENTRYPOINT 后,CMD 的内容将会作为参数传递给 ENTRYPOINT ,而这里 -i 就是新的CMD,因此会作为参数传递给curl,从而达到了我们预期的效果。
场景二:应用运行前的准备工作
启动容器就是启动主进程,但有些时候,启动主进程前,需要一些准备工作。比如 mysql 类的数据库,可能需要一些数据库配置、初始化的工作,这些工作要在最终的mysql 服务器运行之前解决。此外,可能希望避免使用root 用户去启动服务器, 从而提高安全性,而在启动还需要以 root 身份执行一些必要的准备工作,最后切换到服务用户启动服务等。或者除了服务外,其它命令依旧可以使用 root 身份执行,方便调试等。
这些准备工作是和容器 CMD 无关的,无论CMD 是什么,都需要事先进行一个预处理的工作。这种情况下,可以写一个脚本,然后放入 ENTRYPOINT 中去执行,而这个脚本会接到的参数 (也就是CMD)作为指令,在脚本最后执行。比如官方的redis 中就是这样做的:
FROM alpine:3.4
...
RUN addgroup -S redis && adduser -S -G redis redis
...
ENTRYPOINT ["docker-entrypoint.sh"]
EXPOSE
CMD ["redis-server"]
可以看到其中为了 redis 服务创建了redis 用户,并在最后指定了 ENTRYPOINT 为 docker-entrypoint.sh 脚本。
#!/bin/bash
...
# allow the container to be started with `--user`
if [ "$1" = 'redis-server' -a "$(id -u)" = '' ]; then
chown -R redis .
exec su-exec redis "$0" "$@"
fi exec "$@"
该脚本的内容就是根据 CMD 的内容来判断,如果是 redis-server 的话,则切换到 redis用户身份启动服务,否则依旧使用 root 身份执行。比如:
# docker run -it redis id
uid=(root) gid=(root) groups=(root)
ENV 设置环境变量
格式:
- ENV <key><value>
- ENV<key1>=<value1> <key2>=<value2>
这个指令很简单,就是设置环境变量,无论是后面的其它指令,如RUN,还是运行时的应用,都可以直接使用这里定义的环境变量。
[root@server myCentos3]# cat Dockerfile #查看编辑好的Dockerfile文件内容
FROM centos
ENV name1 xiaobai
ENV name2=zhazha name3=cainiao
[root@server myCentos3]# docker build -t mycentos:v5 . #构建镜像
[root@server myCentos3]# docker run --rm -it --name test mycentos:v5 #启动一个容器,并以交互式启动
[root@b55929b2c63f /]# echo $name1 #进入容器后调用环境变量name1
xiaobai
[root@b55929b2c63f /]# echo $name2 $name3 #调用环境变量name2,name3
zhazha cainiao
定义了环境变量,可以在后续的指令中直接使用环境变量
FROM centos
ENV URL="https://nginx.org/download/"
ADD $URLnginx.1.12..tar.gz /usr/local/
ARG 构建参数
格式:
- ARG <参数名>[=<默认值>]
构建参数和 ENV的效果一样,都是设置环境变量。所不同的是,ARG 所设置的构建环境和环境变量,在将来容器运行时是不会存在这些环境变量的。但是不要因此就使用 ARG 保存密码之类的信息,因为 docker history 还是可以看到所有值的。
Dockerfile 中的ARG指令是定义参数名称,以及定义其默认值。该默认值可以在构建命令 docker build 中用 --build-arg <参数名>=<值> 来覆盖。
VOLUME 定义匿名卷
格式:
- VOLUME ["<路径1>","<路径2>"...]
- VOLUME <路径>
容器运行时应该尽量保持容器存储层不会发生写操作,对于数据库类需要保存动态数据的应用,其数据文件应该保存在数据卷中,为了防止运行时忘记将动态文件所保存目录挂载为卷,在Dockerfile中,可以事先指定某些目录挂载为匿名卷,这样在运行时如果用户不指定挂载,其应用也可以正常运行,不会向容器存储层写入大量数据。
[root@server myCentos4]# cat Dockerfile #编写Dockerfile文件,内容如下
FROM nginx
VOLUME /usr/share/nginx/html/
[root@server myCentos4]# docker build -t mynginx:v1 . #创建一个mynginx:v1的镜像
[root@server myCentos4]# docker run -it --rm --name nginx mynginx:v1 /bin/bash #利用mynginx:v1镜像启动一个名字叫做nginx的容器
root@eaa3ffb6dda7:/# ls /usr/share/nginx/html/ #查看nginx网站目录的文件
50x.html index.html # 此时打开第二个终端,第一个终端不要关闭
[root@server ~]# docker inspect nginx #在第二个终端查看启动的nginx 容器挂载信息,会发现在宿主机上面自动挂载到了一个目录
"Mounts": [
...
"Source": "/var/lib/docker/volumes/47794aa178f1aa829d8e778f319a6bb678349926a8107f459fcb10d3b00ff8b5/_data",
...
],
[root@server ~]# ls /var/lib/docker/volumes/47794aa178f1aa829d8e778f319a6bb678349926a8107f459fcb10d3b00ff8b5/_data #查看挂载的目录,和容器中的目录一样,有同样的文件
50x.html index.html
[root@server ~]# echo "<h1>hello docker</h1>" >> /var/lib/docker/volumes/47794aa178f1aa829d8e778f319a6bb678349926a8107f459fcb10d3b00ff8b5/_data/test.html #在该目录添加文件 # 此时回到nginx容器启动的第一个终端
root@eaa3ffb6dda7:/# ls /usr/share/nginx/html/ #再次查看该目录会发现也有上面新添加的文件
50x.html index.html test.html
root@eaa3ffb6dda7:/# cat /usr/share/nginx/html/test.html #并且查看文件内容
<h1>hello docker</h1>
从上面可以看出,实际Dockerfile中只做了一件事,那就是将nginx网站目录挂载到了一个宿主机的一个匿名目录,且通过 docker inspect可以找到该目录,这样就实现了动态的更改网站数据目录的内容了。从而提高了灵活性。
同样还可以在运行容器的时候指定挂载:
[root@server myCentos4]# docker run -it --rm -v mydata:/usr/share/nginx/html/ --name nginx mynginx:v1 /bin/bash #指定挂载的目录启动容器
root@f5c496cc9846:/# # 打开第二个终端查看挂载目录
[root@server ~]# docker inspect nginx #查看挂载信息
"Mounts": [
...
"Source": "/var/lib/docker/volumes/mydata/_data",
"Destination": "/usr/share/nginx/html",
...
],
这样 使用了 mydata 这个命令卷挂载到了/usr/share/nginx/html 这个位置,替代了Dockerfile 中定义的匿名卷的挂载配置
EXPOSE 声明端口
格式:
- EXPOSE <端口1> [<端口2>...]
EXPOSE 指令是声明运行容器时提供的服务端口,这只是一个声明,在运行时并不会因为这个声明就会开启这个端口的服务。在Dockerfile中写入这样的声明有两个好处,一个是帮助使用镜像者理解这个镜像服务的守护端口,以方便配置映射;另一个用处则是在运行时使用随机端口映射时,也就是 docker run -P 时,会自动随机映射EXPOSE的端口。
WORKDIR 指定工作目录
格式:
- WORKDIR <工作目录路径>
使用 WORKDIR 指令可以来制定工作目录(或者称为当前目录),以后各层的当前目录就被改为指定的目录,如该目录不存在,则会自动创建。
可以为RUN、CMD、ENTRYPOINT指令配置工作目录,可以使用多个WORKDIR指令,后续参数如果是相对路径,则会基于之前的命令指定的路径。如:WORKDIR /home WORKDIR test。最终路径为/home/test。path路径也可以是环境变量,比如有环境变量HOME=/home, WORKDIR $HOME/test也就是/home/test
[root@server myCentos5]# cat Dockerfile #查看编辑好的Dockerfile文件
FROM centos
WORKDIR /home/testdir
[root@server myCentos5]# docker build -t mycentos:v6 . #创建一个名字叫做mycentos:v6的镜像
[root@server myCentos5]# docker run --rm -it mycentos:v6 #使用上面创建的镜像启动一个容器
[root@4f7ae938d471 testdir]# pwd #进入容器后查看当前工作目录
/home/testdir
USER 指定当前用户
格式:
- USER <用户名>
USER 和WORKDIR 相似,都是改变环境状态并影响以后的层。WORKDIR是改变工作目录,USER 则是指定运行容器时的用户名或UID,后续的RUN、CMD、ENTRYPOINT 也会已该用户身份去运行命令。
当然,USER 只是能够切换到指定用户而已,这个用户必须事先建立好,否则无法切换。
RUN groupadd -r redis && useradd -r -g redis redis
USER redis
RUN ["redis-server"]
HEALTHCHECK 健康检查
格式:
- HEALTHCHECK [选项] CMD <命令>:设置检查容器健康的命令
- HEALTHCHECK NONE:如果基础镜像有健康检查指令,使用这行可以屏蔽掉其健康检查指令
HEALTHCHECK 指令是告诉Docker 应该如何进行判断容器的状态是否正常
当在一个镜像指定了 HEALTHCHECK 指令后,用其启动容器,初始状态会为 starting,在HEALTHCHECK 指令检查成功后变为healthy, 如果连续一定次数失败,则变为 unhealthy。
HEALTHCHECK 支持下列选项:
- --interval=<间隔>:两次健康检查的间隔,默认为30秒;
- --timeout=<时长>:健康检查命令运行超时时间,如果超过这个时间,本次健康检查就被视为失败,默认30秒;
- --retries=<次数>:当连续失败指定次数后,则将容器状态视为unhealthy,默认3次。
和CMD, ENTRYPOINT 一样,HEALTHCHECK 只可以出现一次,如果写了多个,只有最后一个生效。
在HEALTHCHECK [选项] CMD 后面的命令,格式和 ENTRYPOINT 一样,分为 shell 格式,和 exec 格式。命令的返回值决定了该次健康检查的成功与 否:0:成功; 1 :失败; 2 :保留,不要使用这个值。
假设我们有个镜像是个最简单的 Web 服务,我们希望增加健康检查来判断其 Web 服务是否在正常工作,我们可以用 curl 来帮助判断,其 Dockerfile 的 HEALTHCHECK可以这样写:
[root@server myNginx1]# cat Dockerfile
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
[root@server myNginx1]# docker build -t mynginx:v2 .
[root@server myNginx1]# docker run -d --name web -p 80:80 mynginx:v2
这里设置了每5秒检查一次(这里为了测试所以间隔非常短,实际应该相对较长),如果健康检查命令超过3秒没响应就视为失败,并且使用 curl -fs http://localhost/ || exit 1 作为健康检查命令。
当运行改镜像启动的容器后,可以通过 docker ps 看到最初的状态为(health:starting):
[root@server myNginx1]# docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
fb9c72f7a6de mynginx:v2 "nginx -g 'daemon of…" seconds ago Up seconds (health: starting) 0.0.0.0:->/tcp web
再等待几秒钟后,再次 docker ps,就会看到健康检查状态变成了 (healthy):
[root@server myNginx1]# docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
fb9c72f7a6de mynginx:v2 "nginx -g 'daemon of…" seconds ago Up seconds (healthy) 0.0.0.0:->/tcp web
如果健康检查连续失败超过了重试次数,状态就会变为 (unhealthy)。
Docke--Dockerfile指令介绍的更多相关文章
- Docker学习(三): Dockerfile指令介绍
特别声明: 博文主要是学习过程中的知识整理,以便之后的查阅回顾.部分内容来源于网络(如有摘录未标注请指出).内容如有差错,也欢迎指正! =============系列文章============= 1 ...
- docker之Dockerfile指令介绍
Docker通过对于在Dockerfile中的一系列指令的顺序解析实现自动的image的构建 通过使用build命令,根据Dockerfiel的描述来构建镜像 通过源代码路径的方式 通过标准输入流的方 ...
- Dockerfile指令介绍
FROM:指定基础镜像 在Dockerfile中FROM是必备的指令,用于指定基础的镜像. FROM centos:latest LABEL:指定镜像标签 LABEL指令用来指定镜像的标签. 格式: ...
- docker(8)Dockerfile指令介绍
前言 Dockerfile 是一个用来构建镜像的文本文件,文本内容包含了一条条构建镜像所需的指令和说明. Dockerfile简介 Dockerfile是用来构建Docker镜像的构建文件,是由一系列 ...
- docker学习笔记17:Dockerfile 指令 ONBUILD介绍
ONBUILD指令可以为镜像添加触发器.其参数是任意一个Dockerfile 指令. 当我们在一个Dockerfile文件中加上ONBUILD指令,该指令对利用该Dockerfile构建镜像(比如为A ...
- Docker(二):Dockerfile 使用介绍
上一篇文章Docker(一):Docker入门教程介绍了 Docker 基本概念,其中镜像.容器和 Dockerfile .我们使用 Dockerfile 定义镜像,依赖镜像来运行容器,因此 Dock ...
- Docker(二):Dockerfile使用介绍
上一篇文章Docker(一):Docker入门教程介绍了 Docker 基本概念,其中镜像.容器和 Dockerfile .我们使用 Dockerfile 定义镜像,依赖镜像来运行容器,因此 Dock ...
- Docker应用三:Dockerfile使用介绍(以安装redis为例)
Dockerfile使用介绍 一.Dockerfile介绍 Dockerfile用于自定义创建docker镜像,是由一行行命令组成的文件. Docker file中的命令根据作用分为四类: 1.1.指 ...
- C#中的预编译指令介绍
原文:C#中的预编译指令介绍 1.#define和#undef 用法: #define DEBUG #undef DEBUG #define告诉编译器,我定义了一个DEBUG的一个符号,他类似一个变量 ...
- corosync+pacemaker的crmsh的常用指令介绍
配置crmsh的yum仓库,此仓库的RPM包有openSUSE提供,将这个network:ha-clustering:Stable.repo文件直接下载到本地并且命名为crmsh.repo wget ...
随机推荐
- vue的组件化运用(数据在两个组件互传,小问题总结)
一.vue的组件化应用 首先,知道有哪些相关的属性需要用到,再慢慢去理解,运用. 1.两个vue页面 2. slot占位符(可用可不用) 3.props内置属性 4.watch监听函数 5.impor ...
- HTML导出excel
在博客园找到的相关问题http://q.cnblogs.com/q/12952 还有相关的回答http://www.cnblogs.com/zhouxin/archive/2009/12/11/16 ...
- 自托管websocket和webapi部署云服务器域名及远程访问
当写完websocket和webapi服务端时,在本地测试时是没有问题的,因为是通过本地IP及端口号访问(例:127.0.0.1:8080\api\test),也就没有防火墙等安全限制,但当部署到云服 ...
- SQL Server数据库————模糊查询和聚合函数
***********模糊查询*********/ 关键字: like (!!!!字符串类型) in (,,) 匹配()内的某个具体值(括号里可以写多个值) between... and.. 在某两 ...
- WSUS补丁下载速度慢解决办法
windows 2008r2 如果是 WSUS 3.0并使用 Windows Internal Database(默认安装) %programfiles%\Update Services\Setup\ ...
- 周一02.4变量&垃圾回收机制
一.变量 1. 什么是变量 量:记录事物的某种状态,即事物典型的特征 变:事物的状态是可以发生变化的 2. 为何要用变量 是为了让计算机能够像人一样记录事物的状态 3. 如何用变量 (先定义后引用) ...
- git简单提交操作
一.本地仓库操作 1.打开git命令行,先'到需要提交的目录 2.输入git init,初始化本地仓库 3.输入git add <file> 命令添加提交文件 4.输入git status ...
- Springboot整合Kfka
1.首先在pom文件添加依赖 The managed version is 1.1.7.RELEASE The artifact is managed in org.springframework.b ...
- python已经感觉到放弃接近的day08
居然能超过一个星期,我甚至都有点佩服我自己了,今天有两个新的知识点,一个简单一个难,先从简单的开始入手吧,进制,进制分为4种,2进制,8进制,10进制,16进制,一般最常用的就是10进制了,计算机用的 ...
- IDEA Can't Update No tracked branch configured for branch master or the branch doesn't exist.
IDEA Can't Update No tracked branch configured for branch master or the branch doesn't exist.To make ...