当前位置:   article > 正文

Docker 容器镜像制作指令详解

docker制作镜像命令

一、Docker 镜像说明

1、Docker镜像中没有内核

从镜像大小上面来说,一个比较小的镜像只有1MB多点或几MB,而内核文件需要几十MB, 因此镜像里面是没有内核的,镜像在被启动为容器后将直接使用宿主机的内核,而镜像本身则只提供相应的rootfs,即系统正常运行所必须的用户空间的文件系统,比如: /dev/,/proc,/bin,/etc等目录,容器当中/boot目录是空的,而/boot当中保存的就是与内核相关的文件和目录。

2、为什么没有内核

由于容器启动和运行过程中是直接使用了宿主机的内核,不会直接调用物理硬件,所以也不会涉及到硬件驱动,因此也无需容器内拥有自已的内核和驱动。而如果使用虚拟机技术,对应每个虚拟机都有自已独立的内核

3、容器中的程序后台运行会导致此容器启动后立即退出

Docker容器如果希望启动后能持续运行,就必须有一个能前台持续运行的进程,如果在容器中启动传统的服务,如:httpd,php-fpm等均为后台进程模式运行,就导致 docker 在前台没有运行的应用,这样的容器启动后会立即退出。所以一般会将服务程序以前台方式运行,对于有一些可能不知道怎么实现前台运行的程序,只需要在你启动的该程序之后添加类似于 tail ,top 这种可以前台运行的程序即可. 比较常用的方法,如 tail -f /etc/hosts

4、docker镜像生命周期

5、docker制作镜像方式

Docker 镜像制作类似于虚拟机的镜像(模版)制作,即按照公司的实际业务需求将需要安装的软件、相关配置等基础环境配置完成,然后将其做成镜像,最后再批量从镜像批量生成容器实例,这样可以极大的简化相同环境的部署工作.

Docker的镜像制作分为手动制作(基于容器)和自动制作(基于DockerFile),企业通常都是基于Dockerfile制作镜像

  1. docker commit #通过修改现有容器,将之手动构建为镜像
  2. docker build #通过Dockerfile文件,批量构建为镜像

二、构建镜像

1、commit 构建

  • docker commit 格式

  1. docker commit [OPTIONS] CONTAINER [REPOSITORY[:TAG]]
  2. #选项
  3. -a, --author string Author (e.g., "John Hannibal Smith <hannibal@ateam.com>")
  4. -c, --change list Apply Dockerfile instruction to the created image
  5. -m, --message string Commit message
  6. -p, --pause Pause container during commit (default true)
  7. #说明:
  8. 制作镜像和CONTAINER状态无关,停止状态也可以制作镜像
  9. 如果没有指定[REPOSITORY[:TAG]],REPOSITORY和TAG都为<none>
  10. 提交的时候标记TAG号: 生产当中常用,后期可以根据TAG标记创建不同版本的镜像以及创建不同版本的容器

