fbpx

k8sgptを利用してKubernetesクラスタのトラブルシューティングをしよう!

この記事は1年以上前に投稿されました。情報が古い可能性がありますので、ご注意ください。

k8sgptはAIの力を用いてKubernetesクラスタをスキャン・診断・問題のトリアージをしてくれるOSSのツールのようです。
デフォルトでAI ProviderとしてOpenAIのAPIを利用します。
その他にAI ProviderとしてはAzure OpenAIやLocal AI等が利用できるようです。

非常に簡単に利用できるため、ご自身の環境でもぜひ試してみてください。

インストール

k8sgptはCLIツールとして提供されており、いくつかインストール方法が用意されています。
MacやLinuxでbrewがインストールされている環境であれば、そちらを利用するのが最も簡単でしょう。

$ brew tap k8sgpt-ai/k8sgpt
$ brew install k8sgpt

その他のインストール方法は、こちらをご参照ください。なお、この記事執筆ではv0.3.0を利用しています。

クラスタの準備とk8sgptの実行

k8sgptを実行するにはAI Providerの設定が必要です。
ここではChatGPTのAPIを利用します。ChatGPTを利用するにはAPI Keyが必要となります。
API Keyを生成するには以下のコマンドで出力されるURLから取得できます。

$ k8sgpt generate

Please open: https://beta.openai.com/account/api-keys to generate a key for openai
Please copy the generated key and run `k8sgpt auth` to add it to your config filek8sgpt generate

そして取得したkeyを以下のコマンドからセットします。

$ k8sgpt auth new

手軽にローカルで確認するために、kindでクラスタを作成します。

$ kind create cluster

さて、この状態でクラスタを分析してみましょう。クラスタが正常に作成できていれば、クラスタには問題がないはずです。確認してみましょう。

$ k8sgpt analyse

No problems detected

では、クラスタに問題を作っていきましょう。人でも分かりづらい問題の一つとして、権限周りの問題があるかと思います。ここではその権限周りのエラーを発生させて、k8sgptにより問題を分析していきましょう。

今回用意した権限周りのエラーは、PodSecurity AdmissionによりPrivilegedなPodを起動できないという問題です。以下のマニフェストを利用し、k8sgpt-testネームスペース、及びそのネームスペース内にprivilegedという名前のDeploymentを作成します。privilegedというDeploymentは名前からも想像できる通り、privilegedなコンテナを含むPodを作成するものです。
早速作成してきましょう。

apiVersion: v1
kind: Namespace
metadata:
  name: k8sgpt-test
  labels:
    pod-security.kubernetes.io/enforce: baseline
---
apiVersion: apps/v1
kind: Deployment
metadata:
  labels:
    app: privileged
  name: privileged
  namespace: k8sgpt-test
spec:
  selector:
    matchLabels:
      app: privileged
  template:
    metadata:
      labels:
        app: privileged
    spec:
      containers:
      - image: nginx
        name: nginx
        securityContext:
          privileged: true
# 上記YAMLファイルをprivileged.yamlとして保存
$ kubectl apply -f privileged.yaml
namespace/k8sgpt-test created
Warning: would violate PodSecurity "baseline:latest": privileged (container "nginx" must not set securityContext.privileged=true)
deployment.apps/privileged created

k8sgpt-testネームスペースはPodSecurity Admissionの設定のためのラベルである pod-security.kubernetes.io/enforce: baseline ラベルがセットされているため、privilegedなコンテナを含むPodは起動できません。
しかし、この場合でもDeployment自体は作成できてしまいますが、そのDeploymentから最終的に作成されるPodはPodSecurity Admissionにより作成できないため、この問題は初学者を悩ませる問題かと思います。上記のように手元で実行すればWarningですぐに気づけますが、CI/CDでDeployしておりログを見落とす可能性もあります。
そのような場合でもk8sgptを利用すれば対処できるのか確認していきましょう。

ここからk8sgptによりこの問題を分析していきます。使い方は非常に簡単で、k8sgpt analyseコマンドにより問題を分析します。この時点でクラスタに発生しているエラーを返してくれます。

$ k8sgpt analyse

0 k8sgpt-test/privileged()
- Error: Deployment k8sgpt-test/privileged has 1 replicas but 0 are available

1 k8sgpt-test/privileged-f7dcb78c5(Deployment/privileged)
- Error: pods "privileged-f7dcb78c5-rshz7" is forbidden: violates PodSecurity "baseline:latest": privileged (container "nginx" must not set securityContext.privileged=true)

