SSH进入运行中的Docker容器的2种方法
在本教程中,我们将研究如何在后台运行的Docker容器上获取bash shell。
它还将介绍如何在没有活动的控制台会话的情况下,将ssh放入在后台启动并保持运行状态的docker容器。
Docker的采用非常广泛,尤其是在微服务和开发领域。
大多数长时间运行的Docker容器没有活动的Shell控制台。
我们可能会按需连接到bash shell,例如:当我们想在终端上运行一些命令时。
替代方法是使用IP地址通过ssh到容器。
可以通过两种方式来获得在后台运行的容器的重击
1)使用docker exec命令
Docker引擎具有用于与容器交互的命令行工具docker。
命令选项exec用于在正在运行的容器中运行命令。
通过传递一些参数,我们应该能够获得bash会话。
使用的命令语法为:
docker exec [OPTIONS] CONTAINER COMMAND [ARG...]
下面是可以与此一起使用的选项的列表。
-d,--detach分离模式:在后台运行命令
-i,--interactive即使未连接STDIN仍保持打开状态
-t,--tty分配伪TTY
-u,--user字符串用户名或者UID(格式:<名称| uid> [:<group | gid>])
-w,--workdir字符串容器内的工作目录
我们的兴趣在于-t和-i选项,因为bash必须以交互方式运行。
让我们考虑一个例子来阐明这一点。
拉Nginx Docker镜像:
# docker pull nginx Using default tag: latestlatest: Pulling from library/nginx f2aa67a397c4: Pull complete 3c091c23e29d: Pull complete 4a99993b8636: Pull complete Digest: sha256:0edf702c890e9518b95b2da01286509cd437eb994b8d22460e40d72f6b79be49Status: Downloaded newer image for nginx:latest
根据下载的docker镜像在后台启动测试容器。
# docker run --name nginx-bg -d nginx 3bd76e19ad6ce2ff15657ebf4de4cc42eb503c55f608071a438de6ca709ba73b
这将从nginx docker镜像的后台启动一个名为nginx-bg的容器。
检查并确认容器正在运行:
Dockerps
现在运行以下命令以在该容器上获取bash控制台。
# docker exec -it nginx-bg /bin/bash root@3bd76e19ad6c:/# apt-get update Get:2 http://security.debian.org/debian-security stretch/updates InRelease [94.3 kB] Ign:1 http://cdn-fastly.deb.debian.org/debian stretch InRelease Get:3 http://cdn-fastly.deb.debian.org/debian stretch-updates InRelease [91.0 kB] Hit:4 http://cdn-fastly.deb.debian.org/debian stretch Release Fetched 185 kB in 2s (83.4 kB/s) Reading package lists... Done
其中nginx-bg是容器名称,/bin/bash是容器上bash二进制文件的路径。
一旦在bash shell上执行了命令,就可以通过键入exit命令退出。
root@3bd76e19ad6c:/# exit
2)使用docker attach命令
docker exec的替代方法是docker attach。
语法是
# docker attach <container-name>
因此,在本例中,我们将运行:
# docker attach nginx-bg
默认情况下,这将使我们进入bash shell。
ssh到正在运行的容器中
如果要SSH到正在运行的Docker容器,则需要在/etc/hosts上配置的容器IP地址或者主机名或者网络中的有效DNS记录。
如果我们不知道容器的IP地址,则可以使用以下命令获取它:
export INSTANCE_NAME="nginx-bg" docker inspect --format='{{range .NetworkSettings.Networks}}{{.IPAddress}}{{end}}' $INSTANCE_NAME
例子:
# export INSTANCE_NAME="nginx-bg" # docker inspect --format='{{range .NetworkSettings.Networks}}{{.IPAddress}}{{end}}' $INSTANCE_NAME 172.17.0.7
请注意,我们可以使用其ID替换容器名称。
我们得到的IP地址是172.17.0.7,请尝试ping它以查看是否响应。
# ping -c 2 172.17.0.7 PING 172.17.0.7 (172.17.0.7) 56(84) bytes of data. 64 bytes from 172.17.0.7: icmp_seq=1 ttl=64 time=0.107 ms 64 bytes from 172.17.0.7: icmp_seq=2 ttl=64 time=0.058 ms --- 172.17.0.7 ping statistics ---2 packets transmitted, 2 received, 0% packet loss, time 1000ms rtt min/avg/max/mdev = 0.058/0.082/0.107/0.026 ms
我们需要先在容器上配置ssh,然后再对它运行ssh命令。
配置完成后,我们可以使用用户名和容器的IP地址SSH到它。
# ssh [email protected] [email protected]'s password: Linux 672175da3a51 3.10.0-693.17.1.el7.x86_64 #1 SMP Thu Jan 25 20:13:58 UTC 2016 x86_64 The programs included with the Debian GNU/Linux system are free software; the exact distribution terms for each program are described in the individual files in /usr/share/doc/*/copyright. Debian GNU/Linux comes with ABSOLUTELY NO WARRANTY, to the extent permitted by applicable law. root@672175da3a51:~#
容器之间的无密码SSH
如果我们需要无密码身份验证,请在运行它时考虑将SSH公钥复制到该容器。
我不建议创建带有公共密钥的镜像,而是在具有所有公共密钥授权的主机系统上放置文件。
让我们创建一个文件:
# mkdir ~/container-ssh-keys # vim ~/container-ssh-keys/authorized_keys # chmod 0600 ~/container-ssh-keys/authorized_keys
然后将公共SSH密钥添加到文件中,我们可以根据需要添加任意数量。
现在,当启动容器时,将此文件映射到容器上的/root/.ssh/authorized_keys,例如
# docker run --name mycon -it -v $HOME/container-ssh-keys/authorized_keys:/root/.ssh/authorized_keys \ ubuntu:16.04 /bin/bash
然后,我们应该能够使用私钥对从主机系统ssh复制复制的公钥,而无需提示输入密码。
# ssh root@container-ip