如何使用 SSH 进入 Docker 容器? 传统方法包括两个步骤:
第1步:通过 SSH 连接到您的远程 Linux 服务器(如果您在远程系统中运行容器)。
ssh [email protected]_ip_address
第2步:然后您以交互模式进入正在运行的 Docker 容器的外壳,如下所示:
docker exec -it container_ID_or_name /bin/bash
有了它,您可以运行 Linux 命令或对容器内运行的服务进行一些维护。
上述方法没有任何问题。 这是轻松进入容器的传统和推荐方式。
但是,通过一些努力,您实际上可以直接通过 SSH 连接到正在运行的容器,而无需先登录主机系统。
SSH 进入 Docker 容器:但是为什么呢?
这有点奇怪,不是吗? 通过 SSH 登录到容器。 尽管这听起来很不传统,但根据您的用例,它可能对您仍然有用。
以下是通过 SSH 进入容器的能力可以实现的一些目标:
- 您可以为任何潜在的攻击者设置假主机。 通过为主机的 SSH 守护进程使用非标准端口,并在端口 22 为攻击者提供 SSH 连接。
- 完全独立的授权级别,即密码登录或不同的 ssh 密钥都取决于您,并且与您的主机当前使用的任何内容分开。
- 运行任何自动化远程进程,而无需使用团队成员用于登录的相同 ssh 密钥。
在我向您展示如何执行上述所有操作之前,我将引导您了解这实际上是如何工作的。
不建议对现有容器使用 ssh 登录。 这扼杀了主机隔离的全部意义。
为 Docker 容器设置 SSH 访问 [Intermediate to Expert]
如果您对它的工作方式不感兴趣,您可以放心地忽略此部分。 我将向您展示一个虚拟容器。 您可以按照步骤进行练习。
运行一个容器
首先,您需要启动一个 Docker 容器。 我会用极小的 alpine:latest
现在的图像。 使用以下命令启动容器:
docker run --rm --name ssh-test -it -p 7655:22 alpine:latest ash
关于命令行选项的一些值得注意的点如下
- 随着
--rm
选项,您不必在之后显式删除容器。 - 这
-it
选项在那里,以便您可以拥有一个工作的、交互式的容器外壳。 - 最后,您将容器的端口 22 绑定到主机的端口号 7655(或主机系统上的 SSH 守护程序尚未使用的任何其他端口号)。 请记住您使用的是哪个端口。
在容器中设置 SSH 守护进程
现在您需要在容器内安装 ssh 服务器。 在 高山 Linux,您可以使用以下命令:
apk update; apk add openssh-server
接下来,您需要快速更改配置参数以允许 root 登录。 您可以通过手动编辑 /etc/ssh/sshd_config 文件或使用以下命令来完成:
sed -E 's/^#(PermitRootLogin )no/1yes/' /etc/ssh/sshd_config -i
使用以下命令生成主机密钥:
ssh-keygen -A
最后,启动 ssh 服务器,运行 /usr/sbin/sshd &
. 检查它是否正在运行 ps aux
.
为容器的 root 帐户设置密码
默认情况下,您的容器的 root 帐户没有密码。 如果您要打开对它的 SSH 访问,则必须为 root 帐户设置密码。
您可以使用不带任何选项的 passwd 命令并按照屏幕上的说明进行操作:
passwd
通过 SSH 登录到容器
现在从另一台主机尝试登录到容器。
ssh [email protected]_address_of_host_server -p port_number
你不需要 -p
如果您之前绑定到端口 22,请选择此选项。 对于 IP,使用主机服务器的 IP 地址(不是容器的)。
运行命令时,您应该会看到类似于以下内容的输出:
[email protected]:/mnt/data/documents/Linux Handbook/container-ssh$ ssh [email protected]
[email protected]'s password:
Welcome to Alpine!
The Alpine Wiki contains a large amount of how-to guides and general
information about administrating Alpine systems.
See <https://wiki.alpinelinux.org/>.
You can setup the system with the command: setup-alpine
You may change this message by editing /etc/motd.
c4585d951883:~#
这是如何运作的?
这可以从视觉上更好地理解。 请看下图:
将容器想象成一个虚拟机,其端口 22 与主机的端口 7655(或您选择的端口)粘合在一起。 这使您可以在绑定到不同端口的同一台机器上运行两个不同的 ssh 进程。
假设您在主机系统上使用其他一些端口进行 SSH,并将端口 22 与容器的端口粘合在一起。 现在,如果有人尝试使用 SSH 默认端口 22 连接到主机服务器,他/她将位于容器的根文件系统中。
使用 Docker Compose 为容器设置 SSH [Experts]
如果我在没有为 SSH 服务器容器提供一些可靠选项的情况下将您留在这个地方,那将是不公平的。
如果您想利用在远程系统上运行具有单独根文件系统的不同的、隔离的 ssh 服务器,可以这样做,但不能按照前面的演练,即在运行的基础上安装和配置 sshd容器。
仅仅因为它不容易重现,您对正在运行的容器所做的每一次更改都不是持久的,容器重新启动并且一切都消失了。
因此,我在这里为您提供了一种更简单、易于重现、可配置的方式来在远程主机上部署 SSH 服务器容器。
先决条件
您显然需要安装 docker compose。 docker compose 的基础知识在这里是必须的。
由于您将通过 SSH 密钥访问服务器,因此您需要将本地系统的公共 SSH 密钥添加到 docker-compose 文件所在的主机 Linux 服务器目录中,并保留名称“id_rsa.pub”以确保安全。
准备撰写文件
我建议使用 linuxserver/openssh-server
图片。 这是一个非常轻量级的图像,通过环境变量具有足够好的配置选项。
这里将粘贴整个撰写文件。 将其复制到服务器上的某个位置并命名文件 docker-compose.yaml
.
version: "3.7"
services:
ssh:
image: "linuxserver/openssh-server"
ports:
- "22:2222"
volumes:
- "./id_rsa.pub:/pubkey:ro"
environment:
PUID: ${ID}
PGID: ${ID}
TZ: ${TZ}
PUBLIC_KEY_FILE: "/pubkey"
SUDO_ACCESS: "false"
PASSWORD_ACCESS: "false"
USER_NAME: ${USER_NAME}
restart: "always"
相当小的撰写文件,不是吗? 让我解释一下这个 compose 文件的不同部分。
卷: 您只有一个绑定挂载,它将公钥挂载到容器中 pubkey
. 它也是只读的。
端口: 容器内的 sshd 进程在端口 2222 上运行。这就是为什么我将该端口绑定到主机的端口 22。根据您的需要更改 22,但请记住,稍后您将需要它通过 SSH 登录到容器。
环境变量:
- USER_NAME :容器内用户,您将从本地计算机登录。
- PUID & PGID:USER_NAME 的 UID 和 GID。 这是可选的,如果未设置环境变量,容器将自动分配一对非根 ID。
- TZ:您当前的时区。 你可以通过
cat /etc/timezone
. - PUBLIC_KEY_FILE:公钥文件的位置
- SUDO_ACCESS & PASSWORD_ACCESS:不言自明。
重启策略: 我已经设置了“总是”重启策略,即使重新加载了守护进程,它也会重启容器。
部署服务
为了方便您,我制作了一个 Bash 脚本,它会问您几个问题,并根据答案部署服务。
#! /usr/bin/env bash
vars=("ID" "USER_NAME")
defaults=("991" "dummy")
questions=("What'd be your preferred UID & GID for the username of your choice? [default] " "Your preferred username for the container? [dummy] ")
put()
{
echo "$1" >> .env
}
for i in {1..0}; do
read -p "${questions[$i]}" ans
case $ans in
""|"default")
put "${vars[$i]}=${defaults[$i]}" ;;
*)
put "${vars[$i]}=$ans" ;;
esac
done
put "TZ=$(cat /etc/timezone)"
docker-compose up -d
我保存了 bash 脚本作为 deploy.sh 在 docker-compose 文件所在的同一目录中。
现在,如果你运行这个脚本,它会问你一些问题,然后运行 docker 容器:
bash deploy.sh
完成后,尝试登录服务器:
ssh [email protected] -p port
这篇关于 ssh 和 docker 容器的文章到此结束。 如果您喜欢它,或者有其他要提及的,请随时在下面发表评论或发推文给我 @imdebdut.
如果您希望我写其他文章,请随时告诉我。