构建 Docker 直觉。





5.00/5 (3投票s)
本简短教程旨在让读者对常见的 Docker 误解建立有意义的直觉。
引言
本简短教程并非旨在培训读者掌握已知的 Docker 命令,而是为了在读者心中培养一种有意义的直觉,以克服常见的 Docker 误解。在处理 Docker 时,我们可能指的是 Docker daemon,但当我们使用它时,我们实际上使用的是 Docker client。然而,我看到许多用户不知道有这两个实体在起作用:客户端(命令行代理 REST JSON 调用)和服务器(docker daemon)。这种混淆由于这两个实体很可能驻留在同一台机器上而加剧,因此两者之间没有物理分离。
研讨会阶段
- 检查您的 Linux 主机是否已启动
- 客户端校准
- 了解您身在何处?您是否知道自己正在操作什么?您是在 Docker 容器内还是在主机上?(梦中人)
如果您使用的是 Hyper-V 之前的 Windows 计算机,请注意,您需要通过 VirtualBox 镜像来启动您的 Linux 内核(Windows 2010 之前),否则,您可以依赖 Hyper-V 服务。Hyper-V 服务将毫无障碍地启动您的 Linux 镜像。本教程基于 VirtualBox 和随附的默认 boot2docker 发行版。请记住,您的 Docker daemon 已安装在该 boot2docker Linux 安装上。
1. 检查您的 Linux 主机是否已启动
Run
docker-machine ls
2. 客户端校准
我更喜欢将此阶段称为客户端校准。为什么?嗯,您的 Docker 命令行客户端不知道要连接到哪个 Docker daemon。您知道您必须与 daemon 通信才能执行命令,对吗?做到这一点的方法是找到您的 daemon 的连接坐标。您也可以与您网络上另一台机器上的 Docker daemon 进行通信。
Run
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
REM Run this command to configure your shell:
REM @FOR /f "tokens=*" %i IN ('docker-machine env') DO @%i
避免代理问题,谨慎操作
如您所见,您的 daemon 由 IP 地址 192.168.99.100 标识。可能会发生的情况是,如果您位于代理后面,对您的 daemon 的请求将击中代理,但代理不知道您新发布的 IP 地址。此 IP 地址仅在您的本地计算机上临时创建。因此,您需要一种方法来绕过代理,以便在向您自己计算机上的主机发出请求时。
Run
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
REM Run this command to configure your shell:
REM @FOR /f "tokens=*" %i IN ('docker-machine env --no-proxy') DO @%i
要将您的 Docker 客户端指向您的 Docker daemon,请运行上一个列表的最后一行,但去掉 REM 注释符
@FOR /f "tokens=*" %i IN ('docker-machine env --no-proxy') DO @%i
现在您已指向正确的 daemon,让我们看看 Docker daemon 中有哪些容器正在实例化。实例化 不一定意味着它们正在运行,它们也可能处于 EXITED 状态。请注意,Docker 容器遵循生命周期。
Run
docker ps -a
显示本地可用的镜像
docker image ls
3. 了解您身在何处?您是否知道自己正在操作什么?您是在 Docker 容器内、主机上,还是在 Docker 客户端?(梦中人)
我注意到 Docker 用户很容易对自己的确切角色以及他们应该做什么和做什么感到困惑。
首先,让我们登录到主机框并进行侦查。
docker-machine ssh
您可能会问自己,为什么您能以无密码的方式顺利登录到机器?好吧,工作已经为您完成,您的私钥可在您的 DOCKER_CERT_PATH
下找到(在执行 docker-machine env
时上方可见)。
您现在将能够看到 Docker daemon 在端口 2376 上处于监听状态。
netstat -nat | grep LISTEN
回顾进程信号及其重要性。实验
如果您不是 Linux 高级用户,您可能不知道您可以向 Linux 进程传递三个信号:Ctrl-C (SIGINT)、Ctrl-\ (SIGQUIT) 和 Ctrl-Z (SIGSTP)。现在,Docker 架构允许您在运行 Docker 实例时访问此 Linux 功能。您可能已经遇到过运行 docker run 命令时经常出现的 -i
和 -t
开关。它们是什么意思?-i
开关意味着您正在访问远程 Docker 进程的标准输入。但是,除非您的客户端 Docker 可用控制台,否则您无法推送任何数据,这时 -t
就派上用场了。让我们来试验一下。
实验 1:标准输入可用,但在您的 Docker 实例中听不到任何声音
Run
docker run -i tomcat:latest
当您的 tomcat 标准输出控制台开始泛滥时,尝试启动键盘组合 - Ctrl C。进程被中断了,但它真的到达远程进程了吗?
Run
docker ps -a
您将看到以下内容
CONTAINER ID IMAGE COMMAND CREATED STATUS
d154269f742a tomcat:latest "catalina.sh run" 1 minute ago Up 1 minute
如您所见,Docker 实例没有收到此信号,它仍然处于运行状态。
实验 2:标准输入可用,信号已成功传递到您的 Docker 实例
Run
docker run -it tomcat:latest
当您的 tomcat 标准输出控制台开始泛滥时,尝试启动键盘组合 - Ctrl C。进程被中断了,但它真的到达远程进程了吗?
Run
docker ps -a
您将看到以下内容
CONTAINER ID IMAGE COMMAND CREATED STATUS
d154269f742a tomcat:latest "catalina.sh run" 1 minute ago Exited
在这种情况下,Docker 实例接收到了信号,随后被中断,并显示了 **exit** 状态。
这是信号决策树的分解(图 3)。
如果您在后台启动实例,但仍想访问 STDOUT
,您可以使用
docker logs -f instance-name
现在我们完成了信号概述,让我们继续下一个主题,您的镜像会经历的物理变化,即所谓的“分层”过程。
关于对容器和镜像所做的更改。如果您渴望检查导致您的镜像达到其最后保存状态的命令,请运行
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 实例之间创建一些交互
现在让我们展示一个涉及 Docker 客户端的命令。这是 copy 命令。您可以从容器复制文件到本地客户端机器
docker cp [container]:/pathtofile localpathtofile
或反之亦然
docker cp localpathflie [container]:/pathtofile
现在让我们提供一个连接主机和 daemon 的命令示例。通常,我们希望从 Docker daemon 获取两样东西:通信访问我们的新服务以及文件系统访问,对吗?
在此示例中,我们希望为 Tomcat 实例挂载一个卷并共享它。我们还希望访问 Docker 实例端口,即常规的 Tomcat 端口 8080。我们将在端口 8888 上创建一个相应的 Linux 主机端口。请记住,当我们作为 Docker 客户端操作时,我们无法访问 Docker 实例。我们只能访问 Linux 主机,这就是为什么我们将这两个服务提供给 Linux 主机。
至于共享一个通用目录,请确保在您的 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]
历史
- 2020年2月4日:初始版本