この段階ですでに`1:privileged Deploymentのreplicaが足りていないこと`、`2:Deployment/privilegedのPodがPodSecurityにより拒否されたこと`がわかります。k8sgptでは--explainオプションをつけることで、対処方法などの説明を求めることができます。また-lオプションにより説明に利用する言語も選択できます。
せっかくなので日本語で答えを求めてみましょう。

$ k8sgpt analyse --explain -l Japanese
 100% |████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████| (2/2, 3 it/min)

0 k8sgpt-test/privileged()
- Error: Deployment k8sgpt-test/privileged has 1 replicas but 0 are available
問題: k8sgpt-test/privilegedのデプロイメントに1つのレプリカがありますが、利用可能なものは0つしかありません。

解決策: このエラーは、指定されたデプロイメントに対して、要求された数よりも少ない数のレプリカが利用可能であることを示しています。解決策としては、まず、kubectl get podsコマンドを使用して利用可能なポッドの数を確認し、kubectl delete podコマンドを使用して不要なポッドを削除することが考えられます。また、デプロイメントのスケールを変更して、より多くのレプリカを利用可能にすることもできます。

Translation: There is one replica in the k8sgpt-test/privileged deployment, but none of them are available. The solution is to check the number of available pods using the kubectl get pods command and delete any unnecessary pods using the kubectl delete pod command. Another solution is to change the deployment's scale to make more replicas available.
1 k8sgpt-test/privileged-f7dcb78c5(Deployment/privileged)
- Error: pods "privileged-f7dcb78c5-rshz7" is forbidden: violates PodSecurity "baseline:latest": privileged (container "nginx" must not set securityContext.privileged=true)
Kubernetes エラーメッセージを簡略化し、日本語で解決策を提供してください: 「privileged-f7dcb78c5-rshz7」という名前のポッドが禁止されています:PodSecurity "baseline:latest" に違反しています: 特権を与えられた (container "nginx" は securityContext.privileged=true を設定してはいけません)

解決策:nginx コンテナーで securityContext.privileged=false を設定します。これにより、PodSecurity "baseline:latest" に準拠することができます。

1つ目のエラーであるDeploymentのreplicaが足りない問題は、若干解決策が怪しいですが必ずしも間違っているとは言えない内容となっていますね。2つ目のエラーではアプリケーションが本当にprivileged=trueを求めていた場合はこちらの回答では問題がありますが、Podを起動させようとする方法としては間違っていません。

ある程度Kubernetesに慣れている方であれば--explainなしの出力結果で調査を進めることが可能だと思われますが、エラーの状況が全くわからないということであれば調査の初動を決めるのに役に立つかもしれませんね!ちなみに今回利用したOpenAPIのモデルはデフォルトで設定されていたgpt-3.5-turboであるため、他のモデルを利用すれば回答も当然異なるはずです。

k8sgpt実装について

k8sgptがどうやってクラスタの状態を確認し、どうやってAI Providerを利用しているか気になりますよね。
k8sgptの実装を確認しながら確認してみましょう。

k8sgtp analyzeを実行すると、Analyzerで定義された異常をクラスタから収集します。ここではAI Providerは利用せず、あらかじめ実装されているリソースの異常状態の条件を用いて検出します。こちらは力業ですね。
AnalayzerはPod, Deployment, ReplicaSet, PersistentVolumeClaim, Service, Ingress, StatefulSet, CronJob, Node, HorizontalPodAutoScaler, PodDisruptionBudget, NetworkPolicy等があらかじめ用意されています。AnalyzerではPodやDeployment等のオブジェクトに記録された異常状態のメッセージを収集します。

そして--explainフラグをセットして実行された場合のみAI Providerが利用されます
v0.3.0時点ではどのAI Providerを利用していても以下のプロンプトのテンプレートを利用するようです。

default_prompt = "Simplify the following Kubernetes error message and provide a solution in %s: %s"

1つ目の%sには出力言語が、2つ目には上記で収集されたメッセージが埋められます。
とてもシンプルなプロンプトでKubernetesのエラーメッセージを簡単に説明することと解決策を求めるものとなっています。
k8sgptのコード量はそれほど多くないため、興味がある方はぜひご自身でも確認してみてください。

最後に

Kubernetesクラスタのトラブルシュートは、慣れるまでどこを見ればよいか戸惑うものです。このツールはそういった初学者の方々の学習を手助けするものとなり、中級者以上の方でも迅速にトラブルシュートできる可能性があります。
OpenAIのAPIをはじめとしてAIを活用したサービス・ツールが簡単に作成できるようになっています。Kubernetesの世界でも様々なこういったツールが登場してくるでしょう。どういった活用方法が出てくるのか楽しみですね。

新規CTA