Docker 是一种流行的容器化平台,它允许开发者打包应用以及其依赖到一个轻量级的、可移植的容器中。本文将引导读者通过一系列步骤和实验,以理解Docker的基本概念和操作。
在使用Docker时,通常指的是Docker守护进程,但实际上使用的是Docker客户端。许多用户并不了解这两者的区别。Docker客户端通过命令行代理REST JSON调用与守护进程通信。这种混淆部分是因为客户端和守护进程很可能位于同一台机器上,因此两者之间没有物理分离。
在开始之前,需要确保Linux主机正常运行。
运行以下命令来检查:
docker-machine ls
Docker命令行客户端需要知道指向哪个Docker守护进程。要实现这一点,需要找到守护进程的连接坐标。也可以与网络上不同机器上的Docker守护进程通信。
运行以下命令:
docker-machine env
它会输出类似于以下内容:
SET DOCKER_TLS_VERIFY=1
SET DOCKER_HOST=tcp://192.168.99.100:2376
SET DOCKER_CERT_PATH=C:\Users\myuser\.docker\machine\machines\
SET DOCKER_MACHINE_NAME=default
SET COMPOSE_CONVERT_WINDOWS_PATHS=true
为了绕过代理问题,请运行:
docker-machine env --no-proxy
输出内容将类似于:
SET DOCKER_TLS_VERIFY=1
SET DOCKER_HOST=tcp://192.168.99.100:2376
SET DOCKER_CERT_PATH=C:\Users\myuser\.docker\machine\machines\default
SET DOCKER_MACHINE_NAME=default
SET COMPOSE_CONVERT_WINDOWS_PATHS=true
SET no_proxy=192.168.99.100, .eu.int
要将Docker客户端指向Docker守护进程,请运行上一个列表中的最后一条命令,但不要包含REM注释符号:
@FOR /f "tokens=*" %i IN ('docker-machine env --no-proxy') DO @%i
Docker用户很容易混淆他们的角色以及他们应该执行的操作。
首先,登录主机并查看:
docker-machine ssh
可能想知道为什么没有输入任何凭据就登录了机器。这是因为私钥已经可用,位于:
DOCKER_CERT_PATH
现在将能够看到Docker守护进程在端口2376上处于监听状态:
netstat -nat | grep LISTEN
如果不熟悉Linux,可能不知道可以向Linux进程发送三个信号:Ctrl-C (SIGINT),Ctrl-\ (SIGQUIT),和 Ctrl-Z (SIGSTP)。Docker架构允许在运行Docker实例时访问这个Linux特性。
实验1:标准输入可用,但Docker实例中没有听到任何声音
docker run -i tomcat:latest
当尝试按下键盘组合Ctrl C时,进程被中断,但它真的到达了远程进程吗?
docker ps -a
将看到以下内容:
CONTAINER ID IMAGE COMMAND CREATED STATUS
d154269f742a tomcat:latest "catalina.sh run" 1 minute ago Up 1 minute
在这种情况下,Docker实例没有接收到这个信号,仍然处于运行状态。
实验2:标准输入可用,信号确实传递到了Docker实例
docker run -it tomcat:latest
当尝试按下键盘组合Ctrl C时,进程被中断,但它真的到达了远程进程吗?
docker ps -a
将看到以下内容:
CONTAINER ID IMAGE COMMAND CREATED STATUS
d154269f742a tomcat:latest "catalina.sh run" 1 minute ago Exited
在这种情况下,Docker实例确实接收到了信号,随后被中断,并显示了退出状态。
如果想知道导致镜像最后保存状态的命令,可以运行:
docker history image-id
要更美观地显示历史列表:
docker history --no-trunc image-id | tac | tr -s ' ' | cut -d " " -f 5- |
sed 's,^/bin/sh -c #(nop) ,,g' | sed 's,^/bin/sh -c,RUN,g' | sed 's, && ,\n & ,g' |
sed 's,\s*[0-9]*[\.]*[0-9]*[kMG]*B\s*$,,g' | head -n -1
现在让展示一个涉及Docker客户端的命令。这是复制命令。可以从容器复制文件到本地客户端机器:
docker cp [container]:/pathtofile localpathtofile
或者反过来:
docker cp localpathflie [container]:/pathtofile
在这个例子中,希望为Tomcat实例挂载一个数据卷并共享它。也希望访问Docker实例端口,即常规的Tomcat端口8080。将在Linux主机上创建一个对应的端口8888。
要共享一个公共目录,请确保在Linux主机上创建一个名为/home/hostVolume的目录。如果正在启动VirtualBox boot2docker镜像,还有一个额外的步骤,需要通过添加条目来挂载Windows机器上的本地目录:
VirtualBox->Your boot2docker image->Settings->Shared Folders->Adds new shared folder
现在,放入一些文件。运行以下命令,它将在端口之间建立桥梁,并且一次性共享文件目录:
docker run -it -d -v /home/hostVolume:/home/dockerVolume --publish 8888:8080
--name tomcatInstance tomcat:latest
现在让查看共享文件目录。将通过在shell中输入以下命令来访问Docker实例:
docker exec -it tomcatInstance bash
cd /home/dockerVolume
如果想持久化现有实例的状态:
docker commit [container-identifier] [image]
当涉及到导出镜像时,有两个选项。注意,每种导出方案都有其独特的导入方案。不能将两者混合使用。
两个选项是:
要么导出整个版本历史,但会得到一个更大的镜像。此外,引用的是镜像而不是运行中的容器:
docker save [image name] > /path to your tar/name.tar
要导入回来:
docker load /path to your tar/name.tar
或者导出一个运行中的容器,通过压扁其历史记录从而减小其大小:
docker export [container id] > /path to your tar/name.tar
cat /path to your tar/name.tar | docker import - [name]