2

我在 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”,则该节点同时具有基础设施和工作人员标签。所以添加标签或更改标签的值很容易,但是有没有办法通过应用 YAML 文件来删除对象元数据中的标签?

4

4 回答 4

1

你可以删除标签

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

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

于 2020-04-02T05:08:47.127 回答
0

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

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

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

注意:它适用于所有类型的 Kubernetes 对象(结果略有不同。始终检查结果)。

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

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

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: ""

node-role.kubernetes.io/santa如果我尝试用infra替换worker并删除santa ,让我们检查一下 label 发生了什么,(注释中存在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 apply -f当您对使用命令式命令(例如kubectl createkubectl expose第一次)创建的资源使用时,您可能会看到以下警告:

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它可能不包含活动对象中存在的所有参数和标签。

于 2020-04-06T16:22:44.123 回答
0

我会说这是不可能的kubectl apply,至少我试过了,但找不到任何关于它的信息。

正如@Petr Kotas 提到的,您可以随时使用

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

但我看到你在寻找别的东西

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


所以也许答案可能是使用 API 客户端,例如python?我在这里找到了这个例子,由@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)
于 2020-04-02T07:12:43.067 回答
0

尝试将工人标签设置为 false:

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

在 OpenShift 4.4 上为我工作。

编辑: 这不起作用。发生的事情是:

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

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

于 2020-05-29T08:13:03.590 回答