我的Docker容器有两个服务:一个Web服务和一个SSH服务器。
SSH服务器是openssh-server,我需要从容器外部运行命令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
任何评论或想法都会受到赞赏。预先感谢!
答案 0 :(得分:1)
如果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
所以您可以这样编写脚本:
{{1}}
您可能要添加一些睡眠延迟,以避免急于重启。也许ssh服务器在重新启动后只需要一些时间来接受连接。
答案 1 :(得分:-1)
要测试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