メインコンテンツまでスキップ

kubectl よく使うコマンド

· 約8分

日々 Kubernetes クラスタと付き合っていると、ほとんどの操作は kubectl を避けて通れません。コマンド自体は難しくないのですが、難しいのは使いたいときに思い出せないことです。特にノードのメンテナンスや強制削除といった、頻度は低いけれど重要な操作ほどそうです。この記事では、普段最もよく使うコマンドをシーン別に整理しました。忘れたらここに戻って見返します。

kubectl のすべての操作は、本質的には kube-apiserver への REST リクエストです。参照は GET、設定の適用は望ましい状態(desired state)への宣言的な更新、削除はオブジェクトを etcd から取り除き、各コントローラーが実際の状態を収束させる、という流れです。この点を理解しておくと、多くのコマンドの挙動が説明しやすくなります。

まずは最も基本的なところから。パラメータの書き方が不確かなときは、ヘルプ情報が常に最初の入り口です。

# ヘルプ情報を表示。サブコマンドに対しても使える(例: kubectl get --help)
kubectl --help

クラスタとノードの確認

# クラスタのノード数と各ノードの状態(Ready / NotReady)を確認
kubectl get nodes

# node ノードの詳細情報を表示:pod 情報とハードウェアリソースの使用状況
# ノードのリソース不足や Pod がスケジュールできない問題の調査でよく使う
kubectl describe node <ノード名>

describe node の出力では、Conditions、Allocated resources、Events の 3 セクションが最も情報量が多く、ノードに異常があるときはまずここを見ましょう。

Namespace と Pod の確認

Kubernetes は Namespace でリソースを分離しています。参照系コマンドの多くは -n で Namespace を指定する必要があり、指定しない場合はデフォルトで default になります。

# Namespace を確認
kubectl get namespace

# 対応する Namespace 配下の pod 情報を確認
kubectl get pod -n <Namespace>

# すべての Namespace 配下の pod を確認。-A は --all-namespaces の短縮形
kubectl get pods -A

# すべての Namespace 配下の pod を確認(完全なパラメータ表記は --all-namespaces)
kubectl get pod --all-namespace

具体的な Pod を特定した後のトラブルシューティングは、主に describe と logs の 2 つのコマンドで行います。片方はイベントを、もう片方はログを見るためのものです。

# 1 つまたは複数のリソースオブジェクトの詳細情報を表示
# スケジュール失敗、イメージの pull 失敗などの原因はすべて Events に出てくる
kubectl describe

# pod リソースオブジェクト内の 1 つのコンテナのログを出力
# マルチコンテナ Pod では -c でコンテナ名を指定する必要がある
kubectl logs

ひとつ経験則を。Pod が起動しないときはまず describe でイベントを見て、起動しているのに挙動がおかしいときに logs でログを見る。この順序を逆にすると、たいてい無駄に時間を費やすことになります。

リソースの作成と削除

kubectl のリソース管理には 2 つのスタイルがあります。create は命令的で、クラスタに何を作るかを直接指示します。apply は宣言的で、yaml に記述した望ましい状態をクラスタに提出し、既存であれば差分更新を行います。日常的な設定ファイルのメンテナンスには apply がおすすめで、同じファイルを何度でも実行できます。

# yaml/json ファイルまたは標準入力からリソースオブジェクトを作成
kubectl create

# pod 設定ファイルを適用し、リソースを設定。適用済みのファイルなら差分更新になる
kubectl apply -f <pod.yaml>

# pod 設定ファイルの適用を取り消し、リソースを削除
kubectl delete -f <pod.yaml>

# 指定した Namespace 配下の Deployment を削除
# 注意:Deployment を削除すると、それが管理する ReplicaSet と Pod もカスケード削除される
kubectl delete Deployments -n <Namespace> <Deployment名>

一括クリーンアップと強制削除のコマンドです。破壊力は順に大きくなっていきます。

# Terminating 状態のままの pod を強制削除
# --grace-period=0 は graceful shutdown の待機をスキップすることを意味する
kubectl delete pod <podname> -n <namespace> --force --grace-period=0

