如何通过 SSH 连接到 Docker 容器
SSH 是系统管理员工具箱中最常用的命令之一,但它在 Docker 中并不常用。 以下是如何通过 SSH 连接到正在运行的容器,以及为什么在这样做之前应该三思而后行。
你应该在 Docker 容器中使用 SSH 吗?
SSH 进入 Docker 容器通常是一种不好的做法,应该避免。使用 docker exec
命令在容器中获取 shell 要更好。
Docker 新手可能会尝试使用 SSH 来更新容器内的文件。容器应该是一次性的,所以它们在创建后应该被视为不可变的,除了存储在卷中的持久数据。编辑源代码时创建新镜像并重新启动容器。
除了多步骤配置过程之外,在 Docker 镜像中安装 SSH 会添加几个依赖包并暴露另一个潜在的攻击向量。在具有多个活动容器的系统上,您将运行多个独立的 SSH 进程,并且必须记住每个容器的正确端口。
与其将 SSH 添加到单个容器中,不如在运行 Docker 的物理主机上安装一次。使用 SSH 连接到您的主机,然后运行下面的命令来访问各个容器。
$ docker exec -it my-container bash
虽然 docker exec 是首选方法,但仍然存在 SSH 可能有用的场景。 我们可以将其作为权宜之计引入,以与遗留部署系统集成。 它也可能被一些 IDE 和构建工具用于在开发期间提供实时重新加载功能。
在 Docker 容器中安装 SSH 服务器
大多数流行的 Docker 基础镜像都被有意简化了。 你需要自己添加 OpenSSH 服务器,即使是来自流行操作系统发行版的镜像。
下面是一个基于 Debian 的镜像的 Dockerfile 示例:
Dockerfile
RUN apt-get update && apt-get install -y openssh-server RUN sed -i 's/PermitRootLogin prohibit-password/PermitRootLogin yes/' /etc/ssh/sshd_config ENTRYPOINT service ssh start && bash
SSH 配置已修改,因此可以作为 Docker 容器中的默认用户 root 登录。 为了提高安全性,请改为设置专用用户帐户:
RUN useradd -m -s /bin/bash sshuser
这将创建一个名为 sshuser 的新用户,并带有一个主目录 (-m)
。 -s
选项将用户的默认登录 shell 设置为 Bash。
使用 ENTRYPOINT 可确保 SSH 服务始终在容器启动时启动。 然后将执行权交给 Bash 作为容器的前台进程。 我们可以将其替换为应用程序的二进制文件。
配置身份验证
接下来,您需要设置身份验证系统。 可以为自己的 sshuser 帐户分配密码并使用该密码登录:
RUN echo "sshuser:Changeme" | changepasswd
更安全的方法是设置 SSH 密钥身份验证。 您需要在客户端计算机上创建一个密钥对,然后将公共部分复制到容器中。 这样,SSH 守护程序可以在您连接时验证您机器的身份。
更改 Dockerfile 来为用户设置 .ssh
配置文件夹。 使用 docker cp
命令或 Dockerfile 中的 COPY 指令从工作目录复制公钥。 在后一种情况下,密钥将被拷贝到镜像中,任何有权访问的人都可以看到。
COPY id_rsa.pub /home/sshuser/.ssh/authorized_keys
RUN chown -R sshuser:sshuser /home/sshuser/.ssh
RUN chmod 600 /home/sshuser/.ssh/authorized_keys
这一系列命令使用工作目录中的 id_rsa.pub 公钥创建 SSH 的 authorized_keys 文件。 调整文件系统权限以匹配 SSH 的要求。
连接到容器
现在已准备好连接到容器。 使用绑定到主机的端口 22 运行容器:
$ docker run -p 22:22 my-image:latest
运行 ssh sshuser@example.com 将为我们提供容器内的shell。
如果要从托管 Docker 容器的机器进行连接,则可以跳过绑定端口。 使用 docker inspect 获取容器的 IP 地址,然后将其传递给 SSH 连接命令。
$ docker inspect <id-or-name> | grep 'IPAddress' | head -n 1
使用您机器上的 SSH 客户端连接到容器:
$ ssh root@172.17.0.1
# 或者
$ ssh sshuser@172.17.0.1
如果您在主机上运行单独的 SSH 服务器,或者您有多个需要端口 22 的容器,则需要使用备用端口。以下是当 SSH 绑定到端口 2220 时启动连接的方法:
$ docker run -p 22:2220 my-image:latest
$ ssh root@172.17.0.1 -p 2220
使用 SSH Config 设置容器快捷方式
我们可以操作 SSH 配置文件以简化与各个容器的连接。 编辑 ~/.ssh/config
来定义具有预配置端口的快捷键:
Host my-container
HostName 172.17.0.1
Port 2220
User sshuser
现在可以运行 ssh my-container
直接放入您的容器中。 这使得在不记住容器 IP 和端口的情况下处理多个连接变得更容易。
改用 Dockssh 简化容器管理
Dockssh 项目更进一步,提供了另一个守护程序,让我们无需任何手动 SSH 配置即可运行 ssh my-container@example.com 。 无需在容器中安装 SSH 服务器; Dockssh 自动代理 SSH 连接并运行正确的 docker exec
命令。
你必须先安装 Redis 来存储 Dockssh 的配置数据:
$ sudo apt install redis
接下来,通过添加带有容器名称和 SSH 连接密码的 Redis 记录来定义要公开的容器:
$ redis-cli set dockssh:my-container:pass "container-password-here"
然后下载 Dockssh:
$ sudo curl https://github.com/alash3al/dockssh/releases/download/v1.1.0/dockssh_linux_amd64 -O /usr/local/bin/dockssh
$ sudo chmod +x /usr/local/bin/dockssh
$ sudo ufw allow 22022
# 开启 DockSSH 服务
$ dockssh
现在可以连接到您的容器:
$ ssh my-container@example.com -p 22022
Dockssh 默认监听 22022 端口。 打开防火墙来允许使用该端口的进行连接。
连接时会提示您输入容器的密码。 这在我们上面的 Redis 记录中设置为 container-password-here。
使用 Dockssh 可以轻松地通过 SSH 连接到大量 Docker 容器。 当您定期从远程主机连接到您的容器时,这种方法是理想的,因为它将两步“SSH 然后 docker exec”序列简化为一个好记的命令。
将 Dockssh 注册为系统服务以供长期使用:
$ sudo nano /etc/systemd/system/dockssh.service
[Unit]
Description=Dockssh service
After=network.target
[Service]
type=simple
Restart=always
RestartSec=1
User=root
ExecStart=/usr/local/bin/dockssh
[Install]
WantedBy=multi-user.target
使用 systemctl
启用服务:
$ sudo systemctl enable dockssh.service
$ sudo systemctl start dockssh
Dockssh 现在将在您的系统启动时自动启动。
总结
将 SSH 与 Docker 容器相结合被广泛认为是一种反模式,但它仍然在开发、测试和某些遗留环境中使用。 如果别无选择,您可以将 SSH 服务器添加到您的容器中,复制公钥,然后通过容器的 IP 或主机端口绑定进行连接。
想要远程管理大量 Docker 容器的系统管理员可以试试 Dockssh。 它允许您通过无缝的后台映射到 docker exec 来运行熟悉的 ssh 命令,使用未修改的镜像为您提供两全其美的体验。
相关文章
在 Linux 中托管 Docker Internal
发布时间:2023/04/18 浏览次数:138 分类:Docker
-
Docker 允许开发人员通过将应用程序包装在称为容器的标准化单元中来高效地构建、测试和部署应用程序。 在使用 Docker 容器时,您可能会遇到需要将容器与主机连接的场景。
在 Docker 中设置工作目录
发布时间:2023/04/18 浏览次数:81 分类:Docker
-
在 Docker 中,我们可以通过编辑 Dockerfile 并添加密钥 WORKDIR 来设置我们的工作目录。本文将讨论在 Docker 中更改我们当前和默认的工作目录。
在 Docker 容器中公开多个端口
发布时间:2023/04/18 浏览次数:121 分类:Docker
-
Docker 容器使用端口来实现万维网上不同设备之间的通信。 在本篇文章中,我们将学习如何使用 Nginx 应用程序在 Docker 容器中公开多个端口。
将用户添加到 Docker 容器
发布时间:2023/04/18 浏览次数:186 分类:Docker
-
在本文中,我们将学习如何通过实现返回产品数组的 Express 应用程序将用户添加到 Docker 容器。
使用 Docker 网络主机命令
发布时间:2023/04/18 浏览次数:111 分类:Docker
-
在本文中,我们将学习如何使用 --network 命令将容器添加到主机网络。 如果我们不使用此命令指定网络,我们还将了解如何将容器添加到默认网络。
清除 Docker 容器日志
发布时间:2023/04/18 浏览次数:175 分类:Docker
-
本文介绍了我们可以用来清除 docker 容器中日志的不同方法。日志是应用程序在特定事件或状态发生时记录的信息,它们帮助我们监控应用程序并采取必要的措施。
Dockerfile 中 COPY 和 ADD 命令的区别
发布时间:2023/04/18 浏览次数:156 分类:Docker
-
在 Dockerfile 中,我们可以使用 COPY 或 ADD 命令复制这些文件。 这些命令在功能上是相同的; 但是,存在一些差异。本文介绍了 Dockerfile 中 COPY 和 ADD 命令之间的区别。