创建支持带有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,再执行命令完美解决问题。
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退出容器
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
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
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 提示
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.出现的第一个问题
在镜像构建完成后,会自动出现上述信息,要按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.出现的第二个问题
执行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成功启动容器,实在想不明白,望本文有幸技术大牛看到能不吝赐教,谢谢!