在 Kubernetes Pod 中克隆一个安全的 Git 存储库

10

我遇到了一个有趣的问题,需要将私有GitHub仓库克隆到运行在Kubernetes中的Docker容器中。最初我尝试使用gitRepo挂载,然而,在我的部署清单中使用OAuth密钥是不可接受的,我想使用一个与我的GitHub帐户附加的OAuth密钥不同的存储库部署密钥。

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

约束条件

我需要以下内容:

  • 容器内的存储库可以在容器运行期间间歇性地拉取
  • 必须使用GitHub部署密钥访问存储库
  • 密钥必须保持安全(在Kubernetes secret中)并且不存储在docker镜像中
  • 必须在同一pod中的两个容器之间共享该存储库 - 一个写入和一个读取

可能的解决方案:

将SSH密钥作为secret挂载并克隆:

我尝试使用在单独的pod中运行的bash脚本将存储库克隆到一个emptydir中(这个脚本必须运行,我也用它进行其他事情),但是我遇到了将ssh密钥放入pod的问题。这个问题是关于这个问题的,但似乎没有方法解决。我能够通过secret挂载将密钥带入,但权限设置为777。为了绕过这个问题,我将密钥挂载到一个/test/目录中,然后尝试将其复制到/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 exec进入容器后,/root/.ssh/目录下没有任何文件。

我认为我已经基本到达此路径的底部,因此我不认为这将是解决方案。

配置ssh忽略密钥权限

如果SSH有一种方法可以忽略密钥上的权限-默认情况下,它强制执行644或更低的权限-那么上述解决方案可能是可行的。我很惊讶自己没有找到任何可以实现这一点的方法,但我的谷歌搜索结果总是说您只需正确设置权限即可。

以安全的方式将密钥放入容器中的其他方法

理想情况下,我希望在容器中有一个密钥,以便将来扩展此项目并使用其他仓库。可能还有其他方法可以做到这一点,我没有考虑或尝试过。

使用容器内的OAuth密钥克隆

我考虑过尝试在环境变量中使用OAuth密钥,然后使用该密钥通过HTTPS克隆仓库。这不是理想的,但如果有效,我将接受它。现在唯一阻止我这样做的是我无法使用部署密钥。如果有一种可以使用OAuth与部署密钥配合工作的方法,我还没有找到,但如果有人知道更多,它可能是解决方案。

在docker映像中克隆

仓库中没有任何内容会让我不舒服放入docker映像中,所以我可以选择这种方法。但问题在于我需要能够拉取仓库的更新。如果我将其放入容器中,则无法在没有我的密钥的情况下进行拉取。可能有某种解决方法,我还未尝试过。

我已经到了感觉没有任何东西可尝试的地步,因此任何建议都值得一试。


类似的问题

此问题与我正在尝试做的非常相似,但我认为由于他们没有使用Kubernetes,而我是,因此提问是值得的,因为涉及到密钥和不同的文件挂载方法。

这个问题谈论了如何在Kubernetes中将SSH密钥放入容器中,但我并不一定要使用SSH克隆,因此我认为这应该是自己的问题。

1个回答

6

试着像这样挂载包含部署密钥的秘密:

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

默认模式目前对我没有起作用。我打算再试一次看看是否有效,否则我会发布我发现的解决方法。 - 3ocene
1
我忘记更新了。结果发现我使用的是旧版本的Kubernetes,这就是问题的原因。在1.4.0之前,defaultMode是不可用的。 - 3ocene

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接