Spring 云配置服务器在 Docker 中为 Git 和 运行 使用 SSH 密钥

Spring Cloud Config Server using SSH key for Git and running in Docker

在最终将所有内容放在一起之前,我发现了很多问题和教程。想要将其记录下来,以便其他人可以节省很多时间的挫败感。

我正在尝试在 BitBucket 上获取私有 git 存储库,以使用部署密钥与 Spring 引导配置服务器一起使用,并将其 运行 放入 Docker。我 运行 遇到很多问题。

  1. 如何使用 application.yml 文件进行实际配置。

我似乎不知道应该把 SSH 信息放在哪里。所有教程似乎都是针对 https 的。

  1. 如何为配置提供私钥。对于 Dev,YML 中内联的语法是一种痛苦。对于生产,您必须通过环境变量提供它,这是另一个语法问题。

我一直收到私钥无效的错误消息。

  1. 如何让 Docker 容器信任主机密钥,而不需要讨厌的 "do you trust this guy" 提示。

似乎有几种方法可以使这项工作有效,但只有一种对我有用。

第一部分是配置。您想要忽略标准私钥并使用作为环境变量提供的私钥。 (SSH_KEY)。此外,git 存储库是一个 EV (GIT_URL),但如果需要,您可以硬编码。

spring:
  cloud:
    config:
      server:
        git:
          uri:  ${GIT_URL}
          ignore-local-ssh-settings: true
          private-key: ${SSH_KEY}

第 2 部分很棘手。对于 Dev,您需要内联键,因此您需要使用管道在 YAML 中为块添加前缀。 (请注意,此密钥已被丢弃,因为我刚刚生成它,现在已将其丢弃)

private-key: |
                    -----BEGIN RSA PRIVATE KEY-----
                    MIIEpAIBAAKCAQEAszmCR06LVHk/kNYV6LoYgEfHlK4rp75sCsRJ7rdAbWNED+yB
                    bneOm5gue0LGIhT7iTP9D7aN6bKVHv1SBconCA7Pa2NMA9epcMT5ecJc8ndpZOFn
                    iqM77jmMMPvj8EIC06w5oK5zoYwpGotYQFHllf8M+20HtW2fZdPYAYwLcVdmc5tI
                    vLoS+10qw5D3X9zrwk2Cbt37Iqnz1cHOQq+g7sxgVgt18aIKKeg0JslaGqSlWMoT
                    ICUMHj89E4BMHj8ND8otSXHL+VhN+ghd7w1MpckxLWBsNs1+G1FuiJEVAtRq/j+8
                    SOilxgifvI1LqpZ5kO01XFlmkcuN4NMT03qpcwIDAQABAoIBAB5oQGk2sz7mv1kk
                    aV0tzaBeDUd1cWSpUw1UljKRFrY4ZEDLYH5MfH57iE9TWehIZRC3KFU1JMikitZS
                    JktjK9IbKSfQFgKE4XOHh8gXqMteZRw/feCwpydYzic1ZUvK903QZ4qSbn3XGNYv
                    FA79lhUny50Qt4EZkzSkh35js0FMSR9VmyXENxN6IgXUZyoaNAATr44Vkd488BY2
                    7PvdOniemo8/8p4Ij0Aq9Q7rOtm77ZXjyFRX5mDTi2ndSllMEhVcWXHSii+ukbvF
                    117Ns+8M7VWroNfRzI+Ilm/Xz/ePOLlNoYcY0h5+QM9vMPTX9Cpl5WofgOMK1sKd
                    mSdI4ukCgYEA12kcu0aDyIrEPHcyaT9izSFply0Uon2QKS9EQn6cr83vaEGViamh
                    f5q1coYouGnsLfbgKolEMKsYtbmJvInPFDCdc2x0Fmc207Wp1OECsN+HwElEXkrs
                    uPDpGQgs5odjN5Grue9837920oG3UBBdVDAKly2dTOcvoWW+88seFSUCgYEA1P7f
                    p78HDMQ8zTy5+3Rd4+lmJjPsY618XxSQ80j8Elrhi/DyTMA0XGc5c3cKRPmSj+JD
                    GN34WQbw7JO2mKM7YJs+tkSBeTKce8F3cZQy1jy3LNHCtfXylOxmxOFKynV5h2b/
                    jno+pGdmAPK5yvnGASd2eujtzt+AL07XiD2LnLcCgYEAsFRz131WfP/SuShdlLf1
                    WbODKuQVIxojuwLdHo1kF6k805v0G/dGoxzycOgPRz41vj57q3Yn4qr8FC3n6PTq
                    FT3idUyPDpO41r67Ye469KxWBHo1Q/aTJqTWOs5tatvixOcyqoa3MrUZQCI8+4YZ
                    z8Nvt+b3/66zV6vhDtHzMx0CgYAvWW2M0+mUS/ecRHivzqGkrdkYewh87C8uz9qd
                    SsdGqU9kla63oy7Ar+3Unkz5ImYTeGAkIgw4dlOOtBOugPMNOdXKHRaPQ9IHrO2J
                    oUFf4OVzoDnhy4ge1SLPd6nxsgXPNPVwzfopABdr9Ima9sWusgAjuK5NA+ByI9vE
                    HLJxpwKBgQCTM938cdx457ag1hS6EaEKyqljS1/B8ozptB4cy3h0hzw0crNmW84/
                    1Lt9MJmeR4FrWitQkkVLZL3SrYzrP2i+uDd4wVVD5epvnGP/Bk6g05/eB9LgDRx/
                    EeBgS282jUBkXZ6WpzqHCcku3Avs3ajzsC1WaEYx0tCiBxSkiJlaLQ==
                    -----END RSA PRIVATE KEY-----

