Git 後端

EnvironmentRepository 的預設實現使用 Git 後端,這對於管理升級、物理環境以及審計變更非常方便。要更改倉庫的位置,您可以在配置伺服器中設定 spring.cloud.config.server.git.uri 配置屬性(例如在 application.yml 中)。如果您將其設定為 file: 字首,它應該可以從本地倉庫工作,這樣您可以快速輕鬆地入門,而無需伺服器。但是,在這種情況下,伺服器直接操作本地倉庫,而不克隆它(即使它不是裸倉庫也沒關係,因為配置伺服器永遠不會更改“遠端”倉庫)。要擴充套件配置伺服器並使其高可用,您需要讓所有伺服器例項指向同一個倉庫,因此只有共享檔案系統可以工作。即使在這種情況下,最好對共享檔案系統倉庫使用 ssh: 協議,以便伺服器可以克隆它並使用本地工作副本作為快取。

此倉庫實現將 HTTP 資源的 {label} 引數對映到 Git 標籤(提交 ID、分支名稱或標籤)。如果 Git 分支或標籤名稱包含斜槓 (/),則 HTTP URL 中的標籤應使用特殊字串 ({special-string}) 指定(以避免與其他 URL 路徑產生歧義)。例如,如果標籤是 foo/bar,替換斜槓後的標籤將是 foo({special-string})bar。特殊字串 ({special-string}) 的包含也可以應用於 {application} 引數。如果您使用像 curl 這樣的命令列客戶端,請小心 URL 中的括號 — 您應該使用單引號 ('') 從 shell 中轉義它們。

跳過 SSL 證書驗證

可以透過將 git.skipSslValidation 屬性設定為 true(預設為 false)來停用配置伺服器對 Git 伺服器 SSL 證書的驗證。

spring:
  cloud:
    config:
      server:
        git:
          uri: https://example.com/my/repo
          skipSslValidation: true

設定連線超時

您可以配置配置伺服器等待獲取 HTTP 或 SSH 連線的時間(以秒為單位)。使用 git.timeout 屬性(預設為 5)。

spring:
  cloud:
    config:
      server:
        git:
          uri: https://example.com/my/repo
          timeout: 4

Git URI 中的佔位符

Spring Cloud Config Server 支援帶有 {application}{profile} 佔位符(如果您需要,也可以使用 {label},但請記住標籤無論如何都會作為 Git 標籤應用)的 Git 倉庫 URL。因此,您可以透過使用類似於以下的結構來支援“每個應用一個倉庫”的策略:

spring:
  cloud:
    config:
      server:
        git:
          uri: https://github.com/myorg/\{application}

您也可以使用類似模式但使用 {profile} 來支援“每個 profile 一個倉庫”的策略。

此外,在您的 {application} 引數中使用特殊字串 "({special-string})" 可以支援多個組織,如下例所示:

spring:
  cloud:
    config:
      server:
        git:
          uri: https://github.com/\{application}

其中 {application} 在請求時以以下格式提供:organization({special-string})application

模式匹配和多個倉庫

Spring Cloud Config 還支援更復雜的需求,透過對應用程式和 profile 名稱進行模式匹配。模式格式是以逗號分隔的 {application}/{profile} 名稱列表,可以使用萬用字元(請注意,以萬用字元開頭的模式可能需要加引號),如下例所示:

spring:
  cloud:
    config:
      server:
        git:
          uri: https://github.com/spring-cloud-samples/config-repo
          repos:
            simple: https://github.com/simple/config-repo
            special:
              pattern: special*/dev*,*special*/dev*
              uri: https://github.com/special/config-repo
            local:
              pattern: local*
              uri: file:/home/configsvc/config-repo

如果 {application}/{profile} 與任何模式都不匹配,則使用 spring.cloud.config.server.git.uri 下定義的預設 URI。在上例中,對於“simple”倉庫,模式是 simple/*(它僅匹配所有 profile 中名為 simple 的一個應用程式)。“local”倉庫匹配所有 profile 中名稱以 local 開頭的所有應用程式(任何沒有 profile 匹配器的模式都會自動新增 /* 字尾)。

“simple”示例中使用的“一句話”快捷方式只能在唯一需要設定的屬性是 URI 時使用。如果您需要設定其他任何內容(憑據、模式等),則需要使用完整形式。

倉庫中的 pattern 屬性實際上是一個數組,因此您可以使用 YAML 陣列(或屬性檔案中的 [0][1] 等字尾)來繫結到多個模式。如果您要執行具有多個 profile 的應用程式,您可能需要這樣做,如下例所示:

spring:
  cloud:
    config:
      server:
        git:
          uri: https://github.com/spring-cloud-samples/config-repo
          repos:
            development:
              pattern:
                - '*/development'
                - '*/staging'
              uri: https://github.com/development/config-repo
            staging:
              pattern:
                - '*/qa'
                - '*/production'
              uri: https://github.com/staging/config-repo
