fbpx

Plutoとnovaでdeprecated/removedなKubernetes API利用を検出/対応してKubernetesのバージョンアップに備える

はじめに

Kubernetesをインフラに採用してからしっかりと4ヶ月に1回のマイナーリリース適用だけでなく、日々のパッチリリース適用も抜け目なく続けるやり手インフラ担当の方も増えてきた昨今だと思います。

さて、マイナーリリースの適用のときに困る問題があると思いますが、今回はFairwinds Ops社のOSS, plutoを利用してKubernetes APIの非推奨(deprecate)化と削除(remove)をマイナーリリース適用前に検知、同novaでHelm Chartの新バージョンを提案してもらう方法を取り上げます。

先にテスト環境などのマイナーリリース適用を行ってデプロイ物が動かなくなったら対応する、などといったポリシーを変えて検証環境や手数を減らす一助になるかもしれません。

準拠バージョン

本記事では

  • pluto v5.19.0
  • nova v3.7.0

を用います

Plutoをざっくり紹介

Plutoは米国企業Fairwinds Ops社のOSSで、Apache-2.0 licenseで提供されています。

plutoが提供する機能としては

  • Kubernetesで利用するYAML定義ファイルにdeprecated/removedなKubernetes APIが含まれていないかチェックする
  • Helmでデプロイしたリソースにdeprecated/removedなKubernetes APIが含まれていないかチェックする
  • 標準入力でYAML定義を受け付け、deprecated/removedなKubernetes APIが含まれていないかチェックする
    • helm templateコマンドの出力を流したりすると便利
  • Kubernetesにdeprecated/removedなKubernetes APIを使っているリソースがないかチェックする
  • GitHub ActionsでGitHubリポジトリ中にdeprecated/removedなKubernetes APIが含まれていないかチェックする

があります。

某漫画、アニメ作品他、様々なものと名前が競合するのでweb検索する際には「pluto kubernetes」などで行うと良い結果が得られやすいです。

公式ドキュメント: https://pluto.docs.fairwinds.com/

GitHubリポジトリ: https://github.com/FairwindsOps/pluto

Novaもざっくり紹介

Novaも米国企業Fairwinds Ops社のOSSで、Apache-2.0 licenseで提供されています。

novaの提供する機能はシンプルで、

  • Kubernetes内で古いHelm Chart/コンテナイメージが利用されていないかチェック、最新バージョンを提示する

だけです。

しっかりとメンテナンスされているHelm Chartであれば最新バージョンにするだけでdeprecated/removedなKubernetes APIの利用を解消できる可能性があり、deprecated/removed検出後の対応作業で役立ちます。

こちらも名前の競合が多いので、web検索する際は工夫が必要です。

公式ドキュメント: https://nova.docs.fairwinds.com/

GitHubリポジトリ: https://github.com/FairwindsOps/Nova

検証

注意事項

今回の検証では検証用に古いKubernetesクラスタを構築する他、古いソフトウェアをデプロイしますが、これらをインターネット上に公開することはセキュリティ上のリスクになります。

この記事と同じような検証を行う際には隔離環境に構築するなど十分に対策を行ってから実行してください。

また、今回の検証はKubernetes v1.29.x系統まで最終的に上げることを想定して行いますが、検証バージョンのKubernetes v1.23.x系統からワンステップで一気にKubernetes v1.29.x系統までバージョンアップする事を推奨する意図はありません。

検証の目標

今回の検証では一刻も早くKubernetesのバージョンを上げる必要がある切羽詰まった状況(KubernetesリソースやIaCリポジトリの中身を確認している余裕がない状況)を想定します。

検証の目標は

  • Plutoを用いて古いHelm Chartを用いて構築されたfluentdのyaml定義に含まれるdeprecated/removedなKubernetes API利用を検出
  • Novaを用いて最新のHelm Chartを提案してもらい、それを適用することでdeprecated/removedなKubernetes API利用を解消する

にしました。

Plutoのインストール

公式ドキュメントの手順に従い、各種パッケージマネージャ経由のインストール、もしくはバイナリの取得を行ってください。

https://pluto.docs.fairwinds.com/installation/#asdf

ちなみにArch Linuxから利用する場合にはAURからパッケージの作成が可能です。

https://aur.archlinux.org/packages/pluto

https://aur.archlinux.org/packages/pluto-bin

Novaのインストール

こちらも公式ドキュメントの手順に従い、各種パッケージマネージャ経由のインストール、もしくはバイナリの取得を行ってください。

