openssh 远程连接 docker
ide
本文字数:1.7k 字 | 阅读时长 ≈ 8 min

openssh 远程连接 docker

ide
本文字数:1.7k 字 | 阅读时长 ≈ 8 min

使用 openssh 我们可以将 Docker 启动的容器当做一个小型的服务器来使用,这样我们登陆容器的时候就可以用 ssh root@xx.xx.xx 来登陆使用了

注意:使用 openssh 登录 docker 有两种方法,一种是秘钥登录,另一种是密码登录,不论是秘钥登录还是密码登录都需要安装 openssh。这里对于秘钥登录我们给出 dockerfile,对于密码登录我们手动安装,当然也可以根据需求是选择创建镜像时安装还是建好 docker 后在安装

1. 秘钥登录

1.1 Dockerfile 构建

首先免密登陆容器需要秘钥,这里我们将本机的 ssh 文件夹放在与 Dockerfile 相同的文件夹下

ssh 文件夹一般在/home/root/.ssh

然后编写我们的 Dockerfile,下面的 dockerfile 意思是说将本地的 ssh 文件夹传到容器中,然后安装 openssh-server,随后修改密钥登陆,禁止密码登录

# openssh server
COPY ~/.ssh/ /root/.ssh/
RUN apt-get install -y openssh-server && \
    cat ~/.ssh/id_rsa.pub >> /root/.ssh/authorized_keys && \
    chmod 600 /root/.ssh/authorized_keys /root/.ssh/id_rsa.pub /root/.ssh/id_rsa && \
    sed -i 's/#PubkeyAuthentication yes/PubkeyAuthentication yes/g' /etc/ssh/sshd_config && \
    sed -i 's/#PasswordAuthentication yes/PasswordAuthentication no/g' /etc/ssh/sshd_config && \
    sed -i 's/#PermitRootLogin prohibit-password/PermitRootLogin prohibit-password/g' /etc/ssh/sshd_config

上述代码是核心 ssh 代码,其余内容按照自己需求定制即可,然后我们构建镜像,并通过 docker run -it -p 2134:22 image:tag /bin/bash 创建容器,然后运行 ssh -p port root@0.0.0.0(有时候 0.0.0.0 要用本机的 ip),远程连接时会出现如下错误,解决这个问题只需要在容器中运行 service ssh restart 即可。

ssh: connect to host 192.168.9.148 port 2134: Connection refused

但是这样每次关闭容器后需要再次运行上述代码,很麻烦,因此我们写入一个脚本来每次登陆容器时自动运行上述命令,在上述 ssh 的下面加入以下代码即可。一共分为三部分,第一部分写一个 shell 文件来自动启动 ssh,第二部分通过 .bashrc 文件检测 shell 文件的存在,如果存在则运行,最后更新 .bashrc 即可

# auto start openssh
RUN touch /startup_run.sh && \
    chmod 600 /startup_run.sh && \
    echo '#!/bin/bash' >> /startup_run.sh  && \
    echo 'LOGTIME=$(date "+%Y-%m-%d %H:%M:%S")' >> /startup_run.sh  && \
    echo 'echo "[$LOGTIME] startup run..." >> /root/startup_run.log' >> /startup_run.sh  && \
    echo 'service ssh start >> /root/startup_run.log' >> /startup_run.sh  && \
    chmod +x /startup_run.sh

# setup .bashrc to auto run startup_run.sh
RUN echo '# startup run' | tee -a /root/.bashrc  && \
    echo 'if [ -f /startup_run.sh ]; then' | tee -a /root/.bashrc  && \
    echo '      /startup_run.sh' | tee -a /root/.bashrc  && \
    echo 'fi' | tee -a /root/.bashrc
RUN /bin/bash -c "source ~/.bashrc"

1.2 ssh 连接容器

这部分在上述 Dockerfile 中已经写过了,这里在做一下总结。

首先根据 Dockerfile 创建一个镜像

docker build -t <image:tag> .

根据我们的镜像创建一个容器

docker run -it -p 3712:22 image:tag /bin/bash

此时容器已经打开了,然后我们在另一个终端或者在 vscode 中通过 ssh 远程连接即可,这里的 ip 有时候为本机 ip,有时候为 0.0.0.0,可以通过 docker ps 查看,然后用下面命令连接

ssh root@ip -p 3712

1.3 命令解释

  1. COPY .ssh/ /root/.ssh/ 表示将本地的.ssh 文件复制到容器中的/root/.ssh/文件夹下(其实这里相当于把副武器的 ssh 整个内容加入到了 docker 容器中)
  2. 其中的 apt-get install -y openssh-server 表示安装 openssh-server 服务,这样就可以允许秘钥登陆了
  3. cat ~/.ssh/id_rsa.pub >> /root/.ssh/authorized_keys 将本地用户的公钥写入到容器中的 authorized_keys 文件中,这样本地就可以 ssh 自动登录到容器中了
  4. PubkeyAuthentication 是否允许公钥登陆
  5. PasswordAuthentication 是否允许密码登录
  6. PermitRootLogin 参数为 noyesprohibit-passwordno 表示不允许 root 用户登录,yes 表示允许 root 用户登录,prohibit-password 表示不允许 root 用户使用密码登录

