命名空间“卡住”为终止,我如何删除它

时间:2018-09-17 13:45:49

标签: kubernetes namespaces

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

26 个答案:

答案 0 :(得分:13)

如本线程中之前所述,通过使用现代版本的kubectl(其中不确定{{1})可用(不确定哪个版本),存在另一种方法来使用kubectl未公开的API终止名称空间。这样,您将不必生成kubectl replace --raw进程,并避免对curl的依赖(在某些环境下,例如busybox不可用)。希望对其他人有帮助,我在这里离开了这里

kubectl proxy

答案 1 :(得分:8)

需要删除kubernetes的终结器。

步骤1:

kubectl get namespace <YOUR_NAMESPACE> -o json > <YOUR_NAMESPACE>.json
  • 从符合规范的finalizers数组中删除kubernetes

第2步:

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

第3步:

kubectl get namespace

您会看到讨厌的名称空间消失了。

答案 2 :(得分:6)

假设您已经尝试强制删除以下资源: 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 proxy默认在127.0.0.1:8001 处创建侦听器。如果知道群集主服务器的主机名/ IP,则可以使用它。

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

答案 3 :(得分:6)

对我们来说,这是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

答案 4 :(得分:4)

  1. 运行以下命令以查看处于“终止”状态的名称空间:

    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文件。从终结器字段中删除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. 终结器参数已删除。现在验证终止名称空间是否已删除,运行以下命令:

    kubectl获取名称空间

答案 5 :(得分:3)

步骤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"
    }
}

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

    {
        "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步:执行cleanup命令以摆脱烦人的命名空间:

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

享受

答案 6 :(得分:3)

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

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

即将到来的Kubernetes版本1.16应该可以更深入地了解名称空间终结器,因为现在我将依靠标识策略。 尝试自动执行这些操作的很酷的脚本是:https://github.com/thyarles/knsk

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

tl; dr

  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

答案 7 :(得分:3)

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

  • 删除命名空间中的所有资源。
<块引用>

Github issue link

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

原始答案:我通常会遇到同样的问题。

这就是我所做的

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

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

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

然后卷曲这个命令

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

答案 8 :(得分:3)

用您的命名空间替换大使

检查命名空间是否卡住

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 并重试这些步骤。

答案 9 :(得分:2)

请尝试使用以下命令:

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

答案 10 :(得分:2)

我喜欢从here中摘录的答案 只有两个命令。

在一个终端中:

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 @-

答案 11 :(得分:2)

这是由于名称空间控制器无法删除的名称空间中仍然存在的资源引起的。

此命令(带有kubectl 1.11+)将向您显示名称空间中剩余哪些资源:

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

找到并解决并删除它们后,命名空间将被清理

答案 12 :(得分:1)

运行self.contactsProvider.invitees.first

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

因此,只需使用kubectl get apiservice删除该apiservice

这样做之后,具有终止状态的名称空间将消失。

答案 13 :(得分:1)

我发现删除“ terminating”命名空间的唯一方法是删除“ finalizers”部分中的条目。我尝试--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键以删除整行。

保存它,退出编辑器,就像魔术一样。流氓命名空间应该消失了。

并确认一下:

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

请注意,此后可能还有孤立的资源。

答案 14 :(得分:1)

https://stackblitz.com/edit/react-mlvesv完成已经很好的答案。如果您使用Rancher部署了集群,则有一个警告。

Rancher部署会更改每个api调用,并将/k8s/clusters/c-XXXXX/放在URL之前。

您可以轻松地从Rancher UI中获取牧场主(c-XXXXX)上集群的ID,因为它位于URL上。

nobar

因此,在获得群集ID c-xxxx之后,按照nobar的说明进行操作,只需更改包括该牧场主位的api调用即可。

(
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
)

答案 15 :(得分:1)

kubectl edit namespace ${stucked_namespace}

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

它对我有用。

答案 16 :(得分:0)

调试一个类似的问题。

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

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

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


就我而言:

我使用 Terminating 查看了我的命名空间真实状态(卡在 kubectl edit ns <ns-name> 上),在 status -> conditions 下我看到我安装的一些外部 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

答案 17 :(得分:0)

如果在删除该名称空间中的资源后该名称空间陷入终止中,则可以在删除该名称空间的finalizers之前对其进行修补:

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

然后

kubectl delete ns ns_to_be_deleted;

答案 18 :(得分:0)

我已经基于此处的常见答案编写了一个单行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='<my-namespace>'。 例如namespace='trust'

demo


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

答案 19 :(得分:0)

还有另一种非常简单的方法来检查和修复k8s集群中卡住的或孤立的资源,该脚本:https://github.com/thyarles/knsk

要运行它,您必须使用bash并安装curlGithub页上有wget的说明):

  1. 扫描问题
    curl -s https://raw.githubusercontent.com/thyarles/knsk/master/knsk.sh | bash
  1. 再次运行它,但这一次只是为了查看您可以自己尝试解决的命令
    git clone https://github.com/thyarles/knsk.git
    cd knsk
    chmod +x knsk.sh
    ./knsk.sh --dry-run --delete-all --force
  1. 如果显示的命令看起来不错,请在没有--dry-run选项的情况下再次运行它,并让脚本为您修复混乱。使用-谨慎删除所有内容,查看Github页面以查看更多选项:
    ./knsk.sh --delete-all --force

答案 20 :(得分:0)

在我的情况下,发生了类似的事情pv&pvc,我通过将finalizers设置为null来强制删除了它。检查是否可以对ns做类似的事情

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

对于命名空间

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

答案 21 :(得分:0)

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

要知道造成痛苦的原因,请运行:

kubectl api-resources

这应该告诉您哪些api资源会导致问题,一旦确定就将其删除

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

删除后,命名空间应消失

答案 22 :(得分:0)

我编写了一个简单的脚本,以根据@Shreyangi Saxena的解决方案删除卡住的名称空间。

Terminating

此脚本可以检测到处于sed状态的所有名称空间,并将其删除。


PS:

  • 这可能在MacOS中不起作用,因为macos中的本机sed与GNU kubectl不兼容。

    您可能需要在MacOS中安装GNU sed,请参阅https://login.microsoftonline.com/consumers

  • 请确认您可以通过命令v1.15.3访问kubernetes集群。

  • 已在kubernetes版本{{1}}上进行了测试

答案 23 :(得分:0)

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命令。 克服此问题后,我便使用脚本来卸载群集以除去残留物并重新安装。

答案 24 :(得分:0)

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

将所有职业添加到名称空间。如果仍不能解决问题,请继续下一个建议

$ kubectl get all -n your-namespace

某些名称空间具有附加的附件,因此删除起来可能很麻烦。因此,这可以是您想要的任何资源。然后,如果发现任何资源,则删除该资源

$ kubectl get apiservice|grep False

但是主要的收获是,有些东西可能没有完全清除。因此,您可以看到您最初在该名称空间中拥有的内容,然后查看您的YAML产生了什么东西以查看流程。或者,您可以开始搜索Google为什么不正确删除服务X,然后您会发现事情。

答案 25 :(得分:-1)

最简单,最简单的方法是复制bash脚本

select a.ID,    ITEM,    ITEMS_PER_ID

from tbl a
inner join
(
  select ID, count(distinct ITEM) as ITEMS_PER_ID
  from tbl group by ID
)b on a.ID = b.ID

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

然后通过提供名称空间作为参数来执行它(linkerd是我想在此处删除的名称空间)

#!/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

以上提示对我有用。

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

特别感谢Jens Reimann!我认为该脚本应合并到kubectl命令中。