Dockerized Spring Boot应用未使用已安装的Kubernetes ConfigMap(application.properties)

时间:2019-12-05 03:44:17

标签: java spring spring-boot docker kubernetes

我有一个问题,在我的dockerized Spring Boot应用程序中没有使用存储在application.properties中的configMap

但是,当我进入Pod的外壳时,我可以看到并确认configMap已正确安装在Spring Boot应用程序的正确目录中。

请注意,默认情况下我有一个application.properties,其中Kubernetes稍后会挂载/覆盖它。

Spring Boot似乎使用第一个application.properties,并且当k8s覆盖它时,显然它没有使用它。

显然,发生的事情是:

  • 在Dockerized Spring Boot应用程序中运行.jar文件
  • 在运行时使用第一个/默认application.properties文件
  • Kubernetes继续安装configMap
  • 安装/覆盖成功,但是由于Spring Boot已经在运行,它将如何使用它?

这是我的Spring Boot / Docker映像的Dockerfile供参考:

FROM maven:3.5.4-jdk-8-alpine

# Copy whole source code to the docker image
# Note of .dockerignore, this ensures that folders such as `target` is not copied
WORKDIR /usr/src/myproject
COPY . /usr/src/myproject/

RUN mvn clean package -DskipTests

WORKDIR /usr/src/my-project-app
RUN cp /usr/src/myproject/target/*.jar ./my-project-app.jar
EXPOSE 8080
CMD ["java", "-jar", "my-project-app.jar"]

这是我的Kubernetes部署.yaml文件供参考:

apiVersion: extensions/v1beta1
kind: Deployment
metadata:
  name: my-project-api
  namespace: my-cluster
  labels:
    app: my-project-api
spec:
  replicas: 1
  selector:
    matchLabels:
      app: my-project-api
  strategy:
    type: RollingUpdate
    rollingUpdate:
      maxSurge: 1
      maxUnavailable: 0
  template:
    metadata:
      labels:
        app: my-project-api
    spec:
      containers:
        - name: my-project-api
          image: "my-project:latest"
          imagePullPolicy: Always
          env:
            .
            .
            .
          volumeMounts:
          - name: my-project-config
            mountPath: /usr/src/my-project/my-project-service/src/main/resources/config/application.properties
          ports:
            - containerPort: 8080
              name: my-project-api
              protocol: TCP
      volumes:
        # Name of the volume
        - name: my-project-config
          # Get a ConfigMap with this name and attach to this volume
          configMap:
            name: my-project-config

还有我的configMap供参考:

kind: ConfigMap
apiVersion: v1
data:
  application.properties: |-
    # This comment means that this is coming from k8s ConfigMap. Nice!
    server.port=8999
    .
    .
    .
    .

metadata:
  name: my-project-config
  namespace: my-cluster

非常感谢您的帮助...非常感谢..:)

2 个答案:

答案 0 :(得分:1)

问题是您的应用程序使用的/src/main/resources/application.properties默认是jar文件中的那个。如果您打开罐子,应该在那里看到它。 话虽这么说,不幸的是,您对在您的jar所在的目录安装/src/main/resources目录的期望并不令人满意。 These are the docs you should be looking at

我不会详细介绍它,因为它在文档中作了很好的解释,但是我会说,最好是显式声明配置位置,以便项目中的新人们马上知道配置的来源球棒。

您可以执行以下操作:

---
apiVersion: extensions/v1beta1
kind: Deployment
metadata:
  name: my-project-api
  labels:
    app: my-project-api
spec:
  selector:
    matchLabels:
      app: my-project-api
  template:
    metadata:
      labels:
        app: my-project-api
    spec:
      containers:
        - name: my-project-api
          image: "my-project:latest"
          imagePullPolicy: Always
          env:
            - name: JAVA_OPTS
              value: "-Dspring.config.location=/opt/config"
            .
            .
            .
          volumeMounts:
            - name: my-project-config
              mountPath: /opt/config
          ports:
            - containerPort: 8080
      volumes:
        - name: my-project-config
          configMap:
            name: my-project-config

希望有帮助,

干杯!

答案 1 :(得分:0)

我的做法略有不同。我确定我已经在 config/ 安装了 application.properties。 IE;下面是我安装的 application.properties 示例(下面的命令显示 pod 中的值 - 即;在 kubectl exec -it 进入 pod 之后)

/ # pwd
/
/ # cat config/application.properties 
logback.access.enabled=false
management.endpoints.web.exposure.include=health, loggers, beans, configprops, env

基本上,技巧is based on the link in the above answer。以下是链接的摘录,其中确实说 application.properties 将从 config/ 中选择。所以,我确保我的环境(开发、测试、生产)特定的配置映射安装在 config/.请注意以下列表的优先级(根据链接:列表中较高的位置覆盖较低的项目)

A /config subdir of the current directory.
The current directory
A classpath /config package
The classpath root

下面是配置映射定义(刚刚粘贴的数据部分)

data:
  application.properties: |+
    logback.access.enabled={{.Values.logacbkAccessEnabled}}
    management.endpoints.web.exposure.include=health, loggers, beans, configprops, env

您还可以从 actuator/env 端点看到 SpringBootApp 确实选择了这些值。

{
"name": "Config resource 'file [config/application.properties]' via location 'optional:file:./config/'",
"properties": {
"logback.access.enabled": {
"value": "false",
"origin": "URL [file:config/application.properties] - 1:24"
},
"management.endpoints.web.exposure.include": {
"value": "health, loggers, beans, configprops, env",
"origin": "URL [file:config/application.properties] - 2:43"
}
}
},