您现在的位置是:首页 > 文章详情

docker CE on Linux示例浅析(三)镜像与容器管理

日期:2019-05-05点击:463

概述

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台: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目录,所有设置均为默认。

示例

    获取操作系统镜像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

参考

https://docs.docker.com/engine/reference/commandline/docker/
https://docs.docker.com/engine/reference/builder/

原文链接:https://my.oschina.net/superwjc/blog/3045629
关注公众号

低调大师中文资讯倾力打造互联网数据资讯、行业资源、电子商务、移动互联网、网络营销平台。

持续更新报道IT业界、互联网、市场资讯、驱动更新,是最及时权威的产业资讯及硬件资讯报道平台。

转载内容版权归作者及来源网站所有,本站原创内容转载请注明来源。

文章评论

共有0条评论来说两句吧...

文章二维码

扫描即可查看该文章

点击排行

推荐阅读

最新文章