让你的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一样不会更新

相关文章
相关标签/搜索