我有一个带有两个配置文件dev和prod的spring boot应用程序,我的docker文件是:
FROM openjdk:8-jdk-alpine
VOLUME /tmp
ARG DEPENDENCY=target/dependency
COPY ${DEPENDENCY}/BOOT-INF/lib /app/lib
COPY ${DEPENDENCY}/META-INF /app/META-INF
COPY ${DEPENDENCY}/BOOT-INF/classes /app
ENTRYPOINT ["java","-Dspring.profiles.active=dev","-cp","app:app/lib/*","com.my.Application"]
请不要这样,在构建映像时,我将入口点指定为命令行参数。
这是我使用此映像的kubernetes部署的容器部分:
containers:
- name: myapp
image: myregistry.azurecr.io/myapp:0.1.7
imagePullPolicy: "Always"
ports:
- containerPort: 8080
name: myapp
readinessProbe:
httpGet:
path: /actuator/health
port: 8080
timeoutSeconds: 3
periodSeconds: 20
failureThreshold: 3
它可以工作,但有一个主要缺陷:现在如何在不重建映像的情况下切换到生产环境?
最好是在docker文件中删除该ENTRYPOINT,并在kubernetes yml中进行此配置,以便我可以始终使用同一映像...这可能吗?
edit:我看到有一个生命周期说明,但请注意,我有一个基于弹簧保护套执行器的就绪探测器。如果我使用此构造,它将总是失败。
答案 0 :(得分:2)
您可以使用Kubernetes Pod规范的ENTRYPOINT
属性覆盖图像的command
。同样,您可以使用CMD
属性来覆盖args
(另请参见the documentation):
containers:
- name: myapp
image: myregistry.azurecr.io/myapp:0.1.7
imagePullPolicy: "Always"
command: ["java","-Dspring.profiles.active=prod","-cp","app:app/lib/*","com.my.Application"]
ports:
- containerPort: 8080
name: myapp
或者,要提供更高级别的抽象,您可以编写自己的入口点脚本,该脚本从环境变量读取应用程序配置文件:
#!/bin/sh
PROFILE="${APPLICATION_CONTEXT:-dev}"
exec java "-Dspring.profiles.active=$PROFILE" -cp app:app/lib/* com.my.Application
然后,您可以简单地将环境变量传递到您的pod中:
containers:
- name: myapp
image: myregistry.azurecr.io/myapp:0.1.7
imagePullPolicy: "Always"
env:
- name: APPLICATION_CONTEXT
value: prod
ports:
- containerPort: 8080
name: myapp
答案 1 :(得分:2)
而不是将spring.profiles.active
放在入口点的dockerfile中。
使用configmaps和application.properties。
您在dockerfile中的ENTRYPOINT应该如下:
ENTRYPOINT ["java","-cp","app:app/lib/*","com.my.Application","--spring.config.additional-location=/config/application-dev.properties"]
创建一个配置映射,用作您的springboot应用程序的application.properties
---
apiVersion: v1
kind: ConfigMap
metadata:
name: myapp-config
namespace: flow
data:
application-dev.properties: |
spring.application.name=myapp
server.port=8080
spring.profiles.active=dev
注意:在这里,我们指定了spring.profiles.active。
在我的kubernetes部署的容器部分中,将configmap安装在将用作application.properties的容器中。
containers:
- name: myapp
image: myregistry.azurecr.io/myapp:0.1.7
imagePullPolicy: "Always"
command: ["java","-cp","app:app/lib/*","com.my.Application","--spring.config.additional-location=/config/application-dev.properties"]
ports:
- containerPort: 8080
name: myapp
volumeMounts:
- name: myapp-application-config
mountPath: "/config"
readOnly: true
volumes:
- name: myapp-application-config
configMap:
name: myapp-config
items:
- key: application-dev.properties
path: application-dev.properties
readinessProbe:
httpGet:
path: /actuator/health
port: 8080
timeoutSeconds: 3
periodSeconds: 20
failureThreshold: 3
注意:--spring.config.additional-location
指向我们在配置映射中创建的application.properties的位置。
因此,利用configmaps和application.properties可以覆盖应用程序的任何配置,而无需重建映像。
如果要添加新配置或更新现有配置的值,只需在configmap中进行适当的更改,然后kubectl apply
。然后缩小并扩大您的应用程序窗格,以使新配置生效。
希望这会有所帮助。
答案 2 :(得分:0)
有many many ways可以设置Spring配置值。通过some rules,您可以使用普通的环境变量来指定各个属性值。您可能会看到是否可以使用它来代替单独的Spring配置文件控件。
在这里使用环境变量有两个好处:这意味着您(或您的DevOps团队)可以在不重新编译应用程序的情况下更改部署时间设置;并且如果您使用的是诸如Helm这样的部署管理器,其中某些细节(例如主机名)本质上是不可预测的,那么您可以指定直到部署时才知道的值。
例如,假设您具有Redis依赖项:
cache:
redis:
url: redis://localhost:6379/0
您可以在部署时通过设置设置覆盖
containers:
- name: myapp
env:
- name: CACHE_REDIS_URL
value: "redis://myapp-redis.default.svc.cluster.local:6379/0"
答案 3 :(得分:0)
一种方法是使用 spring cloud Kubernetes,如此处所述 https://docs.spring.io/spring-cloud-kubernetes/docs/current/reference/html/index.html#configmap-propertysource
您可以在如下所示的 configmap 中定义您的配置文件
kind: ConfigMap
apiVersion: v1
metadata:
name: demo
data:
application.yml: |-
greeting:
message: Say Hello to the World
farewell:
message: Say Goodbye
---
spring:
profiles: development
greeting:
message: Say Hello to the Developers
farewell:
message: Say Goodbye to the Developers
---
spring:
profiles: production
greeting:
message: Say Hello to the Ops
然后可以通过在 Kubernetes 部署清单中传递环境变量来选择所需的配置文件
apiVersion: apps/v1
kind: Deployment
metadata:
name: deployment-name
labels:
app: deployment-name
spec:
replicas: 1
selector:
matchLabels:
app: deployment-name
template:
metadata:
labels:
app: deployment-name
spec:
containers:
- name: container-name
image: your-image
env:
- name: SPRING_PROFILES_ACTIVE
value: "development"