在第一部分中介绍了一些进入容器的办法,比如attach、exec等命令,但是这些命令都无法解决远程管理容器的问题。因此,当月读者需要远程登录容器内进行一些操作的时候,就需要SSH的支持了。
本章将具体介绍如何自行创建一个带有SSH服务的镜像,并详细介绍了两种创建容器的方法:基于docker commit命令创建和基于Dockerfile 创建。
10.2 基于commit命令创建
Docker提供了docker commit命令,支持用户提交自己对制定容器的修改,并生成新的镜像。命令格式为docker commit CONTAINER [REPOSITORY][:TAG]。
这里将介绍如何用docker commit命令。笔者以ubuntu14:04镜像添加SSH服务的操作流程为例。
1.准备工作
首先,使用ubuntu:14.04 镜像创建一个容器:
[root@localhost ~]# docker run -it ubuntu:14.04 /bin/bash
更新apt缓存,并安装openssh-server:
root@e99a5814bd95:/# apt-get update; apt-get install openssl-server -y
2配置SSH服务
如果需要正常启动SSH服务,则目录/var/run/sshd必须存在。手动创建它,并启动SSH服务:
root@684e3d385ffa:/# mkdir -p /var/run/sshd root@684e3d385ffa:/# /usr/sbin/sshd -D & [1] 3043
此时查看容器的22端口( SSH服务默认监听的端口),可见此端口已经处于监听状态:
root@684e3d385ffa:/# netstat -tunlp Active Internet connections (only servers) Proto Recv-Q Send-Q Local Address Foreign Address State PID/Program name tcp 0 0 0.0.0.0:22 0.0.0.0:* LISTEN 3043/sshd tcp6 0 0 :::22 :::* LISTEN 3043/sshd
修改SSH服务的安全登录配置,取消pam登录限制:
替换一行中的某部分 格式:sed 's/要替换的字符串/新的字符串/g' (要替换的字符串可以用正则表达式)
root@684e3d385ffa:/# sed -ri 's/session required pam_loginuid.so/#session required pam_loginuid.so/g' /etc/pam.d/sshd
在root用户目录下创建.ssh目录,并复制需要登录的公钥信息(一般为本地主机用户目录下的.ssh/id_rsa.pub文件),可由ssh -keygen -t rsa命令生成)到authorized_keys文件中:
root@684e3d385ffa:/# mkdir root/.ssh root@684e3d385ffa:/# vi /root/.ssh/authorized_keys
创建自动启动SSH服务的可执行文件run.sh,并添加可执行权限:
root@684e3d385ffa:/# chmod +x run.sh
其中,run.sh脚本内容如下:
#!/bin/bash /usr/sbin/sshd -D
3.保存镜像
将所退出的容器用docker commit命令保存为一个新的sshd:ubuntu镜像:
[root@localhost ~]# docker commit 684 tjjingpan/ubuntu:14.04
使用docker images查看本地生成的新镜像sshd:ubuntu,目前拥有的镜像如下:
[root@localhost ~]# docker images REPOSITORY TAG IMAGE ID CREATED SIZE index.tenxcloud.com/tjjingpan/httpd_html5 latest 8c4f0c603ea7 Less than a second ago 189MB index.tenxcloud.com/tjjingpan/httpd_html5 v1.0 3094c9c5bce1 Less than a second ago 186MB httpd_html5 v1.0 3094c9c5bce1 Less than a second ago 186MB httpd latest fb2f3851a971 Less than a second ago 177MB tjjingpan/ubuntu 14.04 125e22013caf 5 seconds ago 286MB ubuntu 16.04 c9d990395902 2 weeks ago 113MB ubuntu latest c9d990395902 2 weeks ago 113MB ubuntu 14.04 3b853789146f 2 weeks ago 223MB centos latest e934aafc2206 2 weeks ago 199MB
4.使用镜像
启动容器,并添加端口映射10022-->22。其中10022是宿主主机的端口,22是容器的SSH服务监听端口:
[root@localhost ~]# docker run -p 10022:22 -d tjjingpan/ubuntu:14.04 /run.sh 27fee55e4b71d2da018d649f8f645a5f2e66fc7d51d5b510395cc020eda1159c
启动成功后,可以在宿主主机上看到容器运行的详细信息:
[root@localhost ~]# docker ps CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES 27fee55e4b71 tjjingpan/ubuntu:14.04 "/run.sh" 50 seconds ago Up 49 seconds 0.0.0.0:10022->22/tcp zealous_cray 3240e3c603a3 index.tenxcloud.com/tjjingpan/httpd_html5 "httpd-foreground" 4 hours ago Up 4 hours 0.0.0.0:8080->80/tcp web
在宿主主机或其它主机上,可以通过SSH访问10022端口来登录容器:
Centos7创建支持ssh服务器的docker容器
1、启动一个docker容器:
# docker run -it centos:latest /bin/bash
- 1
这样就会新建一个docker容器,并且进入容器的bash中
2、安装sshd:
# yum -y install openssh-server
# yum -y install openssh-clients
- 1
- 2
3、启动sshd服务:
# /usr/sbin/sshd -D
- 1
我的报一下错误
Could not load host key: /etc/ssh/ssh_host_rsa_key
Could not load host key: /etc/ssh/ssh_host_ecdsa_key
Could not load host key: /etc/ssh/ssh_host_ed25519_key
- 1
- 2
- 3
此时,依次执行下列命令:
一路按回车键确认
# ssh-keygen -t rsa -f /etc/ssh/ssh_host_rsa_key -N ""
# ssh-keygen -t ecdsa -f /etc/ssh/ssh_host_ecdsa_key -N ""
# ssh-keygen -t ed25519 -f /etc/ssh/ssh_host_ed25519_key -N ""
- 1
- 2
- 3
再启动sshd服务,一切正常。
4、编辑sshd_config配置文件
# vim /etc/ssh/sshd_config
- 1
找到UsePAM yes这一段配置,将其改成UsePAM no
UsePAM no
#UsePAM yes
- 1
- 2
5、修改root的密码,如果不能passwd,执行:# yum -y install passwd
# passwd root
Changing password for user root.
New password:
- 1
- 2
- 3
两次输入密码
6、改完密码执行exit命令退出,这时会回到宿主机器的shell,执行下列命令将容器提交到镜像:
# docker commit containerid imagename
- 1
这里的containerid是容器的id,imagename就是提交时候镜像的名称,第一次提交的时候最好使用一个新的名称,不要覆盖了原有的干净的centos镜像。
容器id可以通过docker ps -l命令查看到,启动容器后默认的主机名其实就是容器id。
例如:# docker commit 67bb1912a373 sshd-images
7、通过docker run启动一个新的容器,参数-d表示后台运行,-p表示docker到主机的端口的映射
# docker run -d -p 10022:22 imagename /usr/sbin/sshd -D
- 1
如果启动没问题的话,就可以登录到容器了:
# ssh root@localhost -p 10022
- 1
挂载一个主机目录作为数据卷
使用-v标记也可以指定挂载一个本地的已有目录到容器中去作为数据卷:
# docker run -d -p 10022:22 --name web -v /usr/webapp:/opt/webapp sshd-images:latest /usr/sbin/sshd -D
- 1
上面的命令加载主机的/usr/webapp目录到容器的/opt/webapp目录:
这个功能在进行测试的时候十分方便,比如用户可以放置一些程序或数据到本地目录中,然后在容器内运行和使用。另外,本地目录的
10.2 使用Dockerfile创建
在第一部分中笔者曾介绍过Dockerfile基础知识,下面将介绍如何使用Dockerfile来创建一个支持SSH服务的镜像。
1.创建工具目录
$mkdir sshd_ubuntu #ls sshd_ubuntu
在其中,创建Dockerfile和run.sh文件:
#cd sshd_ubuntu/ #touch Dockerfile run sh #ls Dockerfile run.sh
2.编写run.sh脚本和authorized_keys文件
脚本文件run.sh的内容与上一小节中一致:
#!/bin/bash /usr/sbin/sshd -D
在宿主主机上生成SSH密钥对,并创建authorized_keys文件:
[root@localhost ~]# ssh-keygen -t rsa Generating public/private rsa key pair. Enter file in which to save the key (/root/.ssh/id_rsa): /root/.ssh/id_rsa already exists. Overwrite (y/n)? y Enter passphrase (empty for no passphrase): Enter same passphrase again: Your identification has been saved in /root/.ssh/id_rsa. Your public key has been saved in /root/.ssh/id_rsa.pub. The key fingerprint is: SHA256:EQNrdF1ctxniSW127To3xvvB+m9+ZmsRfQOi0CyplsE [email protected] The key's randomart image is: +---[RSA 2048]----+ | . o.B. o.+o.o| | E * =..+.o=*| | * + . .o++o| | = o o+| | . S ..+| | +=.| | .=+| | .o*| | .oBO| +----[SHA256]-----+
3.编写Dockerfile
下面是Dockerfile的内容及各部分的注释,要可对比上一节利用docker commit命令创建镜像过程,所进行的操作基本一致:
#设置继承镜像 FROM ubuntu:14.04 #提供一些作者信息 MAINTAINER jingpan([email protected]) #下面开始运行更新命令 RUN apt-get update #安装ssh服务 RUN apt-get install -y openssh-server RUN mkdir -p /var/run/sshd RUN mkdir -p /root/.ssh #取消pam限制 RUN sed -ri 's/session required pam_loginuid.so/#session required pam_loginuid.so/g' /etc/pam.d/sshd #复制配置文件到相应位置,并赋予脚本可执行权限 ADD authorized_keys /root/.ssh/authorized_keys ADD run.sh /run.sh RUN chmod 755 /run.sh #开放端口 EXPOSE 22 #设置自启动命令 CMD ["/run.sh"]
4.创建镜像
在sshd_ubuntu目录下,使用docker build 命令来创建镜像。这里需要注意最后琮有一个".",表示使用当前目录中的Dockerfile:
[root@localhost sshd_ubuntu_14_04]# docker build -t ubuntu_sshd:14.04 . Sending build context to Docker daemon 4.608kB Step 1/12 : FROM ubuntu:14.04 ---> 3b853789146f Step 2/12 : MAINTAINER jingpan([email protected]) ---> Using cache ---> 9ed883b4fc59 Step 3/12 : RUN apt-get update ---> Using cache ---> d03178f3eb6e Step 4/12 : RUN apt-get install -y openssh-server ---> Using cache ---> 9d5d93446967 Step 5/12 : RUN mkdir -p /var/run/sshd ---> Using cache ---> 171af44fbf30 Step 6/12 : RUN mkdir -p /root/.ssh ---> Using cache ---> 2544aa32cd5c Step 7/12 : RUN sed -ri 's/session required pam_loginuid.so/#session required pam_loginuid.so/g' /etc/pam.d/sshd ---> Using cache ---> e3aa161ac89f Step 8/12 : ADD authorized_keys /root/.ssh/authorized_keys ---> Using cache ---> 3571507c0094 Step 9/12 : ADD run.sh /run.sh ---> Using cache ---> 7fee5296d78f Step 10/12 : RUN chmod 755 /run.sh ---> Using cache ---> aa44a218b897 Step 11/12 : EXPOSE 22 ---> Using cache ---> fd9bd0a14a9e Step 12/12 : CMD ["/run.sh"] ---> Using cache ---> 1e2214766c16 Successfully built 1e2214766c16 Successfully tagged ubuntu_sshd:14.04
如果读者使用Dockerfile创建自定义镜像,那么需要 注意的是Docker会自动删除中间临时创建的层,还需要注意每一步的操作和编写的Docker中命令的对应关系。
命令执行完毕后,如果读者可见"Successfully build XXX" 字样,则说明镜像创建成功。