Kubernetes クラスターを探索する

KubernetesBeginner
オンラインで実践に進む

はじめに

現在のアプリケーションは、多くの場合 コンテナ としてパッケージ化されています。コンテナは、アプリケーションの実行に必要なライブラリや設定をアプリケーションと一緒にまとめるため、どの環境でも一貫して動かしやすくなります。1 つのコンテナを実行するのは簡単です。しかし、多数のコンテナを安定して運用するには、どこで実行するか、失敗したコンテナをどう再起動するか、アプリケーション同士をどう接続するか、変更をどう安全に反映するかといった判断が必要になります。

Kubernetes は、こうしたクラスター全体に関わる役割を担うコンテナオーケストレーションシステムです。たとえば「この Web アプリケーションを 3 つ実行する」といった望ましい状態を宣言すると、Kubernetes は実際の状態がその状態に一致し続けるように継続的に調整します。

Kubernetes の クラスター は、ノード と呼ばれる 1 台以上のマシンで構成されます。コントロールプレーン がクラスターを管理し、ノードはアプリケーションが利用する CPU、メモリ、ネットワーク、コンテナランタイムを提供します。アプリケーションは、Pod、Deployment、Service などの Kubernetes オブジェクトとして実行されます。

この最初の実験では、まだアプリケーションをデプロイしません。まずは、実際のクラスター内で状況を把握する方法を学びます。

  1. 使用するツール、アクティブなクラスター、Kubernetes のバージョン、ノードの正常性を確認する。
  2. Kubernetes を動かしているコントロールプレーンとノードのコンポーネントを見つける。
  3. クラスターのエンドポイントとノードの詳細情報を調査する。
  4. Namespace をまたいで Pod、Deployment、Service を探索する。

環境はすでに準備されているため、インストールではなく Kubernetes の概念に集中できます。この環境では、labex-v135 というプロファイル名の Minikube v1.38.1 上で Kubernetes v1.35.5 が稼働しています。Minikube は LabEx の VM 上にある Docker コンテナ内で、完全な Kubernetes クラスターを実行します。これは学習用の単一ノード環境ですが、ここで練習する Kubernetes のコマンドや概念は、より大規模なクラスターにもそのまま応用できます。

作業はすべてターミナルで行います。各コマンドを実行する前に説明を読み、実際の出力を記載された確認ポイントと照らし合わせてください。正確な経過時間、再起動回数、生成された名前は異なる場合がありますが、稼働中のシステムでは正常なことです。

事前構成済みクラスターを確認する

環境の起動: この実験では、完全な Kubernetes クラスターが起動します。コントロールプレーン、ノード、ネットワークコンポーネントの構成には通常 2~3 分かかります。環境の読み込みが完了するまで、そのままお待ちください。

このステップでは、ターミナルのツールが Kubernetes に接続する仕組み、用意されているソフトウェアのバージョン、クラスターが使用可能な状態であることを確認します。クラスターを変更する前に、現在どのクラスターが選択されていて、正常に動作しているかを把握することは、管理者にとって基本的な手順です。

ツールを理解する

ここでは、関連する 2 つのコマンドラインツールを使用します。

  • minikube はローカル Kubernetes クラスターを作成・管理します。名前付きの Minikube 環境は プロファイル と呼ばれます。この実験では labex-v135 プロファイルを使用します。
  • kubectl は Kubernetes の標準コマンドラインクライアントです。Kubernetes API サーバーにリクエストを送り、オブジェクトの一覧表示、作成、更新、削除を行います。

クラスターはすでに起動しています。minikube start は実行しないでください。不要なうえ、Minikube が既存環境を再確認するために待ち時間が発生する可能性があります。

作業ディレクトリに移動する

後の実験でマニフェストや、受講者が作成するファイルを保存するプロジェクトディレクトリに移動します。

cd /home/labex/project

cd コマンドはシェルの現在のディレクトリを変更します。成功した場合、通常は何も出力されません。

Minikube のバージョンを確認する

インストールされている Minikube のバージョンを表示します。-- で始まるオプションは、コマンドの動作を変更します。ここでは --short によってバージョン番号だけを表示します。

minikube version --short
v1.38.1

これはクラスター管理ツールのバージョンであり、Kubernetes のバージョンではありません。Minikube と Kubernetes は別々のプロジェクトで、それぞれ異なるバージョン番号を持ちます。

クライアントとサーバーのバージョンを確認する

kubectl にバージョン情報を問い合わせます。このコマンドはクラスターに接続するため、ローカルクライアントとリモート API サーバーの両方を確認できます。

kubectl version
Client Version: v1.35.5
Kustomize Version: ...
Server Version: v1.35.5

Client Version はインストールされている kubectl のバージョン、Server Version は Kubernetes API サーバーが報告するバージョンです。サーバーの行が表示されれば、kubectl がクラスターに正常に到達できたことが分かります。Kustomize はマニフェストのカスタマイズ機能として組み込まれていますが、この実験では使用しません。

アクティブなコンテキストを確認する

1 台のコンピューターには、複数のクラスターへの接続情報を kubeconfig ファイルに保存できます。kubeconfig の コンテキスト は、クラスター、ユーザー認証情報、デフォルト Namespace を選択します。現在のコンテキストを確認することで、誤ったクラスターで作業する事故を防げます。

kubectl config current-context
labex-v135

これは、準備済みの Kubernetes v1.35 プロファイルと一致します。

コンテキストを一覧表示して選択する

実際の kubeconfig ファイルには、複数のコンテキストが含まれていることがよくあります。名前を推測せずに切り替えられるよう、まず一覧表示します。

kubectl config get-contexts

NAME 列にはコンテキスト名が表示され、CURRENT 列ではアクティブなコンテキストに * が付きます。各コンテキストに関連付けられたクラスター、認証情報、デフォルト Namespace は、その他の列に表示されます。

コンテキストを選択する必要がある場合は、use-context を使用します。すでに現在選択されている labex-v135 をもう一度選択しても安全です。実際のコンテキスト切り替え手順を練習するため、ここでも実行します。

kubectl config use-context labex-v135
Switched to context "labex-v135".

current-context は「どれが選択されているか」を確認し、get-contexts は「どの選択肢が存在するか」を確認します。use-context NAME は選択先を変更します。これらのコマンドが変更するのはローカルクライアントの選択だけであり、クラスターを起動・停止したり、クラスター自体を変更したりすることはありません。

Minikube プロファイルを確認する

このプロファイルの状態を Minikube に問い合わせます。短いオプション -pprofile を意味し、その後にプロファイル名を指定します。

minikube status -p labex-v135
labex-v135
type: Control Plane
host: Running
kubelet: Running
apiserver: Running
kubeconfig: Configured

host は Minikube のノードコンテナが実行中であることを示します。kubelet はノードエージェントです。apiserver は Kubernetes API のエンドポイントです。kubeconfig: Configured は、ローカルクライアントの設定がこのクラスターを指していることを意味します。すべてが正常な状態である必要があります。

ノードを一覧表示する

多くの kubectl コマンドは、kubectl <verb> <resource> という形式で使用します。ここでは、get がオブジェクトを読み取り、nodes がリソース種別を表します。

kubectl get nodes
NAME         STATUS   ROLES           AGE   VERSION
labex-v135   Ready    control-plane   ...   v1.35.5

NAME はノードを識別します。STATUS=Ready は、そのノードでワークロードを実行できることを意味します。ROLES は、そのノードがコントロールプレーンをホストしていることを示します。イメージが準備済みスナップショットを復元するため、AGE は今回のセッションより長い場合があります。VERSION は kubelet のバージョンです。

この実験環境では、1 つのノードがコントロールプレーンとワークロードの両方を担当しています。本番クラスターでは、通常これらの役割を複数のマシンに分散します。

ステップの確認

kubectl が意図した labex-v135 クラスターに接続でき、そのノードが Kubernetes v1.35.5 上で Ready であることを確認しました。これは、初めて扱うクラスターに入ったときに役立つ基本的な確認手順です。

Kubernetes アーキテクチャのコンポーネントを特定する

このステップでは、Kubernetes のアーキテクチャモデルを実際のコンポーネントと結び付けます。API サーバー、スケジューラー、kubelet といった名前も、実際に稼働している Pod を確認すると覚えやすくなります。

Kubernetes 内でリクエストが処理される流れ

Kubernetes に Web アプリケーションの実行を依頼する場面を想像してください。まず、kubectlkube-apiserver にリクエストを送り、kube-apiserver がそれを検証して、望ましい状態を etcd に保存します。

次に、kube-scheduler が新しい Pod ごとに実行先のノードを選びます。kube-controller-manager はクラスターを監視し、実際の状態が望ましい状態に一致するように調整します。