Spring Cloud 推斷,包含不以 * 結尾的 profile 的模式意味著您實際上想要匹配以此模式開頭的一系列 profile(因此 */staging["*/staging", "*/staging,*"] 等的快捷方式)。這在例如您需要在本地使用“development”profile 執行應用程式,同時在遠端使用“cloud”profile 時很常見。

每個倉庫還可以選擇將配置檔案儲存在子目錄中,並且可以指定搜尋這些目錄的模式作為 search-paths。以下示例顯示了一個頂層配置檔案:

spring:
  cloud:
    config:
      server:
        git:
          uri: https://github.com/spring-cloud-samples/config-repo
          search-paths:
            - foo
            - bar*

在前例中,伺服器搜尋頂層和 foo/ 子目錄以及名稱以 bar 開頭的任何子目錄中的配置檔案。

預設情況下,伺服器在首次請求配置時克隆遠端倉庫。可以將伺服器配置為在啟動時克隆倉庫,如下面的頂層示例所示:

spring:
  cloud:
    config:
      server:
        git:
          uri: https://git/common/config-repo.git
          repos:
            team-a:
                pattern: team-a-*
                cloneOnStart: true
                uri: https://git/team-a/config-repo.git
            team-b:
                pattern: team-b-*
                cloneOnStart: false
                uri: https://git/team-b/config-repo.git
            team-c:
                pattern: team-c-*
                uri: https://git/team-a/config-repo.git

在前例中,伺服器在啟動時克隆 team-a 的 config-repo,然後才接受任何請求。所有其他倉庫直到請求該倉庫中的配置時才被克隆。

在配置伺服器啟動時設定要克隆的倉庫有助於快速識別配置源配置錯誤(例如無效的倉庫 URI),這在配置伺服器啟動過程中發生。如果未為配置源啟用 cloneOnStart,配置伺服器可能會成功啟動,即使配置源配置錯誤或無效,直到應用程式請求該配置源中的配置時才檢測到錯誤。

認證

要在遠端倉庫上使用 HTTP 基本認證,請分別新增 usernamepassword 屬性(不要放在 URL 中),如下例所示:

spring:
  cloud:
    config:
      server:
        git:
          uri: https://github.com/spring-cloud-samples/config-repo
          username: trolley
          password: strongpassword

如果您不使用 HTTPS 和使用者憑據,當您將金鑰儲存在預設目錄 (~/.ssh) 中並且 URI 指向 SSH 位置(例如 [email protected]:configuration/cloud-configuration)時,SSH 也應該開箱即用。重要的是 ~/.ssh/known_hosts 檔案中存在 Git 伺服器的條目,並且格式為 ssh-rsa。不支援其他格式(例如 ecdsa-sha2-nistp256)。為避免意外,您應該確保 known_hosts 檔案中對於 Git 伺服器只有一個條目,並且與您提供給配置伺服器的 URL 匹配。如果您在 URL 中使用主機名,則希望 known_hosts 檔案中也是完全一樣的主機名(而不是 IP)。倉庫透過 JGit 訪問,因此您找到的任何 JGit 文件都應該適用。HTTPS 代理設定可以在 ~/.git/config 中或(與任何其他 JVM 程序相同的方式)透過系統屬性 (-Dhttps.proxyHost-Dhttps.proxyPort) 進行設定。

如果您不知道 ~/.git 目錄在哪裡,請使用 git config --global 來操作設定(例如,git config --global http.sslVerify false)。

JGit 需要 PEM 格式的 RSA 金鑰。以下是 ssh-keygen(來自 openssh)命令的一個示例,它將生成正確格式的金鑰:

ssh-keygen -m PEM -t rsa -b 4096 -f ~/config_server_deploy_key.rsa

警告:使用 SSH 金鑰時,預期的 SSH 私鑰必須以 -----BEGIN RSA PRIVATE KEY----- 開頭。如果金鑰以 -----BEGIN OPENSSH PRIVATE KEY----- 開頭,則在啟動 spring-cloud-config 伺服器時將無法載入 RSA 金鑰。錯誤類似於:

