[小ネタ]Kubernetesで消せないNamespaceが発生した場合の対処方法

KubenetesでNamespaceを強制的に削除する方法を紹介します。
2019.06.08

はじめに

おはようございます、加藤です。皆さんはKubernetesを壊した事がありますか?私は今月2回ほど、破壊しました。 キャッチアップ中かつ、開発環境での話しなので、笑っていられますが、これが本番環境だったら恐ろしすぎますね。 唐突ですが、ここに本番環境では kubectl を使って操作しない事を誓います(ReadOnly権限の場合を除く)。

事件概要

先日、EKSにArgoCDをどうデプロイするか、設定をどうするか検証していた際に事件は発生しました。Kustomizeで、applyordeleteしたり、Namespaceのcreateordeleteを繰り返していました。その結果、タイミングの影響なのか以下のような奇妙な状況に陥りました。

  • Namespace: argocd は Terminating
  • Applicationという名前の、CRD: demo-appが存在する
  • 上記のCRD定義は削除されており存在しない

この状態の時、Application: demo-appは削除する事ができませんでした。kubectl -n argocd delete applicaton demo-appコマンド自体は成功とレスポンスを受け取りますが、リソースは削除されません。
Namespaceが削除中なので、待ってみますがいつまで待っても削除が完了しません。
CRD定義を追加しようとすると、Namespaceが削除中でロックされており、追加できません。

あ、やってしまったなと気づきました。

推理

Namespaceを削除するには、Namespace内のリソースを削除する必要がある→Applicationリソースを削除するにはCRD定義が必要→CRD定義を追加する為にはNamespaceが必要→Namespaceがロック状態(削除中)から解放される必要がある→(最初にもどる)

こんな状態になっていたと思われます。

Kustomizeで、applyordeleteしたり、Namespaceのcreateordeleteを繰り返していました

これが、原因で作成が完了する前に削除、削除が完了する前に作成が行われて、こんな状態になってしまったと推測しています。

対処

  1. kubectl proxy &
  2. Starting to serve on 127.0.0.1:XXXX と表示されるので XXXXのポートをメモしておく
  3. kubectl describe ns argocd の結果を参考に、ns.jsonを作る
  4. curl -k -H "Content-Type: application/json" -X PUT --data-binary @ns.json http://127.0.0.1:XXXX/api/v1/namespaces/argocd/finalize

ns.json

{
  "kind": "Namespace",
  "apiVersion": "v1",
  "metadata": {
    "name": "argocd",
    "selfLink": "/api/v1/namespaces/argocd",
    "annotations": {
      "kubectl.kubernetes.io/last-applied-configuration": "{\"apiVersion\":\"v1\",\"kind\":\"Namespace\",\"metadata\":{\"annotations\":{},\"name\":\"argocd\"},\"spec\":{\"finalizers\":[\"foregroundDeletion\"]}}\n"
    }
  },
  "spec": {
    "finalizers": [
    ]
  },
  "status": {
    "phase": "Terminating"
  }
}

参考: How to force delete a Kubernetes Namespace? - Stack Overflow

反省

このブログを書いている最中に気づきましたが、CRD定義をdefault namespaceに追加する事が可能で、そうすれば、Applicationリソースの削除ができてのでは?と気づきました...
もう、Kubernetesクラスタ絶対に壊しません!!