在生产方面,您需要在命令提示符下使用 bash 变量来存储密钥,然后再将其传递给运行容器的 Docker 命令。示例:

$ pem=$( cat path_to_key )
$ docker run -e "SSH_KEY=$pem" configserver

此时您应该处理好应用程序。现在您需要做的就是解决 ssh 主机不受信任的问题。为此,将这些行添加到您的 Docker 文件中。将 "bitbucket.org" 替换为您想要的任何主机。这些命令创建 ssh 配置目录,修复权限,然后创建并填充 knownhosts 文件。

RUN mkdir -p /root/.ssh
RUN chmod 700 /root/.ssh
RUN ssh-keyscan bitbucket.org > /root/.ssh/known_hosts

我想对此做进一步的改动,希望可以消除在 YAML 文件(或 env 变量)中乱用 SSH 密钥的需要,这通常是个坏主意。

这围绕着 SSH 配置文件,所以如果应用程序无法访问它,或者它不能被修改,这将不起作用(但我想不出任何现实世界的情况,这会适用,包括云部署:AWS Cloudformation 模板或 Kubernetes ConfigMaps 将提供有用的解决方法)。

问题(大部分)围绕无法在 Spring 配置应用程序属性中指定私钥文件的(相当莫名其妙的)限制。

在您的 ~/.ssh/config 文件中,您可以添加以下内容:

Host git-config
    HostName github.myserver.example.com
    User someone
    IdentityFile /path/to/private_key

(我需要连接到私人 GitHub 企业服务器,并且与 SSH 密钥关联的用户与正在 运行 下的应用程序服务器不同:这工作得很好;如果不是这种情况,只需使用 github.com 作为 HostName,并省略 User)

然后,不使用实际的 GitHub URI,像这样:

git@github.myserver.example.com:my-team/config-properties-demo.git

您将 git-config 替换为主机:

spring:
  cloud:
    config:
      server:
        git:
          uri: git@git-config:my-team/config-properties-demo.git
          strictHostKeyChecking: false

确实有点繁琐,但是自动化比较容易。 一个更好的选择是 Spring Config 添加另一个指向私钥的选项 material:

spring:
  cloud:
    config:
      server:
        git:
          uri: git@github.myserver.example.com:my-team/config-properties-demo.git
          user: someone
          private_key_file: /path/to/private_key
          strictHostKeyChecking: false

我想这是 "enhancement requests" 部分的一个...

请原谅死灵,但这是在 Google(来自 SO)上搜索如何在配置服务器部署到环境时使用 Git 存储库进行 SSH 身份验证时的第一个结果使用临时文件系统 - 我相信我已经找到了一种方法来做到这一点。以下是我目前正在为我的客户实现这一目标所做的工作的要点。

https://gist.github.com/hanserya/43b00162741fa3022481301db60e8acd

它绝对是一只丑小鸭,但功能齐全,应该为任何需要它的人提供坚实的基础。通过此实现,您将能够将卷安装到容器 运行 配置服务器。然后,只需通过任何最适合您的媒介(env 变量、bootstrap.yml 等)spring.cloud.config.server.git.sshLocation 配置密钥将环境用作 SSH 目录

编码愉快!