Spring Boot 应用程序中的 Kubernetes pod 级别配置外部化

Posted

技术标签:

【中文标题】Spring Boot 应用程序中的 Kubernetes pod 级别配置外部化【英文标题】:Kubernetes pod level configuration externalization in spring boot app 【发布时间】:2021-10-07 07:44:01 【问题描述】:

我需要社区的帮助,我还是 K8 和 Spring Boot 的新手。提前谢谢大家。 我需要的是在 K8 环境中运行 4 个 K8 pod,并且每个 pod 的配置略有不同,例如,我的一个 java 类中有一个名为 region 的属性,它从 Application.yml 中提取它的值,比如

@Value("$regions") 私有字符串区域;

现在将它部署到 K8 环境后,我希望运行 4 个 pod(我可以在 helm 文件中对其进行配置),并且每个 pod 中的 regions 字段应该具有不同的值。 这是可以实现的吗?谁能给点建议?

【问题讨论】:

您使用helm这一事实大大简化了任务。您可以在values.yaml 中定义您关心的区域并根据需要应用并将它们作为环境属性公开在部署文件中。反过来,Spring 拥有EnvironmentPostProcessor,它将读取 helm 设置的环境变量。并且不要使用@Value,而是使用@ConfigurationProperties 【参考方案1】:

如果您想以不同的配置运行 4 个不同的 pod,则必须在 kubernetes 中部署 4 个不同的部署。

您可以根据需要创建不同的configmap 存储整个Application.yaml 文件或环境变量并将其注入到不同的 部署

如何将整个application.yaml 存储在config map

apiVersion: v1
kind: ConfigMap
metadata:
  name: yaml-region-first
data:
  application.yaml: |-
    data: test,
    region: first-region

使用第二个部署创建配置映射的方式相同。

 apiVersion: v1
    kind: ConfigMap
    metadata:
      name: yaml-region-second
    data:
      application.yaml: |-
        data: test,
        region: second-region

您可以将此configmap 注入到每个部署中

示例:

apiVersion: apps/v1
kind: Deployment
metadata:
  labels:
    app: hello-app
  name: hello-app
  namespace: default
spec:
  progressDeadlineSeconds: 600
  replicas: 1
  revisionHistoryLimit: 10
  selector:
    matchLabels:
      app: hello-app
  strategy:
    rollingUpdate:
      maxSurge: 25%
      maxUnavailable: 25%
    type: RollingUpdate
  template:
    metadata:
      creationTimestamp: null
      labels:
        app: hello-app
    spec:
      containers:
      - name: nginx
        image: nginx
        imagePullPolicy: IfNotPresent
        volumeMounts:
          - mountPath: /etc/nginx/app.yaml
            name: yaml-file
            readOnly: true
      volumes:
      - configMap:
          name: yaml-region-second
          optional: false
        name: yaml-file

相应地,您还可以创建掌舵图。

如果您只是传递单个环境而不是将整个文件存储在 configmap 中,则可以直接为部署添加价值。

例子:

apiVersion: v1
kind: Pod
metadata:
  name: print-greeting
spec:
  containers:
  - name: env-print-demo
    image: bash
    env:
    - name: REGION
      value: "one"
    - name: HONORIFIC
      value: "The Most Honorable"
    - name: NAME
      value: "Kubernetes"
    command: ["echo"]
    args: ["$(GREETING) $(HONORIFIC) $(NAME)"]

https://kubernetes.io/docs/tasks/inject-data-application/define-environment-variable-container/

对于每个部署,您的环境会有所不同,在 helm 中,您可以使用 CLI 命令 dynamically 也可以 updateoverwrite 它。

【讨论】:

谢谢Harsh,我会试试这个,我会在这里发布结果。 解决方案奏效,交给部署团队进行多 K8 部署。再次感谢。 很高兴听到这个消息,如果有帮助,您也可以投票赞成:)...! 我想这样做,但我没有足够的声誉这样做。 你读过 OP 正在使用 helm 吗?这是提供解决方案的相当奇怪的方式。而且您确实不需要将spring应用程序文件存储在配置映射中,有一个环境后处理器。

以上是关于Spring Boot 应用程序中的 Kubernetes pod 级别配置外部化的主要内容,如果未能解决你的问题,请参考以下文章

1 个 Spring Boot 应用程序中的 Spring mvc 和 webflux

如何使用 Spring Boot Security 修复 Spring Boot Webflux 应用程序中的“名称为 requestMappingHandlerAdapter 的 bean 定义无效

Spring Boot 中的事务同步

Spring Boot中的注解

spring boot 应用在 k8s 中的健康检查

包含Spring Data会破坏Spring Boot应用程序中的自动序列化