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


当前回答

我发现删除“终止”名称空间的唯一方法是删除“终结器”部分中的条目。我试过——强制删除它和——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

其他回答

强制删除名称空间或删除终结器绝对不是正确的方法,因为这可能会使资源注册到一个不存在的名称空间。

这通常很好,但有一天您将无法创建资源,因为它仍然在某个地方徘徊。

即将发布的Kubernetes 1.16版本应该会对名称空间终结器有更多的了解,目前我将依赖于标识策略。 一个很酷的脚本试图自动化这些是:https://github.com/thyarles/knsk

然而,它可以跨所有名称空间工作,这可能是危险的。它的解决方案是:https://github.com/kubernetes/kubernetes/issues/60807#issuecomment-524772920

博士tl;

检查是否有apiservice不可用,因此没有服务它的资源:kubectl get apiservice|grep False 通过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)

我写了一个简单的脚本,删除您卡住的名称空间基于@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

该脚本可以检测到所有处于终止状态的命名空间,并将其删除。


PS:

这可能在MacOS中不起作用,因为MacOS中的本机sed与GNU sed不兼容。 你可能需要在MacOS中安装GNU sed,请参考这个答案。 请确认您可以通过命令kubectl访问您的kubernetes集群。 已在kubernetes v1.15.3版本上测试


更新

我找到了一个更简单的解决办法:

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

将ambassador替换为您的名称空间

检查名称空间是否卡住

kubectl get ns ambassador

NAME         STATUS        AGE
ambassador   Terminating   110d

这个卡了很久了

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

kubectl代理

这将启动本地web服务器

打开另一个终端并运行

kubectl get ns ambassador -o json >tmp.json

编辑tmp文件。Json使用vi或nano

从这个

{
"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"
}

}

to

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

现在使用该命令并用您的名称空间替换ambassador

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,并再次尝试上述步骤。

删除下面列出的所有资源:

kubectl delete -n YOURNAMESPACE —-all

使用kubectl delete -n YOURNAMESPACE <resource> <id>,或者(如果你从上面的输出复制粘贴)kubectl delete -n YOURNAMESPACE <resource>/<id>,对于你看到的列出的每个资源。

kubectl delete -n YOURNAMESPACE <resource>/<id1> <resource>/<id2> <resource2>/<id3> <resource2>/<id4> <resource3>/<id5>等。

可能您试图删除资源,但由于部署或复制集资源,它们正在被重新创建,从而阻止名称空间释放依赖的资源并被清理。

我尝试了3-5个选项来删除ns,但只有这一个对我有用。

这个sh文件将删除所有处于终止状态的名称空间

$ 我们 force-delete-namespaces.sh

$chmod +x force-delete-namespaces.sh

美元。/ force-delete-namespaces.sh

#!/usr/bin/env bash

set -e
set -o pipefail

kubectl proxy &
proxy_pid="$!"
trap 'kill "$proxy_pid"' EXIT

for ns in $(kubectl get namespace --field-selector=status.phase=Terminating --output=jsonpath="{.items[*].metadata.name}"); do
    echo "Removing finalizers from namespace '$ns'..."
    curl -H "Content-Type: application/json" -X PUT "127.0.0.1:8001/api/v1/namespaces/$ns/finalize" -d @- \
        < <(kubectl get namespace "$ns" --output=json | jq '.spec = { "finalizers": [] }')

    echo
    echo "Force-deleting namespace '$ns'..."
    kubectl delete namespace "$ns" --force --grace-period=0 --ignore-not-found=true
done