网站搜索

如何以及为什么使用远程 Docker 主机


docker CLI 程序独立于运行容器的 Docker 守护进程。虽然这两个组件通常都在您的本地计算机上运行,但您可以针对远程 Docker 主机运行 docker 命令。

在一些情况下,使用远程主机可能会有帮助。您可以为小型开发团队设置共享的 Docker 引擎安装。然后,每个开发人员都可以使用本地 docker exec 命令连接到远程容器。

当您拥有一台未使用的强大服务器时,远程主机通常更有价值。如果您的笔记本电脑运行缓慢或存储空间不足,在您的网络上使用专用的 Docker 主机可以大大提高性能。您仍然可以在终端中享受本地 docker CLI 的所有便利。

设置远程主机

确保你已经在将成为你的远程主机的系统上安装了 Docker。您只需要在本地机器上安装 docker-cli 包,因为您不会运行 Docker 引擎。

全新的 Docker 安装默认提供 Unix 套接字。远程访问需要 TCP 套接字。使用 -H 标志运行 dockerd(Docker 守护程序可执行文件)以定义要绑定到的套接字。

sudo dockerd -H unix:///var/run/docker.sock -H tcp://0.0.0.0:2375

此命令会将 Docker 绑定到默认的 Unix 套接字和计算机环回地址上的端口 2375。您可以通过重复 -H 标志绑定到其他套接字和 IP 地址。

每次运行 dockerd 时都需要传递标志。如果您希望它们在重新启动后仍然存在,请创建一个 shell 别名或修改 Docker 服务定义。下面介绍如何使用 systemd 实现后者,大多数 Linux 发行版都使用它来进行服务管理。

编辑 /etc/systemd/system/docker.service.d/options.conf(如果不存在则创建)。找到 [Service] 部分并更改 ExecStart 行:

[Service]
ExecStart=/usr/bin/dockerd -H unix:///var/run/docker.sock -H tcp://0.0.0.0:2375

重新加载您的 systemd 配置以应用更改:

sudo systemctl daemon-reload

如果 Docker 已经在运行,请使用 sudo systemctl restart docker 重新启动服务。 Docker 守护进程现在将在每次启动时绑定到 TCP 端口 2375。确保您的防火墙配置允许流向该端口的流量。如果您使用的是 ufw,请运行 ufw allow 2375 以打开端口。

连接到远程主机

Docker CLI 使用 DOCKER_HOST 环境变量来确定要连接的主机。当未设置变量时,将使用本地守护进程的 Unix 套接字。

您可以通过在 DOCKER_HOST 变量前添加一个远程主机来执行单个 docker 命令:

DOCKER_HOST=tcp://192.168.0.1:2375 docker run httpd:latest -d

这将使用位于 192.168.0.1:2375 的 Docker 引擎从 httpd:latest 映像启动一个新容器。

如果您要在一个会话中运行多个命令,请将 DOCKER_HOST 变量导出到您的 shell 中:

export DOCKER_HOST=tcp://192.168.0.1:2375

docker run httpd:latest -d --name httpd
docker ps
docker rm httpd --force

您可以通过在 shell 的配置文件中全局设置 DOCKER_HOST 让 docker 始终使用远程主机。下面是你在 Bash 中的做法:

echo "export DOCKER_HOST=tcp://192.168.0.1:2375" >> ~/.bashrc

现在 DOCKER_HOST 环境变量将在每次 shell 启动时设置。

增强安全性

基本的 TCP 套接字不受保护。任何可以通过网络访问您机器的人都可以使用 Docker 套接字来控制您的容器。

Docker 支持 SSH 而不是 TCP。如果主机有可用的 SSH 服务器,这通常是更好的选择。它可以防止未经身份验证的用户获得访问权限。使用 SSH 不需要额外的配置。 DOCKER_HOST 允许您传入 SSH 连接字符串:

DOCKER_HOST=ssh://user@hostname docker run -d --name httpd

或者,您可以使用 SSH 绑定直接将远程主机的 Docker Unix 套接字绑定到您的本地机器:

ssh -L /var/run/docker.sock:/var/run/docker.sock

现在你根本不需要使用 DOCKER_HOST。远程 docker.sock 将绑定到其本地副本。 Docker 会自动将其检测为标准的 Unix 套接字。

使用一种基于 SSH 的解决方案是处理 Docker 守护程序安全性的首选方法。如果您提供证书颁发机构以及服务器和客户端密钥,Docker 也支持 TLS:

dockerd --tlsverify --tlscacert=ca.pem --tlscert=cert.pem --tlskey=key.pem -H=0.0.0.0:2375

现在,如果客户端出示受证书颁发机构 ca.pem 信任的有效 SSL 证书,则它们将能够连接到端口 2375。

创建上下文

Docker 允许您设置多个“上下文”以连接到不同的主机。可以使用上下文代替 DOCKER_HOST 环境变量。它们使在多个远程主机之间切换变得更容易。

docker context create --docker host=tcp://192.168.0.1:2375 --description remote
docker context create --docker host=unix:///var/run/docker.sock --description local

这些命令创建了两种不同的上下文——一种用于本地 docker.sock,另一种用于远程连接。

您可以使用 docker context use 命令在上下文之间切换:

docker context use remote

# Container is started on "remote"
docker run httpd:-latest -d

docker context use local

# Lists containers running on "local"
docker ps

当您使用多个 Docker 主机时,上下文很有用。当您在主机之间移动时,它们比不断重置 DOCKER_HOST 变量要简单得多。

远程主机的缺点

我们之前注意到远程主机可以提高构建性能。仅当运行 Docker 引擎的机器比您的本地硬件更快时,此声明才成立。远程主机的最大缺点是通过网络进行交互的额外开销。你也会变得依赖于网络——如果你失去连接,你将无法管理你的容器。

如果你打算使用远程主机作为你的主要构建服务器,你应该有一个可靠的高速网络连接。第一个 docker build 阶段将图像的构建上下文(通常是您的工作目录)的内容发送到 Docker 引擎。当 Docker 在本地运行时这很快,但上传到远程计算机可能需要更长的时间。

通过网络公开 Docker 守护程序实例存在安全风险。您需要确保访问仅限于授权用户和设备。 Docker 守护程序套接字的无意暴露可能使攻击者可以无限制地访问主机。 Docker 通常以 root 身份运行,因此只有受信任的人才能启动容器这一点至关重要。

结论

设置远程 Docker 主机可让您将容器实例与本地开发机器分开。专用的 Docker 构建服务器可以提供改进的性能和更大的图像存储空间。

您应该注意审核实施的安全性。普通 TCP 套接字在专用网络上可能是安全的,但不应部署在任何敏感环境中。如果您实践良好的 SSH 安全卫生,例如强制的基于密钥的身份验证,使用 SSH 有助于降低风险。

相关文章: