config-map kubernetes多个环境

时间:2017-12-09 12:16:55

标签: spring-boot deployment kubernetes

我正在尝试使用来自Kubernetes集群的配置数据部署Spring Boot应用程序。我有一个简单的RestController,它通过从Kubernetes集群读取来打印消息。

    private String message = "Message not coming from Kubernetes config map";

@RequestMapping(value="/echo", method=GET)
public String printKubeConfig() {
    return message;
}

在我的application.yml

中指定了配置映射的名称
spring:
  application:
    name: echo-configmap

回波configmap

apiVersion: v1
kind: ConfigMap
metadata:
  name: echo-configmap
data:
  application.properties: |-
    message=Hello from dev Kubernetes Configmap
  application_qa.properties: |-
    message=Hello from qa Kubernetes Configmap

我有几个环境,如qa,int,test等

  1. 在配置映射中指定特定于环境的属性的最佳方法是什么?以及如何在Spring启动应用程序中访问它们? 例如:如果应用程序部署在qa中,我的服务应该返回消息“Hello from qa Kubernetes Configmap”
  2. 我们还计划将来从GIT读取这些配置文件。如何处理该用例?

5 个答案:

答案 0 :(得分:2)

这听起来像是Helm的一个很好的用例。您可以将应用程序部署为Helm Chart,这基本上允许您从模板生成Kubernetes资源(如ConfigMaps,Deployments以及您需要的任何其他内容)。

您可以使用the documentation on Helm Charts开始使用Helm。创建一个包含helm create的图表后,您将获得一个templates/目录,您可以在该目录中为您的ConfigMap放置以下YAML模板:

apiVersion: v1
kind: ConfigMap
metadata:
  name: {{ printf "%s-%s" .Release.Name .Chart.Name }}
  labels:
    app: {{ .Chart.Name | trunc 63 | trimSuffix "-" }}
    chart: {{ .Chart.Name }}-{{ .Chart.Version | replace "+" "_" }}
    release: {{ .Release.Name }}
    heritage: {{ .Release.Service }}
data:
  application.properties: |-
    message={{ .Values.properties.message }}

您可以为Deployment对象添加第二个YAML模板(实际上,helm create已经创建了合理的默认部署)。只需将ConfigMap添加为卷,即:

containers:
  - name: {{ .Chart.Name }}
    # [...]
    volumes:
      - name: property-volume
        mountPath: /etc/your-app/properties
volumes:
  - name: property-volume
    configMap:
      name: {{ printf "%s-%s" .Release.Name .Chart.Name }}

每个头盔图表都有一个values.yaml文件,您可以在其中定义默认值,然后用于填充模板。此默认文件可能如下所示(请记住上面的ConfigMap模板包含{{ .Values.properties.message }}表达式):

replicaCount: 1
image:
  repository: your-docker-image
  tag: your-docker-tag
properties:
  message: Hello!

接下来,使用此Helm图表和helm install command可以根据需要使用不同的配置多次部署应用程序。您可以提供不同的YAML文件,在其中覆盖values.yaml文件中的特定值,或使用--set覆盖单个值:

$ helm install --name dev --set image.tag=latest --set replicaCount=1 path/to/chart
$ helm install --name prod --set image.tag=stable --set replicaCount=3 --set properties.message="Hello from prod" path/to/chart

至于你的第二个问题:当然你应该把你的头盔图放到版本控制中。然后,您可以使用helm upgrade command将更改应用于已部署的应用程序。

答案 1 :(得分:2)

让我尝试提供一个答案,我认为可以为您提供所需的答案,而不使用任何超出您在大多数盒子上安装的工具。也许先试试这个,如果你发现这种方法难以管理和扩展,那就转向更复杂的东西了。

步骤1:每个环境的版本控制配置映射

创建像k8s/configmaps之类的文件夹,并为每个环境创建一个配置图:

k8s/configmaps/properties.dev.yaml
k8s/configmaps/properties.qa.yaml
k8s/configmaps/properties.sit.yaml
k8s/configmaps/properties.uat.yaml