最後に、選択されたノード上の kubelet がコンテナランタイムに Pod のコンテナを起動するよう依頼します。ネットワークコンポーネントは、Pod と Service が相互に通信できるようにします。

望ましい状態と実際の状態を継続的に比較し、差異を埋めていく仕組みを リコンシリエーション と呼びます。Deployment が 3 つの Pod を要求しているのに 2 つしか存在しない場合、コントローラーが不足している Pod を作成します。

Pod とシステム Namespace を理解する

Pod は、Kubernetes でデプロイ可能な最小単位です。密接に関連する 1 つ以上のコンテナをまとめ、共有ネットワークとストレージのコンテキストを提供します。

Namespace は、Namespace に属するオブジェクトの論理的な範囲を提供します。kube-system にはクラスターの基盤コンポーネントが含まれます。-n kube-system は、デフォルト Namespace ではなく、kube-system 内を検索するよう kubectl に指示します。より長い書き方は --namespace=kube-system で、どちらも同じ範囲を選択します。

Minikube はコントロールプレーンのコンポーネントを 静的 Pod として実行します。kubelet はこれらをノード上のファイルから直接作成するため、通常のスケジューリングが利用可能になる前にコントロールプレーンを起動できます。

コントロールプレーンを一覧表示する

オブジェクトには ラベル を付けられます。ラベルはグループ化や選択に使用するキーと値のメタデータです。-l tier=control-plane を使用して、そのラベルを持つ Pod を選択します。

kubectl get pods -n kube-system -l tier=control-plane
NAME                                 READY   STATUS    RESTARTS   AGE
etcd-labex-v135                      1/1     Running   ...        ...
kube-apiserver-labex-v135            1/1     Running   ...        ...
kube-controller-manager-labex-v135   1/1     Running   ...        ...
kube-scheduler-labex-v135            1/1     Running   ...        ...

API サーバーは Kubernetes への入口です。etcd はクラスターの状態を保存します。スケジューラーは Pod の配置先を選びます。コントローラーマネージャーは、状態を調整するコントローラーを実行します。

READY=1/1 は、Pod に含まれる 1 つのコンテナが準備完了であることを意味します。長時間稼働するコンポーネントは Running になっている必要があります。保存されたクラスターを再開した後では、RESTARTS が 0 以外になる場合があります。AGE は、この実験での経過時間ではなく、オブジェクトが作成されてからの時間を示します。

ラベルを調査する

最後の列にラベルを表示します。

kubectl get pods -n kube-system -l tier=control-plane --show-labels

component=kube-apiservertier=control-plane を確認してください。前者はコンポーネントを識別し、後者はすべてのコントロールプレーン Pod をグループ化します。ラベルはオブジェクトを識別し、セレクターは一致するオブジェクトを検索します。

ノードのネットワークコンポーネントを調査する

k8s-appkube-proxy または calico-node のいずれかであることを意味する集合ベースのセレクターを使用します。引用符は、シェルが括弧を解釈しないようにするためのものです。

kubectl get pods -n kube-system -l 'k8s-app in (kube-proxy,calico-node)'
NAME                READY   STATUS    RESTARTS   AGE
calico-node-...     1/1     Running   ...        ...
kube-proxy-...      1/1     Running   ...        ...

Calico は Pod のネットワークを構成します。kube-proxy は、Service が Pod にトラフィックを転送できるように、ノード上のルールを維持します。kubelet がこの一覧にないのは、Pod の運用を担うホストエージェントであり、自身が管理する通常の Pod としてではなく、ホストサービスとして実行されるためです。

ステップの確認

API サーバーはリクエストを受け付け、etcd は状態を保存し、スケジューラーは配置先を選び、コントローラーは状態を調整します。kubelet はノードを運用し、Calico と kube-proxy はネットワークを支えます。

クラスターとノードの詳細を調査する

このステップでは、単純な正常性確認から、より詳細な調査へ進みます。Kubernetes には簡潔な一覧表示と詳細な説明表示が用意されています。どちらを使うべきかを判断できることは、トラブルシューティングに欠かせない習慣です。

クラスターのエンドポイントを確認する

kubectl cluster-info は、状況を把握するための専用コマンドです。kubectl get のように特定のリソース種別を一覧表示するのではなく、アクティブなクラスターに問い合わせて、API サーバーや CoreDNS など重要なサービスのアドレスを表示します。

kubectl cluster-info
Kubernetes control plane is running at https://...
CoreDNS is running at https://...

