无法从 docker 容器 ECONNREFUSED 127.0.0.1:22 连接到 SSH - NodeJS

Can't connect to SSH from docker container ECONNREFUSED 127.0.0.1:22 - NodeJS

我在 nodejs 上使用 node-ssh 模块。当我开始与 ssh 的连接时,出现错误。我也在使用 WSL Ubuntu 18。我有 docker-compose 文件。我在 /etc/ssh/sshd_config 上将 PasswordAuthentication 标记为 'yes'。我可以从 wsl ubuntu 连接 ssh。但是当我试图从我的 dockerized nodejs 项目连接时。出现错误 ECONNREFUSED 127.0.0.1:22

在 nodejs 上,我正在请求用户身份验证,运行 一些命令等。

const Client = require('node-ssh').NodeSSH;
var client   = new Client();   

client.connect({
     host              : 'localhost',
     port              : 22,
     username          : req.body.username,
     password          : req.body.password,
     keepaliveInterval : 30 * 1000, // 30 minutes for idle as milliseconds
     keepaliveCountMax : 1,
}).then(()=>{

     // LOGIN SUCCESS

}).catch((e)=>{

     console.log(e); // ECONFUSED ERROR
     // LOGIN FAILED

});

docker-compose.yml

version: '3.8'

services:
  api:
    build:
      dockerfile: Dockerfile
      context: "./server"
    ports:
      - "3030:3030"
    depends_on:
      - mysql_db
    volumes:
      - /app/node_modules
      - ./server:/app

 ...

还有我的 api 的 Dockerfile

Dockerfile

FROM node:alpine
WORKDIR /app
COPY package.json ./
COPY package-lock.json ./
COPY ./ ./
RUN npm i
RUN apk update \
&& apk add openssh-server 
COPY sshd_config /etc/ssh/
EXPOSE 22
CMD ["npm", "run", "start"]

[UPDATE__] [Dockerfile]

FROM node:alpine
WORKDIR /app
COPY package.json ./
COPY package-lock.json ./
COPY ./ ./
RUN npm i \
&& apk add --update openssh \
&& rm  -rf /tmp/* /var/cache/apk/*
COPY sshd_config /etc/ssh/
# add entrypoint script
ADD ./docker-entrypoint.sh /usr/local/bin
# make sure we get fresh keys
RUN rm -rf /etc/ssh/ssh_host_rsa_key /etc/ssh/ssh_host_dsa_key
EXPOSE 22
ENTRYPOINT ["docker-entrypoint.sh"]
CMD ["/usr/sbin/sshd","-D"]

[UPDATE__2] [Dockerfile]

FROM node:alpine
WORKDIR /app
COPY package.json ./
COPY package-lock.json ./
COPY ./ ./
RUN npm i
RUN apk update && \
apk add openssh-client \ 
&& rm -rf /tmp/* /var/cache/apk/*

EXPOSE 22
CMD ["npm", "run", "start"]

[解决方案]
我已经更改了 Dockerfile 和我的 nodejs 代码。按照 Stefan Golubović 的建议 host.docker.internal 申请后,我已经从 docker 容器连接了 WSL 的 SSH。并使用 node:latest 而不是 node:alpine docker 图像。感谢@StefanGolubović 和@Etienne Dijon

[固定]

const Client = require('node-ssh').NodeSSH;
var client   = new Client();   

client.connect({
     host              : 'host.docker.internal', // It's worked on WSL2
     port              : 22,
     username          : req.body.username,
     password          : req.body.password,
     keepaliveInterval : 30 * 1000, // 30 minutes for idle as milliseconds
     keepaliveCountMax : 1,
}).then(()=>{

     // LOGIN SUCCESS

}).catch((e)=>{

     console.log(e); // ECONFUSED ERROR
     // LOGIN FAILED

});

Dockerfile [固定]

FROM node:latest
WORKDIR /app
COPY package.json ./
COPY package-lock.json ./
COPY ./ ./
RUN npm i
RUN apt-get update 
EXPOSE 22
CMD ["npm", "run", "start"]

简答

逐步测试您的docker文件

要确保一切正常,您可以做的是手动运行它

docker run -it --rm --name testalpine -v $PWD:/app/ node:alpine /bin/sh

然后:

cd /app/
npm i
apk update && apk add openssh-server
# show listening services, openssh is not displayed
netstat -tlpn

如您所见,openssh 没有自动启动

Alpine 有一个关于它的 wiki 需要 rc-update :

https://wiki.alpinelinux.org/wiki/Setting_up_a_ssh-server

rc-update 在 alpine 图像中不可用。

运行 alpine 容器中的 sshd 服务器

这张图片是关于 运行在 alpine 上安装 ssh 服务器:

https://github.com/danielguerra69/alpine-sshd

如您在 Dockerfile 中所见,涉及更多步骤:

Check repository for updated dockerfile

FROM alpine:edge
MAINTAINER Daniel Guerra <daniel.guerra69@gmail.com>

# add openssh and clean
RUN apk add --update openssh \
&& rm  -rf /tmp/* /var/cache/apk/*
# add entrypoint script
ADD docker-entrypoint.sh /usr/local/bin
# make sure we get fresh keys
RUN rm -rf /etc/ssh/ssh_host_rsa_key /etc/ssh/ssh_host_dsa_key

EXPOSE 22
ENTRYPOINT ["docker-entrypoint.sh"]
CMD ["/usr/sbin/sshd","-D"]

编辑:如果您需要在您的容器中运行命令

您可以在容器启动后使用 docker exec

docker exec -it <container name/id> /bin/sh

文档在这里:

https://docs.docker.com/engine/reference/commandline/exec/

  • 已更新 docker文件
    FROM node:alpine
    
    WORKDIR /app
    
    COPY ./ ./
    
    RUN npm i
    
    ENTRYPOINT ["npm", "run", "start"]