Argo CDでPruneされないnamespaceを一緒に削除するカスタムコントローラーを作った

この記事は🎅GMOペパボ エンジニア Advent Calendar 2024の15日目の記事です!

昨日はugoくんの「SUZURI APIを用いたアプリケーションを作る時に細かなTips集」でした!

SUZURI APIのこだわりがよく分かる記事で、自分もなにか連携して作ってみたいと思いました!


昨年に引き続き、今回も必要に迫られて実装したカスタムコントローラーの話になりました。

作ったもの

namespace-cleaner.homi.run/managed: "true"がmetadata.labelsに設定されているApplicationリソースが削除された際に紐づくNamespaceを削除してくれるカスタムコントローラー。

Argo CDのapplicationリソース以外であまり使うビジョンが見えなかったので今回はそれ以外はサポートしてないです。

何が嬉しいのか

Argo CDにはsyncOptionsでCreateNamespaceというのがあり、以下のように有効化するとリソースのsync時にnamespaceを作成してくれます。

例えばapplicationSetを利用して何かをトリガーに、開発環境のようなapplicationリソースを作成するといった使い方をします。

これにより事前にnamespaceを用意しなくてもエラーにならずにsyncできるわけですが、逆にapplicationを削除するときにはpruneを有効にしてもここで作られたnamespaceは削除されません。作るときは自動なのに削除までは面倒を見てくれないので何もしなければ空のnamespaceが残ったままになるわけです。

確かにnamespaceを削除してしまうとその上で動くリソースも基本全部消えてしまうのでリスクではあるのですが、開発環境のような使っては捨てるようなnamespaceの場合はそんな事を気にしなくて良いので雑に自動で消えてほしいのでした。

使い方

pullしてきて以下を実行してクラスタへapply

kubectl apply -k config/manager -k config/rbac

namespaceが一緒に消えてほしいapplicationリソースにlabelを追加したらOK

applicationリソースが消えたら一緒にspec.destination.namespaceに指定されたnamespaceが削除されます。

仕組み

めちゃくちゃやっていることがシンプルなので簡単に説明していきます。

このコントローラーではKubernetesの finalizersの仕組みを使って機能を実現しています。

finalizersは、リソースが削除される前に特定のクリーンアップ処理を実行するための仕組みです。リソース削除時にfinalizersが登録されていると、その処理が完了するまで削除は保留されます。そしてカスタムコントローラーは監視しているリソースが削除されようとしているのを検知してクリーンアップ処理を実行したあとにfinalizersフィールドの値を削除することで安全に関連リソースの削除を実現しています。

今回はArgo CDのapplicationsリソースにfinalizersを自動で付与し、finalizersのクリーンアップ処理としてnamespaceを削除するようにしています。

以下のコードではnamespace-cleaner.homi.run/managed: "true"が設定されているリソースに対してnamespace-cleaner.homi.run/finalizerを付与しています。

そしてリソースに対して削除処理が始まると付与されるDeletionTimestampが存在し、かつfinalizersも存在しているリソースが存在していればspec.destination.namespaceをみて指定されたnamespaceを削除します。

最後にfinalizerフィールドの値を削除することでapplicationリソースの削除も完了します。

これが一連の流れです。

まとめ

今回実装したカスタムコントローラーを使うことで安全に不要なnamespaceを自動的に削除できるようになります。(もしかしたらもっと簡単な方法があるかもしれないが…)

1年ぶりにカスタムコントローラーを実装しましたが、以前より格段に早く実装を終えることができて成長を実感できた気がします。


明日の「🎅GMOペパボ エンジニア Advent Calendar 2024」はdaiさんです!よろしくお願いします

コメントを残す

メールアドレスが公開されることはありません。 が付いている欄は必須項目です

CAPTCHA