【问题标题】:How to connect to SSHD inside a Docker container from Windows?如何从 Windows 连接到 Docker 容器内的 SSHD?
【发布时间】:2017-07-26 18:21:24
【问题描述】:

我有一个 Ruby on Rails 环境,我正在将其转换为在 Docker 中运行。这主要是因为开发机器是 Windows 笔记本电脑,而服务器不是。我主要启动并运行了 Docker 容器,现在我想连接 RubyMine 调试器。为此,建议在容器中设置 SSH 服务器。

https://intellij-support.jetbrains.com/hc/en-us/community/posts/207649545-Use-RubyMine-and-Docker-for-development-run-and-debug-before-deployment-for-testing-

我使用来自https://docs.docker.com/engine/examples/running_ssh_service/#build-an-egsshd-image 的 dockerfile 行减去 EXPOSE 22 成功地将 SSHD 添加到容器中(因为它不适用于 docker-compose.yml 中的端口映射)。但是本机无法访问该端口

CONTAINER ID        IMAGE               COMMAND                  CREATED             STATUS              PORTS                                          NAMES
6652389d248c        civilservice_web    "bundle exec rails..."   16 minutes ago      Up 16 minutes       0.0.0.0:3000->3000/tcp, 0.0.0.0:3022->22/tcp   civilservice_web_1

当我尝试将 PUTTY 指向 localhost 和 3022 时,它说服务器意外关闭了连接。

我在这里错过了什么?

这是我的 dockerfile

FROM ruby:2.2
RUN apt-get update && apt-get install -y \
    build-essential \
    libpq-dev \
    nodejs \
    openssh-server

RUN mkdir /var/run/sshd
RUN echo 'root:screencast' | chpasswd
RUN sed -i 's/PermitRootLogin prohibit-password/PermitRootLogin yes/' /etc/ssh/sshd_config

# SSH login fix. Otherwise user is kicked off after login
RUN sed 's@session\s*required\s*pam_loginuid.so@session optional pam_loginuid.so@g' -i /etc/pam.d/sshd

ENV NOTVISIBLE "in users profile"
RUN echo "export VISIBLE=now" >> /etc/profile

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

RUN mkdir /MyApp
WORKDIR /MyApp
ADD Gemfile /MyApp/Gemfile
ADD Gemfile.lock /MyApp/Gemfile.lock
RUN bundle install
ADD . /MyApp

这是我的 docker-compose.yml

version: '2'
services:
  web:
    build: .
    command: bundle exec rails s -p 3000 -b '0.0.0.0'
    volumes:
      - .:/CivilService
    ports:
      - "3000:3000"
      - "3022:22"

DOCKER_HOST 似乎不是环境变量

docker version 输出以下内容

Client:
 Version:      17.03.0-ce
 API version:  1.26
 Go version:   go1.7.5
 Git commit:   60ccb22
 Built:        Thu Feb 23 10:40:59 2017
 OS/Arch:      windows/amd64

Server:
 Version:      17.03.0-ce
 API version:  1.26 (minimum version 1.12)
 Go version:   go1.7.5
 Git commit:   3a232c8
 Built:        Tue Feb 28 07:52:04 2017
 OS/Arch:      linux/amd64
 Experimental: true

docker run -it --rm --net container:civilservice_web_1 busybox netstat -lnt 输出

Active Internet connections (only servers)
Proto Recv-Q Send-Q Local Address           Foreign Address         State
tcp        0      0 0.0.0.0:3000            0.0.0.0:*               LISTEN
tcp        0      0 127.0.0.11:35455        0.0.0.0:*               LISTEN

SSHD 现在与 Rails 应用程序一起运行,但我用于设置服务的方法与我的基础映像 https://docs.docker.com/engine/examples/running_ssh_service/#build-an-egsshd-image 附带的 Linux 风格不正确

我使用的图像是基于 Debian 8 的。有人能指出我的例子在哪里出错了吗?

【问题讨论】:

  • 你能用echo $DOCKER_HOSTdocker versiondocker run -it --rm --net container:civilservice_web_1 busybox netstat -lnt的输出更新你的问题吗?
  • @BMitch 我添加了这些项目,虽然看起来没有 DOCKER_HOST 环境变量
  • 您的 SSHD 永远不会运行。每个容器一个 CMD。
  • @user2105103 这是有道理的。将 yml 文件中的命令更改为 /usr/sbin/sshd -D && bundle exec rails s -p 3000 -b '0.0.0.0' 是否可行?
  • 它可能适用于玩耍,但肯定不能用于生产。试一试。

标签: windows docker sshd


【解决方案1】:

您的 sshd 进程没有运行。这在 netstat 输出中可见:

Active Internet connections (only servers)
Proto Recv-Q Send-Q Local Address           Foreign Address         State
tcp        0      0 0.0.0.0:3000            0.0.0.0:*               LISTEN
tcp        0      0 127.0.0.11:35455        0.0.0.0:*               LISTEN

但正如 user2105103 指出的那样,如果我将您的 docker-compose.yml 与 Dockerfile 进行比较,我应该已经意识到。您在镜像中使用 Dockerfile 行定义 sshd 命令:

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

但是当你使用 docker-compose 命令运行容器时,你会覆盖你的图像设置:

command: bundle exec rails s -p 3000 -b '0.0.0.0'

所以,正如您在 netstat 中看到的,唯一运行的是在 3000 上侦听的 rails 应用程序。如果您需要运行多个命令,那么您可以docker exec 启动第二个命令(不推荐用于像这样的第二个服务),使用在后台启动 sshd 并在前台启动 rails 的命令(相当丑陋),或者您可以考虑使用类似 supervisord 的东西。

就我个人而言,我会跳过 sshd 并在需要时使用 docker exec -it civilservice_web_1 /bin/bash 在容器内获取提示。

【讨论】:

  • 问题是调试器需要连接SSH服务器
  • 对于多个进程,请查看supervisord.org。不推荐在 docker 容器中运行多个不同应用程序的解决方案。但既然你需要,这是更好的方法之一。
  • 一个更大的问题可能是,我在这里正确使用了 Docker。我是否应该尝试在 Docker 中托管我的开发环境,期望能够从本地 IDE 进行调试?
  • 我喜欢可以通过某种开放端口直接附加到应用程序的调试器,但是由于您需要使用 ssh 进行连接,所以您走在正确的道路上。如果 sshd 对您的应用没有硬依赖,这将是一个糟糕的设计,但它们紧密相连,您走在正确的道路上。
  • 我对这个 ide 不熟悉(老实说,自从 v1 以来一直是 Rails 开发人员,不久前放弃了调试器,没有重新审视它们,也没有真正错过它们 --- 记录器.debug 和 rails 控制台适用于我)。但是...您很可能必须编写自己的容器,了解流程管理器...我的流程管理器转到 github.com/just-containers/s6-overlay
猜你喜欢
  • 2017-04-06
  • 1970-01-01
  • 2019-03-16
  • 2022-12-16
  • 2022-01-16
  • 2018-10-20
  • 2022-06-27
  • 2020-11-20
  • 2017-05-14
相关资源
最近更新 更多