- Error in object 'spring.cloud.config.server.git': codes [PrivateKeyIsValid.spring.cloud.config.server.git,PrivateKeyIsValid]; arguments [org.springframework.context.support.DefaultMessageSourceResolvable: codes [spring.cloud.config.server.git.,]; arguments []; default message []]; default message [Property 'spring.cloud.config.server.git.privateKey' is not a valid private key]

要糾正上述錯誤,必須將 RSA 金鑰轉換為 PEM 格式。上面提供了一個使用 openssh 生成新金鑰的示例,其格式是適當的。

AWS CodeCommit 認證

Spring Cloud Config Server 還支援 AWS CodeCommit 認證。AWS CodeCommit 在從命令列使用 Git 時使用認證助手。JGit 庫不使用此助手,因此如果 Git URI 與 AWS CodeCommit 模式匹配,則會建立一個用於 AWS CodeCommit 的 JGit CredentialProvider。AWS CodeCommit URI 遵循以下模式:

https://git-codecommit.${AWS_REGION}.amazonaws.com/v1/repos/${repo}

如果您為 AWS CodeCommit URI 提供了使用者名稱和密碼,它們必須是提供倉庫訪問許可權的 AWS accessKeyId 和 secretAccessKey。如果您未指定使用者名稱和密碼,則使用 預設憑證提供程式鏈 獲取 accessKeyId 和 secretAccessKey。

如果您的 Git URI 與 CodeCommit URI 模式(如前所示)匹配,則必須在使用者名稱和密碼中或預設憑證提供程式鏈支援的位置之一提供有效的 AWS 憑據。AWS EC2 例項可以使用 適用於 EC2 例項的 IAM 角色

software.amazon.awssdk:auth jar 是一個可選依賴項。如果 software.amazon.awssdk:auth jar 不在您的 classpath 中,則不會建立 AWS Code Commit 憑證提供程式,無論 Git 伺服器 URI 如何。

Google Cloud Source 認證

Spring Cloud Config Server 還支援針對 Google Cloud Source 倉庫進行認證。

如果您的 Git URI 使用 httphttps 協議且域名是 source.developers.google.com,則將使用 Google Cloud Source 憑證提供程式。Google Cloud Source 倉庫 URI 的格式為 source.developers.google.com/p/${GCP_PROJECT}/r/${REPO}。要獲取您的倉庫 URI,請在 Google Cloud Source UI 中點選“Clone”,然後選擇“Manually generated credentials”。不要生成任何憑據,只需複製顯示的 URI 即可。

Google Cloud Source 憑證提供程式將使用 Google Cloud Platform 應用程式預設憑據。有關如何為系統建立應用程式預設憑據,請參閱 Google Cloud SDK 文件。此方法適用於開發環境中的使用者賬戶和生產環境中的服務賬戶。

com.google.auth:google-auth-library-oauth2-http 是一個可選依賴項。如果 google-auth-library-oauth2-http jar 不在您的 classpath 中,則不會建立 Google Cloud Source 憑證提供程式,無論 Git 伺服器 URI 如何。

使用屬性配置 Git SSH

