【问题标题】:ssh-agent does not remember identities when running inside a docker container in DC/OS在 DC/OS 的 docker 容器内运行时,ssh-agent 不记得身份
【发布时间】:2018-01-18 04:29:05
【问题描述】:

我正在尝试使用 DC/OS 和 Docker 运行服务。我使用来自here 的区域模板创建了我的堆栈。我还创建了以下 Dockerfile:

FROM ubuntu:16.04
RUN apt-get update && apt-get install -y expect openssh-client

WORKDIR "/root"
ENTRYPOINT eval "$(ssh-agent -s)" && \
           mkdir -p .ssh && \
           echo $PRIVATE_KEY > .ssh/id_rsa && \
           chmod 600 /root/.ssh/id_rsa && \
           expect -c "spawn ssh-add /root/.ssh/id_rsa; expect \"Enter passphrase for /root/.ssh/id_rsa:\" send \"\"; interact " && \
           while true; do ssh-add -l; sleep 2; done

我有一个私有存储库,我想在 docker 容器启动时克隆/拉取它。这就是我尝试将私钥添加到ssh-agent 的原因。

如果我将此映像作为本地 docker 容器运行并使用 PRIVATE_KEY 环境变量提供私钥,则一切正常。我看到添加了身份。

我遇到的问题是,当我尝试使用 docker 映像在 DC/OS 上运行服务时,ssh-agent 似乎不记得使用私钥添加的身份。

我已从 DC/OS 检查了错误日志。没有错误。

有谁知道为什么在 DC/OS 上运行 docker 容器与在本地运行相比有何不同?

编辑:我添加了 DC/OS 服务描述的详细信息,以防有帮助:

{
 "id": "/SOME-ID",
 "instances": 1,
  "cpus": 1,
  "mem": 128,
  "disk": 0,
  "gpus": 0,
  "constraints": [],
  "fetch": [],
  "storeUrls": [],
  "backoffSeconds": 1,
  "backoffFactor": 1.15,
  "maxLaunchDelaySeconds": 3600,
  "container": {
                "type": "DOCKER",
                "volumes": [],
                "docker": {
                "image": "IMAGE NAME FROM DOCKERHUB",
                "network": "BRIDGE",
                "portMappings": [{
                                  "containerPort": SOME PORT NUMBER,
                                  "hostPort": SOME PORT NUMBER,
                                  "servicePort": SERVICE PORT NUMBER,
                                  "protocol": "tcp",
                                  "name": “default”
                                 }],
                "privileged": false,
                "parameters": [],
                "forcePullImage": true
               }
  },
  "healthChecks": [],
  "readinessChecks": [],
  "dependencies": [],
  "upgradeStrategy": {
                      "minimumHealthCapacity": 1,
                      "maximumOverCapacity": 1
                     },
  "unreachableStrategy": {
                          "inactiveAfterSeconds": 300,
                          "expungeAfterSeconds": 600
                         },
  "killSelection": "YOUNGEST_FIRST",
  "requirePorts": true,
  "env": {
          "PRIVATE_KEY": "ID_RSA PRIVATE_KEY WITH \n LINE BREAKS",
         }
  }

