Terminatingになったまま消えないNamespaceを削除する

正しい方法なのかわからないが、何度か詰まってたことを解決できたので残す。

# tl;dr

1. `kubectl get namespace <namespace名> -o json > temp.json`

2. `vi temp.json`

3. `"finalizers"`に設定されている`"kubernetes"`を行ごと削除

4. `curl -H "Content-Type: application/json" -X PUT --data-binary @temp.json http://127.0.0.1:8001/api/v1/namespaces/<namespace名>/finalize`
※ダメだったら、別ターミナルで`kubectl proxy`を流した状態で再度実行する

# 困ったこと
* `kubectl delete ns`で削除したnamespaceが消えず、`STATUS:Terminating`で残り続ける

```
$ kubectl get ns
NAME                  STATUS        AGE
catalog               Active        4d2h
default               Active        7d3h
ingress-nginx         Active        7d3h
kube-public           Active        7d3h
kube-system           Active        7d3h
guestbook             Terminating   3h48m
```

# 試したがダメだったこと

* namespaceに所属したままになってそうなリソースを探して削除
* 再度`kubectl delete ns`
* ノードの再起動
* `kubectl delete ns --force --grace-period=0`

削除してダメだった時は、このような表示だった

```
$ kubectl delete ns guestbook
Error from server (Conflict): Operation cannot be fulfilled on namespaces "guestbook": The system is ensuring all content is removed from this namespace.  Upon completion, this namespace will automatically be purged by the system.

$ kubectl delete ns guestbook --force --grace-period=0
warning: Immediate deletion does not wait for confirmation that the running resource has been terminated. The resource may continue to run on the cluster indefinitely.
Error from server (Conflict): Operation cannot be fulfilled on namespaces "guestbook": The system is ensuring all content is removed from this namespace.  Upon completion, this namespace will automatically be purged by the system.
```

# 無理やり削除

```
$ kubectl get namespace guestbook -o json > temp.json
```

```
$ vi temp.json
```

恐らく↓のような感じなので、`"finalizers"`に入っている`"kubernetes"`を行ごと削除する。

```
{
    "apiVersion": "v1",
    "kind": "Namespace",
    "metadata": {
        "creationTimestamp": "2019-10-16T04:12:28Z",
        "deletionTimestamp": "2019-10-16T06:53:17Z",
        "name": "guestbook",
        "resourceVersion": "892758",
        "selfLink": "/api/v1/namespaces/guestbook",
        "uid": "2a67a5bb-efcb-11e9-99ac-0663a4fd98d8"
    },
    "spec": {
        "finalizers": [
            "kubernetes"
        ]
    },
    "status": {
        "phase": "Terminating"
    }
}
```

```
$ curl -H "Content-Type: application/json" -X PUT --data-binary @temp.json http://127.0.0.1:8001/api/v1/namespaces/guestbook/finalize
{
  "kind": "Namespace",
  "apiVersion": "v1",
  "metadata": {
    "name": "guestbook",
    "selfLink": "/api/v1/namespaces/guestbook/finalize",
    "uid": "2a67a5bb-efcb-11e9-99ac-0663a4fd98d8",
    "resourceVersion": "901517",
    "creationTimestamp": "2019-10-16T04:12:28Z",
    "deletionTimestamp": "2019-10-16T06:53:17Z",
    "annotations": {
      "kubectl.kubernetes.io/last-applied-configuration": "{\"apiVersion\":\"v1\",\"kind\":\"Namespace\",\"metadata\":{\"annotations\":{},\"creationTimestamp\":\"2019-10-16T04:12:28Z\",\"deletionTimestamp\":\"2019-10-16T06:53:17Z\",\"name\":\"guestbook\",\"namespace\":\"\",\"resourceVersion\":\"891611\",\"selfLink\":\"/api/v1/namespaces/guestbook\",\"uid\":\"2a67a5bb-efcb-11e9-99ac-0663a4fd98d8\"},\"spec\":{\"finalizers\":[]},\"status\":{\"phase\":\"Terminating\"}}\n"
    }
  },
  "spec": {
    
  },
  "status": {
    "phase": "Terminating"
  }
}
```

もしダメだったら、別ターミナルで↓を実行した状態にして、最後のcurlをリトライする。
(`Starting to serve on 127.0.0.1:8001`が表示されたまま)

```
$ kubectl proxy
Starting to serve on 127.0.0.1:8001
```

# 消えた

```
$ kubectl get ns
NAME                  STATUS        AGE
catalog               Active        4d2h
default               Active        7d3h
ingress-nginx         Active        7d3h
kube-public           Active        7d3h
kube-system           Active        7d3h
```