開發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一樣不會更新