【问题讨论】:

  • 你从上面的代码中得到了什么输出?
  • 代理没有身份。
  • 不确定我是否理解...这应该如何工作?您需要在 Docker 映像中包含密钥并将其推送到注册表,然后在 DC/OS 上使用它,或者您还需要使用 env var(它只会保留在正在运行的容器中,因为您不这样做'不使用任何卷等)
  • 这意味着由于某种原因您没有设法将密钥添加到代理。深入调查哪些命令实际运行,哪些命令没有运行。
  • @Tobi,这就是我使用环境变量$PRIVATE_KEY的原因。我们不想在 docker 镜像中存储任何密钥,因为我们公开存储我们的镜像。

标签: docker ssh-keys dcos


【解决方案1】:

Docker 版本

检查您的本地 Docker 版本是否与 DC/OS 代理上安装的版本相匹配。默认情况下,DC/OS 1.9.3 AWS CloudFormation 模板使用CoreOS 1235.12.0,它附带Docker 1.12.6。从那时起,入口点的行为可能发生了变化。

Docker 命令

检查相关 Marathon 应用程序的 Mesos 任务日志,并查看执行了哪些 docker run 命令。在本地测试时,您可能会传递稍微不同的参数。

脚本错误

正如另一个答案中提到的,您提供的脚本有几个错误可能与故障有关,也可能无关。

  1. echo $PRIVATE_KEY 应该是 echo "$PRIVATE_KEY" 以保留换行符。否则密钥解密将失败并显示Bad passphrase, try again for /root/.ssh/id_rsa:
  2. expect -c "spawn ssh-add /root/.ssh/id_rsa; expect \"Enter passphrase for /root/.ssh/id_rsa:\" send \"\"; interact " 应该是 expect -c "spawn ssh-add /root/.ssh/id_rsa; expect \"Enter passphrase for /root/.ssh/id_rsa:\"; send \"\n\"; interact "。它缺少分号和换行符。否则,expect 命令会失败而不执行。

基于文件的秘密

Enterprise DC/OS 1.10(现已推出 1.10.0-rc1)有一个名为 File Based Secrets 的新功能,允许注入文件(如 id_rsa 文件)而不将其内容包含在 Marathon 应用程序定义中,将它们安全地存储在 @ 987654323@ 使用DC/OS Secrets

基于文件的机密不会为您执行 ssh-add,但它应该可以更轻松、更安全地将文件放入容器中。

Mesos 错误

Mesos 1.2.0 切换到使用 Docker --env_file 而不是 -e 来传递环境变量。这会触发Docker env_file bug,它不支持换行符。 workaround was put into Mesos and DC/OS,但修复程序可能不在您使用的次要版本中。

手动解决方法是将 Marathon 定义的 rsa_id 转换为 base64 并返回到您的入口点脚本中。

【讨论】:

  • 这个答案已被接受 - 我会对触发错误的实际细节感兴趣。你能解释一下哪个方面解决了你的问题@siavashk?
  • Docker 版本。
【解决方案2】:

通过PRIVATE_KEY 传递的密钥文件内容最初包含换行符。将PRIVATE_KEY 变量内容回显到~/.ssh/id_rsa 后,换行符将消失。您可以通过用双引号将 $PRIVATE_KEY 变量括起来来解决该问题。

在没有附加 TTY 的情况下启动容器时会出现另一个问题,通常是通过 -i -t 命令行参数到 docker run。密码请求将失败,并且不会将 ssh 密钥添加到 ssh-agent。对于在 DC/OS 中运行的容器,交互可能没有意义,因此您应该相应地更改入口点脚本。这将要求您的 ssh 密钥是无密码的。

这个更改后的 Dockerfile 应该可以工作:

ENTRYPOINT eval "$(ssh-agent -s)" && \
           mkdir -p .ssh && \
           echo "$PRIVATE_KEY" > .ssh/id_rsa && \
           chmod 600 /root/.ssh/id_rsa && \
           ssh-add /root/.ssh/id_rsa && \
           while true; do ssh-add -l; sleep 2; done

【讨论】:

  • 这并不能解释为什么只有在 docker 容器在 DC/OS 上运行时才会出现问题。
  • 我没有足够的详细信息来说明您的本地环境和 DC/OS 环境之间的区别。我假设您在传递 PRIVATE_KEY 环境时具有不同的 id_rsa 格式或另一个 shell。我可以在 Mac OS 上本地重现您的问题,所以我认为这不是 DC/OS 特定的。
  • 双引号是否解决了问题?也许他们只是为我工作?
  • 不,它没有修复它。我还使用\n 转义了私钥中的新行,因此换行符不是实际问题。实际上,我确实在原始问题中列出了关于云形成的 DC/OS 的配置。可以找到here至于DC/OS服务的json文件,看我的编辑
  • 您/您能否验证容器内的 env 变量是否是具有正确换行符的预期私钥?一个简单的cat .ssh/id_rsa 会显示 ssh-add 和 ssh-agent 会“看到”的实际结果。我还没有完成换行符;-)
猜你喜欢
  • 2021-06-26
  • 2019-06-24
  • 1970-01-01
  • 1970-01-01
  • 2015-05-25
  • 1970-01-01
  • 2022-10-04
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多