基于容器手动制作镜像步骤具体如下:

  • 下载一个系统的官方基础镜像,如: CentOS 或 Ubuntu

  • 基于基础镜像启动一个容器,并进入到容器

  • 在容器里面做配置操作

    安装基础命令

    配置运行环境

    安装服务和配置服务

    放业务程序代码

  • 提交为一个新镜像 docker commit

  • 基于自己的镜像创建容器并测试访问

  1. [root@fsl ~]# docker run -d -p 8080:8080 tomcat
  2. Unable to find image 'tomcat:latest' locally
  3. latest: Pulling from library/tomcat
  4. 0e29546d541c: Pull complete
  5. 9b829c73b52b: Pull complete
  6. cb5b7ae36172: Pull complete
  7. 6494e4811622: Pull complete
  8. 668f6fcc5fa5: Pull complete
  9. dc120c3e0290: Pull complete
  10. 8f7c0eebb7b1: Pull complete
  11. 77b694f83996: Pull complete
  12. 0f611256ec3a: Pull complete
  13. 4f25def12f23: Pull complete
  14. Digest: sha256:9dee185c3b161cdfede1f5e35e8b56ebc9de88ed3a79526939701f3537a52324
  15. Status: Downloaded newer image for tomcat:latest
  16. e7ca2c3f943921ca42ac3fbbb8bea32226f5627215e21982944bc81d68a529b9
  17. [root@fsl ~]# docker ps
  18. CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
  19. e7ca2c3f9439 tomcat "catalina.sh run" 40 seconds ago Up 38 seconds 0.0.0.0:8080->8080/tcp, :::8080->8080/tcp unruffled_lederberg
  20. a1fd8088073d centos:7.8 "bash" 42 hours ago Up 42 hours adoring_pasteur
  21. [root@fsl ~]# curl -I 127.0.0.1:8080
  22. HTTP/1.1 404
  23. Content-Type: text/html;charset=utf-8
  24. Content-Language: en
  25. Transfer-Encoding: chunked
  26. Date: Sat, 12 Feb 2022 09:04:02 GMT
  27. #修改镜像
  28. [root@fsl ~]# docker exec -it e7ca2c3f9439 bash
  29. root@e7ca2c3f9439:/usr/local/tomcat# cp -a webapps.dist/* webapps/
  30. root@e7ca2c3f9439:/usr/local/tomcat#
  31. exit
  32. [root@fsl ~]# curl -I 127.0.0.1:8080
  33. HTTP/1.1 200
  34. Content-Type: text/html;charset=UTF-8
  35. Transfer-Encoding: chunked
  36. Date: Sat, 12 Feb 2022 09:05:12 GMT
  37. #提交镜像
  38. [root@fsl ~]# docker commit -m "add webapps app" -a "test" e7ca2c3f9439 tomcat:v1
  39. sha256:286182cec243a433033f531a5950d0eed138a8920412395c71ff7b0f061ead94
  40. [root@fsl ~]# docker images
  41. REPOSITORY TAG IMAGE ID CREATED SIZE
  42. tomcat v1 286182cec243 3 seconds ago 684MB
  43. tomcat latest fb5657adc892 7 weeks ago 680MB
  44. #新镜像启动
  45. [root@fsl ~]# docker run -d -p 8088:8080 --name tomcatv1 tomcat:v1
  46. 1622e9ca786900a746f9c25f74480d523db55a515d22a85c3e6c7484d3129f4d
  47. [root@fsl ~]# docker ps
  48. CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
  49. 1622e9ca7869 tomcat:v1 "catalina.sh run" 5 seconds ago Up 5 seconds 0.0.0.0:8088->8080/tcp, :::8088->8080/tcp tomcatv1
  50. e7ca2c3f9439 tomcat "catalina.sh run" 5 minutes ago Up 5 minutes 0.0.0.0:8080->8080/tcp, :::8080->8080/tcp unruffled_lederber

2、Dockerfile 构建镜像

2.1、Dockerfile介绍

  • Dockerfile介绍

    DockerFile 是一种被Docker程序解释执行的脚本,由一条条的命令组成的,每条命令对应linux下面的一条命令,Docker程序将这些DockerFile指令再翻译成真正的linux命令,其有自己的书写方式和支持的命令,Docker程序读取DockerFile并根据指令生成Docker镜像,相比手动制作镜像的方式,DockerFile更能直观的展示镜像是怎么产生的,有了DockerFile,当后期有额外的需求时,只要在之前的DockerFile添加或者修改响应的命令即可重新生成新的Docker镜像,避免了重复手动制作镜像的麻烦,类似与shell脚本一样,可以方便高效的制作镜像

    Docker守护程序Dockerfile 逐一运行指令,如有必要,将每个指令的结果提交到新镜像,然后最终输出新镜像的ID。Docker守护程序将自动清理之前发送的上下文

    请注意,每条指令都是独立运行的,并会导致创建新镜像,比如RUN cd /tmp 对下一条指令不会有任何影响。

    Docker将尽可能重用中间镜像层(缓存),以显著加速docker build 命令的执行过程,这由Usingcache 控制台输出中的消息指示

Dockerfile镜像制作流程

2773a20e216b78075c9667e62d2d360d.png

2.2、Dockerfile 文件格式

  • Dockerfile 是一个有特定语法格式的文本文件

  • dockerfile 官方说明

    https://docs.docker.com/engine/reference/builder/
  • 帮助: man 5 dockerfile

