我们一般会在application.properties或是application.yaml中定义Spring Boot的property(比如database url, username等)。
本文介绍了部署在Kubernetes集群中的Spring Boot项目是如何在启动的时候修改property配置的。我们应当避免在DockerFile中hard-code配置,主要原因是如果需要改动的话,要重新build。而是应当在启动的时候动态传入配置。
两种方式:
- 通过设置
Environment variables
(第2章) - 通过设置
JAVA_TOOL_OPTIONS
或JDK_JAVA_OPTIONS
(JDK9+适用)(第3章)
1. 在项目中定义properties配置
我们预先在application.properties中定义一个配置,叫run.env
,如下:
然后我们写一个Controller用来测试:
我们在@PostConstruct中打印,以便在启动的时候就可以测试到:
@Slf4j
@RestController
public class PropertyController {
@Value("${run.env}")
private String runEnv;
@PostConstruct
public void init() {
log.info("Get run.env = {}", runEnv);
}
}
当我们不额外定义变量直接启动时,可以看到runEnv=local:
2022-07-06 22:06:56.250 INFO 28699 --- [ main] com.controller.PropertyController : Get run.env = local
输出日志:2022-07-06 22:08:38.176 INFO 29054 --- [ main] com.controller.PropertyController : Get run.env = test
ps. 这里-D,设成大写也可以的:-DRUN.ENV=test
2. 在K8s中通过声明Environment variables来重写Spring Boot Properties配置
参考:
- https://www.tutorialworks.com/spring-boot-kubernetes-override-properties/#how-to-override-spring-boot-properties-in-kubernetes-using-environment-variables
- https://www.youtube.com/watch?v=5Fphv4lVrmU
2.1 在deployment.yaml中直接定义:
apiVersion: apps/v1
kind: Deployment
metadata:
name: feign-test
labels:
app: feign
spec:
replicas: 1
selector:
matchLabels:
app: feign
template:
metadata:
labels:
app: feign
spec:
containers:
- name: feign-test
image: localhost/feign-test
env:
- name: RUN_ENV
value: kubernetes_test
imagePullPolicy: IfNotPresent
ports:
- containerPort: 8080
重点看env
这几行:
可以看到在Kubernetes中,可以用_
代替.
。
我们配置的RUN_ENV=kubernetes_test
,在运行的时候,会替换application.properties中的run.env=local
。
查看pod log:
kubectl logs -f feign-test-86d465949d-5j682
输出日志:2022-07-05 00:38:08.476 INFO 1 --- [ main] com.controller.PropertyController : Get run.env = kubernetes_test
2.2 value可以从k8s ConfigMap中读取
首先定义一个configMap:
apiVersion: v1
kind: ConfigMap
metadata:
name: feign-configmap
data:
run.env: kubernetes_config_test
在k8s集群中安装feign-config:
image.png
再在deployment.yaml中定义env
的时候,用valueFrom来读取configMap中的值(只显示env部分的代码,完整的deployment.yaml看#2.1):
...
env:
- name: RUN_ENV
valueFrom:
configMapKeyRef:
name: feign-configmap
key: run.env
创建好deployment后查看Pod的log,可以看到value从configMap中读取没有问题:2022-07-05 00:50:16.424 INFO 1 --- [ main] com.controller.PropertyController : Get run.env = kubernetes_config_test
2.3 整个env都可以从configMap中读取
为了更好的配置,我们在application.properties中再加一个配置: image.pngController:
@Slf4j
@RestController
public class PropertyController {
@Value("${run.env}")
private String runEnv;
@Value("${run.version}")
private String runVersion;
@PostConstruct
public void init() {
log.info("Get run.env = {}, run.version = {}", runEnv, runVersion);
}
}
首先是创建config.yaml:
apiVersion: v1
kind: ConfigMap
metadata:
name: feign-configmap
data:
run.env: kubernetes_config_test
run.version: 2.0.0
通过kubectl apply创建:
image.png
再修改deployment.yaml(节选):
...
envFrom:
- configMapRef:
name: feign-configmap
创建好deployment再次查看Pod,可以看到通过envFrom,可以一次性加载多个配置,记得配置的名字要对应,可以是run.env
或是RUN.ENV
或是RUN_ENV
。
输出日志:2022-07-05 00:59:10.554 INFO 1 --- [ main] com.faj.controller.PropertyController : Get run.env = kubernetes_config_test, run.version = 2.0.0
3. 通过设置JAVA_TOOL_OPTIONS
或JDK_JAVA_OPTIONS
(JDK9+适用)
参考:
- https://www.jianshu.com/p/147422fca01b
- https://stackoverflow.com/questions/52986487/what-is-the-difference-between-jdk-java-options-and-java-tool-options-when-using/52989562#52989562
- https://stackoverflow.com/questions/28327620/difference-between-java-options-java-tool-options-and-java-opts
以JAVA_TOOL_OPTIONS
为例:
deployment.yaml节选:
...
image: localhost/feign-test
env:
- name: JAVA_TOOL_OPTIONS
value: "-Drun.env=tool-optionTest -Drun.version=3.0.0"
重新部署deployment.yaml后,日志输出:2022-07-05 05:32:15.211 INFO 1 --- [ main] com.controller.PropertyController : Get run.env = tool-optionTest, run.version = 3.0.0
查看deployment详情:
image.pngkubectl describe deployment feign-test
查看pod也同样会有:
image.pngkubectl describe pod feign-test-7f4c9fdbdb-9t49r
网友评论