讓你的SpringBoot一次build,處處運行

開發web項目的時候,咱們通常會有多個環境(dev,beta,rc,production),而後每次使用maven打包的時候都要指定profilehtml

mven clean package -P beta
複製代碼

這樣就能夠將application-{profile}.properties打入jar包中。這也就意味着對於不一樣的環境咱們要打不一樣的包,雖然他們只有一些配置信息不一樣而已。java

那麼有沒有辦法在不一樣的環境中使用相同的應用程序代碼呢? 固然有,springboot提供了這樣的機會,它容許咱們經過不少種方式來決定配置文件是哪個,固然啦本篇文章並非介紹有哪些加載外部配置文件的方式。web

就好比禍水三千,我只取一瓢。因此此次咱們直接指定property文件的位置便可spring

java -jar myproject.jar --spring.config.location=classpath:/default.properties,/myconfig/application.properties
複製代碼

道理是這麼個道理,可是如今大多的項目都是部署在k8s上的,那麼應該如何作呢?docker

這裏我藉助了k8s configMap來實現加載外部配置文件達到咱們的目的。apache

首先這裏生成了configMapapi

kubectl create configmap application-configmap --from-file=application.properties=../smcp-web/src/main/resources/application-beta.properties -o yaml -n smcp| kubectl replace -f -
複製代碼

解釋下上面命令的意思,每一次在打包鏡像以後,都會從新生成configMap,生成的application-configmap中,key=application.properties,value則是項目中application-beta.properties的內容springboot

生成configmap有不少種方式,能夠根據本身的需求來生成,能夠查看官方文檔 kubernetes.io/docs/tasks/… -n 的意思是指定namespace,若是你使用的是默認的namespace,那麼能夠不用指定。 -n == --namespacebash

咱們生成的上面的configMap能夠經過kubectl get configmap application-configmap -o yaml -n smcp查看app

apiVersion: v1
data:
  application.properties: | logging.level.com.project.smcp=INFO logging.level.org.apache.shiro=INFO logging.level.okhttp3.OkHttpClient=ERROR kind: ConfigMap
metadata:
 creationTimestamp: 2019-10-24T11:41:57Z
 name: application-configmap
 namespace: smcp
 resourceVersion: "62755048"
 uid: 48c8ab36-f653-11e9-9eab-fa163fea9021

複製代碼

能夠看到實際上是將application-beta.properties文件中的內容所有拷貝到了data中,而後這些全部值的key爲application.properties.再來看看在咱們deployment.yml文件中如何使用

apiVersion: apps/v1beta2
kind: Deployment
metadata:
 name: smcp-service
 namespace: smcp
spec:
 selector:
 matchLabels:
 app: smcp-service
 replicas: 1
 template:
 metadata:
 labels:
 app: smcp-service
 spec:
 containers:
 - name: smcp-service
 image: docker-registry.xxx.com/xxx/smcp-web:latest
 args: ["--spring.config.location=/smcp-config/application.properties"]
 ports:
 - containerPort: 9000
 volumeMounts:
 - name: application-config
 mountPath: smcp-config
 envFrom:
 - secretRef:
 name: my-secret
 volumes:
 - name: application-config
 configMap:
 name: application-configmap
 items:
 - key: application.properties
 path: application.properties
---
apiVersion: v1
kind: Service
metadata:
 name: smcp-service
 namespace: smcp
 labels:
 app: smcp-service
spec:
 ports:
 - targetPort: 9000
 port: 9000
 protocol: TCP
 selector:
 app: smcp-service
 type: NodePort
複製代碼

通過上面的配置,如今application.properties文件就處於/smcp-config下了。看到這裏可能會有人有疑問,爲何個人configMap要單獨用命令生成,而不是在demployment.yaml文件中單獨聲明configMap類型的配置呢? 其實也是能夠的,可是若是這樣作你每次添加了環境變量你都要去demployment.yml中添加配置,你這樣可能就要配置兩次(application-{profile}.properties中還要配置一次),因此我就乾脆用命令生成,在開發的時候不要考慮k8s的存在。

還要注意上面的args參數,經過它咱們指定了外部環境變量的路徑。而對於生成鏡像的dockerfile,其實也很簡單

FROM java:8
EXPOSE 9090
ADD target/smcp-web.jar /smcp-web.jar
ENTRYPOINT ["java", "-jar","/smcp-web.jar"]
複製代碼

最後當咱們執行了下面的命令以後,就能夠部署咱們的容器到k8s中了

kubectl apply -f deployment.yml
複製代碼

最後部署後,進入Pod中,能夠看到目錄結構以下

smcp-web.jar
smcp-config
  -- application.properties
複製代碼

而啓動命令也變成了下面這樣,能夠經過ps -ef查看

java -jar /smcp-web.jar --spring.config.location=/smcp-config/application.properties
複製代碼

上面使用configMap的方式處理,固然還能夠直接在環境變量中使用configMap(參考上面secretRef的方式),當使用環境變量的方式注入configMap的時候,你須要使用下面這樣的命令生成數據。

kubectl create configmap application-configmap --fron-env-file=src/main/resources/application-beta.properties
複製代碼

同時yaml文件中關於configMap的修改爲下面這樣,使用環境變量的方式記得把volumes去掉。

envFrom:
- configMapRef:
  name: application-configmap
複製代碼

可是使用環境變量注入的方式有一點須要注意,當你更新了configMap而不從新部署的時候,容器中的變量是不會更新的,而若是使用mountPath的方式,環境變量的值就會更新(大概10s左右)。

若是你還使用mountPath的同時還使用了subpath一樣不會更新

相關文章
相關標籤/搜索