https://nova.docs.fairwinds.com/installation/

Arch Linux利用の場合はこちらもAURにビルドスクリプトが用意されています。(上記手順で入れたものとファイル名が異なるので、実行時はnova-helmコマンドに読み替えてください)

https://aur.archlinux.org/packages/nova

準備編: 古いKubernetesクラスタの構築

こちらは本筋ではないので、お好きな方法で構築していただいて良いと思います。

今回は例として検証用にkind 0.22.0を用いてKubernetes 1.23.17のクラスタを構築します。

kindを導入済みであればコマンド1行で構築が可能です。

> kind create cluster --image kindest/node:v1.23.17
Creating cluster "kind" ...
 ✓ Ensuring node image (kindest/node:v1.23.17) 
 ✓ Preparing nodes 
 ✓ Writing configuration 
 ✓ Starting control-plane 
 ✓ Installing CNI 
 ✓ Installing StorageClass  
Set kubectl context to "kind-kind"
You can now use your cluster with:

kubectl cluster-info --context kind-kind

Thanks for using kind! 

これで検証用Kubernetesクラスタの構築ができました。

準備編: 古いfluentdの構築

Helmを用いて古いfluentdのyaml定義を適用します。

> helm install fluentd fluent/fluentd \
      --set kind=Deployment \
      --set autoscaling.enabled=true \
      --version 0.5.1 \
      --namespace fluent \
      --create-namespace
W0319 12:55:01.512789   71764 warnings.go:70] policy/v1beta1 PodSecurityPolicy is deprecated in v1.21+, unavailable in v1.25+
W0319 12:55:01.521627   71764 warnings.go:70] autoscaling/v2beta2 HorizontalPodAutoscaler is deprecated in v1.23+, unavailable in v1.26+; use autoscaling/v2 HorizontalPodAutoscaler
W0319 12:55:01.562122   71764 warnings.go:70] policy/v1beta1 PodSecurityPolicy is deprecated in v1.21+, unavailable in v1.25+
W0319 12:55:01.588818   71764 warnings.go:70] autoscaling/v2beta2 HorizontalPodAutoscaler is deprecated in v1.23+, unavailable in v1.26+; use autoscaling/v2 HorizontalPodAutoscaler
NAME: fluentd
LAST DEPLOYED: Tue Mar 19 12:55:01 2024
NAMESPACE: fluent
STATUS: deployed
REVISION: 1
NOTES:
Get Fluentd build information by running these commands:

export POD_NAME=$(kubectl get pods --namespace fluent -l "app.kubernetes.io/name=fluentd,app.kubernetes.io/instance=fluentd" -o jsonpath="{.items[0].metadata.name}")
kubectl --namespace fluent port-forward $POD_NAME 24231:24231
curl http://127.0.0.1:24231/metrics

これで古いAPIを利用するfluentdのyaml定義がhelm経由で展開できました。

既にWarnでdeprecated/removedなAPI利用が警告されていますが、読み飛ばしたりしてしまったケースと想定して無視してください。

IaCでhelm installを代替する場合など、読み飛ばす/表示されないケースも実際に想定されます。

実践編: plutoを用いてKubernetesクラスタ上にdeprecated/removedなAPI利用がないか確認する

detect-all-in-clusterコマンドを利用します。

これは

  • Helmでデプロイしたリソースにdeprecated/removedなKubernetes APIが含まれていないかチェックする
  • Kubernetesにdeprecated/removedなKubernetes APIを使っているリソースがないかチェックする

の2つを行うコマンドで、コマンド一発で現状Kubernetesクラスタ上にあるものの確認が可能です。

> pluto detect-all-in-cluster --output wide
NAME              NAMESPACE   KIND                      VERSION               REPLACEMENT      DEPRECATED   DEPRECATED IN   REMOVED   REMOVED IN   REPL AVAIL   REPL AVAIL IN  
fluentd/fluentd   fluent      PodSecurityPolicy         policy/v1beta1                         true         v1.21.0         true      v1.25.0      true                        
fluentd/fluentd   fluent      HorizontalPodAutoscaler   autoscaling/v2beta2   autoscaling/v2   true         v1.23.0         false     v1.26.0      true                     



Want more? Automate Pluto for free with Fairwinds Insights!
https://fairwinds.com/insights-signup/pluto 

outputオプションを変えることでJSONやYAMLに出力することも可能です。

処理結果をパイプする時などに役立ちます。