コントロールプレーンの URL は API サーバーのエンドポイントです。CoreDNS は DNS によるサービスディスカバリを提供し、変化する IP アドレスを直接管理しなくても、名前で Service を見つけられるようにします。アドレスは環境によって異なるため、API サーバーが情報を返したことを示す is running に注目してください。ただし、これだけで全ワークロードが正常だと証明できるわけではありません。

ノード一覧を拡張する

-o wide を追加すると、より多くの列を表示できます。

kubectl get nodes -o wide
NAME         STATUS   ROLES           AGE   VERSION   INTERNAL-IP    ...   OS-IMAGE
labex-v135   Ready    control-plane   ...   v1.35.5   192.168.49.2   ...   Debian GNU/Linux 12 (bookworm)

INTERNAL-IP は、クラスター内部ネットワークで使用されるノードのアドレスです。EXTERNAL-IP=<none> は、Kubernetes が管理するパブリックアドレスが割り当てられていないことを意味します。OS-IMAGEKERNEL-VERSIONCONTAINER-RUNTIME は、ノードのソフトウェア情報を示します。

LabEx のバックエンドは Ubuntu 22.04 ですが、Minikube は Debian ベースの Docker コンテナによって Kubernetes ノードを表現します。ここで Debian と表示されるのは想定どおりです。

ノードを詳細表示する

一覧の情報だけでは不十分な場合は、describe を使用します。形式は kubectl describe <resource-type> <name> です。ここではリソース種別が node、オブジェクト名が labex-v135 です。

kubectl describe node labex-v135

上部付近で、ノードの識別情報とスケジューリング設定を確認します。

Name:               labex-v135
Roles:              control-plane
Taints:             <none>
Unschedulable:      false

Taints は、許容設定を持たない Pod をノードから遠ざけるために使用できます。<none> は、この学習用ノードに Taint がないことを意味します。Unschedulable: false は、Kubernetes がこのノードにワークロードを配置できることを示します。

Conditions テーブルを探します。

Type                 Status   ...   Reason
NetworkUnavailable   False    ...   CalicoIsUp
MemoryPressure       False    ...   KubeletHasSufficientMemory
DiskPressure          False    ...   KubeletHasNoDiskPressure
PIDPressure           False    ...   KubeletHasSufficientPID
Ready                True     ...   KubeletReady

圧力状態や利用不能状態では、問題が発生していないことを示す False が正常です。一方、Ready では True が正常です。必ず状態名と値を組み合わせて読み取ってください。

Capacity は、ノードが報告するリソースの総量です。Allocatable は、システム用の予約分を差し引いた後に Pod へ提供できるリソース量です。System Info には、ランタイムと kubelet の情報が表示されます。その後には、Pod、割り当てられたリクエストと制限、イベントなどが一覧表示されます。正確な値やタイムスタンプは変わる場合があります。

ステップの確認

高速な一覧確認には get、追加の列が必要な場合は get -o wide、特定のオブジェクトについて条件、容量、ランタイムの詳細、イベントを確認する場合は describe を使用します。

Namespace をまたいでリソースを調査する

このステップでは、よく使うオブジェクトの基本的な関係を整理します。Namespace はリソースを分類し、Pod はコンテナを実行し、Deployment は Pod を管理し、Service は安定したネットワークアクセスを提供します。

オブジェクト間の関係を理解する

  • Pod はデプロイ可能な最小単位で、1 つ以上のコンテナを含みます。
  • Deployment は、ステートレスアプリケーションの実行数を宣言し、ReplicaSet を介して Pod を管理します。
  • Service は、選択した Pod に安定した仮想 IP アドレスと DNS 名を提供します。Pod は入れ替わるため、IP アドレスが変わる可能性があるためです。
  • Namespace は Namespace に属するオブジェクトをグループ化し、異なる範囲で同じ名前を使用できるようにします。

単純化すると、Deployment が Pod を管理し、Service がその Pod を選択して、クライアントに安定したエンドポイントを提供します。すべてのオブジェクトが Namespace に属するわけではありません。Node はクラスター全体に属します。

すべての Namespace の Pod を一覧表示する

Namespace オプションを指定しない kubectl get pods は、現在の Namespace だけを検索します。-A--all-namespaces を意味します。

kubectl get pods -A

