【问题标题】:Namespace "stuck" as Terminating, How I removed it命名空间“卡住”为终止,我如何删除它
【发布时间】:2019-02-21 11:12:48
【问题描述】:

我删除了一个“卡住”的命名空间,显示在这个永恒的“终止”状态。

【问题讨论】:

  • 你的命名空间是空的吗?

标签: kubernetes namespaces


【解决方案1】:

我发现删除“terminating”命名空间的唯一方法是删除“终结器”部分中的条目。我试过--force 删除它,--grace-period=0 没有一个有效,但是,这个方法有效:

在命令行上显示来自命名空间的信息:

$ kubectl get namespace your-rogue-namespace -o yaml

这将为您提供 yaml 输出,查找与此类似的行:

deletionTimestamp: 2018-09-17T13:00:10Z
  finalizers:
  - Whatever content it might be here...
  labels:

然后只需编辑命名空间配置并删除该终结器容器内的项目。

$ kubectl edit namespace your-rogue-namespace

这将打开一个编辑器(在我的情况下为 VI),越过我要删除的行并将其删除,我按 D 键两次删除整行。

保存它,退出你的编辑器,然后像变魔术一样。 rogue-namespace 应该消失了。

确认一下:

$ kubectl get namespace your-rogue-namespace -o yaml

【讨论】:

  • 这会缩短与命名空间关联的资源的清理工作,并留下与该命名空间关联的孤立资源
  • 可能是指标 API 服务器或服务目录 API 服务器崩溃/丢失,请参阅 JordanLiggitt 和 AntonioGomezAlvarado 的回答
【解决方案2】:

这是由命名空间控制器无法删除的命名空间中仍然存在的资源造成的。

此命令(使用 kubectl 1.11+)将显示命名空间中剩余的资源:

kubectl api-resources --verbs=list --namespaced -o name \
  | xargs -n 1 kubectl get --show-kind --ignore-not-found -n <namespace>

一旦找到并解决并删除它们,命名空间就会被清理

【讨论】:

  • 这表明我的集群上没有资源,我不认为总是解决方案。
  • 但绝对最好先尝试。总是强制删除命名空间不是一个好建议。
  • 我到了这里,但我使用 powershell 作为我的脚本环境(让我恼火的是这不是答案的强制性信息)所以做同样的事情是:kubectl api-resources --verbs=list - -命名空间 -o 名称 | ForEach-Object { kubectl get $_ --show-kind --ignore-not-found -n }
  • Windows Powershell 等效项:Foreach($x in (kubectl api-resources --verbs=list --namespaced -o name)){ kubectl get --show-kind --ignore-not-found -n YOUR_NAMESPACE_HERE $x }
【解决方案3】:

假设您已经尝试强制删除资源,例如: Pods stuck at terminating status,而您则在尝试恢复命名空间...

您可以强制删除命名空间(可能留下悬空资源):

(
NAMESPACE=your-rogue-namespace
kubectl proxy &
kubectl get namespace $NAMESPACE -o json |jq '.spec = {"finalizers":[]}' >temp.json
curl -k -H "Content-Type: application/json" -X PUT --data-binary @temp.json 127.0.0.1:8001/api/v1/namespaces/$NAMESPACE/finalize
)
  • 这是对答案here 的改进,它基于评论here

  • 我正在使用jq 实用程序以编程方式删除终结器部分中的元素。您可以手动执行此操作。

  • kubectl proxy127.0.0.1:8001 创建监听器默认。如果您知道集群主服务器的主机名/IP,则可以改用它。

  • 有趣的是,即使在使用kubectl edit 进行相同的更改时,这种方法似乎也有效。

【讨论】:

  • 这是唯一对我有用的解决方案。 K8s v1.11.5,kubectl v1.8.0。 jq 安装自stedolan.github.io/jq/download
  • 如果您将kubectl edit 解决方案移到顶部会更好,因为它更容易并且做同样的事情,适用于所有对象。
  • 这很糟糕,因为它会在集群中留下剩余的东西。它更像是在欺骗自己,而不是真正解决问题。无法删除命名空间是有原因的,您最好解决这个问题,而不是寻求表面解决方案。
  • @AntonioGomezAlvarado:对。这通常不会是您尝试的第一件事。但是,不幸的是,发现根本问题并不总是那么容易。在某些情况下,恢复命名空间的需要可能是为了让您可以继续完成工作——而不仅仅是装饰。
  • 更好的解决方案 - stackoverflow.com/a/59667608/429476 请选择它作为新集群的答案 -
