【问题标题】:Clone a secure git repo in Kubernetes pod在 Kubernetes pod 中克隆一个安全的 git 存储库
【发布时间】:2017-04-25 08:38:35
【问题描述】:

我遇到了一个有趣的情况,我需要将私有 github 存储库克隆到我在 Kubernetes 中运行的 docker 容器中。最初我尝试使用 gitRepo 挂载,但是,在我的部署清单中包含 OAuth 密钥是不可接受的,我想使用 repo 部署密钥而不是附加到我的 GitHub 帐户的 OAuth 密钥。

理想情况下,我会使用 gitRepo 挂载,它使用秘密进行身份验证,但在撰写本文时,此功能不可用。

约束

我需要以下物品:

  • 容器内的一个 repo,我可以在容器运行时间歇性地拉取它
  • 必须使用 GitHub 部署密钥访问存储库
  • 密钥必须保持安全(在 Kubernetes 机密中)并且不能存储在 docker 映像中
  • 必须在同一个 pod 中的两个容器之间共享存储库 - 一个用于写入,另一个用于读取

可能的解决方案:

将 SSH 密钥挂载为秘密并克隆:

我尝试使用在单独的 pod 中运行的 bash 脚本将 repo 克隆到一个 emptydir(无论如何,这个脚本必须运行,我也将它用于其他事情),但是我遇到了获取 ssh 的问题钥匙进入吊舱。 This question 是关于这个问题的,但它似乎没有办法做到这一点。我能够通过秘密挂载获取密钥,但随后权限设置为 777。为了解决这个问题,我将密钥挂载到 /test/ 目录中,然后尝试将 cp 挂载到 /root/.ssh/ 中。这给了我这些奇怪的错误:

cp: '/test/id_rsa' and '/root/.ssh/id_rsa' are the same file
cp: '/test/id_rsa.pub' and '/root/.ssh/id_rsa.pub' are the same file

我也尝试使用cat 并将它们传送到他们的文件中,但没有奏效。起初,当我的路径错误时,它给了我这些错误:

cat: /keys/id_rsa: input file is output file
cat: /keys/id_rsa.pub: input file is output file

一旦我修复了路径,它什么也没做,默默地失败了。 kubectl execing 进入容器显示 /root/.ssh/ 中没有文件。

我认为我已经走到了这条路的底部,所以我认为这不会是解决方案。

配置 ssh 忽略密钥权限

如果 SSH 有办法忽略密钥的权限(我相信默认情况下它强制执行 644 或更少),那么上述解决方案可能是可能的。我很惊讶我还没有找到任何方法来做到这一点,但我的 google-fu 总是显示结果说你只需要正确设置权限。

其他一些将密钥安全放入容器的方法

理想情况下,我希望在容器中有一个密钥,以便将来使用其他存储库扩展该项目。可能还有其他一些我没有想到或尝试过的方法。

使用容器内的 OAuth 密钥进行克隆

我曾考虑尝试在环境变量中使用 OAuth 密钥,然后使用它通过 HTTPS 克隆存储库。这不太理想,但如果它有效,我会接受它。现在唯一阻止我这样做的是我不能使用部署密钥。如果有办法通过部署密钥使用 OAuth,我还没有找到,但如果有人知道更多,它可能是解决方案。

在 docker 镜像中克隆

repo 中没有任何东西让我在 docker 映像中感到不舒服,所以我可以走这条路。这样做的问题是我需要能够下拉更新到 repo。如果我把它放在容器里,没有钥匙我就无法拉动。可能有一些我没有尝试过的解决方法。

我觉得我没有什么可尝试的了,所以任何建议都值得一试。


类似问题

This question 与我正在尝试做的非常相似,但是我觉得由于他们没有使用 Kubernetes 而我是,因此值得单独发布,因为秘密和挂载文件的方法不同。

This question 谈到了将 SSH 密钥放入 Kubernetes 中的容器中,但是我对在 SSH 上使用 git 并没有死心,所以我认为这应该是它自己的问题。

【问题讨论】:

    标签: git github docker ssh kubernetes


    【解决方案1】:

    尝试像这样安装包含部署密钥的密钥:

    volumeMounts:
      - mountPath: /root/.ssh
        name: ssh-key
    volumes:
    - name: ssh-key
      secret:
        secretName: ssh-key
        defaultMode: 256
    

    这是我如何使用它的完整示例:

    apiVersion: batch/v2alpha1
    kind: ScheduledJob
    metadata:
      name: transporter
    spec:
      schedule: 0 5 * * *
      jobTemplate:
        spec:
          template:
            spec:
              nodeSelector:
                role: mysqldump
              containers:
              - name: transporter
                image: camil/mysqldump
                command: ["/bin/bash", "-c"]
                args:
                  - ssh-keyscan -t rsa $TARGET_HOST > ~/.ssh/known_hosts && ssh -i /root/.ssh/private/id_rsa $LINUX_USER@$TARGET_HOST 'mkdir mysqldump || true' && scp -i /root/.ssh/private/id_rsa /mysqldump/* $LINUX_USER@$TARGET_HOST:/home/$LINUX_USER/mysqldump
                env:
                  - name: TARGET_HOST
                    valueFrom:
                      configMapKeyRef:
                        name: transporter
                        key: target.host
                  - name: LINUX_USER
                    valueFrom:
                      configMapKeyRef:
                        name: transporter
                        key: linux.user
                imagePullPolicy: Always
                volumeMounts:
                  - mountPath: /mysqldump
                    name: mysqldump
                  - mountPath: /root/.ssh/private
                    name: ssh-key
              volumes:
                - name: mysqldump
                  hostPath:
                    path: /home/core/mysqldump
                - name: ssh-key
                  secret:
                    secretName: ssh-key
                    defaultMode: 256
              restartPolicy: OnFailure
    

    【讨论】:

    • 到目前为止,默认模式对我不起作用。我会再试一次,看看它是否有效,否则我会发布我发现的解决方法。
    • 我忘记更新了。原来我使用的是旧版本的 Kubernetes,这就是导致问题的原因。 defaultMode 在 1.4.0 之前不可用。
    猜你喜欢
    • 1970-01-01
    • 2017-12-29
    • 2013-07-14
    • 1970-01-01
    • 1970-01-01
    • 2013-01-16
    • 1970-01-01
    • 1970-01-01
    • 2021-09-18
    相关资源
    最近更新 更多