> pluto detect-all-in-cluster --output yaml
items:
    - name: fluentd/fluentd
      namespace: fluent
      api:
        version: policy/v1beta1
        kind: PodSecurityPolicy
        deprecated-in: v1.21.0
        removed-in: v1.25.0
        replacement-api: ""
        replacement-available-in: ""
        component: k8s
      deprecated: true
      removed: true
      replacementAvailable: true
    - name: fluentd/fluentd
      namespace: fluent
      api:
        version: autoscaling/v2beta2
        kind: HorizontalPodAutoscaler
        deprecated-in: v1.23.0
        removed-in: v1.26.0
        replacement-api: autoscaling/v2
        replacement-available-in: ""
        component: k8s
      deprecated: true
      removed: false
      replacementAvailable: true
target-versions:
    cert-manager: v1.5.3
    istio: v1.11.0
    k8s: v1.25.0



Want more? Automate Pluto for free with Fairwinds Insights!
https://fairwinds.com/insights-signup/pluto

これでdeprecated/removedなKubernetes API利用が検出できました。

実践編: novaを用いて古いHelm Chartを検出し最新化、deprecated/removedなKubernetes API利用の解消を試みる

ここまででdeprecated/removedなKubernetes APIを利用しているリソースがあることが確認できました。

具体的にどうやってインストールされたのか知らない体で探っていこうと思います。

plutoで検出されたリソースの定義をコマンドで見てみると

> kubectl get horizontalpodautoscalers.autoscaling --namespace fluent fluentd -o yaml
apiVersion: autoscaling/v2
kind: HorizontalPodAutoscaler
metadata:
  annotations:
    meta.helm.sh/release-name: fluentd
    meta.helm.sh/release-namespace: fluent
  labels:
    app.kubernetes.io/instance: fluentd
    app.kubernetes.io/managed-by: Helm
    app.kubernetes.io/name: fluentd
    app.kubernetes.io/version: v1.16.2
    helm.sh/chart: fluentd-0.5.1
  name: fluentd
  namespace: fluent
…

annotationsやlabelからHelmでインストールされたことが推測できます。

ここで「Helm Chartが古い場合は最新化すれば解消するかも...」という発想に至ります。

リリースが一個であればArtifact HubやGitHubリポジトリ等を調べて解消しますが、大量にリソースがあると手間がかかります。

ここでnovaを用いると、

> nova find --format table
Release Name    Installed    Latest    Old     Deprecated
============    =========    ======    ===     ==========
fluentd         0.5.1        0.5.2     true    false    


Want more? Automate Nova for free with Fairwinds Insights!
https://fairwinds.com/insights-signup/nova

といったように古いHelm Chartを利用していたことが分かります。

余談ですがcontainersオプションで古いコンテナイメージも検出できます。

> nova find --containers --format table
Container Name                             Current Version                      Old     Latest                         Latest Minor                         Latest Patch
==============                             ===============                      ===     ======                         =============                        =============
registry.k8s.io/coredns/coredns            v1.8.6                               true    v1.11.1                        v1.11.1                              v1.8.6                               
registry.k8s.io/etcd                       3.5.6-0                              true    3.5.12-0                       3.5.6-0                              3.5.6-0                              
registry.k8s.io/kube-proxy                 v1.23.17                             true    v1.29.3                        v1.29.3                              v1.23.17                             
registry.k8s.io/kube-controller-manager    v1.23.17                             true    v1.29.3                        v1.29.3                              v1.23.17                             
registry.k8s.io/kube-scheduler             v1.23.17                             true    v1.29.3                        v1.29.3                              v1.23.17                             
registry.k8s.io/kube-apiserver             v1.23.17                             true    v1.29.3                        v1.29.3                              v1.23.17                             
fluent/fluentd-kubernetes-daemonset        v1.16.2-debian-elasticsearch7-1.0    true    v1.16.3-debian-s3-arm64-2.1    v1.16.2-debian-elasticsearch7-1.0    v1.16.2-debian-elasticsearch7-1.0    


Want more? Automate Nova for free with Fairwinds Insights!
https://fairwinds.com/insights-signup/nova

# JSON出力だとどこで利用されているかも分かる
> nova find --containers | jq '.container_images[0]'


Want more? Automate Nova for free with Fairwinds Insights!
https://fairwinds.com/insights-signup/nova
{
  "name": "registry.k8s.io/coredns/coredns",
  "current_version": "v1.8.6",
  "latest_version": "v1.11.1",
  "latest_minor_version": "v1.11.1",
  "latest_patch_version": "v1.8.6",
  "outdated": true,
  "affectedWorkloads": [
    {
      "name": "coredns",
      "namespace": "kube-system",
      "kind": "Deployment",
      "container": "coredns"
    }
  ]
}

