|
|
@@ -0,0 +1,150 @@
|
|
|
+# Docker Java SDK 使用教程
|
|
|
+
|
|
|
+> Solomon Hykes — Docker 创始人
|
|
|
+>
|
|
|
+> Docker 提供了一个核心的抽象层,让你可以在任何基础设施上运行任何应用。这种抽象层的本质是:将应用的运行环境打包成一个标准化的单元,这个单元可以在任何地方运行。
|
|
|
+
|
|
|
+那么,从这章开始,就让我们来感受一下,Docker Java SDK 为我们带来了什么。
|
|
|
+
|
|
|
+***
|
|
|
+
|
|
|
+## 前置Docker配置
|
|
|
+
|
|
|
+在使用 Docker Java SDK 之前,我们需要确保本机的 Docker 环境已经正确配置。SDK 通过 Unix socket 或 TCP 协议与 Docker daemon 通信,因此需要根据实际情况选择合适的连接方式并完成相应配置。
|
|
|
+
|
|
|
+### 用户组配置
|
|
|
+
|
|
|
+默认情况下,Docker daemon 的 Unix socket 文件 `/var/run/docker.sock` 的所有者是 `root` 用户,所属组是 `docker`。如果当前用户没有 `docker` 用户组的权限,在连接 Docker 时会遇到权限拒绝的问题:
|
|
|
+
|
|
|
+```
|
|
|
+permission denied while trying to connect to the Docker daemon socket
|
|
|
+```
|
|
|
+
|
|
|
+解决方法是将当前用户添加到 `docker` 用户组中:
|
|
|
+
|
|
|
+```bash
|
|
|
+# 将当前用户添加到 docker 用户组
|
|
|
+sudo usermod -aG docker $USER
|
|
|
+
|
|
|
+# 查看当前用户所属 groups
|
|
|
+groups
|
|
|
+
|
|
|
+# 如果 usermod 不生效,可以尝试 newgrp 刷新组信息
|
|
|
+newgrp docker
|
|
|
+```
|
|
|
+
|
|
|
+添加完成后,需要**重新登录系统**或**重启系统**让修改生效。我们可以通过以下命令验证是否配置成功:
|
|
|
+
|
|
|
+```bash
|
|
|
+# 查看 docker.sock 文件的权限
|
|
|
+ls -la /var/run/docker.sock
|
|
|
+
|
|
|
+# 输出示例:srw-rw---- 1 root docker 0 Sep 15 10:00 /var/run/docker.sock
|
|
|
+# 注意权限中的 's' 表示 socket 文件,所属组为 docker
|
|
|
+```
|
|
|
+
|
|
|
+**思考:** 为什么 Docker 选择使用 Unix socket 而不是普通的文件来进行通信?
|
|
|
+
|
|
|
+Unix socket 是一种进程间通信(IPC)机制,相比 TCP 连接,它在同一台机器上的通信效率更高,且不需要经过网络协议栈,安全性也更好。因此 Docker daemon 默认监听 Unix socket 作为主要的通信方式。
|
|
|
+
|
|
|
+### 网络协议配置
|
|
|
+
|
|
|
+Docker Java SDK 支持两种连接协议:**Unix socket** 和 **TCP**。
|
|
|
+
|
|
|
+#### Unix socket 协议
|
|
|
+
|
|
|
+Unix socket 是默认的连接方式,适用于 Docker daemon 运行在本机的场景。SDK 通过以下地址连接:
|
|
|
+
|
|
|
+```
|
|
|
+unix:///var/run/docker.sock
|
|
|
+```
|
|
|
+
|
|
|
+这种方式的优点是无需额外配置,安全性高(通过文件权限控制访问),但缺点是只能连接本机的 Docker daemon。
|
|
|
+
|
|
|
+#### TCP 协议
|
|
|
+
|
|
|
+当需要远程连接 Docker daemon 时,需要使用 TCP 协议。这要求 Docker daemon 启动时开启 TCP 端口监听。
|
|
|
+
|
|
|
+**方法一:修改 Docker daemon 启动参数**
|
|
|
+
|
|
|
+在 `/etc/docker/daemon.json` 中添加配置:
|
|
|
+
|
|
|
+```json
|
|
|
+{
|
|
|
+ "hosts": ["unix:///var/run/docker.sock", "tcp://0.0.0.0:2375"]
|
|
|
+}
|
|
|
+```
|
|
|
+
|
|
|
+**方法二:修改 systemd service 配置**
|
|
|
+
|
|
|
+创建或编辑 systemd 配置文件:
|
|
|
+
|
|
|
+```bash
|
|
|
+sudo mkdir -p /etc/systemd/system/docker.service.d
|
|
|
+sudo vi /etc/systemd/system/docker.service.d/override.conf
|
|
|
+```
|
|
|
+
|
|
|
+添加以下内容:
|
|
|
+
|
|
|
+```ini
|
|
|
+[Service]
|
|
|
+ExecStart=
|
|
|
+ExecStart=/usr/bin/dockerd -H tcp://0.0.0.0:2375 -H unix://var/run/docker.sock
|
|
|
+```
|
|
|
+
|
|
|
+然后重启 Docker 服务:
|
|
|
+
|
|
|
+```bash
|
|
|
+sudo systemctl daemon-reload
|
|
|
+sudo systemctl restart docker
|
|
|
+```
|
|
|
+
|
|
|
+验证 TCP 监听是否生效:
|
|
|
+
|
|
|
+```bash
|
|
|
+# 查看 Docker daemon 监听的端口
|
|
|
+ss -tlnp | grep 2375
|
|
|
+
|
|
|
+# 或使用 curl 测试
|
|
|
+curl http://localhost:2375/version
|
|
|
+```
|
|
|
+
|
|
|
+**注意:** 开启 TCP 监听后,任何能够访问该端口的客户端都可以操作 Docker daemon,存在严重的安全风险。在生产环境中,建议配合 TLS 证书进行加密通信。
|
|
|
+
|
|
|
+#### TLS 安全通信配置
|
|
|
+
|
|
|
+在生产环境中使用 TCP 协议时,应该启用 TLS 加密:
|
|
|
+
|
|
|
+```bash
|
|
|
+# 创建 TLS 证书(示例)
|
|
|
+mkdir -p /etc/docker/certs
|
|
|
+openssl req -x509 -newkey rsa:4096 -sha256 -days 365 \
|
|
|
+ -keyout /etc/docker/certs/server-key.pem \
|
|
|
+ -out /etc/docker/certs/server-cert.pem \
|
|
|
+ -nodes -subj "/CN=localhost"
|
|
|
+
|
|
|
+# Docker daemon 启动参数
|
|
|
+ExecStart=/usr/bin/dockerd \
|
|
|
+ --tlsverify \
|
|
|
+ --tlscacert=/etc/docker/ca.pem \
|
|
|
+ --tlscert=/etc/docker/certs/server-cert.pem \
|
|
|
+ --tlskey=/etc/docker/certs/server-key.pem \
|
|
|
+ -H tcp://0.0.0.0:2376 \
|
|
|
+ -H unix://var/run/docker.sock
|
|
|
+```
|
|
|
+
|
|
|
+### 连接方式对比
|
|
|
+
|
|
|
+| 特性 | Unix socket | TCP | TCP + TLS |
|
|
|
+|------|-------------|-----|-----------|
|
|
|
+| 适用场景 | 本机连接 | 远程连接 | 远程连接(生产) |
|
|
|
+| 安全性 | 高(文件权限) | 低(明文传输) | 高(证书加密) |
|
|
|
+| 性能 | 高 | 中等 | 中等(加密开销) |
|
|
|
+| 配置复杂度 | 低 | 中 | 高 |
|
|
|
+| 默认端口 | 无 | 2375 | 2376 |
|
|
|
+
|
|
|
+**思考:** 在微服务架构中,如果需要让应用通过 Docker Java SDK 管理容器化的服务,你会选择哪种连接方式?为什么?
|
|
|
+
|
|
|
+***
|
|
|
+
|
|
|
+下一章,我们将正式开始使用 Docker Java SDK,创建 DockerClient 并连接到 Docker daemon。
|