内容简介:历史系列:
1. 概述
github项目地址: https://github.com/superwujc
尊重原创,欢迎转载,注明出处: https://my.oschina.net/superwjc/blog/3045629
历史系列:
docker CE on Linux示例浅析(一)安装与基本运行
docker CE on Linux示例浅析(二)数据存储与持久化
镜像是静态存储的磁盘文件,容器是动态运行的内存进程,二者可以视为 docker 一体的两面。在docker的整个工作流程中,与镜像与容器相关的操作贯穿始终,其他功能大都以此为基础进行展开或封装。本文将以jdk + tomcat为例,简述镜像/容器的基本管理,包括构建与运行,以及迁移与恢复过程。
2. 环境
- 宿主机2台:dock_host_0(192.168.9.168/24),dock_host_1(192.168.9.169/24),均为全新最小化安装,二者的系统与软件环境一致。操作系统版本CentOS Linux release 7.6.1810 (Core),内核版本3.10.0-957.12.1.el7.x86_64,docker为默认安装,版本18.09.5,无其他设置。
- 源码包jdk-8u212-linux-x64.tar.gz与apache-tomcat-8.5.40.tar.gz,位于宿主机/opt/目录下。
- 容器所用镜像为最新版CentOS 7官方镜像。
- jdk环境以命名卷jdks的方式挂载至容器的/opt/jdks目录,以减小镜像占用的磁盘空间,并加快镜像构建的速度。
- tomcat环境位于容器的/opt/apps/app_0目录,所有设置均为默认。
3. 示例
获取操作系统镜像centos,并设置命名卷jdks:
[root@docker_host_0 ~]# ip addr show eth0 | sed -n '/inet /p' | awk '{print $2}'
192.168.9.168/24
[root@docker_host_0 ~]# docker -v
Docker version 18.09.5, build e8ff056
[root@docker_host_0 ~]#
[root@docker_host_0 ~]# docker pull centos
Using default tag: latest
latest: Pulling from library/centos
8ba884070f61: Pull complete
Digest: sha256:8d487d68857f5bc9595793279b33d082b03713341ddec91054382641d14db861
Status: Downloaded newer image for centos:latest
[root@docker_host_0 ~]#
[root@docker_host_0 ~]# docker image ls -a
REPOSITORY TAG IMAGE ID CREATED SIZE
centos latest 9f38484d220f 7 weeks ago 202MB
[root@docker_host_0 ~]#
[root@docker_host_0 ~]# cd /opt/
[root@docker_host_0 opt]#
[root@docker_host_0 opt]# ll
total 199908
-rw-r--r-- 1 root root 9690027 May 5 21:55 apache-tomcat-8.5.40.tar.gz
drwx--x--x 4 root root 28 May 5 22:04 containerd
-rw-r--r-- 1 root root 195013152 May 5 21:55 jdk-8u212-linux-x64.tar.gz
[root@docker_host_0 opt]#
[root@docker_host_0 opt]# docker volume create jdks
jdks
[root@docker_host_0 opt]# docker volume ls
DRIVER VOLUME NAME
local jdks
[root@docker_host_0 opt]#
[root@docker_host_0 opt]# tar axf jdk-8u212-linux-x64.tar.gz -C /var/lib/docker/volumes/jdks/_data/
[root@docker_host_0 opt]# ll /var/lib/docker/volumes/jdks/_data/
total 0
drwxr-xr-x 7 10 143 245 Apr 2 04:49 jdk1.8.0_212
[root@docker_host_0 opt]#
[root@docker_host_1 ~]# ip addr show eth0 | sed -n '/inet /p' | awk '{print $2}'
192.168.9.169/24
[root@docker_host_1 ~]# docker -v
Docker version 18.09.5, build e8ff056
[root@docker_host_1 ~]#
[root@docker_host_1 ~]# docker pull centos
Using default tag: latest
latest: Pulling from library/centos
8ba884070f61: Pull complete
Digest: sha256:8d487d68857f5bc9595793279b33d082b03713341ddec91054382641d14db861
Status: Downloaded newer image for centos:latest
[root@docker_host_1 ~]#
[root@docker_host_1 ~]# docker image ls -a
REPOSITORY TAG IMAGE ID CREATED SIZE
centos latest 9f38484d220f 7 weeks ago 202MB
[root@docker_host_1 ~]#
[root@docker_host_1 ~]# cd /opt/
[root@docker_host_1 opt]# ll
total 199908
-rw-r--r-- 1 root root 9690027 May 5 21:55 apache-tomcat-8.5.40.tar.gz
drwx--x--x 4 root root 28 May 5 21:58 containerd
-rw-r--r-- 1 root root 195013152 May 5 21:55 jdk-8u212-linux-x64.tar.gz
[root@docker_host_1 opt]#
[root@docker_host_1 opt]# docker volume create jdks
jdks
[root@docker_host_1 opt]#
[root@docker_host_1 opt]# docker volume ls
DRIVER VOLUME NAME
local jdks
[root@docker_host_1 opt]#
[root@docker_host_1 opt]# tar axf jdk-8u212-linux-x64.tar.gz -C /var/lib/docker/volumes/jdks/_data/
[root@docker_host_1 opt]# ll /var/lib/docker/volumes/jdks/_data/
total 0
drwxr-xr-x 7 10 143 245 Apr 2 04:49 jdk1.8.0_212
[root@docker_host_1 opt]#
3.1 构建
docker镜像的构建过程为逐层进行,上层镜像称为父(parent)镜像,顶层镜像称为基础(base)镜像,通常为操作系统。对于运行中的容器,其可写层中产生的内容变更经过保存(commit),与父镜像共同组成当前层级的镜像。
镜像的构建可以通过手动与自动的方式。手动方式为重复运行父镜像,将需要定制的内容逐步添加到可写层并保存;自动方式则将需要实现的功能写入到文件(Dockerfile),由docker主进程读取该文件,并按指令完成构建。
3.1.1 手动构建
以名称t_c_0运行centos镜像,并创建/opt/apps目录:
[root@docker_host_0 opt]# docker run --name t_c_0 centos bash -c "mkdir -p /opt/apps" [root@docker_host_0 opt]# [root@docker_host_0 opt]# docker container ls -a CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES 6a6a3ed5a380 centos "bash -c 'mkdir -p /…" 8 seconds ago Exited (0) 7 seconds ago t_c_0 [root@docker_host_0 opt]#
将tomcat复制到容器的/opt/apps/app_0目录:
[root@docker_host_0 opt]# tar axf apache-tomcat-8.5.40.tar.gz [root@docker_host_0 opt]# [root@docker_host_0 opt]# ll -d apache-tomcat-8.5.40 drwxr-xr-x 9 root root 220 May 5 22:15 apache-tomcat-8.5.40 [root@docker_host_0 opt]# [root@docker_host_0 opt]# docker cp apache-tomcat-8.5.40 t_c_0:/opt/apps/app_0 [root@docker_host_0 opt]#
将t_c_0容器的当前状态保存为t_i_0镜像:
[root@docker_host_0 opt]# docker container commit t_c_0 t_i_0 sha256:1aa86a5d25c2933cbf1b5e455435b44b3eb3c5501190116d02c6028cda11a318 [root@docker_host_0 opt]# [root@docker_host_0 opt]# docker image ls -a REPOSITORY TAG IMAGE ID CREATED SIZE t_i_0 latest 1aa86a5d25c2 5 seconds ago 216MB centos latest 9f38484d220f 7 weeks ago 202MB [root@docker_host_0 opt]#
以名称t_c_1运行t_i_0镜像,并指定容器的开放端口(--expose),环境变量(-e/--env),工作目录(-w/--workdir):
[root@docker_host_0 opt]# docker run --name t_c_1 --expose 8080 --env JAVA_HOME=/opt/jdks/jdk1.8.0_212 --workdir /opt/apps/app_0 t_i_0 /bin/bash [root@docker_host_0 opt]# [root@docker_host_0 opt]# docker container ls -a CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES 63258c74cb4b t_i_0 "/bin/bash" 8 seconds ago Exited (0) 6 seconds ago t_c_1 6a6a3ed5a380 centos "bash -c 'mkdir -p /…" 3 minutes ago Exited (0) 3 minutes ago t_c_0 [root@docker_host_0 opt]#
将t_c_1容器的当前状态保存为t_i_1镜像:
[root@docker_host_0 opt]# docker container commit t_c_1 t_i_1 sha256:c5f0d673d958aad49db41e154bf723bb947be257a9999014881ab90e8f155106 [root@docker_host_0 opt]# [root@docker_host_0 opt]# docker image ls -a REPOSITORY TAG IMAGE ID CREATED SIZE t_i_1 latest c5f0d673d958 7 seconds ago 216MB t_i_0 latest 1aa86a5d25c2 2 minutes ago 216MB centos latest 9f38484d220f 7 weeks ago 202MB [root@docker_host_0 opt]#
以t_i_1为父镜像创建t_c_2容器,并添加命令"bin/startup.sh && tail -f logs/catalina.out"
docker create与docker run都可以为镜像添加命令,区别在于create命令仅添加而不运行,run命令则既添加且运行。本例中运行最终镜像需要挂载jdk环境,否则将报错而启动失败,且将不必要的日志文件编译进镜像中,因此使用create命令而非run命令。
[root@docker_host_0 opt]# docker container create --name t_c_2 t_i_1 bash -c "bin/startup.sh && tail -f logs/catalina.out" e414c244d72525431607f4f439fe7590600316a97cda17f78d4ee8b1d0c25bf8 [root@docker_host_0 opt]# [root@docker_host_0 opt]# docker container ls -a CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES e414c244d725 t_i_1 "bash -c 'bin/startu…" 6 seconds ago Created t_c_2 63258c74cb4b t_i_0 "/bin/bash" 2 minutes ago Exited (0) 2 minutes ago t_c_1 6a6a3ed5a380 centos "bash -c 'mkdir -p /…" 5 minutes ago Exited (0) 5 minutes ago t_c_0 [root@docker_host_0 opt]#
将t_c_2容器的当前状态保存为tomcat_app_manual镜像,手动构建完成。
[root@docker_host_0 opt]# docker container commit t_c_2 tomcat_app_manual sha256:557c9112cb3f132de99f850bf11a5954a15816e30fa45fd2ab01f9c3030f02f1 [root@docker_host_0 opt]# [root@docker_host_0 opt]# docker image ls -a REPOSITORY TAG IMAGE ID CREATED SIZE tomcat_app_manual latest 557c9112cb3f 8 seconds ago 216MB t_i_1 latest c5f0d673d958 About a minute ago 216MB t_i_0 latest 1aa86a5d25c2 3 minutes ago 216MB centos latest 9f38484d220f 7 weeks ago 202MB [root@docker_host_0 opt]#
查看镜像的属性信息:
inspect命令的--format选项用于以 go 模板格式化输出,也可以通过 shell 的grep/awk/sed手动过滤,以查看指定块与字段。
[root@docker_host_0 opt]# docker image inspect --format='{{ .Config.Env }}' tomcat_app_manual
[JAVA_HOME=/opt/jdks/jdk1.8.0_212 PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin]
[root@docker_host_0 opt]# docker image inspect --format='{{ .Config.ExposedPorts }}' tomcat_app_manual
map[8080/tcp:{}]
[root@docker_host_0 opt]# docker image inspect --format='{{ .Config.WorkingDir }}' tomcat_app_manual
/opt/apps/app_0
[root@docker_host_0 opt]# docker image inspect --format='{{ .Config.Cmd }}' tomcat_app_manual
[bash -c bin/startup.sh && tail -f logs/catalina.out]
[root@docker_host_0 opt]#
以名称app_man运行tomcat_app_manual镜像,挂载共享卷并映射端口:
[root@docker_host_0 opt]# docker run -dit --name app_man -p 8080:8080 --mount src=jdks,dst=/opt/jdks,ro tomcat_app_manual a5c1750f880c3873d14d48dd237f9e47eaa08184117fe4c79e53e001997dcd2e [root@docker_host_0 opt]# [root@docker_host_0 opt]# docker container ls -a CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES a5c1750f880c tomcat_app_manual "bash -c 'bin/startu…" 5 seconds ago Up 5 seconds 0.0.0.0:8080->8080/tcp app_man e414c244d725 t_i_1 "bash -c 'bin/startu…" 6 minutes ago Created t_c_2 63258c74cb4b t_i_0 "/bin/bash" 8 minutes ago Exited (0) 8 minutes ago t_c_1 6a6a3ed5a380 centos "bash -c 'mkdir -p /…" 11 minutes ago Exited (0) 11 minutes ago t_c_0 [root@docker_host_0 opt]#
容器内的tomcat进程成功启动,并已创建端口映射:
[root@docker_host_0 opt]# docker container top app_man UID PID PPID C STIME TTY TIME CMD root 7769 7751 0 22:25 pts/0 00:00:00 bash -c bin/startup.sh && tail -f logs/catalina.out root 7815 7769 1 22:25 pts/0 00:00:02 /opt/jdks/jdk1.8.0_212/bin/java -Djava.util.logging.config.file=/opt/apps/app_0/conf/logging.properties -Djava.util.logging.manager=org.apache.juli.ClassLoaderLogManager -Djdk.tls.ephemeralDHKeySize=2048 -Djava.protocol.handler.pkgs=org.apache.catalina.webresources -Dorg.apache.catalina.security.SecurityListener.UMASK=0027 -Dignore.endorsed.dirs= -classpath /opt/apps/app_0/bin/bootstrap.jar:/opt/apps/app_0/bin/tomcat-juli.jar -Dcatalina.base=/opt/apps/app_0 -Dcatalina.home=/opt/apps/app_0 -Djava.io.tmpdir=/opt/apps/app_0/temp org.apache.catalina.startup.Bootstrap start root 7816 7769 0 22:25 pts/0 00:00:00 tail -f logs/catalina.out [root@docker_host_0 opt]# [root@docker_host_0 opt]# docker container port app_man 8080/tcp -> 0.0.0.0:8080 [root@docker_host_0 opt]# [root@docker_host_0 opt]# docker container logs app_man Using CATALINA_BASE: /opt/apps/app_0 Using CATALINA_HOME: /opt/apps/app_0 Using CATALINA_TMPDIR: /opt/apps/app_0/temp Using JRE_HOME: /opt/jdks/jdk1.8.0_212 Using CLASSPATH: /opt/apps/app_0/bin/bootstrap.jar:/opt/apps/app_0/bin/tomcat-juli.jar Tomcat started. ... 05-May-2019 22:25:55.060 INFO [main] org.apache.catalina.startup.Catalina.start Server startup in 521 ms [root@docker_host_0 opt]# [root@docker_host_0 opt]# ss -atn | grep 8080 LISTEN 0 128 :::8080 :::* [root@docker_host_0 opt]#
发送请求,访问日志显示tomcat正常运行:
tomcat默认的访问日志以日期命名,形式为 localhost_access_log.YYYY-MM-DD.txt
[root@docker_host_0 opt]# curl localhost:8080 &> /dev/null [root@docker_host_0 opt]# docker exec -it app_man tail -f logs/localhost_access_log.$(date +%F).txt 172.17.0.1 - - [05/May/2019:22:31:47 +0000] "GET / HTTP/1.1" 200 11204
停止容器后,宿主机的端口映射关闭:
[root@docker_host_0 opt]# docker container stop app_man app_man [root@docker_host_0 opt]# [root@docker_host_0 opt]# docker container ls -a CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES a5c1750f880c tomcat_app_manual "bash -c 'bin/startu…" 9 minutes ago Exited (137) 9 seconds ago app_man e414c244d725 t_i_1 "bash -c 'bin/startu…" 15 minutes ago Created t_c_2 63258c74cb4b t_i_0 "/bin/bash" 17 minutes ago Exited (0) 17 minutes ago t_c_1 6a6a3ed5a380 centos "bash -c 'mkdir -p /…" 20 minutes ago Exited (0) 20 minutes ago t_c_0 [root@docker_host_0 opt]# [root@docker_host_0 opt]# ss -atn | grep 8080 [root@docker_host_0 opt]#
3.1.2 自动构建
创建名称为Dockerfile的文件,并添加以下内容:
[root@docker_host_0 opt]# vi Dockerfile FROM centos:latest COPY apache-tomcat-8.5.40 /opt/apps/app_0 EXPOSE 8080 ENV JAVA_HOME /opt/jdks/jdk1.8.0_212 WORKDIR /opt/apps/app_0 CMD bin/startup.sh && tail -f logs/catalina.out
在Dockerfile所在目录下,执行build命令构建镜像,名称为tomcat_app_automatic:
[root@docker_host_0 opt]# docker build -t tomcat_app_automatic . Sending build context to Docker daemon 219.1MB Step 1/6 : FROM centos:latest ---> 9f38484d220f Step 2/6 : COPY apache-tomcat-8.5.40 /opt/apps/app_0 ---> a9ec389212f2 Step 3/6 : EXPOSE 8080 ---> Running in b52093559f48 Removing intermediate container b52093559f48 ---> 7e52baca9d55 Step 4/6 : ENV JAVA_HOME /opt/jdks/jdk1.8.0_212 ---> Running in a39dfd747133 Removing intermediate container a39dfd747133 ---> 9d735d4bf9b1 Step 5/6 : WORKDIR /opt/apps/app_0 ---> Running in 5137688b2b8e Removing intermediate container 5137688b2b8e ---> c7bf4a13f5ef Step 6/6 : CMD bin/startup.sh && tail -f logs/catalina.out ---> Running in 6e234908cd40 Removing intermediate container 6e234908cd40 ---> 88d50ce0f132 Successfully built 88d50ce0f132 Successfully tagged tomcat_app_automatic:latest [root@docker_host_0 opt]#
REPOSITORY与TAG为<none>的镜像为自动构建过程中生成的中间层,每一层对应一条Dockerfile指令:
[root@docker_host_0 opt]# docker image ls -a
REPOSITORY TAG IMAGE ID CREATED SIZE
tomcat_app_automatic latest 88d50ce0f132 5 minutes ago 216MB
<none> <none> a9ec389212f2 5 minutes ago 216MB
<none> <none> 9d735d4bf9b1 5 minutes ago 216MB
<none> <none> 7e52baca9d55 5 minutes ago 216MB
<none> <none> c7bf4a13f5ef 5 minutes ago 216MB
tomcat_app_manual latest 557c9112cb3f 24 minutes ago 216MB
t_i_1 latest c5f0d673d958 26 minutes ago 216MB
t_i_0 latest 1aa86a5d25c2 28 minutes ago 216MB
centos latest 9f38484d220f 7 weeks ago 202MB
[root@docker_host_0 opt]#
[root@docker_host_0 opt]#
[root@docker_host_0 opt]# docker image inspect --format='{{ .ContainerConfig.Cmd }}' 9d735d4bf9b1
[/bin/sh -c #(nop) ENV JAVA_HOME=/opt/jdks/jdk1.8.0_212]
[root@docker_host_0 opt]# docker image inspect --format='{{ .ContainerConfig.Cmd }}' a9ec389212f2
[/bin/sh -c #(nop) COPY dir:2e81cf3513b112d6ce6d7132e7bca23162bdba7cbf381d72f1b9a7a42c87f19d in /opt/apps/app_0 ]
[root@docker_host_0 opt]# docker image inspect --format='{{ .ContainerConfig.Cmd }}' 7e52baca9d55
[/bin/sh -c #(nop) EXPOSE 8080]
[root@docker_host_0 opt]# docker image inspect --format='{{ .ContainerConfig.Cmd }}' c7bf4a13f5ef
[/bin/sh -c #(nop) WORKDIR /opt/apps/app_0]
[root@docker_host_0 opt]# docker image inspect --format='{{ .ContainerConfig.Cmd }}' tomcat_app_automatic
[/bin/sh -c #(nop) CMD ["/bin/sh" "-c" "bin/startup.sh && tail -f logs/catalina.out"]]
[root@docker_host_0 opt]#
以名称app_auto启动tomcat_app_automatic镜像:
[root@docker_host_0 opt]# docker run -dit --name app_auto -p 8080:8080 --mount src=jdks,dst=/opt/jdks,ro tomcat_app_automatic 57878e669fb99606f85dccf6937a43babaa23c327040c7994657fab2ac0e5acb [root@docker_host_0 opt]# [root@docker_host_0 opt]# docker container ls -a CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES 57878e669fb9 tomcat_app_automatic "/bin/sh -c 'bin/sta…" 5 seconds ago Up 4 seconds 0.0.0.0:8080->8080/tcp app_auto a5c1750f880c tomcat_app_manual "bash -c 'bin/startu…" 22 minutes ago Exited (137) 13 minutes ago app_man e414c244d725 t_i_1 "bash -c 'bin/startu…" 28 minutes ago Created t_c_2 63258c74cb4b t_i_0 "/bin/bash" 30 minutes ago Exited (0) 30 minutes ago t_c_1 6a6a3ed5a380 centos "bash -c 'mkdir -p /…" 33 minutes ago Exited (0) 33 minutes ago t_c_0 [root@docker_host_0 opt]# [root@docker_host_0 opt]# docker container top app_auto UID PID PPID C STIME TTY TIME CMD root 8305 8287 0 22:48 pts/0 00:00:00 /bin/sh -c bin/startup.sh && tail -f logs/catalina.out root 8352 8305 3 22:48 pts/0 00:00:02 /opt/jdks/jdk1.8.0_212/bin/java -Djava.util.logging.config.file=/opt/apps/app_0/conf/logging.properties -Djava.util.logging.manager=org.apache.juli.ClassLoaderLogManager -Djdk.tls.ephemeralDHKeySize=2048 -Djava.protocol.handler.pkgs=org.apache.catalina.webresources -Dorg.apache.catalina.security.SecurityListener.UMASK=0027 -Dignore.endorsed.dirs= -classpath /opt/apps/app_0/bin/bootstrap.jar:/opt/apps/app_0/bin/tomcat-juli.jar -Dcatalina.base=/opt/apps/app_0 -Dcatalina.home=/opt/apps/app_0 -Djava.io.tmpdir=/opt/apps/app_0/temp org.apache.catalina.startup.Bootstrap start root 8353 8305 0 22:48 pts/0 00:00:00 tail -f logs/catalina.out [root@docker_host_0 opt]# [root@docker_host_0 opt]# docker container port app_auto 8080/tcp -> 0.0.0.0:8080 [root@docker_host_0 opt]# [root@docker_host_0 opt]# ss -atn | grep 8080 LISTEN 0 128 :::8080 :::* [root@docker_host_0 opt]#
发送请求并查看日志:
[root@docker_host_0 opt]# curl localhost:8080 &> /dev/null [root@docker_host_0 opt]# [root@docker_host_0 opt]# docker exec -it app_auto tail -f logs/localhost_access_log.$(date +%F).txt 172.17.0.1 - - [05/May/2019:22:52:28 +0000] "GET / HTTP/1.1" 200 11204
查看app_auto容器的运行参数:
[root@docker_host_0 opt]# docker container inspect --format='{{ .Config.Env }}' app_auto
[PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin JAVA_HOME=/opt/jdks/jdk1.8.0_212]
[root@docker_host_0 opt]# docker container inspect --format='{{ .Config.ExposedPorts }}' app_auto
map[8080/tcp:{}]
[root@docker_host_0 opt]# docker container inspect --format='{{ .Config.WorkingDir }}' app_auto
/opt/apps/app_0
[root@docker_host_0 opt]# docker container inspect --format='{{ .Config.Cmd }}' app_auto
[/bin/sh -c bin/startup.sh && tail -f logs/catalina.out]
[root@docker_host_0 opt]#
对比两种构建方式,初始状态(centos镜像)与最终状态(tomcat镜像)相同,且目标镜像的大小与运行结果相同。自动构建无需关注中间细节,仅需将功能对应的指令与参数写入到文件,构建过程由docker完成,且自动移除构建过程中产生的中间过渡容器。
Dockerfile中的每一条指令均可以对应到手动构建的命令行选项/参数:
- docker run centos对应于FROM centos
- docker cp对应于COPY
- --expose对应于EXPOST
- --workdir对应于WORKDIR
- --env对应于ENV
- docker container create命令对应于CMD
3.2 迁移
- export与save命令分别以容器与镜像标识作为参数,将容器与镜像以tar包的形式导出。两条命令默认将结果输出至STDOUT,可以通过输出重定向或-o/--output选项写入到指定的文件。
- import命令与load命令将容器与镜像的tar包导入为本地镜像。load命令默认从STDIN读取tar包内容,可以通过输入重定向或-i/--input选项读取指定的文件;import命令直接以tar包文件名为参数进行导入。
- export导出的容器tar包中,包含可写层中的磁盘文件变更,但不包含镜像构建时指定的参数,包括工作目录与环境变量等信息。import导入容器时可以通过-c/--change选项指定Dockerfile指令,每个选项对应一条双引号内的指令,形式为 docker import -c "WORKDIR /opt" -c "EVN JAVA_HOME /opt" 容器tar包 。
- 执行导入与导出操作时,应注意命令与操作对象的匹配,如export命令的操作对象为容器而非镜像,save命令的操作对象为镜像而非容器;此外,export命令与save命令导出的tar包中所含的信息不同,因此export/save命令的输出应与import/load命令的输入严格对应。对export导出的容器tar包执行load,或对save导出的镜像tar包执行import,都将导入失败,或导入成功但运行容器失败,以及导致其他未知行为。
将容器app_auto导出为app_ctr.tar,镜像tomcat_app_automatic导出为app_img.tar。若对export命令指定镜像标识,以及对save命令指定容器标识,则提示容器或镜像不存在,导出失败。
[root@docker_host_0 opt]# docker container ls -a CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES 57878e669fb9 tomcat_app_automatic "/bin/sh -c 'bin/sta…" 11 minutes ago Up 11 minutes 0.0.0.0:8080->8080/tcp app_auto a5c1750f880c tomcat_app_manual "bash -c 'bin/startu…" 33 minutes ago Exited (137) 24 minutes ago app_man e414c244d725 t_i_1 "bash -c 'bin/startu…" 40 minutes ago Created t_c_2 63258c74cb4b t_i_0 "/bin/bash" 42 minutes ago Exited (0) 42 minutes ago t_c_1 6a6a3ed5a380 centos "bash -c 'mkdir -p /…" 45 minutes ago Exited (0) 45 minutes ago t_c_0 [root@docker_host_0 opt]# [root@docker_host_0 opt]# docker image ls -a REPOSITORY TAG IMAGE ID CREATED SIZE tomcat_app_automatic latest 88d50ce0f132 20 minutes ago 216MB <none> <none> 9d735d4bf9b1 20 minutes ago 216MB <none> <none> 7e52baca9d55 20 minutes ago 216MB <none> <none> a9ec389212f2 20 minutes ago 216MB <none> <none> c7bf4a13f5ef 20 minutes ago 216MB tomcat_app_manual latest 557c9112cb3f 39 minutes ago 216MB t_i_1 latest c5f0d673d958 41 minutes ago 216MB t_i_0 latest 1aa86a5d25c2 43 minutes ago 216MB centos latest 9f38484d220f 7 weeks ago 202MB [root@docker_host_0 opt]# [root@docker_host_0 opt]# docker save app_auto > app_img.tar Error response from daemon: No such image: app_auto [root@docker_host_0 opt]# [root@docker_host_0 opt]# docker export tomcat_app_automatic -o app_ctr.tar Error response from daemon: No such container: tomcat_app_automatic [root@docker_host_0 opt]# [root@docker_host_0 opt]# docker export app_auto -o app_ctr.tar [root@docker_host_0 opt]# docker save tomcat_app_automatic -o app_img.tar [root@docker_host_0 opt]# [root@docker_host_0 opt]# ll -h app_ctr.tar app_img.tar -rw------- 1 root root 214M May 5 23:01 app_ctr.tar -rw------- 1 root root 214M May 5 23:02 app_img.tar [root@docker_host_0 opt]#
将两个tar包传输至另一宿主机(docker_host_1),对镜像tar包执行load命令,导入成功,但镜像运行失败:
[root@docker_host_1 opt]# ll -h app_ctr.tar app_img.tar -rw------- 1 root root 214M May 5 23:06 app_ctr.tar -rw------- 1 root root 214M May 5 23:06 app_img.tar [root@docker_host_1 opt]# [root@docker_host_1 opt]# docker import app_img.tar app_img:new sha256:38c69e443d6ff4712e22fcfb4a306776b064a12b3ae1165d5cd725c5dfc4a202 [root@docker_host_1 opt]# [root@docker_host_1 opt]# docker image ls -a REPOSITORY TAG IMAGE ID CREATED SIZE app_img new 38c69e443d6f 6 seconds ago 224MB centos latest 9f38484d220f 7 weeks ago 202MB [root@docker_host_1 opt]# [root@docker_host_1 opt]# docker run -it --rm app_img:new /bin/bash docker: Error response from daemon: OCI runtime create failed: container_linux.go:345: starting container process caused "exec: \"/bin/bash\": stat /bin/bash: no such file or directory": unknown. [root@docker_host_1 opt]# [root@docker_host_1 opt]# docker image rm -f app_img:new Untagged: app_img:new Deleted: sha256:38c69e443d6ff4712e22fcfb4a306776b064a12b3ae1165d5cd725c5dfc4a202 Deleted: sha256:1e2b7840068294c8c3f1c67cc0d7939eb6ac2135afab7f1065616d9c5c852bd5 [root@docker_host_1 opt]#
对镜像tar包执行load操作,提示找不到所需的文件,导入失败:
[root@docker_host_1 opt]# docker load -i app_ctr.tar open /var/lib/docker/tmp/docker-import-466818323/dev/json: no such file or directory [root@docker_host_1 opt]# [root@docker_host_1 opt]# docker image ls -a REPOSITORY TAG IMAGE ID CREATED SIZE centos latest 9f38484d220f 7 weeks ago 202MB [root@docker_host_1 opt]# [root@docker_host_1 opt]#
将容器tar包导入为app_ctr:new,生成的本地镜像中不包含导入前的运行时参数,包括环境变量,开放端口,工作目录与命令,因此容器内的tomcat进程未启动,无法按导入前的状态运行。
[root@docker_host_1 opt]# docker import app_ctr.tar app_ctr:new sha256:dd4c6121da0e03db43892da94fdb02ee6b0fe5a6e7982f7e40bc37a398497ded [root@docker_host_1 opt]# docker image ls -a REPOSITORY TAG IMAGE ID CREATED SIZE app_ctr new dd4c6121da0e 4 seconds ago 216MB centos latest 9f38484d220f 7 weeks ago 202MB [root@docker_host_1 opt]# [root@docker_host_1 opt]# docker run -dit --name app_ctr_0 --mount src=jdks,dst=/opt/jdks,ro -p 8080:8080 app_ctr:new docker: Error response from daemon: No command specified. See 'docker run --help'. [root@docker_host_1 opt]# [root@docker_host_1 opt]# docker run -dit --name app_ctr_0 --mount src=jdks,dst=/opt/jdks,ro -p 8080:8080 app_ctr:new /bin/bash 6dd2d5243b271259d0f6120aebfc697b280add80b423e5ebf26cbbdf2e597941 [root@docker_host_1 opt]# [root@docker_host_1 opt]# docker container top app_ctr_0 UID PID PPID C STIME TTY TIME CMD root 7678 7660 0 23:11 pts/0 00:00:00 /bin/bash [root@docker_host_1 opt]# [root@docker_host_1 opt]# docker container logs app_ctr_0 [root@docker_host_1 opt]# [root@docker_host_1 opt]# ss -atn | grep 8080 LISTEN 0 128 :::8080 :::* [root@docker_host_1 opt]# [root@docker_host_1 opt]# docker container port app_ctr_0 8080/tcp -> 0.0.0.0:8080 [root@docker_host_1 opt]#
再次导入容器tar包,名称为app_ctr:latest,并指定运行时的参数。运行镜像后,tomcat启动,并可正常访问:
[root@docker_host_1 opt]# docker import app_ctr.tar -c "ENV JAVA_HOME /opt/jdks/jdk1.8.0_212" -c "WORKDIR /opt/apps/app_0" -c "EXPOSE 8080" -c "CMD bin/startup.sh && tail -f logs/catalina.out" app_ctr:latest
sha256:c39af6a5bff5bd1069bb89dec43ea32ade37a356fd05113a6003f7c3ee178863
[root@docker_host_1 opt]#
[root@docker_host_1 opt]#
[root@docker_host_1 opt]# docker image ls -a
REPOSITORY TAG IMAGE ID CREATED SIZE
app_ctr latest c39af6a5bff5 10 seconds ago 216MB
app_ctr new dd4c6121da0e 4 minutes ago 216MB
centos latest 9f38484d220f 7 weeks ago 202MB
[root@docker_host_1 opt]#
[root@docker_host_1 opt]# docker image inspect --format='{{ .Config.Env }}' app_ctr:latest
[JAVA_HOME=/opt/jdks/jdk1.8.0_212]
[root@docker_host_1 opt]# docker image inspect --format='{{ .Config.ExposedPorts }}' app_ctr:latest
map[8080/tcp:{}]
[root@docker_host_1 opt]# docker image inspect --format='{{ .Config.WorkingDir }}' app_ctr:latest
/opt/apps/app_0
[root@docker_host_1 opt]# docker image inspect --format='{{ .Config.Cmd }}' app_ctr:latest
[/bin/sh -c bin/startup.sh && tail -f logs/catalina.out]
[root@docker_host_1 opt]#
[root@docker_host_1 opt]# docker container stop app_ctr_0
app_ctr_0
[root@docker_host_1 opt]#
[root@docker_host_1 opt]# docker run -dit --name app_ctr_1 --mount src=jdks,dst=/opt/jdks,ro -p 8080:8080 app_ctr:latest
169fce93e085598ffeb188d4861cc4f62aa8cc14b380da6f6397f32f38b8751e
[root@docker_host_1 opt]#
[root@docker_host_1 opt]# docker container top app_ctr_1
UID PID PPID C STIME TTY TIME CMD
root 7960 7943 0 23:18 pts/0 00:00:00 /bin/sh -c bin/startup.sh && tail -f logs/catalina.out
root 8008 7960 18 23:18 pts/0 00:00:02 /opt/jdks/jdk1.8.0_212/bin/java -Djava.util.logging.config.file=/opt/apps/app_0/conf/logging.properties -Djava.util.logging.manager=org.apache.juli.ClassLoaderLogManager -Djdk.tls.ephemeralDHKeySize=2048 -Djava.protocol.handler.pkgs=org.apache.catalina.webresources -Dorg.apache.catalina.security.SecurityListener.UMASK=0027 -Dignore.endorsed.dirs= -classpath /opt/apps/app_0/bin/bootstrap.jar:/opt/apps/app_0/bin/tomcat-juli.jar -Dcatalina.base=/opt/apps/app_0 -Dcatalina.home=/opt/apps/app_0 -Djava.io.tmpdir=/opt/apps/app_0/temp org.apache.catalina.startup.Bootstrap start
root 8009 7960 0 23:18 pts/0 00:00:00 tail -f logs/catalina.out
[root@docker_host_1 opt]#
[root@docker_host_1 opt]# ss -atn | grep 8080
LISTEN 0 128 :::8080 :::*
[root@docker_host_1 opt]#
[root@docker_host_1 opt]# docker container logs app_ctr_
Error: No such container: app_ctr_
[root@docker_host_1 opt]# docker container logs app_ctr_
app_ctr_0 app_ctr_1
[root@docker_host_1 opt]# docker container logs app_ctr_1
Using CATALINA_BASE: /opt/apps/app_0
Using CATALINA_HOME: /opt/apps/app_0
Using CATALINA_TMPDIR: /opt/apps/app_0/temp
Using JRE_HOME: /opt/jdks/jdk1.8.0_212
Using CLASSPATH: /opt/apps/app_0/bin/bootstrap.jar:/opt/apps/app_0/bin/tomcat-juli.jar
Tomcat started.
...
05-May-2019 23:18:37.452 INFO [main] org.apache.catalina.startup.Catalina.start Server startup in 628 ms
[root@docker_host_1 opt]#
[root@docker_host_1 opt]# curl localhost:8080 &> /dev/null
[root@docker_host_1 opt]# docker exec -it app_ctr_1 tail -n 1 logs/localhost_access_log.$(date +%F).txt
192.168.9.1 - - [05/May/2019:23:20:00 +0000] "GET /favicon.ico HTTP/1.1" 200 21630
[root@docker_host_1 opt]#
导入镜像tar包app_img.tar,生成的本地镜像中包含所有导入前的配置参数,包括REPOSITORY,TAG,环境变量,工作目录,开放端口以及运行命令,因此挂载命名卷并运行后,结果与导入前相同:
[root@docker_host_1 opt]# docker container stop app_ctr_1
app_ctr_1
[root@docker_host_1 opt]#
[root@docker_host_1 opt]# docker load -i app_img.tar
83a1de39c1af: Loading layer 14.39MB/14.39MB
Loaded image: tomcat_app_automatic:latest
[root@docker_host_1 opt]# docker image ls -a
REPOSITORY TAG IMAGE ID CREATED SIZE
app_ctr latest c39af6a5bff5 6 minutes ago 216MB
app_ctr new dd4c6121da0e 11 minutes ago 216MB
tomcat_app_automatic latest 88d50ce0f132 42 minutes ago 216MB
centos latest 9f38484d220f 7 weeks ago 202MB
[root@docker_host_1 opt]#
[root@docker_host_1 opt]# docker image inspect --format='{{ .Config.Env }}' tomcat_app_automatic
[PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin JAVA_HOME=/opt/jdks/jdk1.8.0_212]
[root@docker_host_1 opt]# docker image inspect --format='{{ .Config.WorkingDir }}' tomcat_app_automatic
/opt/apps/app_0
[root@docker_host_1 opt]# docker image inspect --format='{{ .Config.ExposedPorts }}' tomcat_app_automatic
map[8080/tcp:{}]
[root@docker_host_1 opt]# docker image inspect --format='{{ .Config.Cmd }}' tomcat_app_automatic
[/bin/sh -c bin/startup.sh && tail -f logs/catalina.out]
[root@docker_host_1 opt]#
[root@docker_host_1 opt]#
[root@docker_host_1 opt]# docker run -dit --name app_img_0 --mount src=jdks,dst=/opt/jdks,ro -p 8080:8080 tomcat_app_automatic
0193ebdcbf00d688072536162a38ff4f788402d0cc8428c58481a0201151bca0
[root@docker_host_1 opt]#
[root@docker_host_1 opt]# docker container ls -a
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
0193ebdcbf00 tomcat_app_automatic "/bin/sh -c 'bin/sta…" 8 seconds ago Up 7 seconds 0.0.0.0:8080->8080/tcp app_img_0
169fce93e085 app_ctr:latest "/bin/sh -c 'bin/sta…" 4 minutes ago Exited (137) 49 seconds ago app_ctr_1
6dd2d5243b27 app_ctr:new "/bin/bash" 11 minutes ago Exited (137) 4 minutes ago app_ctr_0
[root@docker_host_1 opt]#
[root@docker_host_1 opt]# docker container top app_img_0
UID PID PPID C STIME TTY TIME CMD
root 8455 8437 0 23:22 pts/0 00:00:00 /bin/sh -c bin/startup.sh && tail -f logs/catalina.out
root 8502 8455 7 23:22 pts/0 00:00:02 /opt/jdks/jdk1.8.0_212/bin/java -Djava.util.logging.config.file=/opt/apps/app_0/conf/logging.properties -Djava.util.logging.manager=org.apache.juli.ClassLoaderLogManager -Djdk.tls.ephemeralDHKeySize=2048 -Djava.protocol.handler.pkgs=org.apache.catalina.webresources -Dorg.apache.catalina.security.SecurityListener.UMASK=0027 -Dignore.endorsed.dirs= -classpath /opt/apps/app_0/bin/bootstrap.jar:/opt/apps/app_0/bin/tomcat-juli.jar -Dcatalina.base=/opt/apps/app_0 -Dcatalina.home=/opt/apps/app_0 -Djava.io.tmpdir=/opt/apps/app_0/temp org.apache.catalina.startup.Bootstrap start
root 8503 8455 0 23:22 pts/0 00:00:00 tail -f logs/catalina.out
[root@docker_host_1 opt]#
[root@docker_host_1 opt]# ss -atn | grep 8080
LISTEN 0 128 :::8080 :::*
[root@docker_host_1 opt]#
[root@docker_host_1 opt]# curl localhost:8080 &> /dev/null
[root@docker_host_1 opt]#
[root@docker_host_1 opt]# docker exec -it app_img_0 tail -f logs/localhost_access_log.$(date +%F).txt
172.17.0.1 - - [05/May/2019:23:23:24 +0000] "GET / HTTP/1.1" 200 11204
4. 参考
https://docs.docker.com/engine/reference/commandline/docker/
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持 码农网
猜你喜欢:- docker CE on Linux示例浅析(五)服务编排 原 荐
- docker CE on Linux示例浅析(四)swam群集配置 原 荐
- docker CE on Linux示例浅析(二)数据存储与持久化 原 荐
- 粒子滤波Matlab示例
- transformers示例
- 粒子滤波Matlab示例
本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们。
Domain-Driven Design Distilled
Vaughn Vernon / Addison-Wesley Professional / 2016-6-2 / USD 36.99
Domain-Driven Design (DDD) software modeling delivers powerful results in practice, not just in theory, which is why developers worldwide are rapidly moving to adopt it. Now, for the first time, there......一起来看看 《Domain-Driven Design Distilled》 这本书的介绍吧!