使用 kubernetes yml 文件时如何处理 gradle 中的环境替换?
How to handle environment substitution in gradle when working with kubernetes yml files?
我正在 gradle 构建期间创建 kubernetes api 对象的 zip 工件。 api 个对象包含
- 在构建工件时要替换的环境变量,如版本号
- 环境变量在部署工件之前被替换,例如 kubernetes 命名空间或 url 到另一个系统
- 在应用程序运行时评估的环境变量
一个精简的例子是这个包含部分 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"
$APPLICATION_VERSION
必须在 gradle build 期间替换
$APPLICATION_NAMESPACE
和 $APPLICATION_INSTANCE
必须在部署前更换
$host
和 $proxy_add_x_forwarded_for
由 nginx 在运行时评估,因此不能被 gradle 构建更改。
应用程序将使用 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_NAMESPACE
和 APPLICATION_INSTANCE
实际值的第二次扩展来创建 api 对象描述,无需任何 esc aping.
artifacts的打包使用2nd expansion生成一个适合正常环境扩展的文件,这样APPLICATION_NAMESPACE
和APPLICATION_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
}
}
}
我正在 gradle 构建期间创建 kubernetes api 对象的 zip 工件。 api 个对象包含
- 在构建工件时要替换的环境变量,如版本号
- 环境变量在部署工件之前被替换,例如 kubernetes 命名空间或 url 到另一个系统
- 在应用程序运行时评估的环境变量
一个精简的例子是这个包含部分 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"
$APPLICATION_VERSION
必须在 gradle build 期间替换
$APPLICATION_NAMESPACE
和$APPLICATION_INSTANCE
必须在部署前更换$host
和$proxy_add_x_forwarded_for
由 nginx 在运行时评估,因此不能被 gradle 构建更改。
应用程序将使用 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_NAMESPACE
和 APPLICATION_INSTANCE
实际值的第二次扩展来创建 api 对象描述,无需任何 esc aping.
artifacts的打包使用2nd expansion生成一个适合正常环境扩展的文件,这样APPLICATION_NAMESPACE
和APPLICATION_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
}
}
}