1.4 整个 Dockerfile 文件

要先把 .sshminiconda.sh 文件和 Dockerfile 文件放在同一目录下才能 build

FROM nvidia/cuda:11.7.1-devel-ubuntu20.04
LABEL maintainer wangyh "1061771439@qq.com"

# setup proxy
# ENV http_proxy http://192.168.161.204:7890
# ENV https_proxy http://192.168.161.204:7890

ENV PATH /opt/conda/bin:$PATH
COPY miniconda.sh /miniconda.sh

# install some tools
RUN chmod -R 777 /opt && \
    APT_INSTALL="apt-get install -y --no-install-recommends" && \
    CONDA_INSTALL="conda install -y" && \
    rm -rf /var/lib/apt/lists/* \
           /etc/apt/sources.list.d/cuda.list \
           /etc/apt/sources.list.d/nvidia-ml.list && \
    apt-get update && \
    apt-get -y upgrade && \
    $APT_INSTALL wget vim zip git libgl1-mesa-glx libglib2.0-0 && \
    $APT_INSTALL openssh-server

# install miniconda
RUN rm -rf /opt/conda && \
    /bin/bash /miniconda.sh -b -p /opt/conda && \
    rm /miniconda.sh && \
    pip install --upgrade pip && \
    conda create -n torch -y python=3.10

RUN echo "conda activate torch" >> ~/.bashrc
# RUN python -c "import flask"
SHELL ["/bin/bash", "--login", "-c"]

# setup openssh
RUN mkdir -p /var/run/sshd
RUN mkdir -p /root/.ssh

COPY .ssh/ /root/.ssh/
RUN cat /root/.ssh/id_rsa.pub >> /root/.ssh/authorized_keys
RUN chmod 600 /root/.ssh/authorized_keys /root/.ssh/id_rsa.pub /root/.ssh/id_rsa && \
    sed -i 's/#PubkeyAuthentication yes/PubkeyAuthentication yes/g' /etc/ssh/sshd_config && \
    sed -i 's/#PasswordAuthentication yes/PasswordAuthentication no/g' /etc/ssh/sshd_config && \
    sed -i 's/#PermitRootLogin prohibit-password/PermitRootLogin prohibit-password/g' /etc/ssh/sshd_config

# auto start openssh
RUN touch /startup_run.sh && \
    chmod 600 /startup_run.sh && \
    echo '#!/bin/bash' >> /startup_run.sh  && \
    echo 'LOGTIME=$(date "+%Y-%m-%d %H:%M:%S")' >> /startup_run.sh  && \
    echo 'echo "[$LOGTIME] startup run..." >> /root/startup_run.log' >> /startup_run.sh  && \
    echo 'service ssh start >> /root/startup_run.log' >> /startup_run.sh  && \
    chmod +x /startup_run.sh

# setup .bashrc to auto run startup_run.sh
RUN echo '# startup run' | tee -a /root/.bashrc  && \
    echo 'if [ -f /startup_run.sh ]; then' | tee -a /root/.bashrc  && \
    echo '      /startup_run.sh' | tee -a /root/.bashrc  && \
    echo 'fi' | tee -a /root/.bashrc
RUN /bin/bash -c "source ~/.bashrc"

# install python packages
RUN pip install medpy cython opencv-python cmake blobfile scipy scikit-image

RUN conda clean -y --all && \
    ldconfig && \
    apt-get clean && \
    apt-get autoremove && \
    rm -rf /var/lib/apt/lists/* /tmp/* /var/tmp/* ~/*

2. 密码登录

2.1 安装 openssh

这里我们创建一个普通容器不包含 Openssh,并使用如下命令进入容器

docker run -it xx/xx:xx /bin/bash

此时容器内未安装 openssh,因此我们首先要安装 openssh

apt-get update
apt-get install -y openssh-server
apt-get install -y vim

2.2 设定密码

稍后我们要进行密码登录,所以这里设置一下密码

root@ee767b7c05d6:/workspace# passwd
Enter new UNIX password: 
Retype new UNIX password: 
passwd: password updated successfully

2.3 设置密码登录

默认的,openssh 不允许密码登录,这里我们设置一下

vim /etc/ssh/sshd_config

将其中的 PasswordAuthentication 后面改为 yes

然后重启 openssh

service ssh restart

就可以按照秘钥登录所述 ssh 登录 docker 了,注意如果不修改 PasswordAuthentication 的话登录后输入密码会被 docker 拒绝登录 Permission denied, please try again.

5月 06, 2025