原文地址html
大多數Spring Cloud項目都會使用Spring Cloud Config來管理應用啓動時的配置文件,同時開發人員面臨着多樣化的程序啓動方式:操做系統進程啓動、docker啓動、k8s啓動。那麼如何規劃這些配置文件以適應多種啓動方式呢?本文嘗試給出一些建議java
bootstrap.properties
和application.properties
(或者它們的yaml變種)打到包裏。bootstrap.properties
裏,要針對可變配置項作環境變量化。application.properties
裏,要針對可變配置項作環境變量化。bootstrap.properties
裏,而且要作環境變量化。application-*.properties
裏不得有環境變量。由於既然直接提供配置了,那麼就不該該再使用環境變量。這句話對應The 12-factor App的Config章節。具體作法是在配置文件裏使用placeholder。下面是兩種方式:git
app.name=${APP_NAME} app.description=${APP_DESC:Default description}
第一種方式Spring Boot/Cloud應用在啓動時,會根據這個順序找APP_NAME
的值,若是找不到程序啓動會報錯。github
第二種方式和第一種方式的不一樣在於若是找不到,則使用application.properties
裏定義的默認值。spring
而程序在啓動時應該經過環境變量的方式將這些值傳遞進去。docker
在真實應用中應該儘可能多的使用第二種方式,只有少數的配置纔是程序啓動時必須提供的,通常來講都是一些數據庫鏈接字符串、用戶名密碼等信息。數據庫
bootstrap.properties
裏,而且要作環境變量化。好比這樣:bootstrap
spring.cloud.config.enabled=${CONFIG_ENABLED:true} spring.cloud.config.profile=${CONFIG_PROFILE:production} spring.cloud.config.label=${CONFIG_LABEL:master} spring.cloud.config.uri=${CONFIG_SERVER_URL:http://config-server:8080/}
上面這個配置能夠控制是否鏈接config server,由於在開發環境下咱們可能並不須要config server。也提供了能夠config server啓動程序的可能。
同時也控制了若是鏈接config server,應該使用哪一個application.properties
。api
須要注意的是,若是咱們選擇程序啓動的時候鏈接config server,那麼在程序啓動時提供的環境變量就只能是和config server相關的環境變量(在這個例子裏就是上面的CONFIG_*
),這些配置用來控制如何得到application.properties
。app
由於此時程序所使用的配置都來自於config server,若是config server提供一些,環境變量又提供一些則會形成運維上的混亂。
下面講講各類啓動方式如何傳遞環境變量。
直接以操做系統進程啓動的方法是相似於這樣的:
APP_NAME=my-app APP_DESC="My App Desc" java -jar spring-cloud-app.jar
用docker啓動則是這樣的,參見Docker ENV (environment variables):
docker run --name my-app -e APP_NAME=my-app -e APP_DESC="My App Desc" spring-cloud-app:latest
定義ConfigMap或Secret(用在密碼類配置上),而後在Deployment spec裏使用configMapRef
或者secretRef
或者configMapKeyRef
或者secretKeyRef
,好比下面的例子:
apiVersion: apps/v1 kind: Deployment metadata: name: my-app namespace: <namespace> spec: ... template: ... spec: containers: - name: my-app image: <image repository> ... envFrom: - configMapRef: name: my-app-config - secretRef: name: my-app-secret env: - name: APP_NAME valueFrom: configMapKeyRef: name: my-app-config key: APP_NAME - name: APP_DESC valueFrom: secretKeyRef: name: my-app-secret key: APP_DESC
詳見Configure a Pod to Use a ConfigMap、Secrets和Load env variables from ConfigMaps and Secrets upon Pod boot。