預設情況下,Spring Cloud Config Server 使用的 JGit 庫在透過 SSH URI 連線到 Git 倉庫時會使用 SSH 配置檔案,例如 ~/.ssh/known_hosts/etc/ssh/ssh_config。在像 Cloud Foundry 這樣的雲環境中,本地檔案系統可能是臨時的或不易訪問。對於這些情況,可以使用 Java 屬性設定 SSH 配置。為了啟用基於屬性的 SSH 配置,必須將 spring.cloud.config.server.git.ignoreLocalSshSettings 屬性設定為 true,如下例所示:

  spring:
    cloud:
      config:
        server:
          git:
            uri: [email protected]:team/repo1.git
            ignoreLocalSshSettings: true
            hostKey: someHostKey
            hostKeyAlgorithm: ssh-rsa
            privateKey: |
                         -----BEGIN RSA PRIVATE KEY-----
                         MIIEpgIBAAKCAQEAx4UbaDzY5xjW6hc9jwN0mX33XpTDVW9WqHp5AKaRbtAC3DqX
                         IXFMPgw3K45jxRb93f8tv9vL3rD9CUG1Gv4FM+o7ds7FRES5RTjv2RT/JVNJCoqF
                         ol8+ngLqRZCyBtQN7zYByWMRirPGoDUqdPYrj2yq+ObBBNhg5N+hOwKjjpzdj2Ud
                         1l7R+wxIqmJo1IYyy16xS8WsjyQuyC0lL456qkd5BDZ0Ag8j2X9H9D5220Ln7s9i
                         oezTipXipS7p7Jekf3Ywx6abJwOmB0rX79dV4qiNcGgzATnG1PkXxqt76VhcGa0W
                         DDVHEEYGbSQ6hIGSh0I7BQun0aLRZojfE3gqHQIDAQABAoIBAQCZmGrk8BK6tXCd
                         fY6yTiKxFzwb38IQP0ojIUWNrq0+9Xt+NsypviLHkXfXXCKKU4zUHeIGVRq5MN9b
                         BO56/RrcQHHOoJdUWuOV2qMqJvPUtC0CpGkD+valhfD75MxoXU7s3FK7yjxy3rsG
                         EmfA6tHV8/4a5umo5TqSd2YTm5B19AhRqiuUVI1wTB41DjULUGiMYrnYrhzQlVvj
                         5MjnKTlYu3V8PoYDfv1GmxPPh6vlpafXEeEYN8VB97e5x3DGHjZ5UrurAmTLTdO8
                         +AahyoKsIY612TkkQthJlt7FJAwnCGMgY6podzzvzICLFmmTXYiZ/28I4BX/mOSe
                         pZVnfRixAoGBAO6Uiwt40/PKs53mCEWngslSCsh9oGAaLTf/XdvMns5VmuyyAyKG
                         ti8Ol5wqBMi4GIUzjbgUvSUt+IowIrG3f5tN85wpjQ1UGVcpTnl5Qo9xaS1PFScQ
                         xrtWZ9eNj2TsIAMp/svJsyGG3OibxfnuAIpSXNQiJPwRlW3irzpGgVx/AoGBANYW
                         dnhshUcEHMJi3aXwR12OTDnaLoanVGLwLnkqLSYUZA7ZegpKq90UAuBdcEfgdpyi
                         PhKpeaeIiAaNnFo8m9aoTKr+7I6/uMTlwrVnfrsVTZv3orxjwQV20YIBCVRKD1uX
                         VhE0ozPZxwwKSPAFocpyWpGHGreGF1AIYBE9UBtjAoGBAI8bfPgJpyFyMiGBjO6z
                         FwlJc/xlFqDusrcHL7abW5qq0L4v3R+FrJw3ZYufzLTVcKfdj6GelwJJO+8wBm+R
                         gTKYJItEhT48duLIfTDyIpHGVm9+I1MGhh5zKuCqIhxIYr9jHloBB7kRm0rPvYY4
                         VAykcNgyDvtAVODP+4m6JvhjAoGBALbtTqErKN47V0+JJpapLnF0KxGrqeGIjIRV
                         cYA6V4WYGr7NeIfesecfOC356PyhgPfpcVyEztwlvwTKb3RzIT1TZN8fH4YBr6Ee
                         KTbTjefRFhVUjQqnucAvfGi29f+9oE3Ei9f7wA+H35ocF6JvTYUsHNMIO/3gZ38N
                         CPjyCMa9AoGBAMhsITNe3QcbsXAbdUR00dDsIFVROzyFJ2m40i4KCRM35bC/BIBs
                         q0TY3we+ERB40U8Z2BvU61QuwaunJ2+uGadHo58VSVdggqAo0BSkH58innKKt96J
                         69pcVH/4rmLbXdcmNYGm6iu+MlPQk4BUZknHSmVHIFdJ0EPupVaQ8RHT
                         -----END RSA PRIVATE KEY-----

下表描述了 SSH 配置屬性。

表 1. SSH 配置屬性
屬性名稱 備註

ignoreLocalSshSettings

如果為 true,則使用基於屬性而非基於檔案的 SSH 配置。必須設定為 spring.cloud.config.server.git.ignoreLocalSshSettings不能設定在倉庫定義內部。

privateKey

有效的 SSH 私鑰。如果 ignoreLocalSshSettings 為 true 且 Git URI 為 SSH 格式,則必須設定。

hostKey

有效的 SSH 主機金鑰。如果 hostKeyAlgorithm 也已設定,則必須設定。

hostKeyAlgorithm

以下之一:ssh-dss, ssh-rsa, ssh-ed25519, ecdsa-sha2-nistp256, ecdsa-sha2-nistp384, or ecdsa-sha2-nistp521。如果 hostKey 也已設定,則必須設定。

