如何通过SSH连接Docker容器


原文地址:如何通过SSH连接Docker容器

本篇文章分享了如何使用SSH连接Docker容器系统。

您如何使用SSH进入Docker容器?传统方法包括两个步骤:

步骤1:通过SSH进入远程Linux服务器(如果您在远程系统中运行容器)。

ssh user_name@server_ip_address

第2步:然后以交互方式输入正在运行的Docker容器的Shell,如下所示:

docker exec -it container_ID_or_name /bin/bash

这样,您可以运行Linux命令或对容器中运行的服务进行一些维护。

上述方法没有任何问题。这是毫不费力地进入容器的传统建议方法。

但是,通过一些努力,实际上您可以直接SSH到正在运行的容器中,而无需先登录到主机系统。

SSH进入Docker容器:但是为什么呢?

这有点奇怪,不是吗?通过SSH登录到容器。尽管这听起来很不传统,但根据您的用例,它可能仍然对您有用。

使用SSH到容器中可以实现以下几点:

  1. 您可以为任何潜在的攻击者设置主机。通过将非标准端口用于主机的SSH守护程序,并在22端口为攻击者提供SSH连接。
  2. 完全独立的授权级别,即密码登录或不同的ssh密钥完全由您决定,并与您当前使用的主机分开。
  3. 运行任何自动化的远程过程,而无需使用团队个人用于登录的相同ssh密钥。

在向您展示如何完成上述所有操作之前,我将带您逐步了解其实际工作原理。

不建议对现有容器使用ssh登录。这扼杀了主机隔离的全部要点。

为Docker容器设置SSH访问[中级到专家]

如果您对此操作不感兴趣,可以放心地忽略此部分。我将向您展示一个虚拟容器。您可以按照以下步骤进行练习。

运行一个容器

首先,您需要启动一个Docker容器。我现在将使用非常小的alpine:latest图像。使用以下命令启动容器:

docker run --rm --name ssh-test -it -p 22:7655 alpine:latest ash 

有关命令行选项的一些值得注意的地方如下

  • 使用该--rm选项,您不必随后显式删除容器
  • 这些-it选项在那里,以便您可以使用容器的有效交互外壳。
  • 最后,将容器的端口22绑定到主机的端口号7655(或主机系统上SSH守护程序尚未使用的任何其他端口号)。请记住您正在使用哪个端口。

在容器中设置SSH守护程序

现在,您需要在容器内安装ssh服务器。在Alpine 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帐户设置密码

默认情况下,您容器的根帐户没有密码。如果要打开SSH访问权限,则必须设置root帐户的密码。

您可以不带任何选项地使用passwd命令,并按照屏幕上的说明进行操作:

passwd

通过SSH登录到容器

从其他主机,尝试立即登录到容器。

ssh root@IP_address_of_host_server -p port_number

-p如果您以前绑定到端口22,则不需要此选项。对于IP,请使用主机服务器的IP地址(而不是容器的IP地址)。

运行命令时,应该看到类似于以下的输出:

debdut@shinchan:/mnt/data/documents/Linux Handbook/container-ssh$ ssh root@domain.com
   root@domain.com's password: 
   Welcome to Alpine!
   
   The Alpine Wiki contains a large amount of how-to guides and general
   information about administrating Alpine systems.
   See <http://wiki.alpinelinux.org/>.
   
   You can setup the system with the command: setup-alpine
   
   You may change this message by editing /etc/motd.
   
   c4585d951883:~#

这是如何运作的?

从视觉上可以更好地理解这一点。看下图:

如何通过SSH连接Docker容器

将容器视为虚拟机,其端口22与主机的端口7655(或您选择的端口)粘合在一起。这样,您就可以在绑定到不同端口的同一台计算机上运行两个不同的ssh进程。

假设您在主机系统上对SSH使用其他端口,并将端口22与容器的端口粘合在一起。现在,如果有人尝试使用SSH默认端口22连接到主机服务器,则他/她将位于容器的根文件系统中。

使用Docker Compose为容器设置SSH [专家]

如果我不为您提供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"

相当小的撰写文件,不是吗?让我解释一下此撰写文件的不同部分。

让我解释一下此撰写文件的不同部分。

卷:您只有一个绑定安装,它将容器中的公钥安装为pubkey。它也是只读的。

端口:容器中的sshd进程在端口2222上运行。这就是为什么我将该端口绑定到主机的端口22的原因。请根据您的需要更改22,但请记住,以后需要它通过SSH登录到容器。

环境变量:

  • USER_NAME:容器内用户,您将以本地计算机的身份登录。
  • PUID和PGID:USER_NAME的UID和GID。这是可选的,如果未设置环境变量,容器将自动分配一对非root用户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

我在docker-compose文件所在的目录中将bash脚本另存为deploy.sh。

现在,如果您运行此脚本,它将询问您一些问题,然后运行docker容器:

bash deploy.sh

完成后,尝试登录服务器:

ssh user@ip -p port 

到此结束有关使用docker容器的ssh的文章。

评论

登录后评论

服务器优惠活动

Top