一、镜像管理的常用命令
注:可以使用 --no-trunc 显示完整信息
二、创建镜像
创建镜像的方法主要有三种:基于已有镜像的容器创建、基于本地模板导入、基于Dockerfile创建
2.1 基于已有镜像的容器创建
通过一个已经存在的容器创建一个新的镜像:
docker commit -m "Added a new file example.txt" -a "sawyer" 容器ID sawyerlsy/nginx:0.1
2.2 基于本地模板的导入
docker save -o nginx_image.tar nginx:latest
2.3 基于Dockerfile创建
2.3.1 示例
通常在通过Dockerfile构建镜像的时候,会选择新建一个空白目录,然后在目录中新建一个文件Dockerfile,大致内容如下:
FROM docker.io/mysql:latest MAINTAINER sawyerlsy@gmail.com ENV AUTO_RUN_DIR /docker-entrypoint-initdb.d COPY init/*.sh $AUTO_RUN_DIR/ COPY init/*.sql $AUTO_RUN_DIR/ CMD ["mysqld","--datadir=/opt/mysql/data","--user=mysql"]
构建命令为:docker build -t sawyerlsy/mysql:latest .
结果如下:
2.3.2 详解
Dockerfile是一个文本文件,其内包含了一条条的指令,每条指令构建一层。注意点:
- 上下文:当构建的时候,用户会指定构建镜像上下文的路径,docker build 命令得知这个路径后,会将路径下的所有内容打包,然后上传给 Docker 引擎。这样 Docker 引擎收到这个上下文包后,展开就会获得构建镜像所需的一切文件。所以在构建的时候通常会选择新建一个空白目录,然后在该目录中执行docker build命令。如示例,docker build末尾有一个点(.),代表将当前目录作为上下文。
- 文件名:Dockerfile文件名是默认名字,但并不是固定的,可以通过-f 参数指定名字
- 构建方式:
- 本地Dockerfile
- 直接用git构建:docker build https://xxx.xxx.xxx#:8.14 ,该命令指定了构建所需的 Git repo,并且指定默认的 master 分支,构建目录为 /8.14/,然后 Docker 就会自己去 git clone 这个项目、切换到指定分支、并进入到指定目录后开始构建。
- 用给定的 tar 压缩包构建:docker build http://xxx.xxx.xxx/mysql.tar.gz ,该命令执行后,Docker引擎会自动下载这个包,并自动解压缩,以其作为上下文,开始构建。
- 从标准输入中读取 Dockerfile 进行构建
- 从标准输入中读取上下文压缩包进行构建
- 指令:
- FROM:指定基础镜像
- MAINTAINER:指定作者信息
- RUN:执行命令
- COPY:将从构建上下文目录中 <源路径> 的文件/目录复制到新的一层的镜像内的 <目标路径> 位置,该指令会保留源文件的读、写、执行权限以及变更时间等。使用方式为:COPY init/*.sh /opt/ 或者 COPY ["init/*.sh","/opt/"] 。其中源路径可以指定多个,也可以使用通配符;目标路径可以是容器内的绝对路径,也可以是相对于工作目录的相对路径
- ADD:ADD和COPY用法相同,功能相似,区别在于如果原目标为压缩包,那么ADD会自动解压缩到目标路径。该功能实际并不常用,一般建议使用COPY,如果需要解压缩可以直接使用RUN
- CMD:容器启动命令。该命令可以在运行的时候使用新的命令替换掉。值得注意的是,Docker不是虚拟机,实际上就是进程。CMD的启动程序就是容器应用进程,容器就是为了主进程而存在的,主进程退出,容器就失去了存在的意义,也会退出。所以在编写启动命令的时候,要确保可以使容器始终执行。示例:CMD ["nginx", "-g", "daemon off;"]
- ENTRYPOINT:指定入口点。设置了ENTRYPOINT后,容器启动的时候会执行指定的shell文件,此时CMD的意义将会发生改变,不再作为一个完整的命令,而是以参数的形式传递给ENTRRPOINT文件。示例 ENTRYPOINT [ "curl", "-s", "http://ip.cn" ] 或 ENTRYPOINT [ "/entrypoint.sh"]
- ENV:设置环境变量。EVN变量可以被其他指令及容器内的应用引用。示例:ENV home=/opt 或者 ENV home /opt
- ARG:设置环境变量。ARG变量只能被Dockerfile中的其他指令使用,在将来运行时的容器中是不会存在这些变量的。ARG的变量值可以在docker build中使用--build-arg <参数名>=<值>进行覆盖。示例 :ARG username=sawyer
- VOLUME:定义匿名卷。
- EXPOSE:声明运行时容器提供的端口。这只是一个声明,在运行时并不会因为这个声明应用就会开启这个端口的服务。在 Dockerfile 中写入这样的声明有两个好处,一个是帮助镜像使用者理解这个镜像服务的守护端口,以方便配置映射;另一个用处则是在运行时使用随机端口映射时,也就是 docker run -P 时,会自动随机映射 EXPOSE 的端口。
- WORKDIR:指定工作目录。使用 WORKDIR 指令可以来指定工作目录(或者称为当前目录),以后各层的当前目录就被改为指定的目录,如该目录不存在,WORKDIR 会帮你建立目录。示例:WORKDIR /usr/local/tomcat
- USER:切换用户。USER 指令和 WORKDIR 相似,都是改变环境状态并影响以后的层。WORKDIR 是改变工作目录,USER 则是改变之后层的执行 RUN, CMD 以及 ENTRYPOINT 这类命令的身份。注:该用户必须是存在的。示例: USER redis
- HEALTHCHECK:健康检查。该指令是告诉 Docker 应该如何进行判断容器的状态是否正常。当在一个镜像指定了 HEALTHCHECK 指令后,用其启动容器,初始状态会为 starting,在 HEALTHCHECK 指令检查成功后变为 healthy,如果连续一定次数失败,则会变为 unhealthy。示例:
HEALTHCHECK --interval=5s --timeout=3s CMD curl -fs http://localhost/ || exit 1
--interval=<间隔>:两次健康检查的间隔,默认为 30 秒;
--timeout=<时长>:健康检查命令运行超时时间,如果超过这个时间,本次健康检查就被视为失败,默认 30 秒;
--retries=<次数>:当连续失败指定次数后,则将容器状态视为 unhealthy,默认 3 次。 - ONBUILD:ONBUILD 是一个特殊的指令,它后面跟的是其它指令,比如 RUN, COPY 等,而这些指令,在当前镜像构建时并不会被执行。只有当以当前镜像为基础镜像,去构建下一级镜像的时候才会被执行。示例:ONBUILD COPY /opt/app/* /app/