docker - 如何使用 ssh 在本地连接到 VSCode 容器?

标签 docker visual-studio-code ssh dockerfile vscode-remote

使用 VSCode Dev Container ,我希望能够从我的容器内 ssh 到我的容器内(出于测试目的)。

ssh root@localhost

我已经阅读了很多文章和类似的问题,但我无法创建一个最小的功能示例。

我的Dockerfile如下:

FROM ubuntu:18.04

RUN apt-get update && apt-get install -y --no-install-recommends net-tools iputils-ping openssh-client 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

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

我的devcontainer.json如下:

{
    "name": "Ubuntu",
    "build": {
        "dockerfile": "Dockerfile",
    },
    "settings": {
        "terminal.integrated.shell.linux": "/bin/bash"
    },
    "extensions": [],
    "forwardPorts": [
        22
    ],
    "appPort": 22,
    "runArgs": [
        "--net",
        "host",
        "-p",
        "22:22"
    ]
}

我测试了多种参数组合(forwardPortsappPortEXPOSE 等),但每次都是:

  • ssh 连接被拒绝
  • 我连接到我的主机而不是我的容器

请问您知道如何修改这些文件以便能够从容器的 bash 解释器连接到 ssh 吗?

最佳答案

有几个问题需要解决:

  1. 由于您的主机使用端口 22,您必须使用另一个端口。你可以用 appPort 做到这一点:
    "appPort": "2222:22",

此符号将主机的端口 2222 映射到容器的 22。

  1. runArgsforwardPorts是多余的。

  2. 您需要添加 "overrideCommand": false防止 VSCode 覆盖 CMD在 Dockerfile 中声明。

  3. 你的 sed在 Dockerfile 中不正确,默认配置不包含行 PermitRootLogin prohibit-password但它包含 #PermitRootLogin <some-other-value .更改 sed命令:

RUN sed -i 's/.*PermitRootLogin.*/PermitRootLogin yes/' /etc/ssh/sshd_config

为方便起见,这里是修改后的文件:

Dockerfile:

FROM ubuntu:18.04

RUN apt-get update && apt-get install -y --no-install-recommends net-tools iputils-ping openssh-client openssh-server 


RUN mkdir /var/run/sshd
RUN echo 'root:test' | chpasswd
RUN sed -i 's/.*PermitRootLogin.*/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

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

devcontainer.json:

{
    "name": "Ubuntu",
    "build": {
        "dockerfile": "Dockerfile",
    },
    "settings": {
        "terminal.integrated.shell.linux": "/bin/bash"
    },
    "extensions": [],
    "appPort": "2222:22",
    "overrideCommand": false
}

当您运行容器时,您可以使用 ssh root@localhost -p 2222 连接到它和密码“test”。

另外,我不知道你为什么决定使用 VSCode 特定的方式来实现 Docker,也许这样做有充分的理由,但有更好的方法。您可以使用 docker-compose创建一个测试环境。它是:

  • 更好地记录;
  • 广泛使用;
  • 受许多 IDE(包括 VSCode)支持。

看看这个docker-compose.yml :

# Check out this reference https://docs.docker.com/compose/compose-file/
# for list of available versions, their differences, and the file format in general.
version: "3.0"

# This is where you declare containers you want to run.
services:

  # This is the name of the service. One cool thing about it is that is will be a DNS name
  # in the networks where this service will be present. So when you need to connect this
  # service from another container you can simply do 'ssh username@ssh-server'.
  ssh-server:

    # This is the name of the image to use. In this case I intentionally used a nonexistent name.
    # Because of that when Docker will build the image from the Dockerfile, it will assign this
    # name to the image. This is not required since I've added 'build' property but giving the
    # right name could come handy.
    image: myssh

    # This is equivalent to 'build an image from the Dockerfile in current working directory' or
    # 'docker build .'
    build:
      context: .
      dockerfile: Dockerfile

    # This maps host's port 2222 to container's 22. This isn't necessary unless you want to connect
    # to this container from outside (e.g. from host or another machine). Containers do not
    # require 'exposure' or any other step to reach one another within one network - they have all
    # ports open. That is why it is called port forwarding or mapping.
    ports:
      - "2222:22"

  # Same image as the server but with a different command to execute.
  ssh-client:
    image: myssh
    build:
      context: .
    # Just a loop to run a command every second. Won't work with password, you need a key or some hacks.
    command: bash -c 'while sleep 1; do ssh root@ssh-server ls /; done'

如果将其保存到带有 Dockerfile 的目录中上面,你可以用 docker-compose up 运行它.或者你可以将它与 VSCode 集成:当没有 .devcontainer 时目录,然后单击 Reopen in container , 您可以选择 From 'docker-compose.yml' ,然后选择您想要的服务之一,它将构建并启动一个容器。它还将创建 .devcontainer目录 devcontainer.json

关于docker - 如何使用 ssh 在本地连接到 VSCode 容器?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/65127405/

相关文章:

scala - 为我的sbt添加什么以支持非游戏项目的Docker镜像创建?

docker - 动态更改存储文件夹

django - docker tmpfs 似乎对 postgresql 没有影响

docker - Cloudera管理器未运行

visual-studio-code - 显示悬停工具提示的键盘快捷键

typescript - 如何在 VSCode 中默认使用 settings.json 中定义的 TypeScript 版本?

java - HBase第一次使用,连接本地主机出错

.net - Visual Studio 断点栏不存在(字形边距、概览标尺)

bash - 我需要在UNIX中测试目录

javascript - 从网页在服务器上执行 shell 脚本