本筋に戻りますが、fluentdのHelm Chartが古いことがここまでで判明したので、最新版にアップグレードします。

まずは、アップグレードで解消するのかを確認します。

# 現行のHelm Chartで古いAPIを利用するリソースが展開されることを確認
> helm template fluentd fluent/fluentd --set kind=Deployment --set autoscaling.enabled=true --version 0.5.1 --namespace fluent --create-namespace | pluto detect -
NAME      KIND                      VERSION               REPLACEMENT      REMOVED   DEPRECATED   REPL AVAIL
fluentd   HorizontalPodAutoscaler   autoscaling/v2beta2   autoscaling/v2   false     true         true



Want more? Automate Pluto for free with Fairwinds Insights!
https://fairwinds.com/insights-signup/pluto

#新しいHelm Chartで古いAPI利用が解消されるか確認
> helm template fluentd fluent/fluentd --set kind=Deployment --set autoscaling.enabled=true --version 0.5.2 --namespace fluent --create-namespace | pluto detect -
There were no resources found with known deprecated apiVersions.


Want more? Automate Pluto for free with Fairwinds Insights!
https://fairwinds.com/insights-signup/pluto

最新版へのアップグレードで解消されそうなので、helm upgradeコマンドで解消を試みます。

> helm upgrade fluentd fluent/fluentd --set kind=Deployment --set autoscaling.enabled=true --version 0.5.2 --namespace fluent --create-namespace
W0319 18:45:55.010891   41838 warnings.go:70] policy/v1beta1 PodSecurityPolicy is deprecated in v1.21+, unavailable in v1.25+
W0319 18:45:55.012097   41838 warnings.go:70] policy/v1beta1 PodSecurityPolicy is deprecated in v1.21+, unavailable in v1.25+
W0319 18:45:55.017270   41838 warnings.go:70] policy/v1beta1 PodSecurityPolicy is deprecated in v1.21+, unavailable in v1.25+
Release "fluentd" has been upgraded. Happy Helming!
NAME: fluentd
LAST DEPLOYED: Tue Mar 19 12:45:54 2024
NAMESPACE: fluent
STATUS: deployed
REVISION: 2
NOTES:
Get Fluentd build information by running these commands:

export POD_NAME=$(kubectl get pods --namespace fluent -l "app.kubernetes.io/name=fluentd,app.kubernetes.io/instance=fluentd" -o jsonpath="{.items[0].metadata.name}")
kubectl --namespace fluent port-forward $POD_NAME 24231:24231
curl http://127.0.0.1:24231/metrics

新しいリリースに更新できました。もう一度plutoでスキャンを仕掛けてみます。

> pluto detect-all-in-cluster -o wide
NAME              NAMESPACE   KIND                VERSION          REPLACEMENT   DEPRECATED   DEPRECATED IN   REMOVED   REMOVED IN   REPL AVAIL   REPL AVAIL IN  
fluentd/fluentd   fluent      PodSecurityPolicy   policy/v1beta1                 true         v1.21.0         true      v1.25.0      true                        



Want more? Automate Pluto for free with Fairwinds Insights!
https://fairwinds.com/insights-signup/pluto

対応する項目が減りました。

ちなみに残りのPodSecurityPolicyリソースはKubernetesのバージョンアップに合わせて解消されるようなので、対応不要でした。

これでKubernetesのバージョンアップで動かなくなるリソースがなくなり、安全にバージョンアップできるようになりました。

おわりに

安全にKubernetesをアップグレードする準備段階をシミュレートし、

  • Plutoを用いて古いHelm Chartを用いて構築されたfluentdのyaml定義に含まれるdeprecated/removedなKubernetes API利用を検出
  • Novaを用いて最新のHelm Chartを提案してもらい、それを適用することでdeprecated/removedなKubernetes API利用を解消する

を達成する事ができたと思います。

今すぐKubernetesをアップグレードしたいという切羽詰まった状況でも、作業前に一回はplutoを実行することで不要なトラブル対応や問題の検出にかかる時間を短縮する事ができるのではないでしょうか。

これからもインフラ関連作業は安全第一で行いましょう!

Author

色々やらせてもらっている系エンジニア。
Arch Linuxユーザー。

菅野 洋信の記事一覧

新規CTA