【问题标题】:Script to check if SSH service in Docker is up检查 Docker 中的 SSH 服务是否启动的脚本
【发布时间】:2023-03-20 16:20:01
【问题描述】:

我的 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

感谢任何 cmets 或想法。提前致谢!

【问题讨论】:

  • 这是一个非常不寻常的设置:通常一个 Docker 容器只运行一个服务,它不是 ssh,而且sudoservice 在 Docker 环境中都不能很好地工作。您尝试启动 sshd 的实际目标是什么?您可以通过使用主机的sudo docker exec 来完成它吗?
  • @DavidMaze 我实际上使用sudo docker exec from 来托管在 Docker 容器中启动 SSH 服务。我已经在容器中安装了sudo,我确信sudo service ssh restart 在容器中工作得很好。问题是:docker exec -it my-container sudo service ssh restart 的调用并不总是成功。这就是为什么我想在命令失败时重试该命令。
  • 如果你可以 ssh 到主机和sudo docker exec,为什么你需要在容器中运行一个 ssh 守护进程(伴随着访问、安全和管理方面的考虑)?
  • @DavidMaze 我实际上正在使用容器来模拟主机。在一个容器中运行多个服务是一种不好的做法,但不幸的是我不得不这样做。我只需要编写一个脚本来测试与容器的 ssh 连接。

标签: bash shell docker ssh sh


【解决方案1】:

如果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 服务器重启后只需要一些时间来接受连接。

【讨论】:

    【解决方案2】:

    为了测试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
    

    【讨论】:

    • Urgs。源代码中的私服?我建议将其更改为使用 ssh 密钥。
    猜你喜欢
    • 2016-05-06
    • 2012-09-26
    • 2017-03-03
    • 2016-11-26
    • 2013-10-21
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多