Dockerfile 文件说明

  • 每一行以Dockerfile的指令开头,指令不区分大小写,但是惯例使用大写

  • 使用 # 开始作为注释

  • 每一行只支持一条指令,每条指令可以携带多个参数

  • 指令按文件的顺序从上至下进行执行

  • 每个指令的执行会生成一个新的镜像层,为了减少分层和镜像大小,尽可能将多条指令合并成一条

  • 指令

  • 制作镜像一般可能需要反复多次,每次执行dockfile都按顺序执行,从头开始,已经执行过的指令

  • 已经缓存,不需要再执行,如果后续有一行新的指令没执行过,其往后的指令将会重新执行,所以

  • 为加速镜像制作,将最常变化的内容放下dockerfile的文件的后面

3、Dockerfile 相关指令

dockerfile 文件中的常见指令:

  1. FROM
  2. ADD
  3. COPY
  4. ENV
  5. EXPOSE
  6. FROM
  7. LABEL
  8. STOPSIGNAL
  9. USER
  10. VOLUME
  11. WORKDIR

FROM:指定基础镜像

  • 定制镜像,需要先有一个基础镜像,在这个基础镜像上进行定制。

  • FROM 就是指定基础镜像,此指令通常必需放在Dockerfile文件第一个非注释行。后续的指令都是运行于此基准镜像所提供的运行环境

  • 基础镜像可以是任何可用镜像文件,默认情况下,docker build会在docker主机上查找指定的镜像文件,在其不存在时,则会从Docker Hub Registry上拉取所需的镜像文件.如果找不到指定的镜像文件,docker build会返回一个错误信息

  • 格式

  1. FROM [--platform=<platform>] <image> [AS <name>]
  2. FROM [--platform=<platform>] <image>[:<tag>] [AS <name>]
  3. FROM [--platform=<platform>] <image>[@<digest>] [AS <name>]
  4. #说明:
  5. --platform 指定镜像的平台,比如: linux/amd64, linux/arm64, or windows/amd64
  6. tag 和 digest是可选项,如果不指定,默认为latest示例
  7. FROM ubuntu
  8. FROM ubuntu:bionic
  9. FROM debian:buster-slim

LABEL: 指定镜像元数据

可以指定镜像元数据,如: 镜像作者等

LABEL <key>=<value> <key>=<value> <key>=<value> ...

示例:

  1. LABEL "com.example.vendor"="ACME Incorporated"
  2. LABEL com.example.label-with-value="foo"
  3. LABEL version="1.0"
  4. LABEL description="This text illustrates \
  5. that label-values can span multiple lines."

一个镜像可以有多个label ,还可以写在一行中,即多标签写法,可以减少镜像的的大小

  1. #一行格式
  2. LABEL multi.label1="value1" multi.label2="value2" other="value3"
  3. #多行格式
  4. LABEL multi.label1="value1" \
  5. multi.label2="value2" \
  6. other="value3"

MAINTAINER: 指定维护者信息

  1. #此指令已过时,用LABEL代替
  2. MAINTAINER <name>
  3. MAINTAINER wangxiaochun <root@wangxiaochun.com>
  4. #用LABEL代替
  5. LABEL maintainer="wangxiaochun <root@wangxiaochun.com>"

RUN: 执行 shell命令

RUN 指令用来在构建镜像阶段需要执行 FROM 指定镜像所支持的Shell命令。

通常各种基础镜像一般都支持丰富的shell命令

注意: RUN 可以写多个,每一个RUN指令都会建立一个镜像层,所以尽可能合并成一条指令,比如将多

个shell命令通过 && 连接一起成为在一条指令

每个RUN都是独立运行的,和前一个RUN无关

  1. #shell 格式: 相当于 /bin/sh -c <命令> 此种形式支持环境变量
  2. RUN <命令>
  3. #exec 格式: 此种形式不支持环境变量,注意:是双引号,不能是单引号
  4. RUN ["可执行文件", "参数1", "参数2"]
  5. #exec格式可以指定其它shell
  6. RUN ["/bin/bash","-c","echo hello wang"]

