第10章 为镜像添加SSH服务

       在第一部分中介绍了一些进入容器的办法,比如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" 字样,则说明镜像创建成功。


猜你喜欢

转载自blog.csdn.net/tjjingpan/article/details/80290173