需求
默认从docker hub中下载的Centos镜像是没有安装Openssh功能,不提供ssh服务的。
但是在某些场景下,则是需要容器内部提供ssh服务,让外部可以ssh访问进去。本次,我要解决的一个场景就是使用Pycharm通过ssh同步代码上传至容器内,进行服务调试。
当然,本章节主要还是讲如何给Centos镜像构建使用Openssh,提供SSH服务。
构建步骤
下载centos镜像
代码语言:javascript复制docker pull centos:7
执行如下:
代码语言:javascript复制[root@dev docker_ssh_centos]# docker pull centos:7
7: Pulling from library/centos
Digest: sha256:4a701376d03f6b39b8c2a8f4a8e499441b0d567f9ab9d58e4991de4472fb813c
Status: Image is up to date for centos:7
docker.io/library/centos:7
[root@dev docker_ssh_centos]#
启动centos容器
代码语言:javascript复制docker run -it centos:7 /bin/bash
执行如下:
代码语言:javascript复制# 采用 it 直接进入容器
[root@dev docker_ssh_centos]# docker run -it centos:7 /bin/bash
# 进入容器内
[root@4eb13e778da3 /]# ls
anaconda-post.log bin dev etc home lib lib64 media mnt opt proc root run sbin srv sys tmp usr var
[root@4eb13e778da3 /]#
安装passwd
代码语言:javascript复制yum install passwd -y
执行如下:
代码语言:javascript复制[root@dev docker_ssh_centos]# docker run -it centos:7 /bin/bash
# 在容器内安装 passwd
[root@4eb13e778da3 /]# yum install passwd -y
Loaded plugins: fastestmirror, ovl
... | 7.6 MB 00:00:04
(4/4): base/7/x86_64/primary_db | 6.0 MB 00:00:04
Package passwd-0.79-5.el7.x86_64 already installed and latest version
Nothing to do
# 提示已经安装了
[root@4eb13e778da3 /]#
修改Centos root密码
代码语言:javascript复制[root@dev docker_ssh_centos]# docker run -it centos:7 /bin/bash
# 在容器内使用 passwd 修改 root 密码
[root@4eb13e778da3 /]# passwd
Changing password for user root.
New password:
Retype new password:
passwd: all authentication tokens updated successfully.
[root@4eb13e778da3 /]#
这个密码自己记住就好了,不过后面尽量采用公钥来访问,禁用密码。
安装openssh
代码语言:javascript复制yum install openssh-server -y
执行如下:
代码语言:javascript复制[root@dev docker_ssh_centos]# docker run -it centos:7 /bin/bash
# 在容器内安装openssh
[root@4eb13e778da3 /]# yum install openssh-server -y
...
Installed:
openssh-server.x86_64 0:7.4p1-21.el7
Dependency Installed:
fipscheck.x86_64 0:1.4.1-6.el7 fipscheck-lib.x86_64 0:1.4.1-6.el7 openssh.x86_64 0:7.4p1-21.el7 tcp_wrappers-libs.x86_64 0:7.6-77.el7
Complete!
[root@4eb13e778da3 /]#
生成容器的公钥、私钥
如果需要容器提供的SSH服务,那么则需要生成一下公钥和私钥。具体对应的文件名,可以通过查看ssh的配置文件来确认,如下:
代码语言:javascript复制# 容器内进行 /etc/ssh 路径
[root@27b93fcccc51 ssh]# pwd
/etc/ssh
[root@27b93fcccc51 ssh]#
[root@27b93fcccc51 ssh]# ls
moduli sshd_config
[root@27b93fcccc51 ssh]#
# 查看配置文件
[root@27b93fcccc51 ssh]# cat sshd_config
# 启动ssh服务默认所需要的RSA key,需要我们手动生成
HostKey /etc/ssh/ssh_host_rsa_key
#HostKey /etc/ssh/ssh_host_dsa_key
HostKey /etc/ssh/ssh_host_ecdsa_key
HostKey /etc/ssh/ssh_host_ed25519_key
生成三个HostKey的命令如下:
代码语言:javascript复制ssh-keygen -t rsa -f /etc/ssh/ssh_host_rsa_key
ssh-keygen -t rsa -f /etc/ssh/ssh_host_ecdsa_key
ssh-keygen -t rsa -f /etc/ssh/ssh_host_ed25519_key
执行如下:
代码语言:javascript复制[root@27b93fcccc51 ssh]# ssh-keygen -t rsa -f /etc/ssh/ssh_host_rsa_key
Generating public/private rsa key pair.
Enter passphrase (empty for no passphrase): # 回车
Enter same passphrase again: # 回车
Your identification has been saved in /etc/ssh/ssh_host_rsa_key.
Your public key has been saved in /etc/ssh/ssh_host_rsa_key.pub.
The key fingerprint is:
SHA256:Tx4eA0ymIH W6uOiqdcdNAaEvpwgKlKqbd3uzlHGm 0 root@27b93fcccc51
The key's randomart image is:
---[RSA 2048]----
| .oo o |
| .o.. * |
| . ..= o |
|o o . . |
|o= o.o .S = |
|= . .o O |
| . ooo..o = |
|..=.ooo. . |
|= .. = E |
----[SHA256]-----
[root@27b93fcccc51 ssh]#
[root@27b93fcccc51 ssh]# ls
moduli ssh_host_rsa_key ssh_host_rsa_key.pub sshd_config
[root@27b93fcccc51 ssh]#
[root@27b93fcccc51 ssh]# ssh-keygen -t rsa -f /etc/ssh/ssh_host_ecdsa_key
Generating public/private rsa key pair.
Enter passphrase (empty for no passphrase): # 回车
Enter same passphrase again: # 回车
Your identification has been saved in /etc/ssh/ssh_host_ecdsa_key.
Your public key has been saved in /etc/ssh/ssh_host_ecdsa_key.pub.
The key fingerprint is:
SHA256:92VaqkgZaHelx/YvkteK4 kr0B3DAxRStfsbNtE8sf4 root@27b93fcccc51
The key's randomart image is:
---[RSA 2048]----
| .o o. |
| .. . |
| oo . |
| . =. oo|
| o S. .= =oo|
| . ..=. .O...|
| o. .*o |
| . ... o=o|
| . . *=ooE|
----[SHA256]-----
[root@27b93fcccc51 ssh]#
[root@27b93fcccc51 ssh]# ssh-keygen -t rsa -f /etc/ssh/ssh_host_ed25519_key
Generating public/private rsa key pair.
Enter passphrase (empty for no passphrase): # 回车
Enter same passphrase again: # 回车
Your identification has been saved in /etc/ssh/ssh_host_ed25519_key.
Your public key has been saved in /etc/ssh/ssh_host_ed25519_key.pub.
The key fingerprint is:
SHA256:WlDnJO9RgvhQi5ojsdd2cGYmgkJi7T7pbRVDXBnFpzU root@27b93fcccc51
The key's randomart image is:
---[RSA 2048]----
|.o. .o= O.. |
| o o=.O E |
|. . *o* . |
| . = @.. o |
| * o S . |
| * o = |
| . o o |
| . o |
| . |
----[SHA256]-----
[root@27b93fcccc51 ssh]#
# 查看生成的key文件
[root@27b93fcccc51 ssh]# ls
moduli ssh_host_ecdsa_key ssh_host_ecdsa_key.pub ssh_host_ed25519_key ssh_host_ed25519_key.pub ssh_host_rsa_key ssh_host_rsa_key.pub sshd_config
[root@27b93fcccc51 ssh]#
创建允许外部访问的认证文件
代码语言:javascript复制# 创建认证文件
[root@4eb13e778da3 .ssh]# mkdir -p ~/.ssh
[root@4eb13e778da3 .ssh]# > ~/.ssh/authorized_keys
[root@4eb13e778da3 .ssh]#
[root@4eb13e778da3 .ssh]# cat authorized_keys
[root@4eb13e778da3 .ssh]# ls
authorized_keys
[root@4eb13e778da3 .ssh]#
后续有需要访问容器的外部公钥直接加上去这个文件就可以了。
编写容器的服务启动脚本
代码语言:javascript复制# 在/目录下,创建一个 run.sh 的脚本
vi /run.sh
# 设置脚本内容启动 sshd 服务
#!/bin/bash
/usr/sbin/sshd -D
# 设置可执行权限
chmod x /run.sh
执行如下:
后面启动容器的时候,将需要启动的服务写到这里就可以了。
退出容器,保存镜像
输入exit
退出容器,然后通过docker ps
查看刚刚使用的容器,将容器commit为一个新的镜像。
执行如下:
代码语言:javascript复制# 执行exit退出容器
[root@4eb13e778da3 /]# exit
exit
[root@dev docker_ssh_centos]#
# 通过 docker ps -a 查看使用过的所有未删除的容器,刚刚退出7秒钟的就是我们刚刚操作的容器
[root@dev docker_ssh_centos]# docker ps -a
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
4eb13e778da3 centos:7 "/bin/bash" 29 minutes ago Exited (0) 7 seconds ago peaceful_darwin
# 根据容器的 CONTAINER ID 使用 commit 命令生成一个新的镜像 centos:7-ssh
[root@dev docker_ssh_centos]# docker commit 4eb13e778da3 centos:7-ssh
sha256:3aaa9ee819e62a7d2c7d52b635eff6f80130c923a8b38a7a4cd5cf36f2542c80
[root@dev docker_ssh_centos]#
# 查看新生成的容器镜像,那么这个镜像启动的容器就已经安装好了 ssh 的服务功能
[root@dev docker_ssh_centos]# docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
centos 7-ssh 3aaa9ee819e6 3 seconds ago 318MB
启动容器
代码语言:javascript复制docker run -d --name centos7_ssh -p 2222:22 centos:7-ssh /run.sh
# 参数说明:
-d 后台启动
--name 指定容器名称
-p 2222:22 将容器的22端口服务映射到宿主机的 2222 端口上
执行如下:
代码语言:javascript复制# 启动容器,并且执行 /run.sh 脚本,启动ssh服务
[root@dev docker_ssh_centos]# docker run -d --name centos7_ssh -p 2222:22 centos:7-ssh /run.sh
5cc134321f63ac365835bac764865a82f6f405d2b7387572edffc8c8c090c867
[root@dev docker_ssh_centos]#
# 查看启动的容器
[root@dev docker_ssh_centos]# docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
5cc134321f63 centos:7-ssh "/run.sh" 3 seconds ago Up 2 seconds 0.0.0.0:2222->22/tcp centos7_ssh
[root@dev docker_ssh_centos]#
# 测试使用ssh访问容器
[root@dev docker_ssh_centos]# ssh root@127.0.0.1 -p 2222
The authenticity of host '[127.0.0.1]:2222 ([127.0.0.1]:2222)' can't be established.
RSA key fingerprint is SHA256:Tx4eA0ymIH W6uOiqdcdNAaEvpwgKlKqbd3uzlHGm 0.
RSA key fingerprint is MD5:77:6b:f8:cd:6d:ed:86:eb:a0:10:85:dd:02:00:0c:a1.
Are you sure you want to continue connecting (yes/no)? yes
Warning: Permanently added '[127.0.0.1]:2222' (RSA) to the list of known hosts.
root@127.0.0.1's password:
[root@5cc134321f63 ~]#
[root@5cc134321f63 ~]#
[root@5cc134321f63 ~]# ls
anaconda-ks.cfg
[root@5cc134321f63 ~]#
好了,到此为止,已经可以在外部通过SSH服务访问到容器内部了。
更多精彩原创Devops文章,快来关注我的Devops社群吧: