创建支持带有ssh服务镜像的两种方法:

之前分享了一些容器的办法,比如attach、exec等命令,但这些命令都无法解决远程管理容器的问题。因此,需要远程登录到容器内进行操作的时候,就需要ssh的支持了。

一:基于commit命令创建

1.准备工作

[root@chengcheng ~]# cat /etc/redhat-release

CentOS Linux release 7.3.1611 (Core)

需要先安装基础软件,我用的是最小化安装,yum -y install unzip wget vim gcc* lrzsz yum-fastestmirror

然后安装docker,可用一键安装脚本curl -sSL https://get.docker.com/ | sh

更多安装部署docker请移步我的另一篇博客 https://blog.51cto.com/12943999/2073117

[root@chengcheng ~]# useradd cheng && echo "cheng" | passwd --stdin cheng(这一步我在装系统时做过了)

[root@chengcheng ~]# usermod -aG docker cheng (这一步是用cheng这个用户运行docker命令时候不用sudo)

[root@chengcheng ~]# id cheng

uid=1000(cheng) gid=1000(cheng) groups=1000(cheng),994(docker)

2.使用ubuntu:17.10镜像来创建一个容器,为ubuntu:18.04镜像添加ssh服务。

运行docker run -it ubuntu:17.10 /bin/bash,报错提示docker daemon running 没运行

运行systemctl enable docker && systemctl start docker,再执行命令完美解决问题。

创建支持带有ssh服务镜像的两种方法_第1张图片

3.在容器内安装软件,尝试使用sshd命令,发现容器中没安装此命令,镜像是精简镜像,使用apt-get update更新软件源信息。

apt-get update

apt-get install openssh-server && apt-get install vim net-tools && mkdir -p /var/run/sshd && /usr/sbin/sshd -D &

4.查看端口是否开启,netstat -anptu

5.修改ssh服务的安全登录配置,取消pam登录限制

sed -ri "s/session    required     pam_loginuid.so/#session    required     pam_loginuid.so/g" /etc/pam.d/sshd

6.root用户下创建.ssh目录,并复制需要登陆的公钥信息,一般为本地用户目录下的.ssh/id_rsa.pub文件,可由ssh-key -t rsa命令生成到容器的authorized_keys文件中。(此步可另外开一个终端,在宿主机下运行ssh-key -t rsa,把.ssh/id_rsa.pub里边内容黏贴过来)

mkdir root/.ssh

vi /root/.ssh/authorized_keys

7.创建自启动的可执行文件,并添加可执行权限

vi /run.sh

run.sh脚本内容如下

#!/bin/bash

/usr/sbin/sshd -D

chmod +x run.sh

然后exit退出容器

blob.png

8.保存为一个新的镜像

docker commit -a "chengcheng" -m "my create ubuntu:17.10" 3c28ebc314e6 myubuntu/v1.0.1:17.10

9.启动容器,添加端口映射

docker run -d -p 10022:22 myubuntu/v1.0.1:17.10 /run.sh

10.在宿主主机或其他主机上,可以通过ssh访问10022端口来登陆容

ssh 192.168.44.135 -p 10022

创建支持带有ssh服务镜像的两种方法_第2张图片

11.可看到最下面的红色箭头证明已经成功登录到容器

二:使用Dockerfile创建

如果对Dockerfie文件还不太熟悉的小伙伴可移步我的另一篇博客 https://blog.51cto.com/12943999/2085761   

1.创建工作目录

mkdir sshd_ubuntu

cd sshd_ubuntu/

touch Dockfile run.sh

2.编写run.sh脚本和authorized_keys文件

cat run.sh

#!/bin/bash

/usr/sbin/sshd -D

3.宿主机上生成ssh密钥对,并创建authorized_keys文件

ssh-keygen -t rsa

cat ~/.ssh/id_rsa.pub > authorized_keys

创建支持带有ssh服务镜像的两种方法_第3张图片

4.编写Dockerfile

cat Dockerfile

#This dockerfile uses the ubuntu:17.10

FROM ubuntu:17.10

MAINTAINER Username [email protected]

RUN apt-get update

RUN apt-get install openssh-server vim net-tools && mkdir -p /var/run/sshd

RUN sed -ri "s/session    required     pam_loginuid.so/#session    required     pam_loginuid.so/g" /etc/pam.d/sshd

RUN apt-get clean && apt-get autoclean && apt-get autoremove

ADD authorized_keys /root/.ssh/authorized_keys

ADD run.sh /run.sh

RUN chmod 755 /run.sh

EXPOSE 22

CMD [/run.sh]

5.构建镜像

[root@chengcheng sshd_ubuntu]# docker build -t myubuntu/v1.0.2:17.10 .

这一步一直过不去,搞了半天也没解决,心里还在想着怎么自动输入yes,在RUN apt-get update后添加-y问题还是没解决,最后瞎倒腾在这行前面(/etc/apt/source.list)追加了源,还是不行,网上说在使用apt-get安装软件时,需要加上"-y"的参数,如果不指定-y参数的话,apt-get命令会进入交互模式,需要用户输入命令来进行确认,但在docker环境中是无法响应这种交互的。所以就会造成安装中断这种问题。在RUN apt-get install openssh-server vim net-tools && mkdir -p /var/run/sshd这一行加了-y参数,完美解决问题。下面这份文件和上一份文件增加的部分是绿色,重要的还是加上-y参数,追加不追加源都可以的。

cat Dockerfile

#This dockerfile uses the ubuntu:17.10

FROM ubuntu:17.10

MAINTAINER Username [email protected]

RUN echo deb http://archive.ubuntu.com/ubuntu/ artful main restricted >> /etc/apt/source.list

RUN echo deb http://archive.ubuntu.com/ubuntu/ artful-updates main restricted >> /etc/apt/source.list

RUN echo deb http://archive.ubuntu.com/ubuntu/ artful universe >> /etc/apt/source.list

RUN echo deb-src http://archive.ubuntu.com/ubuntu/ artful universe >> /etc/apt/source.list

RUN echo deb http://archive.ubuntu.com/ubuntu/ artful-updates universe >> /etc/apt/source.list

RUN echo deb-src http://archive.ubuntu.com/ubuntu/ artful-updates universe >> /etc/apt/source.list

RUN echo deb http://archive.ubuntu.com/ubuntu/ artful multiverse >> /etc/apt/source.list

RUN echo deb http://archive.ubuntu.com/ubuntu/ artful-updates multiverse >> /etc/apt/source.list

RUN echo deb http://archive.ubuntu.com/ubuntu/ artful-backports main restricted universe multiverse >> /etc/apt/source.list

RUN apt-get update -y

RUN apt-get install -y openssh-server vim net-tools && mkdir -p /var/run/sshd

RUN sed -ri "s/session    required     pam_loginuid.so/#session    required     pam_loginuid.so/g" /etc/pam.d/sshd

RUN apt-get clean && apt-get autoclean && apt-get autoremove

ADD authorized_keys /root/.ssh/authorized_keys

ADD run.sh /run.sh

RUN chmod 755 /run.sh

EXPOSE 22

CMD [/run.sh]

构建成功会有Successfully XXXXXXX 提示

创建支持带有ssh服务镜像的两种方法_第4张图片

6.查看并验证结果,通过docker images可看到生成的镜像ID为1983f49e9937

[root@chengcheng sshd_ubuntu]# docker images

REPOSITORY          TAG                 IMAGE ID            CREATED             SIZE

myubuntu/v1.0.2     17.10               1983f49e9937        17 minutes ago      245MB

myubuntu/v1.0.1     17.10               8aee079b2d8f        39 minutes ago      245MB

ubuntu              17.10               1af812152d85        8 days ago          98.4MB

[root@chengcheng sshd_ubuntu]# ssh 192.168.44.135 -p 10122

三:小结

对于是否需要Docker容器启用ssh服务网上说法不一,一种说法是Docker的理念是一个容器只提供一个服务,因此一个容器在运行一个ssh服务,违背了这个理念,另外认为根本没有从远程主机进入容器进行维护的必要。另一种说法是如果使用attach方法进入容器,经常会出现卡死的情况,虽然也可以通过exec方法从宿主机进入容器,但是如果从其他远程主机进入容器依然没有好的解决方案。不过话说回来,个人觉得使用ssh方法维护服务依然是Linux用户较为熟悉的方式。

四:问题

1.出现的第一个问题

blob.png

在镜像构建完成后,会自动出现上述信息,要按Ctrl+C才能终止。

我的宿主机系统是CentOS Linux release 7.3.1611 (Core), 这是官方的一个说法:https://serverfault.com/questions/650377/linux-kernel-bug-w-netns-and-or-xen-guest-unregister-netdevice-waiting-for  ,说是一个bug。

2.出现的第二个问题

创建支持带有ssh服务镜像的两种方法_第5张图片

执行docker run -d -p 10122:22 myubuntu/v1.0.2:17.10不能成功进入容器,我在Dockerfile中定义了CMD [/run.sh],并赋予权限,为什么不行,而docker run -d -p 10122:22 myubuntu/v1.0.2:17.10 ./run.sh成功启动容器,实在想不明白,望本文有幸技术大牛看到能不吝赐教,谢谢!