Docker—Dockerfile详解及微服务制作运行容器镜像步骤命令总结
关注微信公众号:CodingTechWork,一起学习进步。
引言
上云、k8s部署,不可避免需要使用容器化,面对容器化,不可避免使用Docker,对于Docker不得不提镜像的制作。本文主要学习和总结Dockerfile声明详解及常用的docker命令。
Dockerfile
文件概述
Dockerfile是一个用于自定义构建镜像的文本文件,其中包含了多条构建镜像所需要的指令、软件依赖和说明。
指令详解
FROM
指定基础镜像
格式:
FROM <image>
FROM <image>:<tag>
FROM <image>@<digest>
描述:
tag和digest可选,不指定时,则使用latest版本基础镜像,digest表示V2版本及以上版本镜像的内容可寻址标识符。
示例:
FROM centos:7
MAINTAINER
维护者信息
格式:
MAINTAINER <name>
描述:
name即为维护者信息,可自定义为姓名、邮箱地址等
示例:
MAINTAINER andya
MAINTAINER andya@163.com
MAINTAINER andya <andya@163.com>
ENV
设置环境变量
格式:
ENV <key> <value>
ENV <key>=<value> ...
描述:
1)ENV <key> <value> 中的<key>后面内容都作为<value>的内容,所以一次只能设置一个变量
2)ENV <key>=<value> ... 可以设置多个变量,若遇到空格等可使用\进行转义,或""进行标识
示例:
ENV addressInfo suzhou xiancheng
ENV addressCity=suzhou
VOLUME
指定持久化目录为匿名卷,防止运行时用户将动态文件所保存目录挂载为卷。
格式:
VOLUME ["<dir01>", "<dir02>", ...]
VOLUME <dir>
描述:
指定持久化目录,卷可以存在于一个或多个容器的指定目录
示例:
VOLUME ["/data/data01", "/data/data02"]
VOLUME /data
COPY
拷贝功能,类似于ADD,但不可以自动解压文件,且不能访问网络资源
格式:
COPY [--chown=<user>:<group>] <src>... <dest>
COPY [--chown=<user>:<group>] ["<src>",... "<dest>"]
描述:
1)[--chown=<user>:<group>]为可选参数,改变文件的所属者和属组。
2)目标路径不存在时,会自动创建。
示例:
COPY demo.tar demo01.tar
COPY --chown=user01:group01 demo.tar demo02.tar
ADD
拷贝功能,类似于COPY,但会自动解压tar等压缩文件。
格式:
ADD <sourceDir1>... <dest>
ADD ["<sourceDir1>", ... "<targetDir>"]
描述:
1)用[],可以支持包含空格的路径。
2)基本功能和格式同COPY。
示例:
ADD demo.jar /app.jar
ADD *.sh /shell
ADD dir01 relativeDir/
ADD dir02 /absoluteDir
RUN
执行命令。
格式:
# shell执行
RUN <command>
# exec执行
RUN ["executable", "param1", "param2"]
描述:
1)Dockerfile的指令每执行一次都会在docker上新建一层,所以尽量合并RUN。
2)exec执行格式是JSON数组,必须使用双引号描述。
3)exec格式不调用命令行shell,需要使用shell格式或者路径。如RUN [ "echo", "$HOME" ]不生效,需要使用RUN [ "sh", "-c", "echo $HOME" ]。
示例:
RUN yum install wget \
&& tar -xvf demo.tar
&& chmod -R 777 /shell
RUN /bin/bash -c 'source $HOME/.bashrc; \
echo $HOME'
RUN /bin/bash -c 'source $HOME/.bashrc; echo $HOME'
RUN ["/bin/bash", "-c", "echo hello"]
EXPOSE
指定与外界交互的端口。
格式:
EXPOSE <port> [<port>/<protocol>...]
描述:
1)默认TCP协议。
2)EXPOSE不是真正的发布该端口,需要在docker run中使用-p进行发布,如docker run -p 80:80/tcp -p 80:80/udp。
示例:
EXPOSE 8080
EXPOSE 10001/tcp 10002/udp
WROKDIR
指定工作目录,类似于cd命令。默认不设置即为容器根目录/
格式:
WROKDIR <dir>
描述:
1)设置工作目录后,Dockerfile后的命令RUN, CMD, ENTRYPOINT, COPY和ADD等命令,都在该目录下运行。
2)若不存在,则自动创建。
3)在docker run时,可以通过-w或--workdir进行覆盖。
4)在Dockerfile中可以多次使用,使用相对路径时,会基于第一个进行拼接成绝对路径。
示例:
# 此时工作目录为根目录/
WROKDIR /
# 此时工作目录为/c
WROKDIR c
ENTRYPOINT
格式:
# exec格式
ENTRYPOINT ["executable", "param1", "param2"]
# shell格式
ENTRYPOINT command param1 param2
描述:
1)shell格式的将会拒绝任何CMD或者run命令行的参数,将以/bin/sh -c开头,只有exec格式的才可以在命令行中使用--entrypoint进行覆盖。
2)Dockerfile中只有最后一个ENTRYPOINT有效。
3)同RUN,exec格式中ENTRYPOINT [ "echo", "$HOME" ]无效,需要指定sh -c,如使用ENTRYPOINT [ "sh", "-c", "echo $HOME" ]
示例:
# exec格式
ENTRYPOINT ["top", "-b"]
CMD ["-c"]
# shell格式
ENTRYPOINT exec top -b
CMD
CMD的最主要目的是为一个执行中容器提供默认值。包括可执行文件/程序。
格式:
# exec form, this is the preferred form
CMD ["executable","param1","param2"]
# shell form
CMD command param1 param2
# as default parameters to ENTRYPOINT
CMD ["param1","param2"]
描述:
1)Dockerfile中若有多个CMD,则只有最后一个CMD有效。
2)当CMD为ENTRYPOINT提供默认参数时,CMD和ENTRYPOINT都需要以JSON数组格式进行声明。
3)同ENTRYPOINT,exec格式中CMD [ "echo", "$HOME" ]无效,需要指定sh -c,如使用CMD [ "sh", "-c", "echo $HOME" ],当然,也可以直接使用shell格式:CMD echo $HOME
4)与RUN不同,RUN是docker build构建docker镜像时执行的命令,真正运行一个命令并提交运行结果。CMD在build时期不执行任何东西,在docker run执行docker镜像构建容器时,为镜像声明了预期的命令。ENTRYPOINT命令一定会执行,一般用于执行脚本。
示例:
# exec格式
CMD ["/usr/bin/wc","--help"]
# shell格式
CMD echo "This is a test." | wc -
LABEL
给镜像添加元数据,LABEL是一堆key-value对。
格式:
LABEL <key>=<value> <key>=<value> <key>=<value> ...
描述:
镜像可以有1个或多个label,且可以在一行设置多个label,通过空格分隔。推荐使用一条LABEL指令指定多个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."
USER
设置用户名(或UID)和可选设置用户组(或GID),用于运行镜像及RUN、CMD、ENTRYPOINT命令。
格式:
USER <user>[:<group>]
USER <UID>[:<GID>]
描述:
1)可以直接指定用户名或所属组名,也可以指定UID或GID。
2)当为用户指定一个用户组,则该用户只有该指定的组关系,其他组成员关系将会被忽略。
示例:
USER userA
ARG
用户指定传递给build构建运行时的变量
格式:
ARG <name>[=<default value>]
描述:
1)docker build命令中通过--build-arg <varname>=<value>进行指定,若Dockerfile不存在该arg声明,则抛警告。
示例:
FROM busybox
ARG user1
ARG buildno
# 设置默认值
FROM busybox
ARG user1=someuser
ARG buildno=1
RUN、ENTRYPOINT和CMD区别
- RUN是docker build构建docker镜像时执行的命令,真正运行一个命令并提交运行结果。
- CMD在docker build时期不执行任何东西,在docker run执行docker镜像构建容器时,为镜像声明了预期的命令。存在多条CMD时,只会执行最后一条,当同时存在ENTRYPOINT时,CMD命令将充当参数(exec格式提供默认值)或者被覆盖。若不存在ENTRYPOINT时,则可以动态覆盖或执行命令。
- ENTRYPOINT命令一定会执行,一般用于执行脚本。shell格式的ENTRYPOINT命令,都不会执行在Dockerfile中存在CMD命令还是在docker run添加的命令。exec格式的ENTRYPOINT命令,CMD命令或docker run添加的命令,会被当做ENTRYPOINT命令的参数执行。
模板示例
基础镜像Dockerfile
编写基础镜像的Dockerfile
# 设置及下载相关服务
RUN yum install -y tar \
&& yum install -y java-1.8.0-openjdk* \
&& yum install -y unzip \
&& yum install -y less \
&& yum install -y vi \
&& cp /usr/share/zoneinfo/Asia/Shanghai /etc/localtime \
&& echo 'Asia/Shanghai' > /etc/timezone
# 解决中文编码
ENV LANG en_US.UTF-8
ENV LANGUAGE en_US:en
ENV LC_ALL en_US.UTF-8
制作基础镜像
$ docker build -t centos-basic:v1.0 .
服务镜像Dockerfile
有了上述的基础镜像,在服务Dockerfile中声明FROM centos-basic:v1.0
。
# base images: 基础镜像
FROM centos-basic:v1.0
# maintainer: 维护者信息
MAINTAINER andya
# env config: 环境变量设置
ENV JAVA_HOME /usr/local/jdk1.8.0_170
ENV PATH $JAVA_HOME/bin:$PATH
# volume:匿名数据卷
VOLUME /nfs
# copy: 拷贝目录或文件(不解压tar包)
COPY --chown=userA:groupA demo.tar demo01.tar
# add:拷贝目录或文件(自动解压tar包)
ADD config /config
ADD sql /sql
ADD micro-service01-1.0.jar /app.jar
# run: 执行命令,修改目录权限
RUN chmod -R 777 /sql
# run: 执行命令,修改文件的访问时间和修改时间为当前时间,而不会修改文件的内容
RUN bash -c 'touch /app.jar'
# expose:暴露端口
EXPOSE 8001
# workdir: 类似于cd进入工作目录
WROKDIR /
# entrypoint:设定容器启动时第一个运行的命令及参数
ENTRYPOINT ["java","-Djava.security.egd=file:/dev/./urandom","-jar","/app.jar"]
镜像制作
-
docker build构建镜像
docker build -t 镜像仓库ip:port/service/micro01:v1.0 .
注意命令尾部的.
-
docker login登录镜像仓库
docker login 镜像仓库ip:port
-
docker images查看进行
docker imgaes | grep micro01
-
docker push推送镜像至镜像仓库
docker push 镜像仓库ip:port/service/micro01:v1.0
-
docker save保存镜像tar包
docker save 容器id > 名字.tar
docker常用命令
运行容器
-
docker load加载镜像
docker load -i 名字.tar
-
docker images
模糊查看镜像iddocker images | grep "xxx"
-
docker run启动容器
docker run image_id
得到container_id -
docker logs查看容器日志
docker logs -f <containter_id>
-
docker exec进入容器
docker exec -it <container_id> /bin/bash
其他命令
-
docker cp将文件拷贝到对应的容器的位置中
docker cp <file> <container_id>:/dir01/dir02
-
docker restart重启容器
docker restart <container_id>
-
docker commit基于某个容器更改重建一个容器
docker commit <container_id> <repository>:<tag>
Usage: docker [OPTIONS] COMMAND
A self-sufficient runtime for containers
Options:
--config string Location of client config files (default "/root/.docker")
-D, --debug Enable debug mode
-H, --host list Daemon socket(s) to connect to
-l, --log-level string Set the logging level ("debug"|"info"|"warn"|"error"|"fatal") (default "info")
--tls Use TLS; implied by --tlsverify
--tlscacert string Trust certs signed only by this CA (default "/root/.docker/ca.pem")
--tlscert string Path to TLS certificate file (default "/root/.docker/cert.pem")
--tlskey string Path to TLS key file (default "/root/.docker/key.pem")
--tlsverify Use TLS and verify the remote
-v, --version Print version information and quit
Management Commands:
builder Manage builds
config Manage Docker configs
container Manage containers
engine Manage the docker engine
image Manage images
network Manage networks
node Manage Swarm nodes
plugin Manage plugins
secret Manage Docker secrets
service Manage services
stack Manage Docker stacks
swarm Manage Swarm
system Manage Docker
trust Manage trust on Docker images
volume Manage volumes
Commands:
attach Attach local standard input, output, and error streams to a running container
build Build an image from a Dockerfile
commit Create a new image from a container's changes
cp Copy files/folders between a container and the local filesystem
create Create a new container
diff Inspect changes to files or directories on a container's filesystem
events Get real time events from the server
exec Run a command in a running container
export Export a container's filesystem as a tar archive
history Show the history of an image
images List images
import Import the contents from a tarball to create a filesystem image
info Display system-wide information
inspect Return low-level information on Docker objects
kill Kill one or more running containers
load Load an image from a tar archive or STDIN
login Log in to a Docker registry
logout Log out from a Docker registry
logs Fetch the logs of a container
pause Pause all processes within one or more containers
port List port mappings or a specific mapping for the container
ps List containers
pull Pull an image or a repository from a registry
push Push an image or a repository to a registry
rename Rename a container
restart Restart one or more containers
rm Remove one or more containers
rmi Remove one or more images
run Run a command in a new container
save Save one or more images to a tar archive (streamed to STDOUT by default)
search Search the Docker Hub for images
start Start one or more stopped containers
stats Display a live stream of container(s) resource usage statistics
stop Stop one or more running containers
tag Create a tag TARGET_IMAGE that refers to SOURCE_IMAGE
top Display the running processes of a container
unpause Unpause all processes within one or more containers
update Update configuration of one or more containers
version Show the Docker version information
wait Block until one or more containers stop, then print their exit codes
Run 'docker COMMAND --help' for more information on a command.