参考文章:[Docker 技术入门与实战]
很多时候,系统管理员都习惯通过 SSH 服务来远程登录管理服务,但是 Docker 的很多镜像时不带 SSH 服务的,那么用户怎样才能管理容器呢?
本章将具体介绍如何自行创建一个带有 SSH 服务的镜像,并详细介绍了两种创建容器的方法:基于 docker commit
命令创建和基于 Dockerfile
创建。
基于 commit 命令创建
Docker 提供了 docker commit
命令,支持用户提交自己对定制容器的修改,并生成新的镜像。命令格式为:
1 | docker commit CONTAINER [REPOSITORY[:TAG]] |
准备工作
首先,获取 ubuntu:18.04
镜像,并创建一个容器:
1 | $ docker pull ubuntu:18.04 |
配置软件源
检查软件源,并使用 apt-get update
命令来更新软件源信息:
1 | root@dc9e2070808d:/# apt-get update |
如果默认的官方源速度慢的话,也可以替换为国内 163,sohu 等镜像的源。以 163 源为例,在容器内创建 /etc/apt/sources.list.d/163.list
文件:
添加如下内容到文件中:
1 | $ cat /etc/apt/sources.list.d/163.list |
之后重新执行 apt-get update
命令即可.
安装和配置 SSH 服务
更新软件包缓存后可以安装 SSH 服务了,选择主流的 openssh-server
作为服务端。可以看到需要下载安装众多的依赖软件包:
1 | root@dc9e2070808d:/# apt-get install openssh-server |
如果需要正常启动 SSH 服务,则目录 /var/run/sshd
必须存在。下面手动创建它,并启动 SSH 服务:
1 | root@dc9e2070808d:/# mkdir -p /var/run/sshd |
此时查看容器的 22
端口(SSH 服务默认监听的端口),可见此端口已经处于监听状态:
1 | root@dc9e2070808d:/# netstat -tunlp |
镜像若无
netstat
命令需要安装net-tools
命令:apt-get install net-tools
修改 SSH 服务的安全登录配置,取消 pam
登录限制:
1 | root@dc9e2070808d:/# 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
文件中:
1 | root@dc9e2070808d:/# mkdir root/.ssh |
创建自动启动 SSH 服务的可执行文件 run.sh
,并添加可执行权限:
1 | root@dc9e2070808d:/# echo '#!/bin/bash' > run.sh |
最后退出容器:
1 | root@dc9e2070808d:/# exit |
保存镜像
将所退出的容器用 docker commit
命令保存为一个新的 sshd:ubuntu
镜像
1 | $ docker commit dc9e2070808d sshd:ubuntu |
使用 docker images
查看本地生成的新镜像 sshd:ubuntu
:
1 | $ docker images |
使用镜像
启动容器,并添加端口映射 10022 –> 22,其中 10022 是宿主机本地的端口,22 是容器的 SSH 服务监听端口:
1 | $ docker run -p 10022:22 -d sshd:ubuntu /run.sh |
启动成功后,可以在宿主机上看到容器运行的详细信息:
1 | $ docker ps |
宿主机上(192.168.1.200)或其他主机上,可以通过 SSH 访问 10022 端口来登录容器:
1 | ssh 192.168.1.200 -p 10022 |
使用 Dockerfile 创建
下面介绍如何使用 Dockerfile 来创建一个支持 SSH 服务的镜像
创建工作目录
首先,创建一个 sshd_ubuntu
工作目录:
1 | mkdir sshd_ubuntu |
在其中创建 Dockerfile
和 run.sh
文件
1 | cd sshd_ubuntu/ |
编写 run.sh 脚本和 authorized_keys 文件
脚本文件 run.sh
内容和上面一致:
1 |
|
在宿主机上生成 SSH 秘钥对,并创建 authorized_keys
文件:
1 | $ ssh-keygen -t rsa |
编写 Dockerfile 文件
下面是 Dockerfile
的内容以及各部分的注释:
1 | # 设置基础镜像 |
创建镜像
在 sshd_ubuntu
目录下,使用 docker build
命令来创建镜像。这里用户需要注意在最后还有一个 “.
“,表示使用当前目录中的 Dockerfile
:
1 | docker build -t sshd-ubuntu:dockerfile . |
如果使用 Dockerfile 创建自定义镜像,那么需要注意的是 Docker 会自动删除中间临时创建的层,还需要注意每一步的操作和编写的 Dockerfile 中命令的对应关系。
命令执行完毕后,如果看见 “Successfully built xxxx” 字样,则说明镜像创建成功。
在本地查看 sshd-ubuntu:dockerfile
镜像已存在:
1 | $ docker images |
测试镜像,运行容器
下面使用刚才创建的 sshd-ubuntu:dockerfile
镜像来运行一个容器,直接启动镜像,映射容器的 22 端口到本地的 10122 端口:
1 | $ docker run -d -p 10122:22 sshd-ubuntu:dockerfile |
在宿主机上新打开一个终端,连接到新建的容器
1 | $ ssh root@172.17.0.7 |