皆様、こんにちは!
アイレット株式会社 DX開発事業部の楊林と申します。
前回の投稿ではKubernetes の基礎について紹介しましたが、今回は実際に Kubernetes はどう構成していくのかについて掘り下げていきます。
Kubernetesの構成方法
Kubernetes では、宣言型と命令型のどちらの方法でも構成できます。宣言型は望ましい状態を YAML ファイルに書いておき、あとは Kubernetes がその状態に合わせてくれる方式です。対して命令型は、管理者がコマンドを発行して直接クラスタの状態を変えるやり方です。
Kubernetes の本質は、クラスタの内部で常に watch ループが動き続け、宣言された理想状態に自動で合わせ続けてくれるところにあります。障害が起きても、Pod が落ちても、適切な数の Pod を立ち上げ直し、理想状態を保とうとします。そのため、大半の運用は宣言型で行われ、命令型はあくまで補助的な用途で使われることが多いです。
宣言型で構成する場合は Deployment のようなマニフェストファイルを用意し、kubectl apply で適用します。レプリカ数を増やしたい場合も、YAML の replicas の値を変えて apply するだけで、Kubernetes が自動的に必要な数の Pod を作ってくれます。反対に命令型で scale コマンドなどを使う方法もありますが、最終的に管理対象を一元化したいなら YAML に寄せていくのが定石です。
オブジェクトとマニフェスト管理
Kubernetes クラスタの中で作られるすべてのオブジェクトには、一意の名前と UID がつきます。これらは YAML または JSON のマニフェストファイルとして記述し、Git などでバージョン管理されるのが一般的です。
マニフェストには主に以下の基本項目があります:
- apiVersion:オブジェクトを作成するKubernetes APIバージョンを示します。
- kind:必要なオブジェクトのタイプを示します、例えばPodなど。
- metadata:オブジェクトの名前、一意のID、 オプションの名前空間を識別するためです。
metadata の name は、同一 namespace 内では重複できない重要な識別子になります。また labels は整理に欠かせない仕組みで、Deployment から Pod をひもづける際にも使われます。ラベルは後から追加したり変更したりでき、kubectl のラベルセレクタで簡単に検索できます。
複数のオブジェクトが密接に関係している場合は、同じ YAML ファイルにまとめておくと管理が楽です。Git などにまとめて保存しておくと、クラスタの再構築やロールバックも簡単になります。GCP で構成管理を行う場合は Cloud Source Repositories を使うパターンがよく見られます。
また、Kubernetes の Pod は使い捨てを前提にしているため、自己修復機能はありません。永続的に運用したい場合は Deployment、StatefulSet、DaemonSet、Job といったコントローラオブジェクトを使い、コントローラに Pod のライフサイクル管理を任せる形になります。
kubectl の役割と構成
kubectl は Kubernetes 管理の中心ツールで、ユーザーが入力したコマンドを Kubernetes API へのリクエストに変換し、kube-apiserver と通信してくれます。ただし kubectl 自体は既存クラスタへの操作ツールであり、クラスタの作成や GKE の設定変更はできません。クラスタの作成・管理は gcloud やコンソール側の役割です。
kubectl がクラスタにアクセスする際は ~/.kube/config の内容を参照します。この中にはクラスタの一覧・認証情報・コンテキスト設定がまとまっており、kubectl はここを元にしてアクセス先を判断します。Cloud Shell を使う場合、gcloud get-credentials を実行すると自動でこのファイルが書き換えられるため、基本はそれだけで接続できます。
kubectlは既存クラスタの内部状態を管理するためのツールですが、新しいクラスタの作成や既存クラスタの形式の変更はできません。そうした操作はGoogle Cloudコンソールやgcloudコマンドを通じてGKEコントロールプレーンで行います。
kubectlの構文は4つの部分で構成されます。
- コマンド:get、describe、logs、execなど、実行するアクションを指定します。情報を表示するコマンドもあれば、クラスタの構成を変更するコマンドもあります。
- 型:処理するオブジェクトの型を指定します。pods、deployments、nodesなどに加え、クラスタ自体も指定できます。
- 名前:オブジェクトを指定します。必須ではありません、特に情報表示のコマンドではよく省略されます。
- オプション:一部のコマンドの末尾に追加して、特別なリクエストを実行できます。追加情報を表示する場合にも使用できます。
kubectlを利用して必要な情報を手軽に取得したり、構成ファイルを適用したりできます。目的のクラスタに確実に向けて操作したい場合は --kubeconfig や --context を指定すると安全です。
## 認証情報の取得とローリングアップデート
GKEクラスタを kubectl で操作するには、まず gcloud get-credentials を実行して認証情報を取得する必要があります。Cloud Shell なら gcloud と kubectl が最初からインストールされているため、すぐに利用できます。一度取得すれば ~/.kube/config に保存され、同じクラスタで再設定する必要はありません。
アプリのバージョンアップ時には、Deployment を更新し、kubectl apply または kubectl rollout で変更を適用します。Kubernetes が自動でローリングアップデートを行い、新しい Pod が安定したら古い Pod を削除するため、サービス停止を最小限に抑えつつ安全に更新できます。
トラブルシューティング
アプリやクラスタで問題が起きたときは、kubectl のいくつかのコマンドを使って状態を調べていきます。
get
getコマンドでPodのフェーズのステータスを確認できます。フェーズとは、Podやそのコンテナの包括的な詳細情報ではなく、概要をまとめたものです。
以下のステータスがあります:
- Pending:KubernetesがまだPodのスケジュール中であることを示します。Pod用に定義されたコンテナイメージがまだコンテナランタイムによって作成されていない状態です。
- Running:Podはノードに正常にアタッチされ、コンテナが全部作成され、Pod内のコンテナが起動中、再起動中、または継続的に実行中の状態です。
- Succeeded:すべてのコンテナが正常に実行完了したか、正常に終了し再起動されないことを表します。
- Failed:コンテナが失敗して終了し再起動されないことを表します。
- Unknown:Podの状態を取得できないことを表します。コントロールプレーンとkubelet間の 通信エラーなどが考えられます。
- CrashLoopBackOff:Pod内に予期せぬ終了と再起動を繰り返しているコンテナがあることを表します。これはよくあるエラーで、通常はPodが適切に構成されていないことが原因です。
describe
describeコマンドでPodを詳しく調べ、Podとコンテナの情報や詳しいステータス情報を取得できます。
Podについて名前、名前空間、ノード名、 ラベル、ステータス、IPアドレスが表示されます。
コンテナについて状態、イメージ、ポート、コマンド、 再起動回数が表示されます。
exec
execコマンドでコンテナ内で単一のコマンドを実行でき、結果が独自のコマンドシェルに表示されます。pingなどの単一のコマンドを実行する場合に便利です。
Pod内での作業が必要になる場合、-itスイッチを使用してインタラクティブシェルを起動します。-i引数はターミナルの標準入力をコンテナに渡すようにkubectlに指示します。-t引数は入力がTTYであることをkubectlに通知します。
これでシェルがコンテナに接続され、コンテナ内で作業できます。これでコンテナの標準入力と標準出力がターミナルウィンドウか、コマンドシェルに接続されます。
logs
logsコマンドはPod内の状態を確認できます。Pod内で動作するアプリによって書き込まれたエラーやデバッグメッセージを確認できるので、トラブルシューティングに役立ちます。
ログにはコンテナ内のアプリが生成した標準出力(stdout)と標準エラーメッセージ(stdeer)が含まれます。正常に実行されなかったコンテナの詳細情報を確認する必要がある場合に特に便利です。
Podに複数のコンテナがある場合には、-c引数を使用してPod内の特定のコンテナのログを表示できます。
ただし、コンテナ内に直接パッケージをインストールして問題を解消するのは避けた方がよいです。コンテナは一時的なものなので、調査してわかった修正点はコンテナイメージに反映し、再デプロイするのが正しい運用です。
最後に
今回の記事では、前回の Kubernetes 基礎に続き、実際に Kubernetes をどう構成して管理していくかをテーマにまとめました。
次回はいよいよ Google Kubernetes Engine(GKE) に踏み込んでいきます。
ぜひ続けて読んでいただけると嬉しいです!
以前の投稿
【Google Cloud入門】クラウドサービスの特徴とGoogle Cloudの触り方
【Google Cloud入門】リソースマネージメント
【Google Cloud入門】アクセス管理の基本 - IAM
【Google Cloud入門】サービスアカウントとCloud Identity
【Google Cloud入門】Compute Engineの基礎
【Google Cloud入門】コンピューティングオプションとマネージドインスタンスグループ
【Google Cloud入門】GKE入門の前準備-コンテナの基礎
【Google Cloud入門】GKE入門の前準備-Kubernetesの基礎