如何使用 ssh 在本地连接到 VSCode 容器?
How to connect to VSCode container locally using ssh?
使用 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"
]
}
我测试了多种参数组合(forwardPorts
、appPort
、EXPOSE
等),但每次都是:
ssh
连接被拒绝
- 我连接到我的主机而不是我的容器
你知道我如何修改这些文件才能从容器的 bash 解释器连接到 ssh
吗?
有几个问题需要解决:
- 由于您的主机正在使用端口 22,您必须使用另一个端口。您可以使用
appPort
:
"appPort": "2222:22",
此表示法将主机的端口 2222 映射到容器的 22。
runArgs
和 forwardPorts
是多余的。
您需要添加 "overrideCommand": false
以防止 VSCode 覆盖 Docker 文件中声明的 CMD
。
您在 Docker 文件中的 sed
不正确,默认配置不包含行 PermitRootLogin prohibit-password
但包含 #PermitRootLogin <some-other-value
。将 sed
命令更改为:
RUN sed -i 's/.*PermitRootLogin.*/PermitRootLogin yes/' /etc/ssh/sshd_config
为了方便起见,这里是修改后的文件:
Docker文件:
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
,可以select From 'docker-compose.yml'
,然后select您想要的服务之一,它将构建并启动一个容器。它还将创建 .devcontainer
目录,其中包含 devcontainer.json
。
使用 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"
]
}
我测试了多种参数组合(forwardPorts
、appPort
、EXPOSE
等),但每次都是:
ssh
连接被拒绝- 我连接到我的主机而不是我的容器
你知道我如何修改这些文件才能从容器的 bash 解释器连接到 ssh
吗?
有几个问题需要解决:
- 由于您的主机正在使用端口 22,您必须使用另一个端口。您可以使用
appPort
:
"appPort": "2222:22",
此表示法将主机的端口 2222 映射到容器的 22。
runArgs
和forwardPorts
是多余的。您需要添加
"overrideCommand": false
以防止 VSCode 覆盖 Docker 文件中声明的CMD
。您在 Docker 文件中的
sed
不正确,默认配置不包含行PermitRootLogin prohibit-password
但包含#PermitRootLogin <some-other-value
。将sed
命令更改为:
RUN sed -i 's/.*PermitRootLogin.*/PermitRootLogin yes/' /etc/ssh/sshd_config
为了方便起见,这里是修改后的文件:
Docker文件:
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
,可以select From 'docker-compose.yml'
,然后select您想要的服务之一,它将构建并启动一个容器。它还将创建 .devcontainer
目录,其中包含 devcontainer.json
。