【问题标题】:kubectl patch: Is it possible to add multiple values to an array within a sinlge patch executionkubectl patch:是否可以在单个补丁执行中向数组添加多个值
【发布时间】:2020-06-25 15:21:48
【问题描述】:

我尝试使用kubectl patch 将另外两个值添加到 kubernetes 部署的 args 列表中。我已经查看了官方记录的 (https://kubernetes.io/docs/tasks/manage-kubernetes-objects/update-api-object-kubectl-patch/) 变体,但没有设法一次附加多个值。

假设这个简单的部署:

apiVersion: apps/v1
kind: Deployment
metadata:
  name: test
spec:
  replicas: 1
  selector:
    matchLabels:
      name: test
  template:
    metadata:
      labels:
        name: test
      name: test
    spec:
      containers:
      - image: alpine
        name: test
        command:
        - echo
        args:
        - my
        - text

我现在想将其他值附加到 args 部分。这一次只适用于一个值:

添加一个附加值

kubectl patch deployments.apps test --type=json -p='[{"op": "add", "path": "/spec/t
emplate/spec/containers/0/args/-", "value": "additional" }]'

这行得通,给我留下了以下内容:

...
        args:
        - my
        - text
        - additional

但是使用一组值运行补丁会给我一个错误:

# running:
k patch deployments.apps test --type=json -p='[{"op": "add", "path": "/spec/template/spec/containers/0/args/-", "value": ["additional","text"] }]'

# results in:
The request is invalid: patch: Invalid value: "...": v1.Deployment.Spec: v1.DeploymentSpec.Template: v1.PodTemplateSpec.Spec: v1.PodSpec.Containers: []v1.Container: v1.Container.Args: []string: ReadString: expects " or n, but found [, error found in #10 byte of ...|itional",["additiona|..., bigger context ...|{"containers":[{"args":["my","text","additional",["additional","text"]],"command":["echo"],"image":"|...

有谁知道在单个补丁命令中将多个值添加到数组而不覆盖整个 args 数组的方法?感谢您的帮助。

【问题讨论】:

  • jsonpatch 不支持向数组添加多个值。可以在补丁数组中使用多个“add”语句来添加多个值。
  • 根据github.com/kubernetes/kubernetes/issues/…,可能可以在单个补丁中添加多个值,但是,在修补争论的情况下,我不太确定如何实现。

标签: json kubernetes patch


【解决方案1】:

以下使用单个补丁,但不是很干燥:

kubectl patch deployment <deployment-name> -n <namespace> --type "json" -p '[
{"op":"add","path":"/spec/template/spec/containers/0/args/-","value":"arg-1"},
{"op":"add","path":"/spec/template/spec/containers/0/args/-","value":"arg-2"},
{"op":"add","path":"/spec/template/spec/containers/0/args/-","value":"arg-3"}]'

我一直在为 cert-manager 做类似的事情以允许全自动 TLS:

kubectl patch deployment cert-manager -n cert-manager --type "json" -p '[
{"op":"add","path":"/spec/template/spec/containers/0/args/-","value":"--default-issuer-name=letsencrypt-prod"},
{"op":"add","path":"/spec/template/spec/containers/0/args/-","value":"--default-issuer-kind=ClusterIssuer"},
{"op":"add","path":"/spec/template/spec/containers/0/args/-","value":"--default-issuer-group=cert-manager.io"}]'

【讨论】:

  • 这是恕我直言的正确答案。不幸的是,在一般情况下,这是不可能的 - 没有办法附加到尚不存在的列表或嵌套在可选对象中的列表。例如,似乎不可能在单个 json/strategic merge/... 补丁中添加节点亲和性术语,除非已经存在节点亲和性术语。
【解决方案2】:

我发现的最简单的方法是使用jq 来编辑json,而不是:

kubectl patch deployment <deployment-name> -n <namespace> --type "json" -p '[
{"op":"add","path":"/spec/template/spec/containers/0/args/-","value":"arg-1"},
{"op":"add","path":"/spec/template/spec/containers/0/args/-","value":"arg-2"},
{"op":"add","path":"/spec/template/spec/containers/0/args/-","value":"arg-3"}]'

你可以使用:

kubectl get deployment <deployment-name> -n <namespace> -o json \
  | jq '.spec.template.spec.containers[0].args += ["arg-1", "arg-2", "arg-3"]'  \
  | kubectl apply -f -

这有一个优点:它允许注入对象,例如修补权限。示例(taken from the requirements for upgrading coredns to 1.8.3):

kubectl get clusterrole system:coredns -n kube-system -o json \
  | jq '.rules += [{"apiGroups":["discovery.k8s.io"],"resources":["endpointslices"],"verbs":["list","watch"]}]' \
  | kubectl apply -f -

【讨论】:

    【解决方案3】:

    您可以使用kubectl edit 命令来编辑资源。
    用法示例:
    kubectl edit deploy &lt;deployment_name&gt;

    更多信息,请参考:https://kubernetes.io/docs/reference/generated/kubectl/kubectl-commands#edit

    编辑:以编程方式执行此操作有一种令人讨厌的方式。您可以通过管道将 yaml 传输到 python,更改要更改的值并应用新的 yaml。在你的情况下,它会是这样的,

    kubectl get deploy &lt;deploy_name&gt; -o yaml | python -c 'import sys,yaml; yml = yaml.safe_load(sys.stdin); yml["spec"]["template"]["spec"]["containers"][0]["args"].extend(["newValue1", "newValue2"]); print(yaml.dump(yml));' | kubectl apply -f -

    显然,只有在没有更简单的方法时,您才想这样做。

    【讨论】:

    • 我知道,但我想以编程方式执行此操作,因此我尝试使用 patch
    猜你喜欢
    • 2020-05-08
    • 2019-01-12
    • 2017-05-07
    • 1970-01-01
    • 2021-04-29
    • 1970-01-01
    • 1970-01-01
    • 2019-12-09
    • 1970-01-01
    相关资源
    最近更新 更多