每个configmap都应包含特定于环境的设置。

第2步:为每个环境设置命名空间

为每个环境创建一个k8s命名空间,例如:

 application-dev
 application-qa
 application-sit
 application-uat

步骤3:为每个环境创建配置映射

有点bash会有所帮助:

#!/usr/bin/env bash
# apply-configmaps.sh
namespace="application-${ENVIRONMENT}"
for configmap in ./k8s/configmaps/*.${ENVIRONMENT}.yml; do
    echo "Processing ConfigMap $configmap"
    kubectl apply -n ${namespace} -f $configmap
done

现在,您需要为任何环境创建或更新配置文件:

ENVIRONMENT=dev ./update-configmaps.sh

步骤4:使用CI / CD

完成作业

现在您可以创建CI / CD管道 - 如果您的configmap源更改,只需运行上面显示的命令。

摘要

基于原始命令而没有特殊工具,您可以:

  • 版本控制配置
  • 管理每个环境的配置
  • 配置代码更改时更新或创建配置
  • 如果需要,可以在CI / CD管道中轻松应用相同的方法

我强烈建议您遵循这个基本原则'第一原则'在开始使用更复杂的工具来解决相同的问题之前,在很多情况下,你可以自己动手做,不需要太多努力,学习关键概念并保存更复杂的工具,直到以后如果你真的需要它。

希望有所帮助!

答案 2 :(得分:1)

我会在您的每个git项目中使用此工具来获取非机密数据。 https://github.com/kubernetes-sigs/kustomize

在元数据中,您可以过滤pod

apiVersion: apps/v1
kind: Deployment
metadata:
  labels:
    app: mycomponent
    env: dev
    tier: backend
  name: mycomponent
  namespace: myapplication

kubectl获取容器-n myapplication -l env = dev,tier = backend,app = mycomponent

答案 3 :(得分:0)

您的用例听起来非常像您应该查看spring-cloud-config - https://cloud.spring.io/spring-cloud-config/

config-server是一个基础架构组件,可以提供可以位于git存储库中的配置。

配置客户端应用程序将在启动时连接到config-server并加载适用于当前配置文件的配置。

您可以为不同的环境设置不同的分支 - 或者为每个环境使用配置文件。在kubernetes部署清单中,您可以通过设置SPRING_PROFILES_ACTIVE环境变量来设置配置文件。

答案 4 :(得分:0)

通常,您希望在qa上运行的应用程序不会干扰production上运行的应用程序。使用Kubernetes,您可以获得这种隔离using different namespaces for different environments。 这样,prod命名空间上的对象与qa命名空间上的对象不同。另一种更昂贵的方法是在不同的环境中使用不同的k8s群集。

通过此设置,您可以在要部署到的特定环境的命名空间中部署应用程序,在该命名空间上创建Deployment对象。 这个Deployment将使用包含Spring Boot属性的ConfigMap对象。我们称之为ConfigMap echo-properties

这样,每个命名空间都会有 echo-properties ConfigMap的唯一副本。每个都包含其所属环境的特定配置。

Deployment对象通过使用环境变量或读取文件来使用ConfigMap属性。这里重要的一点是,如果您更改 echo-properties ConfigMap数据,默认情况下您的应用程序将不会看到这些新值。到目前为止,Kubernetes没有此功能。您无法将ConfigMap与Spring Cloud Config进行比较,后者是一种动态配置解决方案。

一种可以让您获得类似行为(但不完全相同)的方法是使用群集上的fabric8 ConfigMap Controller。此控制器是在您的群集上运行的进程,只要ConfigMap发生更改,它就会重新启动您的应用程序,以便它读取新的配置值。

如果您不希望在配置发生变化时重新启动应用程序,您可能应该坚持使用Spring Cloud Config来获取可能会发生变化的值,并将ConfigMaps用于其他不会更改的属性,例如应用程序名称或端口。