官方文档:
Dockerfile 示例:
Dockerfile 结构主要分为四部分:
docker build -t text:v1 . --no-cache # 要在构建后将映像标记到多个存储库中,请在运行命令-t时添加多个参数 docker build -t shykes/myapp:1.0.2 -t shykes/myapp:latest . ### 参数解释 # -t:指定镜像名称 # . :当前目录Dockerfile # -f:指定Dockerfile路径 # --no-cache:不缓存
# 非交互式运行 docker run centos:7.4.1708 /bin/echo "Hello world" ### 交互式执行 # -t: 在新容器内指定一个伪终端或终端。 #-i: 允许你对容器内的标准输入 (STDIN) 进行交互。 # 会登录到docker环境中,交互式 docker run -it centos:7.4.1708 /bin/bash # -d:后台执行,加了 -d 参数默认不会进入容器 docker run -itd centos:7.4.1708 /bin/bash ### 进入容器 # 在使用 -d 参数时,容器启动后会进入后台。此时想要进入容器,可以通过以下指令进入: #docker exec -it :推荐大家使用 docker exec -it 命令,因为此命令会退出容器终端,但不会导致容器的停止。 #docker attach:容器退出,会导致容器的停止。 docker exec -it b2c0235dc53 /bin/bash docker attach b2c0235dc53
语法格式:
ARG <参数名>[=<默认值>]
示例:
# 在FROM之前定义ARG,只在 FROM 中生效 ARG VERSION=laster FROM centos:${VERSION} # 在FROM之后使用,得重新定义,不需要赋值 ARG VERSION RUN echo $VERSION >/tmp/image_version
语法格式:
FROM [--platform=<platform>] <image> [AS <name>] FROM [--platform=<platform>] <image>[:<tag>] [AS <name>] FROM [--platform=<platform>] <image>[@<digest>] [AS <name>]
示例:
ARG VERSION=latest FROM busybox:$VERSION # FROM --platform="linux/amd64" busybox:$VERSION ARG VERSION RUN echo $VERSION > image_version
语法格式:
MAINTAINER <name>
示例:
LABEL org.opencontainers.image.authors="SvenDowideit@home.org.au"
作用:
语法格式:
# 后面路径是容器内的路径,对应宿主机的目录是随机的 VOLUME ["<路径1>", "<路径2>"...] VOLUME <路径>
示例:
FROM ubuntu RUN mkdir /myvol RUN echo "hello world" > /myvol/greeting VOLUME /myvol
语法格式:
示例:
# 以下三种写法等价 RUN /bin/bash -c 'source $HOME/.bashrc; \ echo $HOME' RUN /bin/bash -c 'source $HOME/.bashrc; echo $HOME' RUN ["/bin/bash", "-c", "source $HOME/.bashrc; echo $HOME"]
语法格式:
COPY [--chown=<user>:<group>] <src>... <dest> COPY [--chown=<user>:<group>] ["<src>",... "<dest>"]
示例:
# 添加所有以“hom”开头的文件: COPY hom* /mydir/ # ?替换为任何单个字符,例如“home.txt”。 COPY hom?.txt /mydir/ # 使用相对路径,并将“test.txt”添加到<WORKDIR>/relativeDir/: COPY test.txt relativeDir/ # 使用绝对路径,并将“test.txt”添加到/absoluteDir/ COPY test.txt /absoluteDir/ # 修改文件权限 COPY --chown=55:mygroup files* /somedir/ COPY --chown=bin files* /somedir/ COPY --chown=1 files* /somedir/ COPY --chown=10:11 files* /somedir/
ADD 指令和 COPY 的使用格类似(同样需求下,官方推荐使用 COPY)。功能也类似,不同之处如下:
语法格式:
ADD [--chown=<user>:<group>] <src>... <dest> ADD [--chown=<user>:<group>] ["<src>",... "<dest>"]
示例:
# 通配符 ADD hom* /mydir/ # 相对路径,拷贝到WORKDIR目录下relativeDir/ ADD test.txt relativeDir/ # 绝对路径 ADD test.txt /absoluteDir/ # 更改权限 ADD --chown=55:mygroup files* /somedir/ ADD --chown=bin files* /somedir/ ADD --chown=1 files* /somedir/ ADD --chown=10:11 files* /somedir/
ADD 和 COPY 的区别和使用场景:
语法格式:
ENV <key1>=<value1> <key2>=<value2>... # 省略"="此语法不允许在单个ENV指令中设置多个环境变量,并且可能会造成混淆。 ENV <key> <value>
示例:
ENV JAVA_HOME=/usr/local/jdk ENV MY_NAME="John Doe" MY_DOG=Rex\ The\ Dog \ MY_CAT=fluffy # 此语法不允许在单个ENV指令中设置多个环境变量,并且可能会造成混淆。 ENV JAVA_HOME /usr/local/jdk
语法格式:
WORKDIR <工作目录路径>
示例:
FROM busybox ENV FOO=/bar WORKDIR ${FOO} # WORKDIR /bar
语法格式:
USER <用户名>[:<用户组>] USER <UID>[:<GID>]
示例:
FROM busybox RUN groupadd --system --gid=9999 admin && useradd --system --home-dir /home/admin --uid=9999 --gid=admin admin USER admin:admin # USER 9999:9999
作用:
语法格式:
# 默认情况下,EXPOSE假定 TCP。 EXPOSE <port> [<port>/<protocol>...]
示例:
EXPOSE 80/TCP 443/TCP EXPOSE 80 443 EXPOSE 80/tcp EXPOSE 80/udp
语法格式:
CMD <shell 命令> CMD ["<可执行文件或命令>","<param1>","<param2>",...] CMD ["<param1>","<param2>",...] # 该写法是为 ENTRYPOINT 指令指定的程序提供默认参数
示例:
CMD cat /etc/profile CMD ["/bin/sh","-c","/etc/profile"]
语法格式:
# exec形式,这是首选形式: ENTRYPOINT ["executable", "param1", "param2"] # 外壳形式: ENTRYPOINT command param1 param2
示例:
FROM ubuntu ENTRYPOINT ["top", "-b"] # CMD作为ENTRYPOINT参数 CMD ["-c"] # 与下面的等价 ENTRYPOINT ["top", "-b -c"] ENTRYPOINT top -b -c
语法格式:
HEALTHCHECK [OPTIONS] CMD command(通过在容器内运行命令检查容器运行状况) HEALTHCHECK NONE(禁用从基础映像继承的任何运行状况检查)
选项CMD有:
命令的exit status指示容器的运行状况。可能的值为:
示例:
FROM nginx MAINTAINER Securitit HEALTHCHECK --interval=5s --timeout=3s \ CMD curl -f http://localhost/ || exit 1 CMD ["usr/sbin/nginx", "-g", "daemon off;"]
语法格式:
ONBUILD <其它指令>
示例:
FROM node:slim RUN mkdir /app WORKDIR /app ONBUILD COPY ./package.json /app ONBUILD RUN [ "npm", "install" ] ONBUILD COPY . /app/ CMD [ "npm", "start" ]
语法格式:
LABEL <key>=<value> <key>=<value> <key>=<value> ...
示例:比如我们可以添加镜像的作者
LABEL org.opencontainers.image.authors="runoob"
当用户同时在 kubernetes 中的 yaml 文件中写了command和args的时候,默认是会覆盖DockerFile中的命令行和参数,完整的情况分类如下:
Dockerfile FROM centos COPY test.sh / RUN chmod +x /test.sh ### ENTRYPOINT将作为的子命令启动/bin/sh -c,它不会传递参数,要传递参数只能这样传参 # ENTRYPOINT ["/bin/sh","-c","/test.sh ENTRYPOINT"] ENTRYPOINT ["/test.sh","ENTRYPOINT"] CMD ["CMD"]
/tmp/test.sh
#!/bin/bash echo $*
构建
docker build -t test1:v1 -f Dockerfile .
yaml 编排
cat << EOF > test1.yaml apiVersion: apps/v1 kind: Deployment metadata: name: test spec: replicas: 1 selector: matchLabels: app: test template: metadata: labels: app: test spec: nodeName: local-168-182-110 containers: - name: test image: test:v1 #command: ['/bin/sh','-c','/test.sh'] #args: ['args'] EOF
执行
kubectl apply -f test.yaml
cat << EOF > test2.yaml apiVersion: apps/v1 kind: Deployment metadata: name: test2 spec: replicas: 1 selector: matchLabels: app: test2 template: metadata: labels: app: test2 spec: nodeName: local-168-182-110 containers: - name: test2 image: test:v1 # ['/bin/sh','-c','/test.sh command','hello'],加了'/bin/sh','-c',也是不能外部传参,不会输出hello,只能通过这样传参,['/bin/sh','-c','/test.sh command'];CMD里面的参数会被忽略 command: ['/test.sh'] # command带参数 # command: ['/test.sh','command'] #args: ['args'] EOF
cat << EOF > test3.yaml apiVersion: apps/v1 kind: Deployment metadata: name: test3 spec: replicas: 1 selector: matchLabels: app: test3 template: metadata: labels: app: test3 spec: nodeName: local-168-182-110 containers: - name: test3 image: test:v1 # ['/bin/sh','-c','/test.sh command','hello'],加了'/bin/sh','-c',也是不能外部传参,不会输出hello,只能通过这样传参,['/bin/sh','-c','/test.sh command'];CMD里面的参数会被忽略 # command: ['/test.sh'] # command带参数 # command: ['/test.sh','command'] args: ['args'] EOF
cat << EOF > test4.yaml apiVersion: apps/v1 kind: Deployment metadata: name: test4 spec: replicas: 1 selector: matchLabels: app: test4 template: metadata: labels: app: test4 spec: nodeName: local-168-182-110 containers: - name: test4 image: test:v1 # ['/bin/sh','-c','/test.sh command','hello'],加了'/bin/sh','-c',也是不能外部传参,不会输出hello,只能通过这样传参,['/bin/sh','-c','/test.sh command'];CMD里面的参数会被忽略 # command: ['/test.sh'] # command带参数,command和args都会带上 command: ['/test.sh','command'] args: ['args'] EOF
镜像构建 Dockerfile 的介绍就到这里了!