1. はじめに
はじめまして、Sreake事業部インターン生の井上秀一です。
Sreake事業部はSRE関連技術に強みを持つエンジニアによるコンサルテーションサービスを提供する事業部であり、私たちもSRE技術の調査と研究を行う目的で2023年3月6日から長期インターン生として参加しています。
本記事は、Kubernetes の運用効率化を ChatGPT で実現する 障害対応編 の続編です。
前記事ではKubernetes上で起きた障害の初期対応をChatGPT-3.0で対応できるか、簡易的な調査を行いました。 本記事では、ChatGPT-4を用いて、前記事よりも更に細かく、調査・評価を行いました。
2. TL;DR
本記事では、 「Kuberentes × ChatGPT = 運用効率化」というテーマで、障害対応にスコープを絞り、OpenAI社のChatGPT-4を用いて以下の事を行いました。
- 検証内容(やった事):
- メモリリソースに関する障害シナリオの作成
- Kubernetes Event Logから障害情報を抽出
- 初期対応(障害箇所特定、要約説明、影響範囲、緊急性)と評価
- 二次対応(トラブルシューティング)と評価
- 結果:
- 初期対応
- 障害情報分析や説明ができている。
- より詳細な情報定義を行う事で、影響範囲や緊急性も判断可能
- 二次対応
- 調査方針を立て、問題箇所の特定などができた。
- ChatGPTが提示した手法に無効なものがいくつかあった。
- 人間側が最適な手法を提示してトラブルシューティングを進めた。
- 初期対応
- 結論:
- ChatGPTを用いた障害対応の完全自動化は困難で、障害の調査方針、情報分析・整理、検証方法を効率的に提示する、障害対応を効率化させる強力なツールという立ち位置が適切。
- 障害対応自体は人間が主体的に進める必要がある。
3. ChatGPTとは?
概要
- 開発元のOpenAI 公式からの引用
- 会話形式でやり取りする ChatGPT というモデルをトレーニングしました。対話形式により、ChatGPT はフォローアップの質問に答えたり、間違いを認めたり、間違った前提に異議を唱えたり、不適切な要求を拒否したりできます。
- 要約すると、対話形式で会話ができるチャットボット。
- GPTとはGenerative Pre-trained Transformerの略で、Transformerと呼ばれるニューラルネットワークアーキテクチャを使用している。
- ChatGPTのバージョン
- GPT-3.5
- GPT-4 (本記事で利用するバージョン)
GPT-4について
- 開発元のOpenAI公式からの引用
- ディープ ラーニングのスケールアップにおける OpenAI の取り組みにおける最新のマイルストーンである GPT-4 を作成しました。GPT-4 は大規模なマルチモーダル モデル (画像とテキストの入力を受け入れ、テキスト出力を発行する) であり、多くの現実世界のシナリオでは人間よりも能力が劣りますが、さまざまな専門的および学術的なベンチマークで人間レベルのパフォーマンスを示します。
- リリースと利用制限
- 米国時間2023年3月14日に発表され、日本国内では2023年3月15日から利用可能になった。
- 2023年3月20日現在、ChatGPT Plus(有料会員)でのみ利用ができる。ただし、4時間で100メッセージが上限、と制約がついている。
- GPT-3.5とGPT-4の比較
- 開発元のOpenAIでは下記の様に説明されている。要約すると、難易度の高い(複雑)なタスクにおいて、GPT-4が優れている。
カジュアルな会話では、GPT-3.5 と GPT-4 の違いは微妙です。タスクの複雑さが十分なしきい値に達すると、違いが現れます。GPT-4 は、GPT-3.5 よりも信頼性が高く、創造的であり、はるかに微妙な指示を処理できます。 2 つのモデルの違いを理解するために、もともと人間向けに設計された試験のシミュレーションなど、さまざまなベンチマークでテストを行いました。私たちは、公開されている最新のテスト (オリンピアードと AP の自由回答問題の場合) を使用するか、2022 年から 2023 年版の模擬試験を購入して進めました。これらの試験のための特別なトレーニングは行いませんでした。試験の問題のごく一部は、トレーニング中にモデルによって確認されましたが、結果は代表的なものであると考えています。詳細については、テクニカル レポートを参照してください。
ChatGPTの学習データについて
主に、インターネット上のテキスト、書籍、ニュース記事、ウィキペディアの記事、映画の字幕、会話文等が含まれます。
IT系の技術も、ウェブサイトの記事、技術ブログ、オンラインの学術論文、コンファレンスのプレゼンテーション、またはオンラインの教育プラットフォームから収集されている。上記の学習データについて質問した際に以下のような返答がされました。
ChatGPTのライセンスや利用規約・利用時の注意事項について(2023年3月13日時点)
公式FAQの引用を翻訳。ChatGPTを利用して作ったアウトプット自体は製作者が権利を持ちます。
ChatGPTで出力したものを商用利用することは可能ですか?
コンテンツポリシーと規約に従い、ChatGPTで作成したアウトプットは、無料プラン、有料プランを問わず、転載、販売、商品化する権利を含め、お客様に帰属します。
ChatGPT-APIについて(2023年3月13日時点)
ChatGPTではAPIの提供がされていて、無料試用枠がある。また、30日間データが保存されるが、API 経由で送信されたお客様のデータを使用してモデルを改善することはありませんと明記されています。
利用上の注意
社外秘なデータ等は、一般的な観点で送信を控えるべきとされています。
問題点とヒント
2023年3月28日現在、ChatGPTは3時間で25メッセージ以下といった制限が課せられており、リリース当初より厳しくなっています。
GPT-4 currently has a cap of 25 messages every 3 hours. Expect significantly lower caps, as we adjust for demand.
2023年3月28日現在、ChatGPTからの返答がハングアップしたり、レスポンスが中途半端に終了する問題があります。
再生成ボタンを押すか、中途半端に終了したメッセージに対して「続けて」と返信する事で続きを書いてくれます。
4. Kuberentes × ChatGPT = 運用効率化
背景
ChatGPTは、学習データにIT系の技術も多く含む事から、Kuberentesについても対応ができる事が予想されます。
ChatGPTでKuberentesに関する問題を質問して、運用チームに回答する事で大幅な運用効率化が期待できます。
特に、障害等のインシデント発生時に、出力されたエラー文や構成情報等を、入力としてChatGPTに与え、影響範囲特定、障害レベル、対応方針を、ChatGPTに回答させる事で、運用チームのtoilを軽減するだけでなく、迅速な復旧が期待できます。
インシデント対応の一般的な処理内容について、PagerDuty株式会社のインシデント処理に関する記事が参考になります。
運用フローへのChatGPT導入の検討
上記のフロー図は、一般的な障害発生時の運用フローの簡易例です。
通常の場合、運用チームがアラートやログを精査して、障害箇所の特定や影響範囲を特定、運用手順に従い、復旧対応を行います。
企業によっては、運用手順内で完結する領域を委託するケース等も考えられます。この場合、運用手順内で解決しない場合、委託元の企業にエスカレーションされます。
上記運用フローでは、ChatGPTを初期対応、二次対応に導入する事で、以下のメリットが得られます。
- 初期対応
通知されるアラートを予めChatGPTが分析する事で、障害発生箇所や、影響範囲を推定し、運用チームの迅速な判断に必要な支援を行う事ができます。 - 二次対応
二次対応では、定められた運用手順で復旧が出来ない場合を想定します。
この際、ChatGPTがシステムの現状態や、得られた障害情報から適切なデバッグ方針を推定、得られた情報やログを随時ChatGPTに共有して、復旧をChatGPTに行わせる。復旧の迅速化が期待できます。
本記事では、「Kuberentes × ChatGPT = 運用効率化」を実現する方法として、ChatGPTを初期対応及び、二次対応に導入した際の検証・評価を行います。
5. 障害シナリオ
シナリオ
上記図の様な「新しくデプロイするdeploymentが、ノードのメモリリソースの上限よりも多くメモリを要求し、新しいPodが配置できない」という障害を想定します。
障害通知・検知方法の想定
Kubernetes EventをエクスポートするOSS等の利用を想定します。
Kubernetes Eventとは、クラスター内のどこかで発生したイベントレポートで、システム内の何らかの状態変化を示します。
また、Kubernetes EventをエクスポートするOSSとして、 KubeCon 2019 San Diegoで発表されたkubernetes-event-exporterがあります。機能として、Slackやwebhookに通知する事ができます。
6. 検証方法
検証手順
- 障害シナリオに基づいた障害を発生させる
- Kubernetes Event Logの収集
- Event logをChatGPTに与え、初期対応・二次対応を行う
ChatGPTへの質問フォーマット
ChatGPTへの質問フォーマットは、インシデントの初期対応、二次対応のそれぞれで作成しました。
必要な情報を盛り込んだ他、Kubernetes Issue Formのテンプレート情報を盛り込みました。 また、ChatGPTがどのような立ち位置で支援するべきか、この質問票がどの時点で起きたものかの状況も盛り込みました。
初期対応
# 要件定義
- 貴方は、Kubernetes運用チームの一人で、運用中に障害が発生しました。
- 運用チームの頼れるエンジニアの一人として、以下に情報を元に、障害復旧の支援をお願いします。
- 現在のフェーズは、障害発生直後です。
- 障害情報の収集と障害箇所特定を行い、緊急性の有無を判断する必要があります。
# 解答は以下のフォーマット(markdown)でお願いします。ChatGPTの回答は<ChatGPT_Answer>に入力して下さい。
1. 障害箇所特定
- 障害箇所 : <ChatGPT_Answer>
- 根拠 : <ChatGPT_Answer>
2. 障害内容の説明
- <ChatGPT_Answer>
3. 障害の原因
- <ChatGPT_Answer>
4. 障害の影響範囲
- <ChatGPT_Answer>
5. 緊急性の判断
- <ChatGPT_Answer>
6. その他コメント(運用チームの頼れるエンジニアの一人として、アドバイスできる事。または、エンジニアとして、緊急性を判断するのに必要な他情報を要求する事が出来ます。)
- <ChatGPT_Answer>
# Kubernetesの構成に関する情報
- Kubernetes のバージョン
- 1.26.2
- インストール方法又はクラウドプロバイダー
- K0sctl
- OSバージョン
- Linux ubuntu 20.04
- インストール済みのツール
- Helm
- 関連するプラグイン (CNI、CSI など) とバージョン (該当する場合)
- CNI
- Kube-Router v1.5.1
- クラスタ構成
- Master Node: 1
- Worker Node: 2
# Kubernetes Event Logは以下です。
<エラー文を挿入>
二次対応
二次対応では、初期対応の質問に後追いで、トラブルシューティングを試みます。
ここではChatGPTを大きく頼る方針を取りました。
# 追加目標
- 先程提供した障害情報と、貴方から得られた情報を整理・判断した結果、早急に復旧する必要があると判断しました。従って、情報収集・原因究明・復旧のフェーズに移ります。
- 貴方は、運用チームのエンジニアの一人として、先程発生した障害の解決を試みてください。
- 貴方は、障害の解決に必要な情報を随時要求する事が出来ます。ただし、その場合、情報の取得方法まで提示する必要があります。
- 最終的に障害復旧が出来れば目標達成となります。
- 進め方としては、貴方が指示を出して、私がそれを実行し、結果を投げます。得られた情報を精査して、ネクストアクションを決定してください。
評価軸
- 初期対応
- 質問項目毎の評価
- 障害箇所特定
- 障害内容の説明
- 障害の原因
- 障害の影響範囲
- 緊急性の判断
- その他コメント
- 重要視するポイント
- アラート内容を適切に要約できているか?
- アラート内容を適切に説明できているか?
- 障害発生箇所を特定できているか?
- 発生したアラートから、影響範囲を特定出来ているか?
- 質問項目毎の評価
- 二次対応
- デバッグ・調査方針が適切に定められるか?
- ChatGPTだけの指示で復旧を行えるか?
検証環境
Ubuntu 20.04が動作するVMを3つ用意して、1つをMaster Node、2つをWorker NodeとしてKubernetesクラスタを用意しました。割り当てたリソースは以下の通りです。
- Master Node ×1
- CPU: 4
- メモリ: 8192MB
- Worker Node ×2
- CPU: 4
- メモリ: 12000MB
7. 検証・評価
障害シナリオ再現~Kubernetes Event Log取得まで
1. 障害シナリオに基づいた障害を発生させる
Kubernetesクラスタのノードを意図的にメモリ不足にさせるため、以下のマニフェスト(nginx-with-5gi.yaml
)をデプロイします。
# nginx-with-5gi.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: nginx-with-5gi
spec:
replicas: 1
selector:
matchLabels:
app: nginx-app
template:
metadata:
labels:
app: nginx-app
spec:
containers:
- name: nginx
image: nginx:latest
resources:
requests:
cpu: "1"
memory: "5Gi"
デプロイと確認をします。
# nginx-with-5gi.yamlをデプロイ
$ kubectl apply -f nginx-with-5gi.yaml
# デプロイされた事を確認する。
$ kubectl get pods -o=wide
NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES
nginx-with-5gi-5df78f6ccb-dmbb7 1/1 Running 0 9s 10.244.1.77 3shake-k8s-node-002 <none> <none>
次に、以下のマニフェスト(nginx-with-10gi.yaml
)をデプロイします。
# nginx-with-10gi.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: nginx-with-10gi
spec:
replicas: 2
selector:
matchLabels:
app: nginx-app
template:
metadata:
labels:
app: nginx-app
spec:
containers:
- name: nginx
image: nginx:latest
resources:
requests:
cpu: "1"
memory: "10Gi"
デプロイされたマニフェスト(nginx-with-10gi
)の二つのPodの内、一つがPendingの状態から5分立っても起動しない事を確認します。
# nginx-with-5gi.yamlをデプロイ
$ kubectl apply -f nginx-with-10gi.yaml
# デプロイされた事を確認する。
$ kubectl get pods -o=wide
NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES
nginx-with-10gi-586b8cfcd-4kfld 1/1 Running 0 4s 10.244.0.110 3shake-k8s-node-001 <none> <none>
nginx-with-10gi-586b8cfcd-84s9k 0/1 Pending 0 4s <none> <none> <none> <none>
nginx-with-5gi-5df78f6ccb-dmbb7 1/1 Running 0 24s 10.244.1.77 3shake-k8s-node-002 <none> <none>
2. Kubernetes Event Logの収集
以下のコマンドでKubernetes Event Logを取得します。取得したEvent Logを質問フォーマットに挿入して、ChatGPTへ質問します。
$ kubectl get event
LAST SEEN TYPE REASON OBJECT MESSAGE
50s Normal Scheduled pod/nginx-with-10gi-586b8cfcd-4kfld Successfully assigned default/nginx-with-10gi-586b8cfcd-4kfld to 3shake-k8s-node-001
<invalid> Normal Pulling pod/nginx-with-10gi-586b8cfcd-4kfld Pulling image "nginx:latest"
<invalid> Normal Pulled pod/nginx-with-10gi-586b8cfcd-4kfld Successfully pulled image "nginx:latest" in 1.381759148s (1.381763661s including waiting)
<invalid> Normal Created pod/nginx-with-10gi-586b8cfcd-4kfld Created container nginx
<invalid> Normal Started pod/nginx-with-10gi-586b8cfcd-4kfld Started container nginx
50s Warning FailedScheduling pod/nginx-with-10gi-586b8cfcd-84s9k 0/2 nodes are available: 2 Insufficient memory. preemption: 0/2 nodes are available: 2 No preemption victims found for incoming pod..
11m Normal Scheduled pod/nginx-with-10gi-586b8cfcd-hv7lj Successfully assigned default/nginx-with-10gi-586b8cfcd-hv7lj to 3shake-k8s-node-002
9m10s Normal Pulling pod/nginx-with-10gi-586b8cfcd-hv7lj Pulling image "nginx:latest"
9m3s Normal Pulled pod/nginx-with-10gi-586b8cfcd-hv7lj Successfully pulled image "nginx:latest" in 7.339842916s (7.339846559s including waiting)
9m3s Normal Created pod/nginx-with-10gi-586b8cfcd-hv7lj Created container nginx
9m3s Normal Started pod/nginx-with-10gi-586b8cfcd-hv7lj Started container nginx
9m2s Normal Killing pod/nginx-with-10gi-586b8cfcd-hv7lj Stopping container nginx
69s Normal Scheduled pod/nginx-with-5gi-5df78f6ccb-dmbb7 Successfully assigned default/nginx-with-5gi-5df78f6ccb-dmbb7 to 3shake-k8s-node-002
<invalid> Normal Pulled pod/nginx-with-5gi-5df78f6ccb-dmbb7 Container image "nginx:stable" already present on machine
<invalid> Normal Created pod/nginx-with-5gi-5df78f6ccb-dmbb7 Created container nginx
<invalid> Normal Started pod/nginx-with-5gi-5df78f6ccb-dmbb7 Started container nginx
初期対応の検証
ChatGPTから得られた回答
# From ChatGPT
1. 障害箇所特定
- 障害箇所 : Worker Nodeのリソース不足
- 根拠 : イベントログの "FailedScheduling" により、"0/2 nodes are available: 2 Insufficient memory."
2. 障害内容の説明
- ワーカーノードに十分なメモリリソースがなく、新しいPodがスケジュールされていない。
3. 障害の原因
- クラスタ内のワーカーノードのメモリリソースが不足しており、新たなPodをデプロイするのに十分なリソースが確保できない状況が発生している。
4. 障害の影響範囲
- メモリリソースが不足しているワーカーノード上で新しいPodがデプロイできない。
5. 緊急性の判断
- 緊急性が高い。Podがデプロイできないため、サービスに影響が出る可能性がある。
6. その他コメント
- メモリリソースの状況を確認するために、kubectl describe nodes コマンドを実行してください。
- 不要なPodが実行中であれば、それらを削除することで一時的なリソースの解放が可能です。
- 長期的な対策として、ワーカーノードのリソースを増やすか、クラスタに追加のワーカーノードを追加することを検討してください。
- リソース要求と制限を適切に設定することで、リソースの効率的な使用が可能になります。これにより、クラスタ内のリソース不足に対処できる場合があります。
初期対応の評価
- 項目毎の評価
- 評価:障害箇所特定
- 該当コンテナがFailedSchedulingである点と、
"0/2 nodes are available: 2 Insufficient memory."
という点からWorker Nodeのリソース不足である事を説明できている。
- 該当コンテナがFailedSchedulingである点と、
- 評価:障害内容の説明
- 障害箇所特定と同様、適切に説明出来ている。
- 評価:障害の原因
- 障害の原因として、クラスタ内のワーカーノードのメモリリソースが不足と言及しているので、適切な原因説明である。
- 評価:障害の影響範囲
- メモリリソースが不足しているワーカーノード上で新しいPodがデプロイできない、と説明している。厳密には7GB未満のデプロイメントであれば展開は出来ると考えるが、現時点でChatGPTに与えた情報に限定すると、適切な推測であると言える。
- 評価:緊急性の判断
- Podがデプロイできないため、サービスに影響が出る可能性が高いと適切な判断している。
- 評価:その他コメント
- ネクストアクションとして、メモリリソースの状況を確認方法を提示する他、アドバイスとして、一時的なリソース解放、長期的な対策まで提示されている。
- 評価:障害箇所特定
- 総合的な評価
- どのような障害が出ているか、影響範囲、メモリリソース不足が原因である事まで、適切な判断が出来ている。
二次対応の検証(トラブルシューティング)
初期対応に後追いする形で、二次対応用の質問フォーマットをChatGPTに提出し、以下の回答が得られました。
# From ChatGPT
まずは、ワーカーノードのリソース状況を確認して、問題の特定を試みましょう。
1. ワーカーノードのリソース状況を確認してください。
- 実行コマンド: kubectl describe nodes
このコマンドの結果を共有していただけると、次のステップに進めます。
回答に従い、情報共有を行います。
# To ChatGPT
以下に要求された情報を提示します。
Name: 3shake-k8s-node-001
Roles: <none>
Labels: beta.kubernetes.io/arch=amd64
beta.kubernetes.io/os=linux
kubernetes.io/arch=amd64
kubernetes.io/hostname=3shake-k8s-node-001
kubernetes.io/os=linux
Annotations: node.alpha.kubernetes.io/ttl: 0
volumes.kubernetes.io/controller-managed-attach-detach: true
CreationTimestamp: Thu, 27 Apr 2023 02:17:37 +0000
Taints: <none>
Unschedulable: false
Lease:
HolderIdentity: 3shake-k8s-node-001
AcquireTime: <unset>
RenewTime: Thu, 27 Apr 2023 05:17:40 +0000
Conditions:
Type Status LastHeartbeatTime LastTransitionTime Reason Message
---- ------ ----------------- ------------------ ------ -------
MemoryPressure False Thu, 27 Apr 2023 05:16:05 +0000 Thu, 27 Apr 2023 02:20:24 +0000 KubeletHasSufficientMemory kubelet has sufficient memory available
DiskPressure False Thu, 27 Apr 2023 05:16:05 +0000 Thu, 27 Apr 2023 02:20:24 +0000 KubeletHasNoDiskPressure kubelet has no disk pressure
PIDPressure False Thu, 27 Apr 2023 05:16:05 +0000 Thu, 27 Apr 2023 02:20:24 +0000 KubeletHasSufficientPID kubelet has sufficient PID available
Ready True Thu, 27 Apr 2023 05:16:05 +0000 Thu, 27 Apr 2023 02:20:46 +0000 KubeletReady kubelet is posting ready status. AppArmor enabled
Addresses:
InternalIP: 192.168.50.62
Hostname: 3shake-k8s-node-001
Capacity:
cpu: 4
ephemeral-storage: 40581564Ki
hugepages-2Mi: 0
memory: 11973936Ki
pods: 110
Allocatable:
cpu: 4
ephemeral-storage: 37399969321
hugepages-2Mi: 0
memory: 11871536Ki
pods: 110
System Info:
Machine ID: d2828f6258a8434789a32b8d70ca40d6
System UUID: 6dee713d-d208-8942-b70d-e01720945627
Boot ID: 05d5c559-e850-42c1-91df-61f70943c6df
Kernel Version: 5.4.0-146-generic
OS Image: Ubuntu 20.04.5 LTS
Operating System: linux
Architecture: amd64
Container Runtime Version: containerd://1.6.18
Kubelet Version: v1.26.2+k0s
Kube-Proxy Version: v1.26.2+k0s
PodCIDR: 10.244.0.0/24
PodCIDRs: 10.244.0.0/24
Non-terminated Pods: (6 in total)
Namespace Name CPU Requests CPU Limits Memory Requests Memory Limits Age
--------- ---- ------------ ---------- --------------- ------------- ---
default nginx-with-10gi-586b8cfcd-4kfld 1 (25%) 0 (0%) 10Gi (88%) 0 (0%) 115m
kube-system coredns-7bf57bcbd8-7zj4b 100m (2%) 0 (0%) 70Mi (0%) 170Mi (1%) 3h
kube-system konnectivity-agent-grbfz 0 (0%) 0 (0%) 0 (0%) 0 (0%) 3h
kube-system kube-proxy-jzlsk 0 (0%) 0 (0%) 0 (0%) 0 (0%) 3h
kube-system kube-router-55bxq 250m (6%) 0 (0%) 16Mi (0%) 0 (0%) 3h
kube-system metrics-server-7446cc488c-59pkl 10m (0%) 0 (0%) 30M (0%) 0 (0%) 3h
Allocated resources:
(Total limits may be over 100 percent, i.e., overcommitted.)
Resource Requests Limits
-------- -------- ------
cpu 1360m (34%) 0 (0%)
memory 10857595776 (89%) 170Mi (1%)
ephemeral-storage 0 (0%) 0 (0%)
hugepages-2Mi 0 (0%) 0 (0%)
Events: <none>
Name: 3shake-k8s-node-002
Roles: <none>
Labels: beta.kubernetes.io/arch=amd64
beta.kubernetes.io/os=linux
kubernetes.io/arch=amd64
kubernetes.io/hostname=3shake-k8s-node-002
kubernetes.io/os=linux
Annotations: node.alpha.kubernetes.io/ttl: 0
volumes.kubernetes.io/controller-managed-attach-detach: true
CreationTimestamp: Thu, 27 Apr 2023 02:17:40 +0000
Taints: <none>
Unschedulable: false
Lease:
HolderIdentity: 3shake-k8s-node-002
AcquireTime: <unset>
RenewTime: Thu, 27 Apr 2023 05:17:45 +0000
Conditions:
Type Status LastHeartbeatTime LastTransitionTime Reason Message
---- ------ ----------------- ------------------ ------ -------
MemoryPressure False Thu, 27 Apr 2023 05:17:03 +0000 Thu, 27 Apr 2023 02:50:28 +0000 KubeletHasSufficientMemory kubelet has sufficient memory available
DiskPressure False Thu, 27 Apr 2023 05:17:03 +0000 Thu, 27 Apr 2023 02:50:28 +0000 KubeletHasNoDiskPressure kubelet has no disk pressure
PIDPressure False Thu, 27 Apr 2023 05:17:03 +0000 Thu, 27 Apr 2023 02:50:28 +0000 KubeletHasSufficientPID kubelet has sufficient PID available
Ready True Thu, 27 Apr 2023 05:17:03 +0000 Thu, 27 Apr 2023 02:50:28 +0000 KubeletReady kubelet is posting ready status. AppArmor enabled
Addresses:
InternalIP: 192.168.50.63
Hostname: 3shake-k8s-node-002
Capacity:
cpu: 4
ephemeral-storage: 40581564Ki
hugepages-2Mi: 0
memory: 11973936Ki
pods: 110
Allocatable:
cpu: 4
ephemeral-storage: 37399969321
hugepages-2Mi: 0
memory: 11871536Ki
pods: 110
System Info:
Machine ID: 5cf5e5ba72794bfdbbf019e61995028f
System UUID: 5bec1077-cba4-6943-8c3a-5ef99aff4d71
Boot ID: 931e0dec-9af5-4a07-b685-4248572bdbf3
Kernel Version: 5.4.0-146-generic
OS Image: Ubuntu 20.04.5 LTS
Operating System: linux
Architecture: amd64
Container Runtime Version: containerd://1.6.18
Kubelet Version: v1.26.2+k0s
Kube-Proxy Version: v1.26.2+k0s
PodCIDR: 10.244.1.0/24
PodCIDRs: 10.244.1.0/24
Non-terminated Pods: (5 in total)
Namespace Name CPU Requests CPU Limits Memory Requests Memory Limits Age
--------- ---- ------------ ---------- --------------- ------------- ---
default nginx-with-5gi-5df78f6ccb-dmbb7 1 (25%) 0 (0%) 5Gi (44%) 0 (0%) 115m
kube-system coredns-7bf57bcbd8-t4xsk 100m (2%) 0 (0%) 70Mi (0%) 170Mi (1%) 179m
kube-system konnectivity-agent-8cw5g 0 (0%) 0 (0%) 0 (0%) 0 (0%) 3h
kube-system kube-proxy-rgbd9 0 (0%) 0 (0%) 0 (0%) 0 (0%) 3h
kube-system kube-router-p2lhb 250m (6%) 0 (0%) 16Mi (0%) 0 (0%) 3h
Allocated resources:
(Total limits may be over 100 percent, i.e., overcommitted.)
Resource Requests Limits
-------- -------- ------
cpu 1350m (33%) 0 (0%)
memory 5206Mi (44%) 170Mi (1%)
ephemeral-storage 0 (0%) 0 (0%)
hugepages-2Mi 0 (0%) 0 (0%)
Events: <none>
情報提示により、ChatGPTから以下の回答が得られました。
# From ChatGPT
ワーカーノードのリソース状況から、以下のことがわかります。
- 3shake-k8s-node-001:
- CPU: 使用率34% (リクエスト1360m)
- メモリ: 使用率89% (リクエスト10,857,595,776)
- 3shake-k8s-node-002:
- CPU: 使用率33% (リクエスト1350m)
- メモリ: 使用率44% (リクエスト5,206Mi)
どちらのワーカーノードも、CPU使用率は問題なさそうですが、メモリ使用率が高いことがわかります。特に3shake-k8s-node-001では、メモリ使用率が89%となっており、これがパフォーマンス低下の原因となっている可能性があります。
次のステップとして、問題が発生しているPodを特定しましょう。
1. nginx-with-10gi-586b8cfcd-4kfld (3shake-k8s-node-001) と nginx-with-5gi-5df78f6ccb-dmbb7 (3shake-k8s-node-002) の両方のPodのログを確認してください。
- 実行コマンド:
- kubectl logs nginx-with-10gi-586b8cfcd-4kfld
- kubectl logs nginx-with-5gi-5df78f6ccb-dmbb7
2. これらのPodに関連するイベントを確認してください。
- 実行コマンド:
- kubectl describe pod nginx-with-10gi-586b8cfcd-4kfld
- kubectl describe pod nginx-with-5gi-5df78f6ccb-dmbb7
これらのコマンドの結果を共有していただけると、問題の特定に役立ちます。
ChatGPTは問題が発生しているPodを特定すると回答しましたが、提示された方法では、正常に動作しているPodの情報しか取得する事が出来ないため、以下のような提案を行います。
# To ChatGPT
問題が発生しているPodはkubectl get podsでも見つかるのではないのでしょうか?
$ kubectl get pods
NAME READY STATUS RESTARTS AGE
nginx-with-10gi-586b8cfcd-4kfld 1/1 Running 0 139m
nginx-with-10gi-586b8cfcd-84s9k 0/1 Pending 0 139m
nginx-with-5gi-5df78f6ccb-dmbb7 1/1 Running 0 140m
nginx-with-10gi-586b8cfcd-84s9kかと思いますが合っていますでしょうか?
# From ChatGPT
おっしゃる通り、kubectl get pods コマンドを使って問題のあるPodを確認できます。ご提示いただいた結果から、次の状況がわかります。
- nginx-with-10gi-586b8cfcd-4kfld: Running状態で、問題なさそうです。
- nginx-with-10gi-586b8cfcd-84s9k: Pending状態で、まだ実行されていません。これが問題のPodかもしれません。
- nginx-with-5gi-5df78f6ccb-dmbb7: Running状態で、問題なさそうです。
問題のあるPod(nginx-with-10gi-586b8cfcd-84s9k)に関して、以下の情報が必要です。
1. そのPodの詳細を確認してください。
- 実行コマンド: kubectl describe pod nginx-with-10gi-586b8cfcd-84s9k
2. イベントと状態が示されている部分を特に注意して確認してください。
これらの情報をもとに、問題の原因を特定し、解決策を提案できるようになります。
回答に従い、情報共有を行います。
# To ChatGPT
以下に要求された情報を提示します。
$ kubectl describe pod nginx-with-10gi-586b8cfcd-84s9k
Name: 3shake-k8s-node-001
Roles: <none>
Labels: beta.kubernetes.io/arch=amd64
beta.kubernetes.io/os=linux
kubernetes.io/arch=amd64
kubernetes.io/hostname=3shake-k8s-node-001
kubernetes.io/os=linux
Annotations: node.alpha.kubernetes.io/ttl: 0
volumes.kubernetes.io/controller-managed-attach-detach: true
CreationTimestamp: Thu, 27 Apr 2023 02:17:37 +0000
Taints: <none>
Unschedulable: false
Lease:
HolderIdentity: 3shake-k8s-node-001
AcquireTime: <unset>
RenewTime: Thu, 27 Apr 2023 05:17:40 +0000
Conditions:
Type Status LastHeartbeatTime LastTransitionTime Reason Message
---- ------ ----------------- ------------------ ------ -------
MemoryPressure False Thu, 27 Apr 2023 05:16:05 +0000 Thu, 27 Apr 2023 02:20:24 +0000 KubeletHasSufficientMemory kubelet has sufficient memory available
DiskPressure False Thu, 27 Apr 2023 05:16:05 +0000 Thu, 27 Apr 2023 02:20:24 +0000 KubeletHasNoDiskPressure kubelet has no disk pressure
PIDPressure False Thu, 27 Apr 2023 05:16:05 +0000 Thu, 27 Apr 2023 02:20:24 +0000 KubeletHasSufficientPID kubelet has sufficient PID available
Ready True Thu, 27 Apr 2023 05:16:05 +0000 Thu, 27 Apr 2023 02:20:46 +0000 KubeletReady kubelet is posting ready status. AppArmor enabled
Addresses:
InternalIP: 192.168.50.62
Hostname: 3shake-k8s-node-001
Capacity:
cpu: 4
ephemeral-storage: 40581564Ki
hugepages-2Mi: 0
memory: 11973936Ki
pods: 110
Allocatable:
cpu: 4
ephemeral-storage: 37399969321
hugepages-2Mi: 0
memory: 11871536Ki
pods: 110
System Info:
Machine ID: d2828f6258a8434789a32b8d70ca40d6
System UUID: 6dee713d-d208-8942-b70d-e01720945627
Boot ID: 05d5c559-e850-42c1-91df-61f70943c6df
Kernel Version: 5.4.0-146-generic
OS Image: Ubuntu 20.04.5 LTS
Operating System: linux
Architecture: amd64
Container Runtime Version: containerd://1.6.18
Kubelet Version: v1.26.2+k0s
Kube-Proxy Version: v1.26.2+k0s
PodCIDR: 10.244.0.0/24
PodCIDRs: 10.244.0.0/24
Non-terminated Pods: (6 in total)
Namespace Name CPU Requests CPU Limits Memory Requests Memory Limits Age
--------- ---- ------------ ---------- --------------- ------------- ---
default nginx-with-10gi-586b8cfcd-4kfld 1 (25%) 0 (0%) 10Gi (88%) 0 (0%) 115m
kube-system coredns-7bf57bcbd8-7zj4b 100m (2%) 0 (0%) 70Mi (0%) 170Mi (1%) 3h
kube-system konnectivity-agent-grbfz 0 (0%) 0 (0%) 0 (0%) 0 (0%) 3h
kube-system kube-proxy-jzlsk 0 (0%) 0 (0%) 0 (0%) 0 (0%) 3h
kube-system kube-router-55bxq 250m (6%) 0 (0%) 16Mi (0%) 0 (0%) 3h
kube-system metrics-server-7446cc488c-59pkl 10m (0%) 0 (0%) 30M (0%) 0 (0%) 3h
Allocated resources:
(Total limits may be over 100 percent, i.e., overcommitted.)
Resource Requests Limits
-------- -------- ------
cpu 1360m (34%) 0 (0%)
memory 10857595776 (89%) 170Mi (1%)
ephemeral-storage 0 (0%) 0 (0%)
hugepages-2Mi 0 (0%) 0 (0%)
Events: <none>
Name: 3shake-k8s-node-002
Roles: <none>
Labels: beta.kubernetes.io/arch=amd64
beta.kubernetes.io/os=linux
kubernetes.io/arch=amd64
kubernetes.io/hostname=3shake-k8s-node-002
kubernetes.io/os=linux
Annotations: node.alpha.kubernetes.io/ttl: 0
volumes.kubernetes.io/controller-managed-attach-detach: true
CreationTimestamp: Thu, 27 Apr 2023 02:17:40 +0000
Taints: <none>
Unschedulable: false
Lease:
HolderIdentity: 3shake-k8s-node-002
AcquireTime: <unset>
RenewTime: Thu, 27 Apr 2023 05:17:45 +0000
Conditions:
Type Status LastHeartbeatTime LastTransitionTime Reason Message
---- ------ ----------------- ------------------ ------ -------
MemoryPressure False Thu, 27 Apr 2023 05:17:03 +0000 Thu, 27 Apr 2023 02:50:28 +0000 KubeletHasSufficientMemory kubelet has sufficient memory available
DiskPressure False Thu, 27 Apr 2023 05:17:03 +0000 Thu, 27 Apr 2023 02:50:28 +0000 KubeletHasNoDiskPressure kubelet has no disk pressure
PIDPressure False Thu, 27 Apr 2023 05:17:03 +0000 Thu, 27 Apr 2023 02:50:28 +0000 KubeletHasSufficientPID kubelet has sufficient PID available
Ready True Thu, 27 Apr 2023 05:17:03 +0000 Thu, 27 Apr 2023 02:50:28 +0000 KubeletReady kubelet is posting ready status. AppArmor enabled
Addresses:
InternalIP: 192.168.50.63
Hostname: 3shake-k8s-node-002
Capacity:
cpu: 4
ephemeral-storage: 40581564Ki
hugepages-2Mi: 0
memory: 11973936Ki
pods: 110
Allocatable:
cpu: 4
ephemeral-storage: 37399969321
hugepages-2Mi: 0
memory: 11871536Ki
pods: 110
System Info:
Machine ID: 5cf5e5ba72794bfdbbf019e61995028f
System UUID: 5bec1077-cba4-6943-8c3a-5ef99aff4d71
Boot ID: 931e0dec-9af5-4a07-b685-4248572bdbf3
Kernel Version: 5.4.0-146-generic
OS Image: Ubuntu 20.04.5 LTS
Operating System: linux
Architecture: amd64
Container Runtime Version: containerd://1.6.18
Kubelet Version: v1.26.2+k0s
Kube-Proxy Version: v1.26.2+k0s
PodCIDR: 10.244.1.0/24
PodCIDRs: 10.244.1.0/24
Non-terminated Pods: (5 in total)
Namespace Name CPU Requests CPU Limits Memory Requests Memory Limits Age
--------- ---- ------------ ---------- --------------- ------------- ---
default nginx-with-5gi-5df78f6ccb-dmbb7 1 (25%) 0 (0%) 5Gi (44%) 0 (0%) 115m
kube-system coredns-7bf57bcbd8-t4xsk 100m (2%) 0 (0%) 70Mi (0%) 170Mi (1%) 179m
kube-system konnectivity-agent-8cw5g 0 (0%) 0 (0%) 0 (0%) 0 (0%) 3h
kube-system kube-proxy-rgbd9 0 (0%) 0 (0%) 0 (0%) 0 (0%) 3h
kube-system kube-router-p2lhb 250m (6%) 0 (0%) 16Mi (0%) 0 (0%) 3h
Allocated resources:
(Total limits may be over 100 percent, i.e., overcommitted.)
Resource Requests Limits
-------- -------- ------
cpu 1350m (33%) 0 (0%)
memory 5206Mi (44%) 170Mi (1%)
ephemeral-storage 0 (0%) 0 (0%)
hugepages-2Mi 0 (0%) 0 (0%)
Events: <none>
ChatGPTからの回答
# From ChatGPT
`kubectl describe pod` の出力結果から、`nginx-with-10gi-586b8cfcd-84s9k` Pod のスケジューリングに問題があることがわかります。Pod のステータスが Pending のままで、次のイベントが記録されています。
```
Warning FailedScheduling 14m (x27 over 149m) default-scheduler 0/2 nodes are available: 2 Insufficient memory. preemption: 0/2 nodes are available: 2 No preemption victims found for incoming pod..
```
このメッセージによると、利用可能なノードが 0/2 で、2 つのノードともメモリが不足しています。このため、`nginx-with-10gi-586b8cfcd-84s9k` Pod がスケジュールされません。
この問題を解決するためには、以下の方法が考えられます。
1. クラスターに新しいノードを追加し、より多くのリソースを利用可能にする。これにより、メモリ不足の問題が解決される可能性があります。
2. nginx コンテナのリソース要求を見直し、メモリ要求を減らす。ただし、アプリケーションの性能に影響がある場合がありますので、注意が必要です。
まずは、現在のクラスターのリソース使用状況を確認し、適切な解決策を選択してください。リソース要求を変更する場合は、Deployment の YAML ファイルを更新し、再度デプロイしてください。
リソースを追加するか、メモリ要求を減らす選択肢が提示されました。
リソース追加でも解決すると考えますが、ここではメモリリソースを下げる方針を取ります。
# To ChatGPT
二番目の選択肢で進めます。指示をお願いします。
ChatGPTからの回答
# From ChatGPT
2番目の選択肢で進める場合、nginx コンテナのメモリ要求を減らす必要があります。以下の手順で実行してください。
1. まず、Deployment の YAML ファイルを開きます。ファイル名が `nginx-deployment.yaml` と仮定すると、エディタで開きます。
```
$ vi nginx-deployment.yaml
```
2. YAML ファイルの `resources` セクションを探し、`memory` 要求を減らします。例えば、10Gi から 5Gi に変更する場合、以下のように編集します。
```yaml
...
spec:
containers:
- name: nginx
image: nginx:latest
resources:
requests:
cpu: 1
memory: 5Gi
...
```
3. 変更を保存し、ファイルを閉じます。
4. 更新された YAML ファイルを使って、Deployment を再度適用します。
```
$ kubectl apply -f nginx-deployment.yaml
```
5. 変更が適用され、Pod のステータスが更新されるのを確認します。
```
$ kubectl get pods
```
6. 必要に応じて、`kubectl describe pod <POD_NAME>` を使用して、Pod の詳細情報を表示し、問題が解決されたことを確認します。
これらの手順に従って、nginx コンテナのメモリ要求を減らし、クラスター内のノードでスケジュールされるようになるはずです。ただし、メモリ要求を減らすことでアプリケーションの性能に影響がある場合がありますので、注意が必要です。適切なリソース要求値を見つけるために、アプリケーションの性能とリソース使用状況を監視してください。
提示された方法を元に、デプロイメントを編集・適用しました。
結果として、以下の様に、nginx-with-10gi
のPodが2つ、nginx-with-5gi
が一つ正常に動作する事を確認しました。しかし、nginx-with-10gi-788f4bd694-lwkhm
というPodが生成されPending状態です。
本来は不要なPodであるため、ChatGPTに質問をしました。
# 障害発生時のPods
$ kubectl get pods
NAME READY STATUS RESTARTS AGE
nginx-with-10gi-586b8cfcd-4kfld 1/1 Running 0 139m
nginx-with-10gi-586b8cfcd-84s9k 0/1 Pending 0 139m
nginx-with-5gi-5df78f6ccb-dmbb7 1/1 Running 0 140m
# 障害解消後のPods
$ kubectl get pods -o=wide
NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES
nginx-with-10gi-586b8cfcd-4kfld 1/1 Running 0 3h19m 10.244.0.110 3shake-k8s-node-001 <none> <none>
nginx-with-10gi-788f4bd694-lwkhm 0/1 Pending 0 68s <none> <none> <none> <none>
nginx-with-10gi-788f4bd694-zqn94 1/1 Running 0 71s 10.244.1.78 3shake-k8s-node-002 <none> <none>
nginx-with-5gi-5df78f6ccb-dmbb7 1/1 Running 0 3h19m 10.244.1.77 3shake-k8s-node-002 <none> <none>
# To ChatGPT
デプロイメントの定義通りに、nginx-with-10giのPodがそれぞれのノードで一つずつ動作しました。
しかし、デプロイメントの編集後、元々Pending状態になっていたnginx-with-10gi-586b8cfcd-84s9kが消えて、新たなnginx-with-10gi-788f4bd694-lwkhmが生成され、Pendingのまま放置されています。
既に、nginx-with-10gi-586b8cfcd-4kfldとnginx-with-10gi-788f4bd694-zqn94がそれぞれのノードで動作しているため、nginx-with-10gi-788f4bd694-lwkhmは不要なはずです。どうすれば良いですか?
NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES
nginx-with-10gi-586b8cfcd-4kfld 1/1 Running 0 3h19m 10.244.0.110 3shake-k8s-node-001 <none> <none>
nginx-with-10gi-788f4bd694-lwkhm 0/1 Pending 0 68s <none> <none> <none> <none>
nginx-with-10gi-788f4bd694-zqn94 1/1 Running 0 71s 10.244.1.78 3shake-k8s-node-002 <none> <none>
nginx-with-5gi-5df78f6ccb-dmbb7 1/1 Running 0 3h19m 10.244.1.77 3shake-k8s-node-002 <none> <none>
ChatGPTからの回答
# From ChatGPT
デプロイメントの編集後、新しいレプリカセットが作成され、古いレプリカセットがまだ存在しているため、このような状況が発生しています。古いレプリカセットから不要なPodを削除することで、問題を解決できます。
まず、現在のレプリカセットを確認して、古いものを特定します。
```
$ kubectl get replicaset
```
次に、不要な古いレプリカセットのレプリカ数を0にスケールダウンします。以下のコマンドでは、`<OLD_REPLICASET_NAME>` を古いレプリカセットの名前に置き換えて実行してください。
```
$ kubectl scale replicaset <OLD_REPLICASET_NAME> --replicas=0
```
これにより、古いレプリカセットが管理する不要なPodが削除されます。その後、`kubectl get pods` を使用して、不要なPodが削除されたことを確認できます。
ただし、将来的に同じ問題が発生しないように、デプロイメントに `spec.strategy.type` を `Recreate` に設定して、デプロイメントが更新されるたびに古いPodがすべて削除されてから新しいPodが作成されるようにします。これを行うには、デプロイメントのYAMLファイルを開いて、次のように編集します。
```yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: nginx-deployment
spec:
strategy:
type: Recreate
...
```
変更を保存し、ファイルを閉じた後、更新されたYAMLファイルを適用します。
```
$ kubectl apply -f nginx-deployment.yaml
```
これで、今後デプロイメントが更新されるたびに、古いPodが削除されてから新しいPodが作成されるようになります。
提示された方法により、不要なPod(nginx-with-10gi-788f4bd694-lwkhm
)が除去された事が確認できました。
以上で二次対応(トラブルシューティング)が完了です。
$ kubectl get pods -o=wide
NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES
nginx-with-10gi-788f4bd694-lwkhm 1/1 Running 0 50m 10.244.0.111 3shake-k8s-node-001 <none> <none>
nginx-with-10gi-788f4bd694-zqn94 1/1 Running 0 50m 10.244.1.78 3shake-k8s-node-002 <none> <none>
nginx-with-5gi-5df78f6ccb-dmbb7 1/1 Running 0 4h9m 10.244.1.77 3shake-k8s-node-002 <none> <none>
二次対応(トラブルシューティング)の評価
今回設定した障害シナリオは「新しくデプロイするdeploymentが、ノードのメモリリソースの上限よりも多くメモリを要求し、新しいPodが配置できない」でした。評価を以下に示します。
- 評価1:デバッグ・調査方針が適切に定められるか?
状況を把握するため、ワーカーノードのリソース状況の分析、問題が発生しているPodの特定作業等を行いましたが、デバッグ・調査方針としては、概ね適切であると感じました。
しかし、分析過程でChatGPTが提示した手法に無効なものがあり、こちらから最適な手法を提示しました。 - 評価2:ChatGPTだけの指示で復旧を行えるか?
障害内容から調査方針を定めて、障害に関するログや情報を分析させる事は可能だが、ChatGPTに全てを対処させる事は困難であると考えます。あくまで、人間が主体的に障害対応にあたり、ChatGPTには情報分析や、補助、または「○○という可能性を調査するにはどういう手法があるか?」といった強力な効率化ツールとして扱う事が適切であると考えます。
8. おわりに
本記事では、Kubernetes運用時の障害を想定して、初期対応と二次対応をChatGPT-4に対応させました。
初期対応では、Kubernetes Event logから障害情報の抽出、要約説明、影響範囲等を説明する事が出来ました。二次対応では、ChatGPTにトラブルシューティングを行わせ、結果として、障害解決に至りましたが人間が主体的に対応しなければ、無効な手法や最適では無いアクションに行きつく事が分かりました。
以上の内容から、「Kuberentes × ChatGPT = 運用効率化」というテーマにおいて、ChatGPTを障害対応(初期対応・二次対応)に組み込む事を想定した場合、ChatGPTに任せっきりというのは適切ではないと考えられそうです。
あくまで、ChatGPTは、障害の調査方針、情報分析・整理、検証方法を効率的に提示する強力なツール、という立ち位置が適切で、障害対応自体は人間が主体的に進める必要があると感じました。
また、本記事の執筆中に Kubernetes クラスタ内部の問題を検索するK8sGPTと呼ばれる技術が登場したため、今後、K8sGPTに関する調査も行いたいと思っています。