strictHostKeyChecking

truefalse。如果為 false,則忽略主機金鑰錯誤。

knownHostsFile

自定義 .known_hosts 檔案的位置。

preferredAuthentications

覆蓋伺服器認證方法順序。這應該允許在伺服器將 keyboard-interactive 認證置於 publickey 方法之前時繞過登入提示。

Git 搜尋路徑中的佔位符

Spring Cloud Config Server 還支援帶有 {application}{profile} 佔位符(如果您需要,也可以使用 {label})的搜尋路徑,如下例所示:

spring:
  cloud:
    config:
      server:
        git:
          uri: https://github.com/spring-cloud-samples/config-repo
          search-paths: '\{application}'

前面的列表導致搜尋倉庫中與目錄同名(以及頂層)的檔案。萬用字元在帶有佔位符的搜尋路徑中也是有效的(任何匹配的目錄都包含在搜尋中)。

在 Git 倉庫中強制拉取

如前所述,Spring Cloud Config Server 會克隆遠端 Git 倉庫,以防本地副本變髒(例如,資料夾內容因 OS 程序而更改),導致 Spring Cloud Config Server 無法從遠端倉庫更新本地副本。

為解決此問題,有一個 force-pull 屬性,如果本地副本髒了,它將使 Spring Cloud Config Server 強制從遠端倉庫拉取,如下例所示:

spring:
  cloud:
    config:
      server:
        git:
          uri: https://github.com/spring-cloud-samples/config-repo
          force-pull: true

如果您有多個倉庫配置,可以為每個倉庫配置 force-pull 屬性,如下例所示:

spring:
  cloud:
    config:
      server:
        git:
          uri: https://git/common/config-repo.git
          force-pull: true
          repos:
            team-a:
                pattern: team-a-*
                uri: https://git/team-a/config-repo.git
                force-pull: true
            team-b:
                pattern: team-b-*
                uri: https://git/team-b/config-repo.git
                force-pull: true
            team-c:
                pattern: team-c-*
                uri: https://git/team-a/config-repo.git
force-pull 屬性的預設值為 false

刪除 Git 倉庫中的未跟蹤分支

由於 Spring Cloud Config Server 在檢出分支到本地倉庫(例如透過標籤獲取屬性)後會克隆遠端 Git 倉庫,它將永久保留此分支,直到下次伺服器重啟(這會建立新的本地倉庫)。因此,可能會出現遠端分支被刪除,但本地副本仍可用於獲取的情況。如果 Spring Cloud Config Server 客戶端服務以 --spring.cloud.config.label=deletedRemoteBranch,master 啟動,它將從 deletedRemoteBranch 本地分支獲取屬性,而不是從 master 獲取。

為了保持本地倉庫分支幹淨並與遠端保持一致,可以設定 deleteUntrackedBranches 屬性。這將使 Spring Cloud Config Server 強制刪除本地倉庫中的未跟蹤分支。例如:

spring:
  cloud:
    config:
      server:
        git:
          uri: https://github.com/spring-cloud-samples/config-repo
          deleteUntrackedBranches: true
deleteUntrackedBranches 屬性的預設值為 false

Git 重新整理頻率

您可以使用 spring.cloud.config.server.git.refreshRate 控制配置伺服器從 Git 後端獲取更新配置資料的頻率。此屬性的值以秒為單位指定。預設值為 0,表示配置伺服器在每次請求時都會從 Git 倉庫獲取更新的配置。如果值為負數,則不會發生重新整理。

預設標籤

Git 使用的預設標籤是 main。如果您未設定 spring.cloud.config.server.git.defaultLabel 且名為 main 的分支不存在,配置伺服器預設也會嘗試檢出名為 master 的分支。如果您想停用回退分支行為,可以將 spring.cloud.config.server.git.tryMasterBranch 設定為 false

在容器中使用 Git 執行配置伺服器

如果您在容器中執行配置伺服器時遇到類似於以下的 java.io.IOException

2022-01-03 20:04:02,892 [tributeWriter-2] ERROR org.eclipse.jgit.util.FS$FileStoreAttributes.saveToConfig - Cannot save config file 'FileBasedConfig[/.config/jgit/config]'
java.io.IOException: Creating directories for /.config/jgit failed

您必須要麼

  1. 在容器內提供一個具有寫入許可權的主目錄的使用者。

  2. 在容器內設定環境變數 XDG_CONFIG_HOME,指向 Java 程序具有寫入許可權的目錄。