【问题标题】:SSH directly into a docker containerSSH 直接进入 docker 容器
【发布时间】:2015-07-28 05:30:46
【问题描述】:

我有一些 docker conatiners,现在我想使用 ssh 访问其中一个。那是有效的,我通过 ssh 连接到 docker 容器。

但是现在我有一个问题,我不知道我可以通过哪个用户访问这个容器?

我已经对主机上的两个用户(web 和 root)进行了尝试。但它们不起作用。 要知道什么?

【问题讨论】:

  • 你真的需要ssh连接吗?您只需sudo docker exec -i -t container-name /bin/bash 即可访问正在运行的容器。
  • 是需要直接在特定容器中访问
  • 好的,可以分享一下错误信息吗?
  • 我已经在容器中安装了 openssh-server。设置根密码。当我想连接时,我只得到拒绝访问
  • 您是否将/etc/ssh/sshd_config 中的PermitRootLogin 选项设置为yes 值?

标签: ssh debian docker


【解决方案1】:

您可以使用以下命令直接放入正在运行的容器中:

$ docker exec -it myContainer /bin/bash

您可以在未运行的容器上获取​​ shell:

$ docker run -it myContainer /bin/bash

这是在容器上获取​​ shell 的首选方法。运行 SSH 服务器被认为不是一种好的做法,尽管存在一些用例,但应尽可能避免。

【讨论】:

  • 我只需要控制台就可以在这个容器中使用 Jenkins 进行访问。
  • 我是 docker 的新手。现在在其中一个 docker 中使用 Jenkins,但我观察到,Jenkins 没有单独的 IP。我正在使用主机 IP 访问网站。
【解决方案2】:

如果您想直接连接到 Docker 容器,而不连接到 docker 主机,您的 Dockerfile 应包含以下内容:

# SSH login fix. Otherwise user is kicked off after login
RUN echo 'root:pass' | chpasswd
RUN mkdir /var/run/sshd
RUN sed 's@session\s*required\s*pam_loginuid.so@session optional pam_loginuid.so@g' -i /etc/pam.d/sshd

EXPOSE 22
CMD ["/usr/sbin/sshd", "-D"]

然后使用带有 -p 和 -d 标志的 docker run。示例:

docker run -p 8022:22 -d your-docker-image

您可以联系:

ssh root@your-host -p8022

【讨论】:

  • 每个容器是否有可能获得多个 ssh 会话?现在我可以通过 ssh 连接,但只能从一个地方连接。当我同时尝试从另一个地方连接时,我只会收到以下错误 - ssh_exchange_identification: read: Connection reset by peer
  • 它在 Debian 上效果不佳。我正在使用 Debian,即使我使用的是您提供给 @miguelghz 的 Dockerfile,我似乎也获得了拒绝的权限
【解决方案3】:

1.发出命令docker inspect (containerId or name)

你会得到这样的结果

   "IPv6Gateway": "",
            "MacAddress": "",
            "Networks": {
                "my_bridge": {
                    "IPAMConfig": {
                        "IPv4Address": "172.17.0.20"
                    },
                    "Links": null,
                    "Aliases": [
                        "3784372432",
                        "xxx",
                        "xxx2"
                    ],
                    "NetworkID": "ff7ea463ae3e6e6a099e0e044610cdcdc45b21f7e8c77a814aebfd3b2becd306",
                    "EndpointID": "6be4ea138f546b030bb08cf2c8af0f637e8e4ba81959c33fb5125ea0d93af967",
                    "Gateway": "172.17.0.1",
                    "IPAddress": "172.17.0.20",
                    "IPPrefixLen": 24,
...

  1. 从那里读出并复制 IP 地址,通过命令 ssh existingUser@IpAddress 连接到它,例如 someExistingUser@172.17.0.20。如果用户不存在,请在来宾映像中创建他,最好使用 sudo 权限。可能不直接使用 root 用户,因为据我所知,该用户预设为通过 ssh 密钥连接到图像,或者具有预设密码并且更改它可能最终导致无法通过 ssh 连接到图像终端通过常规方式进行docker exec -it containerName /bin/bashdocker-compose exec containerName /bin/bash

【讨论】:

    【解决方案4】:

    更强大的解决方案是将nsenter 下拉到您的服务器,然后从那里插入并运行docker-enter。这样你就不需要在容器中运行多个进程(ssh 服务器 + 容器的用途),或者担心 ssh 用户的所有额外开销等等(更不用说安全问题了)。

    【讨论】:

    • 这更像是直接 ssh 的安全失败。因为Maschine中还有很多其他的码头工人。一个简单的 SSH 应该可以工作......只有身份验证是一个问题
    • 创建nsenter docker 镜像的人实际上是在recommends 上使用docker exec 而不是nsenter。自引入docker exec 以来,这被认为是最佳实践。另见this question
    【解决方案5】:

    容器背后的想法是容器运行单个进程,以便它可以被守护进程监控。如果这个过程停止 ||由于某种原因失败,它可以根据您在配置中的偏好重新启动。 ssh 服务器是一个正在运行的进程。因此,如果您需要对您的设置进行 ssh 访问,请创建一个 ssh 服务器服务,该服务可以与在设置中与其一起运行的其他容器共享卷。

    直接在主机中的容器上打开外壳:

    假设您在家中的 PC 上,并且您有一台运行 docker 并运行容器的远程计算机,并且您想直接在容器上打开一个 shell,而无需在远程主机上“停下来”: (-t 标志暴露了 tty)

    ssh -t user@remote.host 'docker exec -it running_container_name /bin/bash'
    

    如果您已经在主机上,喜欢接受的答案: (-i 交互 -t tty)

    docker exec -it running_container_name /bin/bash
    

    【讨论】: