【问题标题】:How to change a ConfigMap of a Deployment using a script?如何使用脚本更改部署的 ConfigMap?
【发布时间】:2018-03-24 06:41:03
【问题描述】:

有些部署可能使用名称类似于cm-myapp-* 的配置映射。如何编写一个脚本来查看所有部署并将它们从使用它们的一些 cm-myapp-* 重新配置为新的特定 cm-myapp-123

apiVersion: apps/v1beta1
kind: Deployment
metadata:
  name: myapp
spec:
  template:
    metadata:
      labels:
        app: myapp
    spec:
      containers:
      - name: myapp
        image: myapp:2
        volumeMounts:
          - name: config-volume
            mountPath: /etc/myapp/
      volumes:
        - name: config-volume
          configMap:
            name: cm-myapp-9375546193
---
apiVersion: v1
kind: ConfigMap
metadata:
  name: cm-myapp-123
data:
  myapp.conf: |
    hi

kubectl patch 接受“JSON 补丁”,kubectl edit 看起来像仅交互。一些 kubectl 命令接受 go-templates,但它们不用于编辑。转储整个配置会提供一些多余的字段。

可以提取一些东西:

kubectl get deployment -o go-template --template="{{range .items}}{{\$deploymentName := .metadata.name}}{{range .spec.template.spec.volumes}}{{if .configMap}}{{\$deploymentName}} {{.configMap}}:{{end}}{{end}}{{end}}" | tr ':' '\n'

kubectl get deployment myapp -ojsonpath="{.spec.template.spec.volumes[0].configMap.name}}"

需要修补它(不工作):

kubectl patch deployment myapp -p '{ "op": "replace", "path": ".spec.template.spec.volumes[0].name", "value": "cf" }'

那么怎么做呢? kubectl patch的语法是什么?

【问题讨论】:

  • echo "xx: cm-my-app-*" | sed s/cm-my-app-[*]/cm-my-app-123/ ?
  • @mh-cbon,Kubernetes 返回的配置有其他我不习惯应用的字段。
  • 我尝试做同样的事情,发现patch 不适用于同一个文件中的多个资源。如果您将它们拆分为单独的文件,您应该可以使用patch
  • @TaylorWood,没关系,使用kubectl patch时没有文件。

标签: json go kubernetes


【解决方案1】:

使用jq,即“awk for json”来转换 JSON 文档。我不确定您要确切更改哪些字段,但是如何调整它应该从 jq 参数中清楚。

$ cat x.json 
{
  "apiVersion": "apps/v1beta1",
  "kind": "Deployment",
  "foo": "myapp"
  "metadata": {
    "name": "myapp"
  },
  "spec": {
    "template": {
      "metadata": {
        "labels": {
          "app": "myapp"
        }
      }
    }
  }
}

$ jq '
  .metadata.name = "cm-myapp-123"
| .spec.template.metadata.labels.app = "cm-myapp-123"
| .
' < x.json 
{
  "apiVersion": "apps/v1beta1",
  "kind": "Deployment",
  "foo": "myapp"
  "metadata": {
    "name": "cm-myapp-123"
  },
  "spec": {
    "template": {
      "metadata": {
        "labels": {
          "app": "cm-myapp-123"
        }
      }
    }
  }
}

【讨论】:

  • 我无法提取部署的明确定义。我不需要jq,我已经有了kubectl patch
【解决方案2】:

在我看来,如果您提前了解部署,那将是最佳选择。您应该生成您从一些模板解决方案应用的清单(我建议您熟悉helm,这不仅仅是模板),然后使用模板管理配置映射。

【讨论】:

  • 我不需要模板解决方案,尤其是helm
【解决方案3】:

输出一个旧的配置名称、它在“volumes”数组中的索引和部署的名称。过滤掉我们不感兴趣的配置,修补所有部署。

#!/bin/bash

name=cm-myapp
unique_name=cm-myapp-123

# Columns: ConfigMap name, index in volumes, Deployment name.
kubectl get deployment -o go-template --template="{{range .items}}{{\$deploymentName := .metadata.name}}{{range \$i, \$v := .spec.template.spec.volumes}}{{if .configMap}}{{.configMap.name}} {{\$i}} {{\$deploymentName}}:{{end}}{{end}}{{end}}" | tr ':' '\n' |
    egrep "^$name-[^-]+ " | while read l; do
        i=$(printf '%s\n' "$l" | awk '{print $2}')
        deployment=$(printf '%s\n' "$l" | awk '{print $3}')
        kubectl patch deployment $deployment --type=json -p "[{ \"op\": \"replace\", \"path\": \"/spec/template/spec/volumes/$i/configMap/name\", \"value\": \"$unique_name\" }]"
    done

【讨论】:

    【解决方案4】:

    这是我用来按容器名称修补图像的一些 kubectl patch 语法:

    -p "{\"spec\":{\"template\":{\"spec\":{\"volumes\":[{\"name\":\"myapp\",\"image\":\"$imageUri\"}]}}}}"
    

    通过修补volumes 键,同样的事情可能对你有用:

    -p "{\"spec\":{\"template\":{\"spec\":{\"volumes\":[{\"name\":\"config-volume\",\"configMap\":{\"name\":\"myapp-123\"}}]}}}}"
    

    kubectl 补丁的语法是什么?

    官方文档为here,示例为here。根据该指南,您可以尝试在您的patch 命令上设置--type=json

    有两种语法:JSON PatchJSON Merge Patch

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2020-03-25
      • 1970-01-01
      • 2021-06-30
      • 1970-01-01
      • 2011-10-17
      • 2022-10-06
      • 2019-10-07
      • 1970-01-01
      相关资源
      最近更新 更多