Kubernetes 1.16のリリースから時間が経ち、各種マネージドKubernetesプラットフォームでも段階的に展開が進んでいます。これに伴い「APIの非推奨化」という言葉を耳にした方も多いのではないでしょうか。対応自体は難しくありませんが、放置するとサービスに深刻な影響を及ぼしかねません。

APIの非推奨化とは
Kubernetesの機能が進化するのに合わせて、APIもそれに追随して進化していく必要があります。互換性と安定性を保つためのルールも整備されています¹。すべてのリリースで起こるわけではありませんが、いずれは旧バージョンがサポート対象外となり、新しいAPIバージョンとフォーマットへの移行を避けられないタイミングがやってきます。
なぜ1.16リリースで重要なのか
ここ数バージョンのKubernetesで残されてきた非推奨APIのうち、いくつかが1.16でついに完全に削除されます。具体的には以下のAPIグループとバージョンです。
- Deployment —
extensions/v1beta1、apps/v1beta1、apps/v1beta2 - NetworkPolicy —
extensions/v1beta1 - PodSecurityPolicy —
extensions/v1beta1 - DaemonSet —
extensions/v1beta1、apps/v1beta2 - StatefulSet —
apps/v1beta1、apps/v1beta2 - ReplicaSet —
extensions/v1beta1、apps/v1beta1、apps/v1beta2
1.16でこれらを使ってリソースを作成しようとしても、操作はそのまま失敗します。
自分が影響を受けているか確認するには
すべてのマニフェストを手作業でチェックすることもできますが、相応の時間がかかります。見落としも起きやすく、複数チームが同じクラスタにデプロイしていたり、最新のマニフェストが一カ所にまとまっていなかったりすると、現実的な方法とは言えません。そこで役立つのが、Kube-No-Trouble、通称kubentです。
仕組みのポイント
あるリソースがどのAPIバージョンで作成されたかという情報は、通常は取得できません。リソースは内部的に常に推奨ストレージバージョンへ変換されたうえで保存されるためです。ただし、kubectlやHelmでリソースをデプロイしている場合は、元のマニフェストもクラスタ内に保存されているため、それを利用できます²。
非推奨化の悩みを解決する
最も簡単なインストール方法は次のとおりです。
sh -c "$(curl -sSL 'https://git.io/install-kubent')"
これで、最新版のkubentが/usr/local/binにインストールされます³。
kubectlのカレントコンテキストをチェック対象のクラスタに切り替え、kubentコマンドを実行してください。

図1:kubent実行時のサンプル出力
kubentはクラスタに接続し、影響を受ける可能性のあるリソースをすべて取得してスキャンし、該当するものを一覧で出力します。
CI/CDパイプラインへの組み込みや結果のさらなる加工を行いたい場合は、-f jsonフラグでJSON形式の出力に切り替えると便利です。利用できる設定オプションの詳細は、doitintl/kube-no-troubleリポジトリのREADMEを参照してください。
検出されたリソースはどう扱うべきか
マニフェストのapiVersionを書き換えるだけで済むケースもありますが、構造そのものが変わっていて調整が必要な場合もあります。また、バージョン間で多くのデフォルト値が変更されている点にも注意が必要です⁴。apiVersionだけを変更して同じマニフェストを適用すると、結果が変わってしまうことがあります。たとえばStatefulSetのupdateStrategy.typeはOnDeleteからRollingUpdateに変更されており、挙動が大きく異なります。
かつて使われていたkubectl convertコマンドは現在非推奨となっており、上述のデフォルト値の変更を踏まえた正しい変換が行われない可能性があります。
おそらく最も確実な方法は、リソースをそのまま再適用し(kubentで検出済みであれば手元にあるはずです)、APIから新しいバージョンを取得することです。こうすればリソースは新バージョンへ正しく変換されます。なお、kubectlが返すバージョンは必ずしも一定ではない点にお気づきの方もいるでしょう。特定のAPIバージョンを指定したい場合は、次のように完全な形式で指定します。
kubectl get ingress.v1beta1.extensions -o yaml
フィードバックお待ちしています
本記事が、Kubernetesクラスタ内で使われている非推奨APIをトラブルになる前に検出し、対処するための一助となれば幸いです。
kubentはまだ生まれたばかりのツールです。ご意見やご提案、「役に立った」という感想など、ぜひお寄せください。よい航海を! ⛵⛵⛵
- [1] KubernetesのDeprecation Policyドキュメントは、システムの各要素をどのように非推奨化し、削除していくかを定めています。
- [2] kubectlの場合は
kubectl.kubernetes.io/last-applied-configurationアノテーションとして、Helmの場合はConfigMapまたはSecretとして保存されます。 - [3] 私と同じく、ブログ記事に貼られたスクリプトをそのまま実行するのは抵抗があるという方は、お使いのプラットフォーム向けの最新リリースをダウンロードし、好きな場所に展開してください。
- [4] このテーマに関する優れた記事として、David Schweikert氏のKubernetes 1.16 API deprecations and changed defaultsがあります。
参考資料
- Kube-No-Trouble — kubent GitHubリポジトリ — https://github.com/doitintl/kube-no-trouble
- Vallery Lancey氏によるブログ記事「Deprecated APIs Removed In 1.16: Here's What You Need To Know」 — https://kubernetes.io/blog/2019/07/18/api-deprecations-in-1-16/