简介
一般情况下,Linux系统管理员通过SSH服务来管理操作系统,但Docker的很多镜像是不带SSH服务的,那么我们怎样才能管理操作系统呢?
在第一部分中我们介绍了一些进入容器的办法,比如用exec命令,但是这些命令都无法解决远程管理容器的问题。因此,当读者需要远程登录到容器内进行一些操作的时候,就需要SSH的支持了。
本文将具体介绍如何自行创建一个带有SSH服务的镜像,并详细介绍两种创建容器的方法:基于docker commit命令创建和基于Dockerfile创建。
基于 commit 创建
Docker 提供了 docker commit 命令,支持用户提交自己对容器的修改,并生成新的镜像。命令格式为 docker commit CONTAINER [REPOSITORY[:TAG]]。
这里将介绍如何使用 docker commit 命令,为 ubuntu 镜像添加SSH服务。
准备工作
首先,使用 ubuntu 镜像来创建一个容器:
[root@gavin /]# sudo docker run -it ubuntu /bin/bash
首先尝试使用 SSHD 命令,大家会发现容器中并没有安装该服务:
root@c8178608e454:/# sshd
bash: sshd: command not found
同时,笔者从 apt 包管理器的软件源信息中亦找不到启动 SSH 服务需要的 openssh-server,这是因为 Ubuntu 官方镜像中并没有包含软件包的缓存文件:
root@c8178608e454:/# apt-get install openssh-server
Reading package lists... Done
Building dependency tree
Reading state information... Done
E: Unable to locate package openssh-server
下面,笔者将演示如何更新软件包缓存,并安装 SSHD 服务。
配置软件源
检查软件源,并使用 apt-get update 来更新软件源信息:
root@c8178608e454:/# apt-get update
Get:1 http://security.ubuntu.com/ubuntu bionic-security InRelease [88.7 kB]
Get:3 http://archive.ubuntu.com/ubuntu bionic-updates InRelease [88.7 kB]
Get:4 http://security.ubuntu.com/ubuntu bionic-security/multiverse amd64 Packages [4957 B]
...
Fetched 14.4 MB in 36s (404 kB/s)
Reading package lists... Done
安装和配置 SSH 服务
更新软件包缓存后,已经可以安装 SSH 服务了,选择主流的 openssh-server 作为服务端。可以看到需要下载安装众多的依赖软件包:
root@c8178608e454:/# apt-get install openssh-server
...
done.
Processing triggers for systemd (237-3ubuntu10.28) ...
要正常启动 SSH 服务,需要目录 /var/run/sshd 存在,手动创建它,并启动服务:
root@c8178608e454:/# mkdir -p /var/run/sshd
root@c8178608e454:/# /usr/sbin/sshd -D &
修改 SSH 服务的安全登录配置,取消pam登录限制:
root@c8178608e454:/# 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@c8178608e454:/# mkdir root/.ssh
root@c8178608e454:/# vi /root/.ssh/authorized_keys
创建自动启动 SSH 服务的可执行文件 run.sh,并添加可执行权限:
root@c8178608e454:/# vi /run.sh
bash: vi: command not found
此时发现无法使用 vi 命令,这是因为vim没有安装,使用如下命令安装:
root@c8178608e454:/# apt-get install vim
Reading package lists... Done
Building dependency tree
Reading state information... Done
...
Processing triggers for libc-bin (2.27-3ubuntu1) ...
创建自动启动 SSH 服务的可执行文件 run.sh,并添加可执行权限:
root@c8178608e454:/# vi /run.sh
root@c8178608e454:/# chmod +x run.sh
run.sh 脚本内容如下:
#!/bin/bash
/usr/sbin/sshd -D
如果想要使用 root 登录,需要修改 /etc/ssh/sshd_config,使得可以直接使用 root 登录(此步骤需要重启后生效):
vim /etc/ssh/sshd_config
/etc/ssh/sshd_config 追加内容如下:
PermitRootLogin yes
UsePAM no
设置 root 密码:
root@c8178608e454:/# passwd root
Enter new UNIX password:
Retype new UNIX password:
passwd: password updated successfully
最后,退出容器:
root@c8178608e454:/# exit
exit
保存镜像
将所退出的容器用 docker commit 命令保存为一个新的 sshd:ubuntu 镜像:
[root@gavin /]# sudo docker commit c8178608e454 sshd:ubuntu
sha256:00eb7bf408ece207efae9a349b8d36d15d0c9c858ccb013e05561230c9e5c2ab
使用 docker images 查看本地生成的新镜像 sshd:ubuntu,目前拥有的镜像如下:
[root@gavin /]# sudo docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
sshd ubuntu 00eb7bf408ec About a minute ago 243MB
ubuntu latest a2a15febcdf3 2 weeks ago 64.2MB
使用镜像
启动容器,并添加端口映射 10022-->22。其中 10022 是宿主主机的端口,22 是容器的 SSH 服务监听端口:
[root@gavin /]# sudo docker run -p 10022:22 -d sshd:ubuntu /run.sh
ec6a0c53dc5790a569d1eb7b63866856748fc39285f13ffb57e66cfcf5adb061
启动成功后,可以在宿主主机上看到容器运行的详细信息:
[root@gavin /]# sudo docker ps -a
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
ec6a0c53dc57 sshd:ubuntu "/run.sh" 44 seconds ago Up 43 seconds 0.0.0.0:10022->22/tcp focused_knuth
在宿主主机或其他主机上,可以通过 SSH 访问 10022 端口来登录容器 :
[root@gavin ~]# ssh 192.168.41.15 -p 10022
root@192.168.41.15's password:
Welcome to Ubuntu 18.04.3 LTS (GNU/Linux 3.10.0-957.el7.x86_64 x86_64)
* Documentation: https://help.ubuntu.com
* Management: https://landscape.canonical.com
* Support: https://ubuntu.com/advantage
This system has been minimized by removing packages and content that are
not required on a system that users do not log into.
To restore this content, you can run the 'unminimize' command.
Last login: Wed Sep 4 13:25:49 2019 from 192.168.41.15
root@bc419278a175:~#
使用 Dockerfile 创建
在第一部分中笔者曾介绍过 Dockerfile 的基础知识,下面将介绍如何使用 Dockerfile 来创建一个支持 SSH 服务的镜像。
创建工作目录
首先创建一个 sshd_ubuntu 工作目录:
[root@gavin /]# mkdir sshd_ubuntu
[root@gavin /]# cd sshd_ubuntu/
[root@gavin sshd_ubuntu]# touch Dockerfile run.sh sources.list
[root@gavin sshd_ubuntu]# ls
Dockerfile run.sh
编写 run.sh 脚本的内容与上一小节中一致:
#!/bin/bash
/usr/sbin/sshd -D
更换源为国内源(这里用的是阿里源)下载速度快,编写 source.list 内容:
deb http://mirrors.aliyun.com/ubuntu/ bionic main restricted universe multiverse
deb-src http://mirrors.aliyun.com/ubuntu/ bionic main restricted universe multiverse
deb http://mirrors.aliyun.com/ubuntu/ bionic-security main restricted universe multiverse
deb-src http://mirrors.aliyun.com/ubuntu/ bionic-security main restricted universe multiverse
deb http://mirrors.aliyun.com/ubuntu/ bionic-updates main restricted universe multiverse
deb-src http://mirrors.aliyun.com/ubuntu/ bionic-updates main restricted universe multiverse
deb http://mirrors.aliyun.com/ubuntu/ bionic-proposed main restricted universe multiverse
deb-src http://mirrors.aliyun.com/ubuntu/ bionic-proposed main restricted universe multiverse
deb http://mirrors.aliyun.com/ubuntu/ bionic-backports main restricted universe multiverse
deb-src http://mirrors.aliyun.com/ubuntu/ bionic-backports main restricted universe multiverse
在宿主主机上生成 SSH 秘钥对,并创建 authorized_keys 文件:
[root@gavin /]# ssh-keygen -t rsa
...
[root@gavin sshd_ubuntu]# cat ~/.ssh/id_rsa.pub >authorized_keys
编写 Dockerfile
下面是 Dockerfile 的内容及各部分的注释,可以发现,对比上一节中利用 docker commit 命令创建镜像过程,所进行的操作基本一致。
# 设置继承镜像
FROM ubuntu
# 提供一些作者信息
MAINTAINER from gavin_g@qq.com
# 更换源为国内源
ADD sources.list /etc/apt/
# 配置软件源
RUN apt-get clean
RUN apt-get update --fix-missing
# 安装和配置 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"]
创建镜像
在 sshd_ubuntu 目录下,使用 docker build 命令来创建镜像。注意一下,在最后还有一个“.”,表示使用当前目录中的 Dockerfile。
[root@gavin sshd_ubuntu]# sudo docker build -t sshd:dockerfile .
如果读者使用 Dockerfile 创建自定义镜像,那么需要注意的是 Docker 会自动删除中间临时创建的层,还需要注意每一步的操作和编写的 Dockerfile 中命令的对应关系。
执行 docker build 命令的输出参考结果如下:
Sending build context to Docker daemon 4.608kB
Step 1/12 : FROM ubuntu
---> a2a15febcdf3
Step 2/12 : MAINTAINER from gavin_g@qq.com
---> Using cache
---> dc49243843b7
Step 3/12 : RUN apt-get update
---> Using cache
---> ce8282eea754
Step 4/12 : RUN apt-get install -y openssh-server
---> Running in 8ceb2d7d95fc
Reading package lists...
Building dependency tree...
Reading state information...
The following additional packages will be installed:
ca-certificates dbus dmsetup file gir1.2-glib-2.0 krb5-locales libapparmor1
libargon2-0 libbsd0 libcap2 libcryptsetup12 libdbus-1-3 libdevmapper1.02.1
libedit2 libexpat1 libgirepository-1.0-1 libglib2.0-0 libglib2.0-data
libgssapi-krb5-2 libicu60 libidn11 libip4tc0 libjson-c3 libk5crypto3
libkeyutils1 libkmod2 libkrb5-3 libkrb5support0 libmagic-mgc libmagic1
libmpdec2 libnss-systemd libpam-systemd libpsl5 libpython3-stdlib
libpython3.6-minimal libpython3.6-stdlib libreadline7 libsqlite3-0
libssl1.0.0 libssl1.1 libsystemd0 libwrap0 libx11-6 libx11-data libxau6
libxcb1 libxdmcp6 libxext6 libxml2 libxmuu1 mime-support multiarch-support
ncurses-term networkd-dispatcher openssh-client openssh-sftp-server openssl
publicsuffix python3 python3-certifi python3-chardet python3-dbus python3-gi
python3-idna python3-minimal python3-pkg-resources python3-requests
python3-six python3-urllib3 python3.6 python3.6-minimal readline-common
shared-mime-info ssh-import-id systemd systemd-sysv ucf wget xauth
xdg-user-dirs xz-utils
Suggested packages:
default-dbus-session-bus | dbus-session-bus krb5-doc krb5-user iw
| wireless-tools keychain libpam-ssh monkeysphere ssh-askpass molly-guard
rssh ufw python3-doc python3-tk python3-venv python-dbus-doc
python3-dbus-dbg python3-setuptools python3-cryptography python3-openssl
python3-socks python3.6-venv python3.6-doc binutils binfmt-support
readline-doc systemd-container policykit-1
The following NEW packages will be installed:
ca-certificates dbus dmsetup file gir1.2-glib-2.0 krb5-locales libapparmor1
libargon2-0 libbsd0 libcap2 libcryptsetup12 libdbus-1-3 libdevmapper1.02.1
libedit2 libexpat1 libgirepository-1.0-1 libglib2.0-0 libglib2.0-data
libgssapi-krb5-2 libicu60 libidn11 libip4tc0 libjson-c3 libk5crypto3
libkeyutils1 libkmod2 libkrb5-3 libkrb5support0 libmagic-mgc libmagic1
libmpdec2 libnss-systemd libpam-systemd libpsl5 libpython3-stdlib
libpython3.6-minimal libpython3.6-stdlib libreadline7 libsqlite3-0
libssl1.0.0 libssl1.1 libwrap0 libx11-6 libx11-data libxau6 libxcb1
libxdmcp6 libxext6 libxml2 libxmuu1 mime-support multiarch-support
ncurses-term networkd-dispatcher openssh-client openssh-server
openssh-sftp-server openssl publicsuffix python3 python3-certifi
python3-chardet python3-dbus python3-gi python3-idna python3-minimal
python3-pkg-resources python3-requests python3-six python3-urllib3 python3.6
python3.6-minimal readline-common shared-mime-info ssh-import-id systemd
systemd-sysv ucf wget xauth xdg-user-dirs xz-utils
The following packages will be upgraded:
libsystemd0
1 upgraded, 82 newly installed, 0 to remove and 14 not upgraded.
Need to get 27.3 MB of archives.
After this operation, 118 MB of additional disk space will be used.
Get:1 http://archive.ubuntu.com/ubuntu bionic-updates/main amd64 libsystemd0 amd64 237-3ubuntu10.28 [204 kB]
Get:2 http://archive.ubuntu.com/ubuntu bionic-updates/main amd64 libssl1.1 amd64 1.1.1-1ubuntu2.1~18.04.4 [1300 kB]
Get:3 http://archive.ubuntu.com/ubuntu bionic-updates/main amd64 libpython3.6-minimal amd64 3.6.8-1~18.04.1 [533 kB]
...
Successfully built 18f9de8b84b7
Successfully tagged sshd:dockerfile
命令执行完毕后,如果可见 “Successfully built xxx”字样,则说明镜像创建成功。可以看到,以上命令生成的镜像ID是 18f9de8b84b7。
在本地查看 sshd:dockerfile 镜像已存在:
[root@gavin sshd_ubuntu]# sudo docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
sshd dockerfile 18f9de8b84b7 5 minutes ago 207MB
测试镜像,运行容器
使用刚才创建的 sshd:dockerfile 镜像来运行一个容器。直接启动镜像,映射容器的 22 端口到本地的 10122 端口:
[root@gavin sshd_ubuntu]# sudo docker run -d -p 10122:22 sshd:dockerfile
177ebf24952b871bd5de74a665d1bf962859f6f453e18c5d6b038df7be6c47ba
[root@gavin sshd_ubuntu]# sudo docker ps -a
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
177ebf24952b sshd:dockerfile "/run.sh" 4 seconds ago Up 3 seconds 0.0.0.0:10122->22/tcp vigorous_matsumoto
在宿主机打开一个新的终端,连接到新建的容器:
[root@gavin sshd_ubuntu]# ssh 192.168.41.15 -p 10122
Welcome to Ubuntu 18.04.3 LTS (GNU/Linux 3.10.0-957.el7.x86_64 x86_64)
* Documentation: https://help.ubuntu.com
* Management: https://landscape.canonical.com
* Support: https://ubuntu.com/advantage
This system has been minimized by removing packages and content that are
not required on a system that users do not log into.
To restore this content, you can run the 'unminimize' command.
Last login: Thu Sep 5 14:02:46 2019 from 192.168.41.15
root@177ebf24952b:~#
效果与上一节一致,镜像创建成功。
这篇文章是我学习 Docker 的记录,内容参考自《Docker技术入门与实战》