NAMESPACE は論理的な範囲です。NAME はその範囲内で Pod を識別します。READY は、準備完了コンテナ数を総コンテナ数で割った値です。STATUS はライフサイクルの状態を示します。RESTARTS は再起動回数、AGE はオブジェクトの経過時間です。

長時間稼働する基盤コンポーネントは Running になっている必要があります。一部の Ingress のアドミッション用 Pod は、一度だけ実行される Job を完了して正常終了するため、0/1 の準備状態で Completed と表示される場合があります。正常性は、ワークロードの目的に応じて判断してください。

Deployment を一覧表示する

複数形のリソース名 deployments は、Deployment オブジェクトを取得します。システムの Deployment は現在の default Namespace 以外に存在するため、ここでも -A を付けます。

kubectl get deployments -A
NAMESPACE       NAME                       READY   UP-TO-DATE   AVAILABLE   AGE
ingress-nginx   ingress-nginx-controller   1/1     1            1           ...
kube-system     calico-kube-controllers    1/1     1            1           ...
kube-system     coredns                    1/1     1            1           ...
kube-system     metrics-server             1/1     1            1           ...

READY は、準備完了レプリカ数を要求レプリカ数で割った値です。UP-TO-DATE は、現在の Pod テンプレートを使用しているレプリカ数を示します。AVAILABLE は、目的を果たせる状態で利用可能なレプリカ数です。先ほど確認した coredns-... Pod は、coredns Deployment によって管理されています。

Service を一覧表示する

Pod は入れ替え可能なため、クライアントは Pod の IP アドレスに直接依存すべきではありません。安定した Service のエンドポイントを一覧表示します。

kubectl get services -A
NAMESPACE       NAME                       TYPE        CLUSTER-IP    EXTERNAL-IP   PORT(S)   AGE
default         kubernetes                 ClusterIP   10.96.0.1     <none>        443/TCP   ...
kube-system     kube-dns                   ClusterIP   10.96.0.10    <none>        ...       ...
ingress-nginx   ingress-nginx-controller   NodePort    ...           <none>        ...       ...

TYPE は公開方法を示します。ClusterIP はクラスター内部からアクセスでき、NodePort はノードポートも開きます。CLUSTER-IP は安定した仮想アドレスです。EXTERNAL-IP=<none> は、外部アドレスが割り当てられていないことを意味します。PORT(S) には、公開されているプロトコルとポートが表示されます。

kubernetes Service は、クラスター内部から API にアクセスするためのものです。kube-dns は CoreDNS への安定したアクセスを提供します。Ingress の Service は、受信 HTTP および HTTPS トラフィックをサポートします。

複合的な一覧を作成する

どの一般的なワークロード種別が存在するかまだ分からない場合は、kubectl get all を使うと、クラスターの全体像を把握できます。-A を追加すると、ここまでと同じくすべての Namespace が対象になります。

kubectl get all -A

このコマンドでは、Pod、Service、DaemonSet、Deployment、ReplicaSet、Job など、よく使うリソースがまとめて表示されます。同じコンポーネントが Deployment、ReplicaSet、Pod という複数のレベルで表示されることもあります。

名前に all とありますが、get all がすべてのリソースを返すわけではありません。ConfigMap、Secret、NetworkPolicy など、多くのリソースは対象外です。まずは全体を把握するために使用し、その後、必要なリソース種別を明示的に指定してください。

ステップの確認

Namespace は範囲を提供し、Pod はコンテナを実行し、Deployment は望ましい Pod レプリカ数を維持し、Service は変化する Pod に対して安定したネットワークアクセスを提供します。

まとめ

Kubernetes クラスターを初めて体系的に探索しました。Kubernetes がノード全体で望ましい状態を管理し、kubectl がアクティブな kubeconfig コンテキストを使用して API サーバーと通信することを学びました。

Minikube、Kubernetes、kubectl のバージョンを区別する方法、コンテキストとノードの準備状態を確認する方法、コントロールプレーン・ノード・ネットワークのコンポーネントを特定する方法、ラベルとセレクターを使用する方法、getget -o widedescribe を使い分ける方法、ノードの状態と容量を解釈する方法、Namespace、Pod、Deployment、Service の関係を理解する方法を練習しました。

初心者にとって重要な習慣は、何かを変更する前にまず調査することです。コンテキストを確認し、ノードの正常性を確認し、対象となる Namespace とリソース種別を特定し、報告された状態を注意深く読み取りましょう。これからの実験では、このモデルを基礎として、自分のワークロードを作成していきます。