【解决方案4】:

对我们来说,这是 metrics-server 崩溃。

因此,通过以下运行检查这是否与您的情况相关:kubectl api-resources

如果你得到

error: unable to retrieve the complete list of server APIs: metrics.k8s.io/v1beta1: the server is currently unable to handle the request

那应该是同一个问题

致谢@javierprovecho here

【讨论】:

  • 对我们来说这是一个服务目录 CRD 剩余:servicecatalog.k8s.io/v1beta1: the server is currently unable to handle the request
  • 你是做什么的? @PawełPrażak 删除它?或者我如何找到它?
  • @vonGohren AFAIR 我们删除了它 CR 以解决问题,但我不记得我们是如何解决的,抱歉
  • 您可以部署最新(0.4.1)版本的metrics-server来解决这个问题:kubectl apply -f github.com/kubernetes-sigs/metrics-server/releases/download/…;
  • @vonGohren 那时您确实应该删除该资源。正如另一个答案中提到的那样,运行kubectl api-resources --verbs=list --namespaced -o name \ | xargs -n 1 kubectl get --show-kind --ignore-not-found -n &lt;namespace&gt; 来找到它;然后我用kubectl delete APIService v1beta1.custom.metrics.k8s.io 删除了它
【解决方案5】:

完成nobar 已经很好的回答。如果您使用 Rancher 部署集群,则需要注意。

Rancher 部署会更改每个 api 调用,将 /k8s/clusters/c-XXXXX/ 添加到 URL。

rancher 上的集群 ID (c-XXXXX) 是您可以从 Rancher UI 轻松获取的,因为它会在 URL 上。

所以当你得到集群 ID c-xxxx 后,就按照 nobar 说的做,只是改变 api 调用,包括那个 rancher 位。

(
NAMESPACE=your-rogue-namespace
kubectl proxy &
kubectl get namespace $NAMESPACE -o json |jq '.spec = {"finalizers":[]}' >temp.json
curl -k -H "Content-Type: application/json" \
  -X PUT --data-binary @temp.json \
  127.0.0.1:8001/k8s/clusters/c-XXXXX/api/v1/namespaces/$NAMESPACE/finalize
)

