Docker Machine深入学习
发布时间 - 2026-01-11 02:05:21 点击率:次笔者在《Docker Machine 简介》一文中简单介绍了 Docker Machine 及其基本用法,但是忽略的细节实在是太多了。比如 Docker 与 Docker Machine 的区别?又如当我们执行 docker-machine create 命令时,Docker Machine 都做了哪些重要的事情使得我们可以远程操作 Docker daemon?这样的远程操作安全吗?本文将试图解读这些问题。注:本文的演示环境为 Ubuntu16.04。

Docker 与 Docker Machine 的区别
Docker 是一个 Client-Server 架构的应用,人家是有官称的:Docker Engine。Docker 只是大家对 Docker Engine 的昵称,当然 Docker 还有其他的意思,比如一家公司的名称。简单起见,本文中的 Docker 等同于 Docker Engine。
提到 Docker 我们必须要知道它包含了三部分内容:
- Docker daemon
- 一套与 Docker daemon 交互的 REST API
- 一个命令行客户端
下图很清晰的展示了它们之间的关系:
Docker Machine 则是一个安装和管理 Docker 的工具。它有自己的命令行工具:docker-machine。
Docker daemon socket
既然 Docker 客户端要和 Docker daemon 通过 REST API 通信,那就让我们看看它们可以采用的方法有哪些:
- Unix socket
- Systemd socket activation
- Tcp
我们可以简单的把 1 和 2 理解成一种方式,就是同一台主机上的进程间通信。至于 3 则很好理解:通过 tcp 协议进行跨网络的通信。
既然 1 和 2 用于同一台机器上的进程间通信,那么我们可以猜想:安装在同一主机上的 Docker 客户端和 Docker daemon 就是通过这种方式来通信的。事实也正是如此,我们可以查看安装 Docker 时默认添加的 Docker daemon 启动配置,打开文件 /etc/systemd/system/multi-user.target.wants/docker.service:
图中的 -H 用来指定 Docker Daemon 监听的 socket,此处指定的类型为 system socket activation。使用类型 1 和 2 进行通信需要进程具有 root 权限。这也是 Docker 安装过程中会自动创建一个具有 root 权限的用户和用户组的主要原因。新创建的用户和用户组名称为 docker,建议大家把需要操作 Docker 的用户都加入到这个组中,否则当你执行命令时就会碰到下图显示的问题:
我们还可以同时指定多个 -H 参数让 Docker daemon 同时监听不同的 socket 类型。比如要添加对 TCP 端口 2376 的监听就可以使用下面的命令行参数:
$ sudo dockerd -H fd:// -H tcp://0.0.0.0:2376
运行上面的命令,然后查看本机监听的端口:
此时我们就可以从远程主机上的 Docker 客户端访问这部主机的 2376 端口了。
DOCKER_HOST 环境变量
Docker 客户端默认的配置是访问本机的 Docker daemon,当你指定了 DOCKER_HOST 变量后,Docker 客户端会访问这个变量中指定的 Docker daemon。让我们回顾一下 docker-machine env 命令:
原来我们在前文中执行的 $ eval $(docker-machine env krdevdb) 命令就是在设置 DOCKER_HOST 环境变量。
解决安全问题
我们的 Docker daemon 监听了 tcp 端口,糟糕的是此时我们没有做任何的保护措施。因此任何 Docker 客户端都可以通过 tcp 端口与我们的 Docker daemon 交互,这显然是无法接受的。解决方案是同时启用 Docker daemon 和 Docker 客户端的 TLS 证书认证机制。这样 Docker daemon 和 Docker 客户端之间的通信会被加密,并且只有安装了特定证书的客户端才能够与对应的 Docker daemon 交互。
至此本文的铺垫部分终于结束了,接下来我们将讨论 Docker Machine 相关的内容。
Docker Machine create 命令
根据 Docker Machine 驱动的不同,create 命令执行的操作也不太一样,但其中有两步是我们在这里比较关心的:
docker-machine 会在您指定的主机上执行下面的操作:
- 安装 Docker,并进行配置。
- 生成证书保护 Docker 服务的安全。
配置 Docker daemon
Docker 的安装过程并没有什么秘密,这里不再赘述。我们重点关注 Docker daemon 的配置。仔细观察我们会发现,通过 docker-machine 安装的 Docker 在 /etc/systemd/system 目录下多出了一个 Docker 相关的目录:docker.service.d。这个目录中只有一个文件 10-machine.conf:
好吧,-H tcp://0.0.0.0:2376 出现在这里并没有让我们太吃惊。在我们做了巨多的铺垫之后,你应该觉得这是理所当然才是。--tls 开头的几个参数主要和证书相关,我们会在后面的安全设置中详细的介绍它们。让人多少有些疑惑的地方是上图中的 /usr/bin/docker。当前最新版本的 Docker Machine 还在使用旧的方式设置 Docker daemon,希望在接下来的版本中会有所更新。
这个配置文件至关重要,因为它会覆盖 Docker 默认安装时的配置文件,从而以 Docker Machine 指定的方式启动 Docker daemon。至此我们有了一个可以被远程访问的 Docker daemon。
生成证书
我们在 Docker daemon 的配置文件中看到四个以 --tls 开头的参数,分别是 --tlsverify、--tlscacert、--tlscert和 –tlskey。其中的 --tlsverify 告诉 Docker daemon 需要通过 TLS 来验证远程客户端。其它三个参数分别指定了一个 pem 格式文件的路径,按照它们指定的文件路径去查看一下:
对比一下手动安装的 Docker,会发现 /etc/docker 目录下并没有这三个文件。毫无疑问它们是 Docker Machine 生成的,主要是为了启用 Docker daemon 的 TLS 验证功能。关于 TLS,笔者在《局域网内部署 Docker Registry》一文中略有涉及,当时是手动配置的证书,感兴趣的朋友可以参考一下。
现在让我们回到安装了 Docker Machine 的主机上。
查看 /home/nick/.docker/machines/krdevdb 目录,发现了一些同名的文件(ca.pem、server-key.pem 和 server.pem),和主机 drdevdb 上的文件对比一下,发现它们是一样的!
让我们再来观察一下这幅图:
除了我们关注过的 DOCKER_HOST,还有另外三个环境变量。其中的 DOCKER_TLS_VERIFY 告诉 Docker 客户端需要启用 TLS 验证。DOCKER_CERT_PATH 则指定了 TLS 验证所依赖文件的目录,这个目录正是我们前面查看的 /home/nick/.docker/machines/krdevdb 目录。
行文至此,困扰我们的安全问题终于得到了解释:Docker Machine 在执行 create 命令的过程中,生成了一系列保证安全性的秘钥和数字证书(*.pem)文件。这些文件在本地和远程 Docker 主机上各存一份,本地的用于配置 Docker 客户端,远程主机上的用于配置 Docker daemon,让两边都设置 TLS 验证的标记,依此实现安全的通信。
总结
从本文的前一部分可以看到,Docker 其实把该提供的都提供了,只是配置起来比较麻烦!但是对用户来说,需要的总是更简单,更容易的配置。因此从使用者的角度来看,Docker Machine 确实很酷,一个命令下去不仅能够安装虚机和 Docker,还完成了很多手动搞起来令人生畏的配置。然后带来几个清晰、简单的命令。再然后,同学们就可以开心愉快的玩耍了!
# Docker
# Machine
# docker之docker-machine用法详解
# Docker Machine远程部署Docker的方法
# Docker Machine创建Azure虚拟主机
# Docker Machine是什么?
# Docker Machine深入详解
# 客户端
# 让我们
# 我们可以
# 几个
# 在这里
# 命令行
# 配置文件
# 就可以
# 当你
# 会在
# 本机
# 图中
# 中会
# 自己的
# 安装过程
# 的是
# 是一个
# 这是
# 有什么
# 令人生畏
相关栏目:
【
网站优化151355 】
【
网络推广146373 】
【
网络技术251813 】
【
AI营销90571 】
相关推荐:
奇安信“盘古石”团队突破 iOS 26.1 提权
Windows10怎样连接蓝牙设备_Windows10蓝牙连接步骤【教程】
JS中对数组元素进行增删改移的方法总结
Laravel怎么清理缓存_Laravel optimize clear命令详解
Google浏览器为什么这么卡 Google浏览器提速优化设置步骤【方法】
Laravel怎么创建控制器Controller_Laravel路由绑定与控制器逻辑编写【指南】
Laravel模型事件有哪些_Laravel Model Event生命周期详解
实例解析angularjs的filter过滤器
Android okhttputils现在进度显示实例代码
Laravel如何处理跨站请求伪造(CSRF)保护_Laravel表单安全机制与令牌校验
JS中页面与页面之间超链接跳转中文乱码问题的解决办法
MySQL查询结果复制到新表的方法(更新、插入)
昵图网官网入口 昵图网素材平台官方入口
Python数据仓库与ETL构建实战_Airflow调度流程详解
如何在IIS中新建站点并配置端口与IP地址?
为什么php本地部署后css不生效_静态资源加载失败修复技巧【技巧】
Laravel如何与Vue.js集成_Laravel + Vue前后端分离项目搭建指南
再谈Python中的字符串与字符编码(推荐)
Laravel怎么进行数据库事务处理_Laravel DB Facade事务操作确保数据一致性
教你用AI将一段旋律扩展成一首完整的曲子
php 三元运算符实例详细介绍
网站设计制作书签怎么做,怎样将网页添加到书签/主页书签/桌面?
高性能网站服务器配置指南:安全稳定与高效建站核心方案
微信小程序 闭包写法详细介绍
公司网站制作需要多少钱,找人做公司网站需要多少钱?
佛山企业网站制作公司有哪些,沟通100网上服务官网?
绝密ChatGPT指令:手把手教你生成HR无法拒绝的求职信
Laravel如何使用Socialite实现第三方登录?(微信/GitHub示例)
香港服务器选型指南:免备案配置与高效建站方案解析
Java Adapter 适配器模式(类适配器,对象适配器)优缺点对比
Laravel如何配置Horizon来管理队列?(安装和使用)
北京专业网站制作设计师招聘,北京白云观官方网站?
b2c电商网站制作流程,b2c水平综合的电商平台?
Laravel怎么实现一对多关联查询_Laravel Eloquent模型关系定义与预加载【实战】
七夕网站制作视频,七夕大促活动怎么报名?
Laravel如何实现登录错误次数限制_Laravel自带LoginThrottles限流配置【方法】
Laravel如何使用Seeder填充数据_Laravel模型工厂Factory批量生成测试数据【方法】
如何在Windows环境下新建FTP站点并设置权限?
公司网站制作价格怎么算,公司办个官网需要多少钱?
独立制作一个网站多少钱,建立网站需要花多少钱?
Laravel怎么实现前端Toast弹窗提示_Laravel Session闪存数据Flash传递给前端【方法】
Laravel如何安装使用Debugbar工具栏_Laravel性能调试与SQL监控插件【步骤】
Laravel API路由如何设计_Laravel构建RESTful API的路由最佳实践
laravel服务容器和依赖注入怎么理解_laravel服务容器与依赖注入解析
如何在万网开始建站?分步指南解析
香港代理服务器配置指南:高匿IP选择、跨境加速与SEO优化技巧
Linux系统命令中tree命令详解
JavaScript如何实现类型判断_typeof和instanceof有什么区别
Laravel队列由Redis驱动怎么配置_Laravel Redis队列使用教程
Laravel如何配置和使用队列处理异步任务_Laravel队列驱动与任务分发实例

