使用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,随后修改密钥登陆,禁止密码登录
1 2 3 4 5 6 7 8 # 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即可。
1 ssh: connect to host 192.168.9.148 port 2134: Connection refused
但是这样每次关闭容器后需要再次运行上述代码,很麻烦,因此我们写入一个脚本来每次登陆容器时自动运行上述命令,在上述ssh的下面加入以下代码即可。一共分为三部分,第一部分写一个shell文件来自动启动ssh,第二部分通过.bashrc文件检测shell文件的存在,如果存在则运行,最后更新.bashrc即可
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 # 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创建一个镜像
1 docker build -t <image:tag> .
根据我们的镜像创建一个容器
1 docker run -it -p 3712:22 image:tag /bin/bash
此时容器已经打开了,然后我们在另一个终端或者在vscode中通过ssh远程连接即可,这里的ip有时候为本机ip,有时候为0.0.0.0,可以通过docker ps查看,然后用下面命令连接
1.3 命令解释
COPY .ssh/ /root/.ssh/表示将本地的.ssh文件复制到容器中的/root/.ssh/文件夹下(其实这里相当于把副武器的ssh整个内容加入到了docker容器中)
其中的apt-get install -y openssh-server表示安装openssh-server服务,这样就可以允许秘钥登陆了
cat ~/.ssh/id_rsa.pub >> /root/.ssh/authorized_keys将本地用户的公钥写入到容器中的authorized_keys文件中,这样本地就可以ssh自动登录到容器中了
PubkeyAuthentication是否允许公钥登陆
PasswordAuthentication是否允许密码登录
PermitRootLogin参数为no,yes,prohibit-password。no表示不允许root用户登录,yes表示允许root用户登录,prohibit-password表示不允许root用户使用密码登录
1.4 整个Dockerfile文件
要先把.ssh和miniconda.sh文件和Dockerfile文件放在同一目录下才能build
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 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,并使用如下命令进入容器
1 docker run -it xx/xx:xx /bin/bash
此时容器内未安装openssh,因此我们首先要安装openssh
1 2 3 apt-get update apt-get install -y openssh-server apt-get install -y vim
2.2 设定密码
稍后我们要进行密码登录,所以这里设置一下密码
1 2 3 4 root@ee767b7c05d6:/workspace# passwd Enter new UNIX password: Retype new UNIX password: passwd: password updated successfully
2.3 设置密码登录
默认的,openssh不允许密码登录,这里我们设置一下
1 vim /etc/ssh/sshd_config
将其中的PasswordAuthentication后面改为yes
然后重启openssh
就可以按照秘钥登录所述ssh登录docker了,注意如果不修改PasswordAuthentication的话登录后输入密码会被docker拒绝登录Permission denied, please try again.