【问题标题】:How to remove a label from a kubernetes object just with "kubectl apply -f file.yaml"?如何仅使用“kubectl apply -f file.yaml”从 kubernetes 对象中删除标签?
【发布时间】:2020-07-13 09:25:59
【问题描述】:

我在 Redhat Openshift 中使用 GitOps 和 ArgoCD。我的目标是将工作节点切换到基础节点。

我想使用描述性 YAML 文件来执行此操作,而不是使用命令行手动执行此操作(使用 kubectl label node 很容易...)

为了使节点成为基础设施节点,我想添加一个标签“基础设施”并从中获取标签“工人”。之前,对象看起来像这样(省略了不相关的标签):

apiVersion: v1
kind: Node
metadata:
  labels:
    node-role.kubernetes.io/infra: ""
  name: node6.example.com
spec: {}

应用 YAML 文件后,它应该如下所示:

apiVersion: v1
kind: Node
metadata:
  labels:
    node-role.kubernetes.io/worker: ""
  name: node6.example.com
spec: {}

如果我将后一个配置放在一个文件中,并执行“kubectl apply -f”,则该节点同时具有 infra 和 worker 标签。所以添加标签或更改标签的值很容易,但是有没有办法通过应用 YAML 文件来删除对象元数据中的标签?

【问题讨论】:

  • 我认为更改节点上的标签而不是为基础设施节点创建新的 MachineSet 不是一个好主意。

标签: kubernetes yaml label openshift argocd


【解决方案1】:

你可以删除标签

kubectl label node node6.example.com node-role.kubernetes.io/infra-

您可以使用新标签再次运行kubectl apply。 您将启动并运行。