# ある namespace 配下のすべての pod を削除
# Deployment などのコントローラーに管理されている Pod は自動的に再作成される
kubectl delete --all pods --namespace=<namespace>

# namespace ごと削除。配下のすべてのリソースがまとめてカスケード削除される
kubectl delete ns <namespace>

さらに変更系のコマンドが 2 つあります。リソースにラベルを付けたり、設定を一時的に変更したりするのに使います。

# リソースのラベルを設定。ラベルは Service がバックエンドを選択したり、ノードアフィニティでスケジュールしたりする際の根拠になる
kubectl label

# デフォルトエディタでサーバー上に定義されたリソースオブジェクトを編集。保存すると即時反映される
kubectl edit

edit は緊急デバッグに向いていますが、変更はローカルの yaml ファイルには同期されません。変更後は忘れずに設定ファイルへ反映しましょう。そうしないと次回の apply で上書きされてしまいます。

ノードのメンテナンス

ノードをメンテナンス(カーネルアップグレード、ハードウェア交換)のためにオフラインにする標準フローは、まず cordon、それから drain です。cordon はノードをスケジュール不可としてマークするだけで、既存の Pod には影響しません。drain はそれに加えて、ノード上の既存 Pod を退避させ、コントローラーが他のノードで再作成します。

# ノードを退避準備:ノードをスケジュール不可としてマークし、新しい Pod はこのノードにスケジュールされなくなる
kubectl cordon <ノード名>

# ノードの pod を退避
kubectl drain

# そのノードのすべての pod を退避
# --ignore-daemonsets:DaemonSet 管理の Pod をスキップ(もともと各ノードに 1 つずつ存在し、退避しても再作成される)
# --delete-local-data:emptyDir のローカルデータを使う Pod も併せて削除
kubectl drain <ノード名> --delete-local-data --force --ignore-daemonsets

# メンテナンス完了後、クラスタから node ノードを削除
kubectl delete nodes <ノード名>

リソース設定のエクスポート

本番環境で手動変更したリソースの現在の状態を yaml ファイルとして固定化したいときは、-o yaml とリダイレクトを組み合わせてエクスポートできます。

# 既存の pod を yaml 設定ファイルとしてエクスポート
kubectl get deployment -n <Namespace> <pod名> -o yaml > <ファイル名>.yaml

エクスポートされた yaml には status、resourceVersion、uid といったクラスタランタイムのフィールドが含まれます。別の場所で apply する前に、これらをクリーンアップして spec 関連の部分だけを残すのがよいでしょう。

ハマりどころと注意点

1)--all-namespace という表記は覚え間違えやすく、完全なパラメータは --all-namespaces(s 付き)です。日常的には短縮形の -A を使うのが一番手軽です。

2)--force --grace-period=0 による強制削除は、API Server にオブジェクトを即時に取り除かせるだけで、コンテナのプロセスが本当に終了したとは限りません。ステートフルなサービスでは慎重に使いましょう。同一インスタンスが「スプリットブレイン」的に 2 つ動いてしまう恐れがあります。

3)Namespace の削除はカスケード操作で、配下の Deployment、Service、ConfigMap がすべて一緒に消えます。実行前に kubectl get all -n <namespace> で中に何が残っているかを一度確認しましょう。

4)drain の際に --ignore-daemonsets を付けないと、DaemonSet 管理の Pod に遭遇した時点でコマンドがエラーで中断します。また --delete-local-data は新しいバージョンでは --delete-emptydir-data に改名されています。旧パラメータでエラーになったら新しい名前に替えてください。

警告

drain は実際に業務 Pod を退避させます。本番環境で実行する前に、レプリカ数が十分か、他のノードに余裕があるかを確認し、サービス容量の急落を避けてください。

まとめ

このリストは、確認、作成と削除、ノードのメンテナンス、設定のエクスポートという 4 つの高頻度シーンをカバーしています。コマンドを全部覚えられなくても大丈夫です。2 つの流れさえ覚えておけば十分です。参照とトラブルシューティングは get → describe → logs、ノードのオフライン化は cordon → drain → delete node。それ以外は、--help でいつでも調べられます。

COMMENTS