使用 kubernetes yml 文件时如何处理 gradle 中的环境替换?

How to handle environment substitution in gradle when working with kubernetes yml files?

我正在 gradle 构建期间创建 kubernetes api 对象的 zip 工件。 api 个对象包含

一个精简的例子是这个包含部分 nginx 配置的片段:

kind: "ConfigMap"
apiVersion: "v1"
metadata:
  name: "nginx-config"
  namespace: "$APPLICATION_NAMESPACE"
data:
  nginx.conf: |
    http {
        server {
            location /application/ {
                proxy_set_header X-Forwarded-Host $host;
                proxy_set_header X-Forwarded-Server $host;
                proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
                proxy_set_header X-Forwarded-Prefix /application;
                proxy_pass $APPLICATION_INSTANCE/;
            }
        }
    }
---
kind: "Deployment"
apiVersion: "apps/v1"
metadata:
  name: "application-nginx"
  namespace: "$APPLICATION_NAMESPACE"
  annotations:
    application.version: "$APPLICATION_VERSION"

应用程序将使用 kubectl 部署到 minikube。因此,应该有另一个 gradle 任务来替换 $APPLICATION_NAMESPACE$APPLICATION_INSTANCE 变量。例如,此 gradle 任务要求将运行时变量转义为 $host

应用程序将使用 jenkins 部署到 kubernetes Kubernetes Continuous Deploy Plugin。这要求运行时的变量不被转义。

但现在这是一个矛盾的局面。 minikube 部署需要对运行时变量进行两次转义,例如 \$host。但是用jenkins部署kubernetes要求只转义一次

gradle 文件当前如下所示:

plugins {
    id 'base'
}

task processResources(type: Copy) {
    from 'src/main/resources'
    into "$buildDir/resources/main/"
    expand(APPLICATION_VERSION: version)
}

task packageDistributionKubernetesDev(type: Zip) {
    dependsOn processResources
    from fileTree("$buildDir/resources/main/kubernetes-dev")
    classifier 'kubernetes-dev'
    expand()
}

task packageDistributionMinikube(type: Zip) {
    dependsOn processResources
    from fileTree("$buildDir/resources/main/minikube")
    classifier 'minikube'
    expand()
}

task prepareMinikube(type: Copy) {
    dependsOn processResources
    from "$buildDir/resources/main/minikube"
    into "$buildDir/minikube"
    expand(APPLICATION_NAMESPACE: project.kubernetesNamespace, APPLICATION_INSTANCE: project.applicationInstance)
}

assemble {
    dependsOn packageDistributionKubernetesDev, packageDistributionMinikube
}

publishing {
    publications {
        mavenJava(MavenPublication) {
            artifact source: packageDistributionKubernetesDev
            artifact source: packageDistributionMinikube
        }
    }
}

如何在 gradle 构建中的资源过滤期间正确处理 kuberntes api 对象,并同时支持使用 jenkins 和 minikube 进行部署?

最后,我从要在构建期间或部署之前替换的变量中删除了所有 escaping。在构建期间和准备 minikube 部署时,我将这些变量替换为变量本身,以便在下一次扩展期间获取它们。所以扩展实际上使用 `APPLICATION_NAMESPACE: '\${APPLICATION_NAMESPACE}'.

在运行时计算的变量被转义两次,例如\$host

使用 gradle 准备 minikube 部署使用具有 APPLICATION_NAMESPACEAPPLICATION_INSTANCE 实际值的第二次扩展来创建 api 对象描述,无需任何 esc aping.

artifacts的打包使用2nd expansion生成一个适合正常环境扩展的文件,这样APPLICATION_NAMESPACEAPPLICATION_INSTANCE以及像host这样的运行时变量就不会了没有逃脱。

构建文件如下所示:

plugins {
    id 'base'
}

task processResources(type: Copy) {
    from 'src/main/resources'
    into "$buildDir/resources/main/"
    expand(APPLICATION_VERSION: version, APPLICATION_NAMESPACE: '${APPLICATION_NAMESPACE}', APPLICATION_INSTANCE: '${APPLICATION_INSTANCE}')
}

task packageDistributionKubernetesDev(type: Zip) {
    dependsOn processResources
    from fileTree("$buildDir/resources/main/kubernetes-dev")
    classifier 'kubernetes-dev'
    expand(APPLICATION_NAMESPACE: '${APPLICATION_NAMESPACE}', APPLICATION_INSTANCE: '${APPLICATION_INSTANCE}')
}

task packageDistributionMinikube(type: Zip) {
    dependsOn processResources
    from fileTree("$buildDir/resources/main/minikube")
    classifier 'minikube'
    expand(APPLICATION_NAMESPACE: '${APPLICATION_NAMESPACE}', APPLICATION_INSTANCE: '${APPLICATION_INSTANCE}')
}

task prepareMinikube(type: Copy) {
    dependsOn processResources
    from "$buildDir/resources/main/minikube"
    into "$buildDir/minikube"
    expand(APPLICATION_NAMESPACE: project.kubernetesNamespace, APPLICATION_INSTANCE: project.applicationInstance)
}

assemble {
    dependsOn packageDistributionKubernetesDev, packageDistributionMinikube
}

publishing {
    publications {
        mavenJava(MavenPublication) {
            artifact source: packageDistributionKubernetesDev
            artifact source: packageDistributionMinikube
        }
    }
}