【讨论】:

    【解决方案2】:

    我会说这不可能与kubectl apply 有关,至少我尝试过但找不到任何相关信息。

    正如@Petr Kotas 所说,您可以随时使用

    kubectl label node node6.example.com node-role.kubernetes.io/infra-
    

    但我看到你正在寻找其他东西

    我想使用描述性 YAML 文件来执行此操作,而不是使用命令行手动执行此操作(使用 kubectl label node 很容易...)


    所以也许答案是使用 API 客户端,例如python?我找到了这个例子here,由@Prafull Ladha 制作

    如前所述,正确的 kubectl 示例删除标签,但没有提及使用 API 客户端删除标签。如果要使用 API 删除标签,则需要提供一个带有 labelname: None 的新主体,然后将该主体修补到节点或 pod。我正在使用 kubernetes python 客户端 API 作为示例目的

    from pprint import pprint
    from kubernetes import client, config
    
    config.load_kube_config()
    client.configuration.debug = True
    
    api_instance = client.CoreV1Api()
    
    body = {
        "metadata": {
            "labels": {
                "label-name": None}
            }
    }
    
    api_response = api_instance.patch_node("minikube", body)
    
    print(api_response)
    

    【讨论】:

      【解决方案3】:

      尝试将worker标签设置为false:

      node-role.kubernetes.io/worker: "false"
      

      在 OpenShift 4.4 上为我工作。

      编辑: 这行不通。发生的事情是:

      • 应用的 YML 文件包含 node-role.kubernetes.io/worker: "false"
      • 自动进程运行从节点删除 node-role.kubernetes.io/worker 标签(由于未在 YML 中指定它会自动应用)

      有趣的是,如果标签为空而不是设置为 false,自动化过程不会删除标签。

      【讨论】:

        【解决方案4】:

        我已经非常成功地使用kubectl replacekubectl apply 更改了我的Kubernetes 集群(使用kubeadm 创建)中的节点标签。

        必需:如果您的节点配置是使用命令式命令(如 kubectl label)手动更改的,则需要使用以下命令修复 last-applied-configuration 注释(将 node2 替换为您的节点名称):

        kubectl get node node2 -o yaml | kubectl apply -f -
        

        注意:它对所有类型的 Kubernetes 对象的工作方式相同(结果略有不同。请始终检查结果)。

        注意 2kubectl get--export 参数已弃用,没有它也可以正常工作,但如果使用它,last-applied-configuration 注释似乎更短且更易于阅读。

        在不应用现有配置的情况下,下一个kubectl apply 命令将忽略last-applied-configuration 注释中不存在的所有字段。
        以下示例说明behavior

        kubectl get node node2 -o yaml | grep node-role 
        
          {"apiVersion":"v1","kind":"Node","metadata":{"annotations":{"flannel.alpha.coreos.com/backend-data":"{\"VtepMAC\":\"46:c6:d1:f0:6c:0a\"}","flannel.alpha.coreos.com/backend-type":"vxlan","flannel.alpha.coreos.com/kube-subnet-manager":"true","flannel.alpha.coreos.com/public-ip":"10.156.0.11","kubeadm.alpha.kubernetes.io/cri-socket":"/var/run/dockershim.sock","node.alpha.kubernetes.io/ttl":"0","volumes.kubernetes.io/controller-managed-attach-detach":"true"},"creationTimestamp":null,  
        "labels":{  
         "beta.kubernetes.io/arch":"amd64", 
         "beta.kubernetes.io/os":"linux",
         "kubernetes.io/arch":"amd64",
         "kubernetes.io/hostname":"node2",
         "kubernetes.io/os":"linux",
         "node-role.kubernetes.io/worker":""},          # <--- important line: only worker label is present
         "name":"node2","selfLink":"/api/v1/nodes/node2"},"spec":{"podCIDR":"10.244.2.0/24"},"status":{"daemonEndpoints":{"kubeletEndpoint":{"Port":0}},"nodeInfo":{"architecture":"","bootID":"","containerRuntimeVersion":"","kernelVersion":"","kubeProxyVersion":"","kubeletVersion":"","machineID":"","operatingSystem":"","osImage":"","systemUUID":""}}}
        node-role.kubernetes.io/santa: ""
        node-role.kubernetes.io/worker: ""
        

        如果我尝试用 infra 替换 worker 并删除 santa,让我们检查 node-role.kubernetes.io/santa 标签发生了什么,( worker 存在于注解中):

        # kubectl diff is used to comare the current online configuration, and the configuration as it would be if applied
        kubectl get node node2 -o yaml | sed 's@node-role.kubernetes.io/worker: ""@node-role.kubernetes.io/infra: ""@' | sed 's@node-role.kubernetes.io/santa: ""@@'| kubectl diff -f -
        
        diff -u -N /tmp/LIVE-380689040/v1.Node..node2 /tmp/MERGED-682760879/v1.Node..node2
        --- /tmp/LIVE-380689040/v1.Node..node2   2020-04-08 17:20:18.108809972 +0000
        +++ /tmp/MERGED-682760879/v1.Node..node2 2020-04-08 17:20:18.120809972 +0000
        @@ -18,8 +18,8 @@
             kubernetes.io/arch: amd64
             kubernetes.io/hostname: node2
             kubernetes.io/os: linux
        +    node-role.kubernetes.io/infra: ""         # <-- created as desired
             node-role.kubernetes.io/santa: ""         # <-- ignored, because the label isn't present in the last-applied-configuration annotation
        -    node-role.kubernetes.io/worker: ""        # <-- removed as desired
           name: node2
           resourceVersion: "60973814"
           selfLink: /api/v1/nodes/node2
        exit status 1
        

        修复注释后(通过运行 kubectl get node node2 -o yaml | kubectl apply -f - ),kubectl apply 可以很好地替换和删除标签:

        kubectl get node node2 -o yaml | sed 's@node-role.kubernetes.io/worker: ""@node-role.kubernetes.io/infra: ""@' | sed 's@node-role.kubernetes.io/santa: ""@@'| kubectl diff -f -
        
        diff -u -N /tmp/LIVE-107488917/v1.Node..node2 /tmp/MERGED-924858096/v1.Node..node2
        --- /tmp/LIVE-107488917/v1.Node..node2   2020-04-08 18:01:55.776699954 +0000
        +++ /tmp/MERGED-924858096/v1.Node..node2 2020-04-08 18:01:55.792699954 +0000
        @@ -18,8 +18,7 @@
             kubernetes.io/arch: amd64
             kubernetes.io/hostname: node2
             kubernetes.io/os: linux
        -    node-role.kubernetes.io/santa: ""         # <-- removed as desired
        -    node-role.kubernetes.io/worker: ""        # <-- removed as desired, literally replaced with the following label
        +    node-role.kubernetes.io/infra: ""         # <-- created as desired
           name: node2
           resourceVersion: "60978298"
           selfLink: /api/v1/nodes/node2
        exit status 1
        

        这里还有几个例子:

        # Check the original label ( last filter removes last applied config annotation line)
        $ kubectl get node node2 -o yaml | grep node-role | grep -v apiVersion
            node-role.kubernetes.io/infra: ""
        
        # Replace the label "infra" with "worker" using kubectl replace syntax
        $ kubectl get node node2 -o yaml | sed 's@node-role.kubernetes.io/infra: ""@node-role.kubernetes.io/worker: ""@' | kubectl replace -f -
        node/node2 replaced
        
        # check the new state of the label
        $ kubectl get node node2 -o yaml | grep node-role | grep -v apiVersion
            node-role.kubernetes.io/worker: ""
        # label replaced     -------^^^^^^
        
        # Replace the label "worker" back to "infra" using kubectl apply syntax
        $ kubectl get node node2 -o yaml | sed 's@node-role.kubernetes.io/worker: ""@node-role.kubernetes.io/infra: ""@' | kubectl apply -f -
        node/node2 configured
        
        # check the new state of the label
        $ kubectl get node node2 -o yaml | grep node-role | grep -v apiVersion
            node-role.kubernetes.io/infra: ""  
        # label replaced     -------^^^^^
        
        # Remove the label from the node ( for demonstration purpose)
        $ kubectl get node node2 -o yaml | sed 's@node-role.kubernetes.io/infra: ""@@' | kubectl apply -f -
        node/node2 configured
        
        # check the new state of the label
        $ kubectl get node node2 -o yaml | grep node-role | grep -v apiVersion
        # empty output
        # label "infra" has been removed
        

        当您第一次在使用命令式命令(如 kubectl createkubectl expose)创建的资源上使用 kubectl apply -f 时,您可能会看到以下警告:

        Warning: kubectl apply should be used on resource created by either kubectl create --save-config or kubectl apply
        

        在这种情况下,last-applied-configuration 注释将使用kubectl apply -f filename.yaml 命令中使用的文件内容创建。它可能不包含活动对象中存在的所有参数和标签。

        【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2019-04-09
        • 1970-01-01
        • 1970-01-01
        • 2021-03-27
        • 2019-01-03
        • 1970-01-01
        • 2020-06-14
        • 1970-01-01
        相关资源
        最近更新 更多