【讨论】:

    【解决方案6】:

    简单的技巧

    您只能在控制台上编辑命名空间 kubectl edit &lt;namespace name&gt;finalizer 部分中删除/删除“Kubernetes”,然后按回车键或保存/应用更改。

    你也可以一步完成。

    技巧:1

    1. kubectl 获取命名空间烦人的命名空间删除 -o json > tmp.json

    2. 然后编辑tmp.json并删除“kubernetes”

    3. 打开另一个终端并运行kubectl proxy

    curl -k -H "Content-Type: application/json" -X PUT --data-binary @tmp.json https://localhost:8001/api/v1/namespaces/&lt;NAMESPACE NAME TO DELETE&gt;/finalize

    它应该删除你的命名空间。

    技巧:2

    检查 kubectl 集群信息

    1. kubectl cluster-info
    

    Kubernetes master 运行在 https://localhost:6443

    KubeDNS 运行于 https://localhost:6443/api/v1/namespaces/kube-system/services/kube-dns:dns/proxy

    要进一步调试和诊断集群问题,请使用

    2. kubectl cluster-info dump

    现在使用命令启动代理:

    3. kubectl proxy

    kubectl 代理 & 开始服务 127.0.0.1:8001

    查找命名空间

    4. `kubectl get ns`
    

    {您的命名空间名称}终止 1d

    放入文件中

    5. kubectl get namespace {Your namespace name} -o json &gt; tmp.json

    编辑文件tmp.json 并删除终结器

    }, "spec": { "finalizers": [ "kubernetes" ] },

    编辑后应该是这样的

    }, "spec": { "finalizers": [ ] },

    我们快到了,现在只需运行命令

    curl -k -H "Content-Type: application/json" -X PUT --data-binary @tmp.json http://127.0.0.1:8001/api/v1/namespaces/{Your namespace name}/finalize
    

    没了

    **

    【讨论】:

    【解决方案7】:

    您可以运行几件事。但这通常意味着,命名空间的自动删除无法完成,并且有一个正在运行的进程必须手动删除。要找到它,您可以执行以下操作:

    获取所有附加到名称空间的 prossesse。如果这没有产生任何结果,请转到下一个建议

    $ kubectl get all -n your-namespace
    

    一些命名空间附加了apisrivces,删除起来可能很麻烦。就此而言,这可以是您想要的任何资源。然后,如果它找到任何东西,你就删除该资源

    $ kubectl get apiservice|grep False
    

    但主要的收获是,可能有一些东西没有被完全删除。因此,您可以查看最初在该命名空间中拥有的内容,然后查看使用 YAML 生成的内容以查看进程。或者你可以开始谷歌为什么不能正确删除服务X,你会发现的。

    【讨论】:

      【解决方案8】:

      正如之前在这个线程中提到的,还有另一种方法可以使用 kubectl 未公开的 API 来终止命名空间,方法是使用 kubectl 的现代版本,其中kubectl replace --raw 可用(不确定来自哪个版本)。这样,您就不必生成 kubectl proxy 进程并避免依赖 curl (在某些环境中,如busybox 不可用)。希望这对其他人有所帮助,我将其留在这里:

      kubectl get namespace "stucked-namespace" -o json \
        | tr -d "\n" | sed "s/\"finalizers\": \[[^]]\+\]/\"finalizers\": []/" \
        | kubectl replace --raw /api/v1/namespaces/stucked-namespace/finalize -f -
      

      【讨论】:

      • 这个在 kubectl 版本 v1.17、k8 v1.16 中为我工作
      • 太棒了。只有当集群中没有节点时对我们有用。
      • 在“tr”上挖掘错误。术语 tr 无法识别。
      • export NS=istio-system && kubectl get namespace "$NS" -o json \ | tr -d "\n" | sed "s/\"终结器\": [[^]]\+]/\"终结器\": []/" \ | kubectl 替换 --raw /api/v1/namespaces/$NS/finalize -f -
      【解决方案9】:
      1. 运行以下命令查看卡在 Terminating 状态的命名空间:

        kubectl 获取命名空间

      2. 选择一个终止命名空间并查看命名空间的内容以找出终结器。运行以下命令:

        kubectl 获取命名空间 -o yaml

      3. 您的 YAML 内容可能类似于以下输出:

              apiVersion: v1
              kind: Namespace
              metadata:
                 creationTimestamp: 2019-12-25T17:38:32Z
                 deletionTimestamp: 2019-12-25T17:51:34Z
                 name: <terminating-namespace>
                 resourceVersion: "4779875"
                 selfLink: /api/v1/namespaces/<terminating-namespace>
                 uid: ******-****-****-****-fa1dfgerz5
               spec:
                 finalizers:
                 - kubernetes
               status:
                 phase: Terminating
      
      1. 运行以下命令创建一个临时 JSON 文件:

        kubectl 获取命名空间 -o json >tmp.json

      2. 编辑您的 tmp.json 文件。从 finalizers 字段中删除 kubernetes 值并保存文件。输出如下:

          {
              "apiVersion": "v1",
              "kind": "Namespace",
              "metadata": {
                  "creationTimestamp": "2018-11-19T18:48:30Z",
                  "deletionTimestamp": "2018-11-19T18:59:36Z",
                  "name": "<terminating-namespace>",
                  "resourceVersion": "1385077",
                  "selfLink": "/api/v1/namespaces/<terminating-namespace>",
                  "uid": "b50c9ea4-ec2b-11e8-a0be-fa163eeb47a5"
              },
              "spec": {
              },
      
              "status": {
                  "phase": "Terminating"
              }
          }
      
      1. 要设置临时代理 IP 和端口,请运行以下命令。在删除卡住的命名空间之前,请务必保持终端窗口打开:

        kubectl 代理

      2. 您的代理 IP 和端口可能类似于以下输出:

        开始服务于 127.0.0.1:8001

      3. 在新的终端窗口中,使用您的临时代理 IP 和端口进行 API 调用:

        curl -k -H "Content-Type: application/json" -X PUT --data-binary @tmp.json http://127.0.0.1:8001/api/v1/namespaces/your_terminating_namespace/finalize
      

      你的输出会是这样的:

          {
             "kind": "Namespace",
             "apiVersion": "v1",
             "metadata": {
               "name": "<terminating-namespace>",
               "selfLink": "/api/v1/namespaces/<terminating-namespace>/finalize",
               "uid": "b50c9ea4-ec2b-11e8-a0be-fa163eeb47a5",
               "resourceVersion": "1602981",
               "creationTimestamp": "2018-11-19T18:48:30Z",
               "deletionTimestamp": "2018-11-19T18:59:36Z"
             },
             "spec": {
      
             },
             "status": {
               "phase": "Terminating"
             }
          }
      
      1. finalizer 参数被移除。现在验证终止命名空间是否已删除,运行以下命令:

        kubectl 获取命名空间

      【讨论】:

        【解决方案10】:

        最简单和最简单的方法是复制这个 bash 脚本

        #!/bin/bash
        
        ###############################################################################
        # Copyright (c) 2018 Red Hat Inc
        #
        # See the NOTICE file(s) distributed with this work for additional
        # information regarding copyright ownership.
        #
        # This program and the accompanying materials are made available under the
        # terms of the Eclipse Public License 2.0 which is available at
        # http://www.eclipse.org/legal/epl-2.0
        #
        # SPDX-License-Identifier: EPL-2.0
        ###############################################################################
        
        set -eo pipefail
        
        die() { echo "$*" 1>&2 ; exit 1; }
        
        need() {
            which "$1" &>/dev/null || die "Binary '$1' is missing but required"
        }
        
        # checking pre-reqs
        
        need "jq"
        need "curl"
        need "kubectl"
        
        PROJECT="$1"
        shift
        
        test -n "$PROJECT" || die "Missing arguments: kill-ns <namespace>"
        
        kubectl proxy &>/dev/null &
        PROXY_PID=$!
        killproxy () {
            kill $PROXY_PID
        }
        trap killproxy EXIT
        
        sleep 1 # give the proxy a second
        
        kubectl get namespace "$PROJECT" -o json | jq 'del(.spec.finalizers[] | select("kubernetes"))' | curl -s -k -H "Content-Type: application/json" -X PUT -o /dev/null --data-binary @- http://localhost:8001/api/v1/namespaces/$PROJECT/finalize && echo "Killed namespace: $PROJECT"
        
        # proxy will get killed by the trap
        

        在 deletenamepsace.sh 文件中添加上述代码。

        然后通过提供命名空间作为参数来执行它(linkerd是我要在这里删除的命名空间)

        ➜ kubectl get namespaces
        linkerd           Terminating   11d
        
        ➜ sh deletenamepsace.sh linkerd
        Killed namespace: linkerd
        
        ➜ kubectl get namespaces
        
        

        以上提示对我有用。

        老实说,我认为 kubectl 删除命名空间 mynamespace --grace-period=0 --force 根本不值得尝试。

        特别感谢 Jens Reimann!我认为这个脚本应该包含在 kubectl 命令中。

        【讨论】:

        • 肯定复制了这里的解决方案
        【解决方案11】:

        解决方案:

        第 1 步:在一个终端中运行以下命令:

        kubectl 代理

        第 2 步:打开另一个终端,然后将描述符作为 JSON 转储到文件中

        kubectl 获取命名空间 YOURNAMESPACE -o json > logging.json

        使用文本编辑器打开文件:

        {
            "apiVersion": "v1",
            "kind": "Namespace",
            "metadata": {
                "creationTimestamp": "2019-05-14T13:55:20Z",
                "labels": {
                    "name": "logging"
                },
                "name": "logging",
                "resourceVersion": "29571918",
                "selfLink": "/api/v1/namespaces/logging",
                "uid": "e9516a8b-764f-11e9-9621-0a9c41ba9af6"
            },
            "spec": {
                "finalizers": [
                    **"kubernetes"**
                ]
            },
            "status": {
                "phase": "Terminating"
            }
        }
        

        删除终结器数组的内容并将其留空,如下例所示:

            {
                "apiVersion": "v1",
                "kind": "Namespace",
                "metadata": {
                    "creationTimestamp": "2019-05-14T13:55:20Z",
                    "labels": {
                        "name": "logging"
                    },
                    "name": "logging",
                    "resourceVersion": "29571918",
                    "selfLink": "/api/v1/namespaces/logging",
                    "uid": "e9516a8b-764f-11e9-9621-0a9c41ba9af6"
                },
                "spec": {
                    "finalizers": [
                    ]
                },
                "status": {
                    "phase": "Terminating"
                }
            }
        

        第 3 步:执行清理命令以摆脱烦人的命名空间:

        curl -k -H "Content-Type: application/json" -X PUT --data-binary @logging.json http://127.0.0.1:8001/api/v1/namespaces/YOURNAMESPACE/finalize
        

        享受

        【讨论】:

        • 不是最好的主意。这很可能会留下一些悬空资源,导致最初的终止问题。
        【解决方案12】:

        运行kubectl get apiservice

        对于上述命令,您将找到一个带有 Available Flag=Flase 的 apiservice。

        所以,只需使用 kubectl delete apiservice &lt;apiservice name&gt; 删除该 apiservice

        完成此操作后,终止状态的命名空间将消失。

        【讨论】:

        • 在我的情况下,所有都是 Available=True,所以这无济于事(至少并非总是如此)
        • 使用其他描述的方法得到 404。这解决了我的问题
        【解决方案13】:
        curl -k -H "Content-Type: application/json" -X PUT --data-binary @tmp.json 127.0.0.1:8001/k8s/clusters/c-mzplp/api/v1/namespaces/rook-ceph/finalize
        

        这对我有用,命名空间消失了。

        详细解释可以在链接https://github.com/rook/rook/blob/master/Documentation/ceph-teardown.md找到。

        这发生在我中断 kubernetes 安装(Armory Minnaker)时。然后我继续删除命名空间并重新安装它。由于终结器,我被困在终止状态的 pod 中。我将命名空间放入 tmp.json,从 tmp.json 文件中删除了终结器并执行了 curl 命令。 一旦我解决了这个问题,我使用脚本卸载集群以删除残留物并重新安装。

        【讨论】:

        • 也许您想分解您的 URL 并解释发生了什么?
        【解决方案14】:

        需要删除 Kubernetes 的终结器。

        第 1 步:

        kubectl get namespace <YOUR_NAMESPACE> -o json > <YOUR_NAMESPACE>.json
        
        • 从规范中的终结器数组中删除 kubernetes

        第 2 步:

        kubectl replace --raw "/api/v1/namespaces/<YOUR_NAMESPACE>/finalize" -f ./<YOUR_NAMESPACE>.json
        

        第 3 步:

        kubectl get namespace
        

        你可以看到烦人的命名空间不见了。

        【讨论】:

        • 我缺少这个命名空间 api。有办法安装吗?
        • 这也可以通过kubectl edit &lt;stuck_resource&gt; 来实现,并删除“finalizers”列表中的项目。这样做的好处是可以在不知道它们的api路径的情况下删除其他卡住的资源。我用它来删除一个顽固的 CRD。
        • 您还可以使用基于 ui 的工具,例如 Lens,这使得执行/访问这些任务/信息以及许多其他任务/信息变得非常容易。
        【解决方案15】:

        我根据@Shreyangi Saxena 的解决方案编写了简单的脚本来删除您的卡住命名空间。

        cat > delete_stuck_ns.sh << "EOF"
        #!/usr/bin/env bash
        
        function delete_namespace () {
            echo "Deleting namespace $1"
            kubectl get namespace $1 -o json > tmp.json
            sed -i 's/"kubernetes"//g' tmp.json
            kubectl replace --raw "/api/v1/namespaces/$1/finalize" -f ./tmp.json
            rm ./tmp.json
        }
        
        TERMINATING_NS=$(kubectl get ns | awk '$2=="Terminating" {print $1}')
        
        for ns in $TERMINATING_NS
        do
            delete_namespace $ns
        done
        EOF
        
        chmod +x delete_stuck_ns.sh
        

        此脚本可以检测到所有Terminating状态的命名空间,并将其删除。


        PS:

        • 这可能不适用于 MacOS,因为 macOS 中的原生 sed 与 GNU sed 不兼容。

          您可能需要在您的 MacOS 中安装 GNU sed,请参阅 this answer

        • 请确认您可以通过命令kubectl访问您的kubernetes集群。

        • 已经在kubernetes版本v1.15.3测试过


        更新

        我找到了一个更简单的解决方案:

        kubectl patch RESOURCE NAME -p '{"metadata":{"finalizers":[]}}' --type=merge
        

        【讨论】:

        • 一个非常好的、简单且有效的解决方案。干得好,谢谢!
        【解决方案16】:

        我的问题是由自定义指标引起的。

        要知道是什么导致了痛苦,只需运行以下命令:

        kubectl api-resources | grep -i false
        

        这应该会告诉你是哪些 api 资源导致了问题,一旦确定就删除它

        kubectl delete apiservice v1beta1.custom.metrics.k8s.io
        

        命名空间一旦删除就会消失

        【讨论】:

        • false 在我的情况下是小写的。所以也许:kubectl api-resources | grep -i false
        【解决方案17】:

        我喜欢从here 中提取的这个答案 它只有 2 个命令。

        在一个终端中:

        kubectl proxy
        

        在另一个终端:

        kubectl get ns delete-me -o json | \
          jq '.spec.finalizers=[]' | \
          curl -X PUT http://localhost:8001/api/v1/namespaces/delete-me/finalize -H "Content-Type: application/json" --data @-
        

        【讨论】:

        • 我在这里尝试了一些,这是第一个有效的 - 谢谢!
        • 删除终结者可能会导致以后未注册的挂起资源。
        • 这对我有用
        【解决方案18】:

        在我的情况下发生了类似的事情,它是 pv 和 pvc ,我通过将终结器设置为 null 来强行删除它。检查你是否可以用 ns 做类似的事情

        kubectl patch pvc <pvc-name> -p '{"metadata":{"finalizers":null}}'
        

        对于命名空间,它会是

        kubectl patch ns <ns-name> -p '{"spec":{"finalizers":null}}'
        

        【讨论】:

          【解决方案19】:

          我已经根据此处的常见答案编写了一个单行 Python3 脚本。此脚本会删除有问题的命名空间中的 finalizers

          python3 -c "namespace='<my-namespace>';import atexit,subprocess,json,requests,sys;proxy_process = subprocess.Popen(['kubectl', 'proxy']);atexit.register(proxy_process.kill);p = subprocess.Popen(['kubectl', 'get', 'namespace', namespace, '-o', 'json'], stdout=subprocess.PIPE);p.wait();data = json.load(p.stdout);data['spec']['finalizers'] = [];requests.put('http://127.0.0.1:8001/api/v1/namespaces/{}/finalize'.format(namespace), json=data).raise_for_status()"
          

          ? 用你的命名空间重命名namespace='&lt;my-namespace&gt;'。 例如namespace='trust'


          完整脚本:https://gist.github.com/jossef/a563f8651ec52ad03a243dec539b333d

          【讨论】:

          • 这成功了!我终于能够移除卡住的命名空间了!
          • 哇,在其他一些方法不起作用之后,包括自己通过编辑删除终结器!谢谢!
          • 这成功了!我终于能够移除卡住的命名空间了!
          【解决方案20】:

          强行删除命名空间或删除终结器绝对不是可行的方法,因为它可能会将资源注册到不存在的命名空间。

          这通常很好,但有一天您将无法创建资源,因为它仍然悬在某处。

          即将推出的 Kubernetes 1.16 版应该会提供更多关于命名空间终结器的见解,目前我将依赖识别策略。 一个很酷的脚本试图自动化这些是:https://github.com/thyarles/knsk

          但是,它适用于所有命名空间,并且可能很危险。它基于的解决方案是:https://github.com/kubernetes/kubernetes/issues/60807#issuecomment-524772920

          tl;博士

          1. 检查是否有任何 apiservice 不可用,因此不提供其资源:kubectl get apiservice|grep False
          2. 通过kubectl api-resources --verbs=list --namespaced -o name | xargs -n 1 kubectl get -n $your-ns-to-delete查找仍然存在的所有资源

          (信用:https://github.com/kubernetes/kubernetes/issues/60807#issuecomment-524772920

          【讨论】:

          • 同意,绝对不是要走的路。卡住删除最常见的原因是某些资源没有被正确删除,从而阻塞了命名空间终止。检查并删除它们,命名空间最终将被删除。值得一提的是,卡在“终止”中的命名空间会阻止另一个命名空间的删除。至少这是发生在我身上的事情,看起来在 GKE 中删除是连续的。
          【解决方案21】:

          如果命名空间卡在 Terminating 而该命名空间中的资源已经被删除,您可以在删除之前修补命名空间的 finalizers

          kubectl patch ns ns_to_be_deleted -p '{"metadata":{"finalizers":null}}';
          

          然后

          kubectl delete ns ns_to_be_deleted;
          

          编辑:

          请先查看@Antonio Gomez Alvarado 的回答。根本原因可能是那个答案中提到的metrics server

          【讨论】:

            【解决方案22】:
            kubectl edit namespace ${stucked_namespace}
            

            然后在vi模式下删除finalizers并保存。

            它在我的情况下有效。

            【讨论】:

              【解决方案23】:

              请尝试以下命令:

              kubectl patch ns <your_namespace> -p '{"metadata":{"finalizers":null}}'
              

              【讨论】:

              • 点评来源: Stack Overflow 不鼓励仅使用命令/代码的答案,因为它们没有解释它是如何解决问题的。请编辑您的答案以解释此代码的作用以及它如何回答问题,以便它对 OP 以及其他有类似问题的用户有用。请参阅:How do I write a good answer?。谢谢
              • 只有这个对我有用。没有其他解决方案使用 POST json 来完成 api 工作。
              【解决方案24】:

              编辑: 不建议删除终结器。 正确的做法是:

              • 删除命名空间中的所有资源。

              Github issue link

              我常用的工作区是一个小型 k8s 集群,我经常将其销毁并重建回来,这就是为什么删除终结器方法对我有用。

              原答案:我经常遇到同样的问题。

              这就是我的工作

              kubectl get ns your-namespace -o json > ns-without-finalizers.json
              

              编辑 ns-without-finalizers.json。用空数组替换所有终结器。

              运行 kubectl 代理(通常在另一个终端上运行)

              然后 curl 这个命令

              curl -X PUT http://localhost:8001/api/v1/namespaces/your-namespace/finalize -H "Content-Type: application/json" --data @ns-without-finalizers.json
              

              【讨论】:

                【解决方案25】:

                用你的命名空间替换大使

                检查命名空间是否卡住

                kubectl get ns ambassador
                
                NAME         STATUS        AGE
                ambassador   Terminating   110d
                

                这个卡很久了

                打开管理终端/cmd 提示符或 powershell 并运行

                kubectl 代理

                这将启动一个本地网络服务器:Starting to serve on 127.0.0.1:8001

                打开另一个终端并运行

                kubectl get ns ambassador -o json >tmp.json
                

                使用 vi 或 nano 编辑 tmp.json

                从这里

                {
                "apiVersion": "v1",
                "kind": "Namespace",
                "metadata": {
                    "annotations": {
                        "kubectl.kubernetes.io/last-applied-configuration": "{\"apiVersion\":\"v1\",\"kind\":\"Namespace\",\"metadata\":{\"annotations\":{},\"name\":\"ambassador\"}}\n"
                    },
                    "creationTimestamp": "2021-01-07T18:23:28Z",
                    "deletionTimestamp": "2021-04-28T06:43:41Z",
                    "name": "ambassador",
                    "resourceVersion": "14572382",
                    "selfLink": "/api/v1/namespaces/ambassador",
                    "uid": "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
                },
                "spec": {
                    "finalizers": [
                        "kubernetes"
                    ]
                },
                "status": {
                    "conditions": [
                        {
                            "lastTransitionTime": "2021-04-28T06:43:46Z",
                            "message": "Discovery failed for some groups, 3 failing: unable to retrieve the complete list of server APIs: compose.docker.com/v1alpha3: an error on the server (\"Internal Server Error: \\\"/apis/compose.docker.com/v1alpha3?timeout=32s\\\": Post https://0.0.0.1:443/apis/authorization.k8s.io/v1beta1/subjectaccessreviews: write tcp 0.0.0.0:53284-\u0026gt;0.0.0.0:443: write: broken pipe\") has prevented the request from succeeding, compose.docker.com/v1beta1: an error on the server (\"Internal Server Error: \\\"/apis/compose.docker.com/v1beta1?timeout=32s\\\": Post https://10.96.0.1:443/apis/authorization.k8s.io/v1beta1/subjectaccessreviews: write tcp 0.0.0.0:5284-\u0026gt;10.96.0.1:443: write: broken pipe\") has prevented the request from succeeding, compose.docker.com/v1beta2: an error on the server (\"Internal Server Error: \\\"/apis/compose.docker.com/v1beta2?timeout=32s\\\": Post https://0.0.0.0:443/apis/authorization.k8s.io/v1beta1/subjectaccessreviews: write tcp 1.1.1.1:2284-\u0026gt;0.0.0.0:443: write: broken pipe\") has prevented the request from succeeding",
                            "reason": "DiscoveryFailed",
                            "status": "True",
                            "type": "NamespaceDeletionDiscoveryFailure"
                        },
                        {
                            "lastTransitionTime": "2021-04-28T06:43:49Z",
                            "message": "All legacy kube types successfully parsed",
                            "reason": "ParsedGroupVersions",
                            "status": "False",
                            "type": "NamespaceDeletionGroupVersionParsingFailure"
                        },
                        {
                            "lastTransitionTime": "2021-04-28T06:43:49Z",
                            "message": "All content successfully deleted",
                            "reason": "ContentDeleted",
                            "status": "False",
                            "type": "NamespaceDeletionContentFailure"
                        }
                    ],
                    "phase": "Terminating"
                }
                

                }

                    {
                  "apiVersion": "v1",
                  "kind": "Namespace",
                  "metadata": {
                    "annotations": {
                      "kubectl.kubernetes.io/last-applied-configuration": "{\"apiVersion\":\"v1\",\"kind\":\"Namespace\",\"metadata\":{\"annotations\":{},\"name\":\"ambassador\"}}\n"
                    },
                    "creationTimestamp": "2021-01-07T18:23:28Z",
                    "deletionTimestamp": "2021-04-28T06:43:41Z",
                    "name": "ambassador",
                    "resourceVersion": "14572382",
                    "selfLink": "/api/v1/namespaces/ambassador",
                    "uid": "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
                  },
                  "spec": {
                    "finalizers": []
                  }
                }
                

                通过删除终结器中的状态和 kubernetes

                现在使用命令并将大使替换为您的命名空间

                curl -k -H "Content-Type: application/json" -X PUT --data-binary @tmp.json http://127.0.0.1:8001/api/v1/namespaces/ambassador/finalize
                

                你会看到另一个像之前一样的 json 然后运行

                然后运行命令

                 kubectl get ns ambassador
                Error from server (NotFound): namespaces "ambassador" not found
                

                如果它仍然显示终止或任何其他错误,请确保您以正确的方式格式化您的 json,然后重试这些步骤。

                【讨论】:

                  【解决方案26】:

                  调试一个类似的问题。

                  需要考虑的两个重要事项:

                  1 ) 在从您的命名空间中删除 finalizers 之前请三思,因为您可能不想自动删除某些资源,或者至少了解为排除故障而删除的内容。

                  2 ) 像 kubectl api-resources --verbs=list 这样的命令可能不会为您提供由外部 crds 创建的资源。


                  就我而言:

                  我使用kubectl edit ns &lt;ns-name&gt;status -&gt; conditions 查看了我的命名空间真实状态(卡在Terminating),我看到我安装的一些外部crd 未能删除,因为它们添加了finalizers 定义:

                   - lastTransitionTime: "2021-06-14T11:14:47Z"
                      message: 'Some content in the namespace has finalizers remaining: finalizer.stackinstall.crossplane.io
                        in 1 resource instances, finalizer.stacks.crossplane.io in 1 resource instances'
                      reason: SomeFinalizersRemain
                      status: "True"
                      type: NamespaceFinalizersRemaining
                  

                  【讨论】:

                    猜你喜欢
                    • 2021-04-16
                    • 2020-09-26
                    • 1970-01-01
                    • 1970-01-01
                    • 1970-01-01
                    • 2014-12-11
                    • 2023-02-07
                    • 1970-01-01
                    • 1970-01-01
                    相关资源
                    最近更新 更多