dockerfile指令:
FROM:构建的新镜像是基于哪个镜像,例如:FROM centos:6
语法:
FROM <image>FROM <image>:<tag>
FROM <image>:<digest>
三种写法,其中<tag>和<digest> 是可选项,如果没有选择,那么默认值为latest
MAINTAINER:镜像维护者姓名或邮箱地址,例如:MAINTAINER [email protected]
语法:
MAINTAINER <name>RUN:构建镜像时运行的Shell命令,例如:RUN ["yum", "install", "httpd"] 或 RUN yum install httpd
RUN命令有两种格式
1. RUN <command>2. RUN ["executable", "param1", "param2"]
第一种后边直接跟shell命令,在linux操作系统上默认 /bin/sh -c,在windows操作系统上默认 cmd /S /C
第二种是类似于函数调用。可将executable理解成为可执行文件,后面就是两个参数。
两种写法比对:
RUN /bin/bash -c 'source $HOME/.bashrc; echo $HOMERUN ["/bin/bash", "-c", "echo hello"]
注意:多行命令不要写多个RUN,原因是Dockerfile中每一个指令都会建立一层。多少个RUN就构建了多少层镜像,会造成镜像的臃肿、多层,不仅仅增加了构件部署的时间,还容易出错。RUN书写时的换行符是\。
CMD:运行容器时执行的Shell命令,
语法有三种写法
CMD ["executable","param1","param2"]
CMD ["param1","param2"]
CMD command param1 param2
第三种比较好理解了,就时shell这种执行方式和写法。第一种和第二种其实都是可执行文件加上参数的形式。
例如:
CMD ["-c", "/start.sh"]
CMD ["/usr/sbin/sshd", "-D"]
CMD /usr/sbin/sshd -D
EXPOSE:声明容器运行的服务端口,例如:EXPOSE 80 443
功能为暴漏容器运行时的监听端口给外部,但是EXPOSE并不会使容器访问主机的端口。如果想使得容器与主机的端口有映射关系,必须在容器启动的时候加上-P参数。
ENV:设置容器内环境变量,例如:ENV MYSQL_ROOT_PASSWORD 123456
功能为设置环境变量,语法有两种:
ENV <key> <value>ENV <key>=<value> ...
两者的区别就是第一种是一次设置一个,第二种是一次设置多个。
ADD:拷贝文件或目录到镜像,如果是URL或者压缩包会自动下载或自动解压
用法:ADD <src>...<dest>
ADD ["<src>",..."<dest>"]
说明:<dest>路径的填写可以是容器内的绝对路径,也可以是相对于工作目录的相对路径
<src>可以是一个本地文件或者是一个本地压缩文件,还可以是一个url
如果把<src>写成一个url,那么ADD就类似于wget命令
注意:尽量不要把<scr>写成一个文件夹,如果<src>是一个文件夹了,复制整个目录的内容,包括文件系统元数据
例如:
ADD https://xxx.com/html.tar.gz /var/www/html
ADD html.tar.gz /var/www/html
COPY:拷贝文件或目录到镜像,例如:COPY ./start.sh /start.sh
语法如下:
COPY <src>... <dest>COPY ["<src>",... "<dest>"]
与ADD的区别:
COPY的<src>只能是本地文件,其他用法一致
ENTRYPOINT:运行容器时执行的Shell命令
语法如下:
ENTRYPOINT ["executable", "param1", "param2"]ENTRYPOINT command param1 param2
差别:第一种就是可执行文件加参数,第二种就是写shell
例如:ENTRYPOINT ["/bin/bash", "-c", "/start.sh"]
ENTRYPOINT /bin/bash -c '/start.sh'
与CMD比较说明(这俩命令太像了,而且还可以配合使用):
1. 相同点:
只能写一条,如果写了多条,那么只有最后一条生效
容器启动时才运行,运行时机相同
2. 不同点:
ENTRYPOINT不会被运行的command覆盖,而CMD则会被覆盖
如果我们在Dockerfile种同时写了ENTRYPOINT和CMD,并且CMD指令不是一个完整的可执行命令,那么CMD指定的内容将会作为ENTRYPOINT的参数
VOLUME:指定容器挂载点到宿主机自动生成的目录或其他容器,例如:VOLUME ["/var/lib/mysql"]
语法为:
VOLUME ["/data"]说明:
["/data"]可以是一个JsonArray ,也可以是多个值。
所以如下几种写法都是正确的:
VOLUME ["/var/log/"]
VOLUME /var/logVOLUME /var/log /var/db
使用场景:一般的使用场景为需要持久化存储数据时,容器使用的是AUFS,这种文件系统不能持久化数据,当容器关闭后,所有的更改都会丢失,所以当数据需要持久化时用这个命令。
USER:为RUN、CMD和ENTRYPOINT执行命令指定运行用户USER <user>[:<group>]或USER <UID>[:<GID>],例如:USER zhangsan
注意:如果设置了容器以daemon用户去运行,那么RUN, CMD 和 ENTRYPOINT 都会以这个用户去运行WORKDIR:为RUN、CMD、ENTRYPOINT、COPY和ADD设置工作目录,例如:WORKDIR /data
语法:
WORKDIR /path/to/workdir设置工作目录,对RUN,CMD,ENTRYPOINT,COPY,ADD生效。如果不存在则会创建,也可以设置多次。
例如:
WORKDIR /aWORKDIR b
WORKDIR c
RUN pwd
pwd执行的结果是/a/b/c
HEALTHCHECK:健康检查
语法有两种:
1. HEALTHCHECK [OPTIONS] CMD command2. HEALTHCHECK NONE
说明:第一个的功能是在容器内部运行一个命令来检查容器的健康状况
第二个的功能是在基础镜像中取消健康检查命令
[OPTIONS]的选项支持以下三中选项:
--interval=DURATION 两次检查默认的时间间隔为30秒
--timeout=DURATION 健康检查命令运行超时时长,默认30秒
--retries=N 当连续失败指定次数后,则容器被认为是不健康的,状态为unhealthy,默认次数是3
注意:HEALTHCHECK命令只能出现一次,如果出现了多次,只有最后一个生效。
CMD后边的命令的返回值决定了本次健康检查是否成功,具体的返回值如下:
0: success - 表示容器是健康的
1: unhealthy - 表示容器已经不能工作了
2: reserved - 保留值
例如:
HEALTHCHECK --interval=5m --timeout=3s --retries=3 CMD curl -f http://localhost/ || exit 1
健康检查的命令是curl -f http://localhost/ ,两次健康检查的间隔时间是5m,命令超时时间为3s。
ARG:在构建镜像时指定一些参数
语法:
ARG <name>[=<default value>]设置变量命令,ARG命令定义了一个变量,在docker build创建镜像的时候,使用 --build-arg <varname>=<value>来指定参数
如果用户在build镜像时指定了一个参数没有定义在Dockerfile种,那么将有一个Warning,提示如下:
[Warning] One or more build-args [foo] were not consumed.例如:
FROM centos:6
ARG user # 定义一个参数,不在dockerfile中赋值
USER $user
# docker build --build-arg user=root Dockerfile .
LABEL:为镜像指定标签
语法:
LABEL <key>=<value> <key>=<value> <key>=<value> ...一个Dockerfile种可以有多个LABEL,如下:
LABEL "com.example.vendor"="ACME Incorporated"LABEL com.example.label-with-value="foo"
LABEL version="1.0"
LABEL description="This text illustrates \
that label-values can span multiple lines."
但是并不建议这样写,最好就写成一行,如太长需要换行的话则使用\符号
如下:
LABEL multi.label1="value1" \multi.label2="value2" \
other="value3"
说明:LABEL会继承基础镜像种的LABEL,如遇到key相同,则值覆盖
STOPSIGNAL:当容器推出时给系统发送什么样的指令
语法:
STOPSIGNAL signal使用dockerfile构建带ssh服务的centos容器:
# 创建dockerfile
[root@centos7 ~]# mkdir dockerfile/centos_ssh -p [root@centos7 ~]# cd dockerfile/centos_ssh/ [root@centos7 centos_ssh]# vi dockerfile [root@centos7 centos_ssh]# cat dockerfile FROM centos MAINTAINER "[email protected]" ENV ROOT_PASSWORD 123456 RUN yum -y install openssh-server && yum clean all && \ ssh-keygen -t rsa -f /etc/ssh/ssh_host_rsa_key && \ ssh-keygen -t dsa -f /etc/ssh/ssh_host_dsa_key && \ /bin/echo $ROOT_PASSWORD |passwd --stdin root EXPOSE 22 CMD ["/usr/sbin/sshd", "-D"]
# 使用dockerfile创建镜像
[root@centos7 centos_ssh]# docker build -t centos_ssh:v1 . Sending build context to Docker daemon 2.048 kB Step 1/6 : FROM centos ---> 1e1148e4cc2c Step 2/6 : MAINTAINER "[email protected]" ---> Running in 8cad47a9e80a ---> ace0609297a5 Removing intermediate container 8cad47a9e80a Step 3/6 : ENV ROOT_PASSWORD 123456 ---> Running in a7ec1235fddb ---> 49d86fd09a96 Removing intermediate container a7ec1235fddb Step 4/6 : RUN yum -y install openssh-server && yum clean all && ssh-keygen -t rsa -f /etc/ssh/ssh_host_rsa_key && ssh-keygen -t dsa -f /etc/ssh/ssh_host_dsa_key && /bin/echo $ROOT_PASSWORD |passwd --stdin root ---> Running in e9eb19cd496f ...... ---> c366592c89f8 Removing intermediate container e9eb19cd496f Step 5/6 : EXPOSE 22 ---> Running in 5c0e295c1ed7 ---> 7717f93524ae Removing intermediate container 5c0e295c1ed7 Step 6/6 : CMD /usr/sbin/sshd -D ---> Running in f8b4fe42d264 ---> e63f4d45cd57 Removing intermediate container f8b4fe42d264 Successfully built e63f4d45cd57
# 查看构建好的镜像
[root@centos7 centos_ssh]# docker images REPOSITORY TAG IMAGE ID CREATED SIZE centos_ssh v1 e63f4d45cd57 2 hours ago 228 MB docker.io/nginx latest f09fe80eb0e7 3 weeks ago 109 MB docker.io/busybox latest 3a093384ac30 2 months ago 1.2 MB docker.io/centos latest 1e1148e4cc2c 2 months ago 202 MB
# 使用构建完毕的镜像创建容器
[root@centos7 centos_ssh]# docker run -itd --name centos_ssh_01 -p 2222:22 centos_ssh:v1 ac59ac35955142095a1b59520f134a3de71a9a3f0d0305350d64adc91f886637 [root@centos7 centos_ssh]# docker ps -a CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES ac59ac359551 centos_ssh:v1 "/usr/sbin/sshd -D" 2 hours ago Up 2 hours 0.0.0.0:2222->22/tcp centos_ssh_01
# 尝试使用ssh直接连接docker容器