说明:

  1. shell格式中,<command>通常是一个shell命令,且以"/bin/sh -c”来运行它,这意味着此进程在容器
  2. 中的PID不为1,不能接收Unix信号,因此,当使用docker stop <container>命令停止容器时,此进程
  3. 接收不到SIGTERM信号
  4. exec格式中的参数是一个JSON格式的数组,其中<executable>为要运行的命令,后面的<paramN>为传递
  5. 给命令的选项或参数;然而,此种格式指定的命令不会以"/bin/sh -c"来发起,因此常见的shell操作如变
  6. 量替换以及通配符(?,*等)替换将不会进行;不过,如果要运行的命令依赖于此shell特性的话,可以将其替
  7. 换为类似下面的格式。
  8. RUN ["/bin/bash", "-c", "<executable>", "<param1>"]

示例:

  1. RUN echo 'Hello, Docker!' > /usr/share/nginx/html/index.html
  2. RUN ["/bin/bash", "-c", "echo hello world"]
  3. RUN yum -y install epel-release \
  4. && yum -y install nginx \
  5. && rm -rf /usr/share/nginx/html/*
  6. && echo " docker test nginx " > /usr/share/nginx/html/index.html
  7. #多个 前后RUN 命令独立无关和shell命令不同
  8. #world.txt并不存放在/app内
  9. RUN cd /app
  10. RUN echo "hello" > world.txt

ENV: 设置环境变量

ENV 可以定义环境变量和值,会被后续指令(如:ENV,ADD,COPY,RUN等)通过KEY或KEY或{KEY}进行引用,

并在容器运行时保持

  1. #变量赋值格式1
  2. ENV <key> <value> #此格式只能对一个key赋值,<key>之后的所有内容均会被视作其<value>的组成
  3. 部分
  4. #变量赋值格式2
  5. ENV <key1>=<value1> <key2>=<value2> \ #此格式可以支持多个key赋值,定义多个变量建议使用,
  6. 减少镜像层
  7. <key3>=<value3> ...
  8. #如果<value>中包含空格,可以以反斜线\进行转义,也可通过对<value>加引号进行标识;另外,反斜线也
  9. 可用于续行
  10. #只使用一次变量
  11. RUN <key>=<value> <command>
  12. #引用变量
  13. RUN $key .....
  14. #变量支持高级赋值格式
  15. ${key:-word}
  16. ${kye:+word}

如果运行容器时如果需要修改变量,可以执行下面通过基于exec 机制实现

注意: 下面方式只影响容器运行时环境,而不影响构建镜像的过程,即只能覆盖docker run时的环境变量,

而不会影响docker build时环境变量的值

  1. docker run -e|--env <key>=<value>
  2. #说明
  3. -e, --env list #Set environment variables
  4. --env-file filename #Read in a file of environment variables
  1. #格式1
  2. ENV myName="John Doe" myDog=Rex\ The\ Dog \
  3. myCat=fluffy
  4. #格式2
  5. ENV myName John Doe
  6. ENV myDog Rex The Dog
  7. ENV myCat fluffy

示例:

  1. ENV VERSION=1.0 DEBUG=on NAME="Happy Feet"
  2. ENV PG_MAJOR 9.3
  3. ENV PG_VERSION 9.3.4
  4. RUN curl -SL http://example.com/postgres-$PG_VERSION.tar.xz | tar -xJC
  5. /usr/src/postgress && …
  6. ENV PATH /usr/local/postgres-$PG_MAJOR/bin:$PATH

COPY: 复制文本

复制本地宿主机的 到容器中的 。

  1. COPY [--chown=<user>:<group>] <src>... <dest>
  2. COPY [--chown=<user>:<group>] ["<src>",... "<dest>"#路径中有空白字符时,建议使用此格式

说明

  • 可以是多个,可以使用通配符,通配符规则满足Go的filepath.Match 规则filepath.Match 参考链接:  https://golang.org/pkg/path/filepath/#Match

  • 必须是build上下文中的路径(为 Dockerfile 所在目录的相对路径),不能是其父目录中的文件

  • 如果是目录,则其内部文件或子目录会被递归复制,但目录自身不会被复制

  • 如果指定了多个, 或在中使用了通配符,则必须是一个目 录,且必须以 / 结尾

  • 可以是绝对路径或者是WORKDIR 指定的相对路径

  • 使用 COPY 指令,源文件的各种元数据都会保留。比如读、写、执行权限、文件变更时间等

  • 如果事先不存在,它将会被自动创建,这包括其父目录路径,即递归创建目录

  1. COPY hom* /mydir/
  2. COPY hom?.txt /mydir/

ADD: 复制和解包文件

该命令可认为是增强版的COPY,不仅支持COPY,还支持自动解缩。可以将复制指定的 到容器中的

  1. ADD [--chown=<user>:<group>] <src>... <dest>
  2. ADD [--chown=<user>:<group>] ["<src>",... "<dest>"]

说明:

  • 可以是Dockerfile所在目录的一个相对路径;也可是一个 URL;还可是一个 tar 文件(自动解压)

  • 可以是绝对路径或者是WORKDIR 指定的相对路径

  • 如果是目录,只复制目录中的内容,而非目录本身

  • 如果是一个 URL ,下载后的文件权限自动设置为 600

  • 如果为URL且不以/结尾,则指定的文件将被下载并直接被创建为,如果以 / 结尾,则文件名URL指定的文件将被直接下载并保存为/< filename>

  • 如果是一个本地文件系统上的打包文件,如: gz, bz2 ,xz ,它将被解包 ,其行为类似于"tar -x"命令,但是通过URL获取到的tar文件将不会自动展开

  • 如果有多个,或其间接或直接使用了通配符,则必须是一个以/结尾的目录路径;如果不以/结尾,则其被视作一个普通文件,的内容将被直接写入到

  1. ADD test relativeDir/ # adds "test" to `WORKDIR`/relativeDir/
  2. ADD test /absoluteDir/ # adds "test" to /absoluteDir/
  3. ADD --chown=55:mygroup files* /somedir/
  4. ADD --chown=bin files* /somedir/
  5. ADD --chown=1 files* /somedir/
  6. ADD --chown=10:11 files* /somedir/
  7. ADD ubuntu-xenial-core-cloudimg-amd64-root.tar.gz /

CMD: 容器启动命令

一个容器中需要持续运行的进程一般只有一个,CMD 用来指定启动容器时默认执行的一个命令,且其运行结束后,容器也会停止,所以一般CMD 指定的命令为持续运行且为前台命令.

  • 如果docker run没有指定任何的执行命令或者dockerfile里面也没有ENTRYPOINT,那么开启容器时就会使用执行CMD指定的默认的命令

  • 前面介绍过的 RUN 命令是在构建镜像进执行的命令,注意二者的不同之处

  • 每个 Dockerfile 只能有一条 CMD 命令。如指定了多条,只有最后一条被执行

  • 如果用户启动容器时用 docker run xxx 指定运行的命令,则会覆盖 CMD 指定的命令

  1. # 使用 exec 执行,推荐方式,第一个参数必须是命令的全路径,此种形式不支持环境变量
  2. CMD ["executable","param1","param2"]
  3. # 在 /bin/sh 中执行,提供给需要交互的应用;此种形式支持环境变量
  4. CMD command param1 param2
  5. # 提供给 ENTRYPOINT 命令的默认参数
  6. CMD ["param1","param2"]

示例:

CMD ["nginx", "-g", "daemon off;"]

ENTRYPOINT: 入口点

功能类似于CMD,配置容器启动后执行的命令及参数

  1. # 使用 exec 执行
  2. ENTRYPOINT ["executable", "param1", "param2"]
  3. # shell中执行
  4. ENTRYPOINT command param1 param2

ENTRYPOINT 不能被 docker run 提供的参数覆盖,而是追加,即如果docker run 命令有参数,那么参数全部都会作为ENTRYPOINT的参数

如果docker run 后面没有额外参数,但是dockerfile中的CMD里有(即上面CMD三种用法),即Dockerfile中即有CMD也有ENTRYPOINT,那么CMD的全部内容会作为ENTRYPOINT的参数

如果docker run 后面有额外参数,同时Dockerfile中即有CMD也有ENTRYPOINT,那么docker run后面的参数覆盖掉CMD参数内容,最终作为ENTRYPOINT的参数可以通过docker run --entrypoint string 参数在运行时替换,注意string不要加空格

使用CMD要在运行时重新写命令本身,然后在后面才能追加运行参数,ENTRYPOINT则可以运行时无需重写命令就可以直接接受新参数每个 Dockerfile 中只能有一个 ENTRYPOINT,当指定多个时,只有最后一个生效

ARG: 构建参数

ARG指令在build 阶段指定变量,和ENV不同的是,容器运行时不会存在这些环境变量

ARG <name>[=<default value>]

如果和ENV同名,ENV覆盖ARG变量

可以用 docker build --build-arg <参数名>=<值> 来覆盖

  1. [root@ubuntu1804 ~]#cat Dockerfile
  2. FROM busybox
  3. ARG author="test"
  4. LABEL maintainer="${author}"
  5. [root@ubuntu1804 ~]#docker build --build-arg author="test" -t
  6. busybox:v1.0 .

说明: ARG 和 FROM

  1. #FROM指令支持由第一个FROM之前的任何ARG指令声明的变量
  2. #示例:
  3. ARG CODE_VERSION=latest
  4. FROM base:${CODE_VERSION}
  5. CMD /code/run-app
  6. FROM extras:${CODE_VERSION}
  7. CMD /code/run-extras
  8. #在FROM之前声明的ARG在构建阶段之外,所以它不能在FROM之后的任何指令中使用。要使用在第一个FROM
  9. 之前声明的ARG的默认值,请在构建阶段内使用没有值的ARG指令
  10. #示例:
  11. ARG VERSION=latest
  12. FROM busybox:$VERSION
  13. ARG VERSION
  14. RUN echo $VERSION > image_version

VOLUME: 匿名卷

在容器中创建一个可以从本地主机或其他容器挂载的挂载点,一般用来存放数据库和需要保持的数据

等,一般会将宿主机上的目录挂载至VOLUME 指令指定的容器目录。即使容器后期被删除,此宿主机

的目录仍会保留,从而实现容器数据的持久保存。

宿主机目录为

/var/lib/docker/volumes/<volume_id>/_data

语法:

  1. VOLUME <容器内路径>
  2. VOLUME ["<容器内路径1>", "<容器内路径2>"...]

注意:

  • Dockerfile中的VOLUME实现的是匿名数据卷,无法指定宿主机路径和容器目录的挂载关系

  • 通过docker rm -fv <容器ID> 可以删除容器的同时删除VOLUME指定的卷

范例: 在容器创建两个/data/ ,/data2的挂载点

VOLUME [ "/data1","/data2" ]

EXPOSE: 暴露端口

指定服务端的容器需要对外暴露(监听)的端口号,以实现容器与外部通信。

EXPOSE 仅仅是声明容器打算使用什么端口而已,并不会真正暴露端口,即不会自动在宿主进行端口映射

因此,在启动容器时需要通过 -P 或-p ,Docker 主机才会真正分配一个端口转发到指定暴露的端口才可

使用

注意: 即使 Dockerfile没有EXPOSE 端口指令,也可以通过docker run -p 临时暴露容器内程序真正监

听的端口,所以EXPOSE 相当于指定默认的暴露端口,可以通过docker run -P 进行真正暴露

  1. EXPOSE <port>[/ <protocol>] [<port>[/ <protocol>] ..]
  2. #说明
  3. <protocol>用于指定传输层协议,可为tcp或udp二者之一,默认为TCP协议
  4. EXPOSE 80 443
  5. EXPOSE 11211/udp 11211/tcp

WORKDIR: 指定工作目录

为后续的 RUN、CMD、ENTRYPOINT 指令配置工作目录,当容器运行后,进入容器内WORKDIR指定

的默认目录

WORKDIR 指定工作目录(或称当前目录),以后各层的当前目录就被改为指定的目录,如该目录不存

在,WORKDIR 会自行创建

  1. WORKDIR /path/to/workdir
  2. #两次RUN独立运行,不在同一个目录,
  3. RUN cd /app
  4. RUN echo "hello" > world.txt
  5. #如果想实现相同目录可以使用WORKDIR
  6. WORKDIR /app
  7. RUN echo "hello" > world.txt

ONBUILD: 子镜像引用父镜像的指令

可以用来配置当构建当前镜像的子镜像时,会自动触发执行的指令,但在当前镜像构建时,并不会执行,即

延迟到子镜像构建时才执行

ONBUILD [INSTRUCTION]

USER: 指定当前用户

指定运行容器时的用户名或 UID,后续的 RUN 也会使用指定用户

当服务不需要管理员权限时,可以通过该命令指定运行用户

这个用户必须是事先建立好的,否则无法切换

如果没有指定 USER,默认是 root 身份执行

  1. USER <user>[:<group>]
  2. USER <UID>[:<GID>]
  3. RUN groupadd -r mysql && useradd -r -g mysql mysql
  4. USER mysql

HEALTHCHECK: 健康检查

检查容器的健康性

  1. HEALTHCHECK [选项] CMD <命令> #设置检查容器健康状况的命令
  2. HEALTHCHECK NONE #如果基础镜像有健康检查指令,使用这行可以屏蔽掉其健康检查指令
  3. HEALTHCHECK 支持下列选项:
  4. --interval=<间隔> #两次健康检查的间隔,默认为 30 秒
  5. --timeout=<时长> #健康检查命令运行超时时间,如果超过这个时间,本次健康检查就被视为失败,默
  6. 认 30 秒
  7. --retries=<次数> #当连续失败指定次数后,则将容器状态视为 unhealthy,默认3次
  8. --start-period=<FDURATION> #default: 0s
  9. #检查结果返回值:
  10. 0 #success the container is healthy and ready for use
  11. 1 #unhealth the container is not working correctly
  12. 2 #reserved do not use this exit code

示例

  1. FROM nginx
  2. RUN apt-get update && apt-get install -y curl && rm -rf /var/lib/apt/lists/*
  3. HEALTHCHECK --interval=5s --timeout=3s \
  4. CMD curl -fs http://localhost/ || exit 1

STOPSIGNAL: 退出容器的信号

该STOPSIGNAL 指令设置将被发送到容器退出的系统调用信号。该信号可以是与内核syscall表中的位置

匹配的有效无符号数字(例如9),也可以是SIGNAME格式的信号名称(例如SIGKILL)

STOPSIGNAL signal

SHELL : 指定shell

SHELL指令允许覆盖用于命令的shell形式的默认SHELL, 必须在Dockerfile中以JSON形式编写SHELL指

令。

SHELL ["executable", "parameters"]

4、Dockerfile 构建过程

从基础镜像运行一个容器

执行一条指令,对容器做出修改

执行类似docker commit的操作,提交一个新的中间镜像层(可以利用中间层镜像创建容器进行调试和排错)

再基于刚提交的镜像运行一个新容器

执行Dockerfile中的下一条指令,直至所有指令执行完毕

Dockerfile指令总结

13b1d588f51fa0e2ff2573b931e4b428.png

5、构建镜像docker build 命令

docker build命令使用Dockerfile文件创建镜像

  1. docker build [OPTIONS] PATH | URL | -
  2. 说明:
  3. PATH | URL | - #可以使是本地路径,也可以是URL路径。若设置为 - ,则从标准输入获取
  4. Dockerfile的内容
  5. -f, --file string #Dockerfile文件名,默认为 PATH/Dockerfile
  6. --force-rm #总是删除中间层容器,创建镜像失败时,删除临时容器
  7. --no-cache #不使用之前构建中创建的缓存
  8. -q --quiet=false #不显示Dockerfile的RUN运行的输出结果
  9. --rm=true #创建镜像成功时,删除临时容器
  10. -t --tag list #设置注册名称、镜像名称、标签。格式为 <注册名称>/<镜像名称>:<标签>(标
  11. 签默认为latest)

示例:

  1. docker build .
  2. docker build /usr/local/src/nginx
  3. docker build -f /path/to/a/Dockerfile .
  4. docker build -t shykes/myapp .
  5. docker build -t shykes/myapp:1.0.2 -t shykes/myapp:latest .
  6. docker build -t test/myapp .
  7. docker build -t nginx:v1 /usr/local/src/nginx

查看镜像的构建历史: docker history 镜像ID

示例:利用Dockerfile构建基于CentOS的nginx镜像

  1. [root@fsl nginx]# cat Dockerfile
  2. FROM centos:7.8
  3. LABEL maintainer="test"
  4. RUN yum install -y nginx && echo Nginx Website in Docker > /usr/share/nginx/html/index.html
  5. EXPOSE 80
  6. CMD ["nginx","-g","daemon off"]
  7. [root@fsl nginx]#docker build -t nginx_centos:v1 .
  8. [root@fsl nginx]#docker run -d -P --name nginx-web nginx_centos8.2:v1.14.1
  9. #修改镜像缓存
  10. [root@fsl nginx]# cat Dockerfile
  11. FROM centos:7.8
  12. LABEL maintainer="test"
  13. RUN yum install -y nginx && echo Nginx Website in Docker > /usr/share/nginx/html/index.html
  14. #修改下面行,从下面行开始不再使用缓存
  15. ENV REFRESH_DATA 2022-01-01
  16. EXPOSE 80
  17. CMD ["nginx","-g","daemon off"]
  18. [root@fsl nginx]#docker build -t nginx_centos:v2 .

6、示例

基础镜像制作

  1. [root@fsl centos]# cat Dockerfile
  2. FROM centos:7.8
  3. LABEL maintainer="test"
  4. RUN yum -y install wget && rm -f /etc/yum.repos.d/* && wget -P /etc/yum.repos.d/ http://mirrors.aliyun.com/repo/Centos-7.repo \
  5. && wget -P /etc/yum.repos.d/ http://mirrors.aliyun.com/repo/epel-7.repo \
  6. && yum -y install vim-enhanced tcpdump lrzsz tree telnet bash-completion net-tools wget curl bzip2 lsof zip unzip nfs-utils gcc make gcc-c++ glibc glibc-devel pcre pcre-devel openssl openssl-devel systemd-devel zlib-devel \
  7. && yum clean all \
  8. && rm -f /etc/localtime \
  9. && ln -s ../usr/share/zoneinfo/Asia/Shanghai /etc/localtime

制作nginx镜像

  1. [root@fsl 1.16]# cat Dockerfile
  2. FROM centos7.8-base:v2
  3. LABEL maintainer="test_contos_nginx" 
  4. ADD nginx-1.16.1.tar.gz /usr/local/src
  5. RUN cd /usr/local/src/nginx-1.16.1 \
  6. && ./configure --prefix=/apps/nginx \
  7. && make && make install \
  8. && rm -rf /usr/local/src/nginx* \
  9. && useradd -r nginx
  10. ADD app.tar.gz /apps/nginx/html/
  11. EXPOSE 80 443
  12. #CMD ["/apps/nginx/sbin/nginx","-g","daemon off"] #未在Dockerfile中启动Nginx,需要进入容器中启动或者在Dockerfile中启动

启动测试

  1. [root@fsl 1.16]#docker run -itd -p 8000:80 --name nginx cenos7.8_nginx:v1
  2. [root@fsl 1.16]# curl 127.0.0.1:8000/app/
  3. Test Dockerfile

直接编写Dockerfile文件安装Nginx

  1. [root@fsl]#cat Dockerfile
  2. #Nginx Dockerfile
  3. FROM centos:centos7.7.1908
  4. MAINTAINER test
  5. RUN yum install -y gcc gcc-c++ pcre pcre-devel zlib zlib-devel openssl
  6. openssl-devel \
  7. && useradd -r -s /sbin/nologin nginx \
  8. && yum clean all
  9. ADD nginx-1.16.1.tar.gz /usr/local/src/
  10. RUN cd /usr/local/src/nginx-1.16.1 \
  11. && ./configure --prefix=/apps/nginx \
  12. && make \
  13. && make install \
  14. && rm -rf /usr/local/src/nginx*
  15. ADD nginx.conf /apps/nginx/conf/nginx.conf
  16. COPY index.html /apps/nginx/html/
  17. RUN ln -s /apps/nginx/sbin/nginx /usr/sbin/nginx
  18. EXPOSE 80 443
  19. CMD ["nginx","-g","daemon off;"]
source: https://blog.51cto.com/u_11591673/5003545

记得点「」和「在看」↓

爱你们

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/Gausst松鼠会/article/detail/679311
推荐阅读
相关标签
  

闽ICP备14008679号