我的docker容器有两个服务:Web服务和SSH服务器。
SSH服务器是openssh服务器,我需要从容器外部运行命令docker exec -it my-container sudo service ssh restart
来启动SSH服务器。
但是,该命令并非始终成功。每次我需要使用以下命令手动检查 SSH 服务器是否在容器中启动时:ssh root@localhost
:
1( 如果SSH服务器启动失败,结果ssh_exchange_identification: Connection closed by remote host
2(否则,它会要求输入密码。(这表示SSH服务器已启动(
由于我必须同时部署多个容器,因此手动检查每个容器是不现实的。因此,如果 SSH 服务无法启动,我想自动重试docker exec -it my-container sudo service ssh restart
命令。但是我不确定如何编写bash脚本来实现这一点。它基本上应该像这样工作:
while (ssh_server_fails_to_start):
docker exec -it my-container sudo service ssh restart
任何意见或想法都值得赞赏。提前感谢!
如果sshd
正在运行,它将接受其特定端口上的连接。 否则,连接尝试将失败。
如果运行以下命令:
ssh -o PasswordAuthentication=No root@localhost true
无论哪种方式,这都会失败,但输出会有所不同。 在服务器正在运行并接受连接的情况下,显式关闭密码身份验证将使其失败,并显示以下消息:
Permission denied (publickey,password).
否则,它将打印出如下消息:
ssh: connect to host localhost port 22: Connection refused
所以我建议扫描错误消息以获取这样的提示:
if ssh -o PasswordAuthentication=No root@localhost true
|& grep -q "Connection refused"
then
echo "No server reachable!"
else
echo "Server reachable."
fi
所以你可以像这样写你的脚本:
while ssh -o PasswordAuthentication=No root@localhost true
|& grep -q "Connection refused"
do
docker exec -it my-container sudo service ssh restart
done
您可能需要添加一些睡眠延迟以避免匆忙重新启动。 也许 ssh 服务器在重新启动后只需要一些时间来接受连接。
要测试 ssh 连接,我们可以sshpass
包在命令行中提供密码。
while : ; do
docker exec -it my-container sudo service ssh restart
sleep 5s
sshpass -p 'root' ssh -q root@localhost -p 2222 exit
if [ $? == 0 ]; then
echo "SSH server is running."
break
fi
echo "SSH server is not running. Restarting..."
done