如何用 SSH 連進遠端主機內的 docker container?

Docker 是個好用的虛擬服務技術,可以快速將開發環境建立在其他電腦上,例如 Tensorflow 就有提供官方的 Docker image。但是如果想要用 Pycharm 遠端開發,會發現沒辦法直接跟遠端主機中 Docker container 內的 python 溝通。這時就得將 Container 的 SSH 服務安裝起來,讓 Container 直接可以對外連線,這樣對 Pycharm 而言就像是在另一台遠端主機上開發一樣。

如何將 container 的  port 22 暴露出去利用網際網路連線呢?

參考資料:Dockerize an SSH service

首先我們要建立一個名為 Dockerfile 的空白文件,以下是官方的 Dockerfile 範例:

FROM ubuntu:16.04
 
RUN apt-get update && apt-get install -y 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"]

FROM 是作為基礎的 Docker image,可以至 Docker hub 選用官方的 image 作為基礎。
RUN 執行 shell 指令,如果需要安裝其他套件會很有用。
注意第五行 screencast 為 root 的密碼,記得一定要改掉,不然就等著被攻擊吧哈哈哈!
EXPOSE 22 為暴露 SSH 連線預設的 port 22 給外面的網路 (不能改),實際上暴露到網路的 port 會在 docker run 的地方設定。
CMD 為最後 container 生成後第一個執行的指令,為了不讓 sshd 服務被推到背景而停止。


另外這是我安裝 Tensorflow + Obspy 的 Dockerfile:

FROM tensorflow/tensorflow:latest-gpu-py3
RUN sed -i 's/archive.ubuntu.com/free.nchc.org.tw/g' /etc/apt/sources.list
 
RUN apt update && apt install wget
RUN echo deb http://deb.obspy.org xenial main >> /etc/apt/sources.list
RUN wget --quiet -O - https://raw.github.com/obspy/obspy/master/misc/debian/public.key | apt-key add - 
RUN apt update
 
RUN apt install -y openssh-server python3-obspy
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"]

做好 Dockerfile 後就用以下指令產生 image:

docker build -t ubuntu_sshd .

ubuntu_sshd 是自訂的 image 名稱
. 為 Dockerfile 所在的位置


接下來用這個 image 啟動一個 container:

docker run -d -p 49154:22 -v /home/user/data:/mnt/data --name my_server ubuntu_sshd

-d (detach) 讓container 生成後不要占用 terminal。
-p 指定主機上的 port 49154  接上 container 的 port 22,實際暴露的 port 除了不要覆蓋到原本主機的 port 22 外,可以自行選定,基於安全性原則一定要改
-v 將主機上的資料夾 /home/user/data mount 到 container 的 /mnt/data 上。
–name 命名這個虛擬機的名稱 my_server。


最後用一般 SSH 的方法使用 root 連線到主機的 ip,-p 設定為轉接的 port 49154 上:

ssh [email protected] -p49154

密碼為剛剛前面設定的 screencast

之後就可以像遠端主機一樣使用 container 了

 


在〈“如何用 SSH 連進遠端主機內的 docker container?”〉中有 1 則留言

  1. 幫備註一下, 因為ssh進去到container後發現PATH路徑會亂掉, 所以建議再加一行
    ENV NOTVISIBLE “in users profile”
    RUN echo “export VISIBLE=now” >> /etc/profile
    RUN env | grep = >> /etc/environment

steven 發表迴響取消回覆