Kubernetes アプリケーションを探索してデバッグする

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

はじめに

この実験では、Kubernetes アプリケーションを探索およびデバッグします。Minikube を使ってローカル Kubernetes クラスタを起動し、サンプル アプリケーションをデプロイし、アプリケーション構成の検査、ログの表示、ポッド内でのコマンドの実行、クラスタ イベントの調査など、さまざまなデバッグ テクニックを学びます。これらのスキルは、Kubernetes ベースのアプリケーションの開発とトラブルシューティングに欠かせないものです。

Kubernetes クラスタの起動

このステップでは、Minikube を使用してローカルの Kubernetes クラスタを起動し、検証する方法を学びます。これは、ローカルマシンで Kubernetes アプリケーションを開発およびテストするための重要な最初のステップです。

まず、Minikube クラスタを起動します。

minikube start

出力例:

😄  minikube v1.29.0 on Ubuntu 22.04
✨  Automatically selected the docker driver
📌  Using Docker driver with root permissions
🔥  Creating kubernetes in kubernetes cluster
🔄  Restarting existing kubernetes cluster
🐳  Preparing Kubernetes v1.26.1 on Docker 20.10.23 ...
🚀  Launching Kubernetes ...
🌟  Enabling addons: storage-provisioner, default-storageclass
🏄  Done! kubectl is now configured to use "minikube" cluster and "default" namespace

次に、複数のコマンドを使用してクラスタのステータスを確認します。

minikube status
kubectl get nodes

出力例:

minikube
type: Control Plane
host: Running
kubelet: Running
apiserver: Running
kubeconfig: Configured

NAME       STATUS   ROLES           AGE   VERSION
minikube   Ready    control-plane   1m    v1.26.1

これらのコマンドは、以下を確認します。

  1. Minikube が正常に実行されていること
  2. ローカルの Kubernetes クラスタが作成されたこと
  3. クラスタが使用できる状態になっていること
  4. コントロールプレーン機能を持つシングルノードクラスタがあること

クラスタのコンテキスト(context)を確認して、正しいクラスタに接続されていることを確認しましょう。

kubectl config current-context

出力例:

minikube

これは、kubectl が Minikube クラスタを使用するように構成されていることを検証します。

Kubernetes クラスタ設定の図

サンプルアプリケーションのデプロイ

このステップでは、YAML マニフェストを使用して、簡単な Kubernetes アプリケーションを作成およびデプロイする方法を学びます。Pod と Deployment の両方を作成して、さまざまなアプリケーションのデプロイ方法を示します。

まず、Kubernetes マニフェスト用のディレクトリを作成します。

mkdir -p ~/project/k8s-manifests
cd ~/project/k8s-manifests

簡単な NGINX Pod マニフェストを作成します。

nano nginx-pod.yaml

次のコンテンツを追加します。

apiVersion: v1
kind: Pod
metadata:
  name: nginx-pod
  labels:
    app: nginx
spec:
  containers:
    - name: nginx
      image: nginx:latest
      ports:
        - containerPort: 80

Ctrl+X、次に Y、そして Enter を押して保存し、終了します。

次に、Deployment マニフェストを作成します。

nano nginx-deployment.yaml

次のコンテンツを追加します。

apiVersion: apps/v1
kind: Deployment
metadata:
  name: nginx-deployment
  labels:
    app: nginx
spec:
  replicas: 3
  selector:
    matchLabels:
      app: nginx
  template:
    metadata:
      labels:
        app: nginx
    spec:
      containers:
        - name: nginx
          image: nginx:latest
          ports:
            - containerPort: 80

マニフェストを適用して、リソースを作成します。

kubectl apply -f nginx-pod.yaml
kubectl apply -f nginx-deployment.yaml

出力例:

pod/nginx-pod created
deployment.apps/nginx-deployment created

作成されたリソースを確認します。

kubectl get pods
kubectl get deployments

出力例:

NAME                                READY   STATUS    RESTARTS   AGE
nginx-pod                           1/1     Running   0          1m
nginx-deployment-xxx-yyy            1/1     Running   0          1m
nginx-deployment-xxx-zzz            1/1     Running   0          1m
nginx-deployment-xxx-www            1/1     Running   0          1m

NAME               READY   UP-TO-DATE   AVAILABLE   AGE
nginx-deployment   3/3     3            3           1m

Deployment がレプリカを作成するまで待ちます。すべてのレプリカの準備が完了すると、READY 列に 3/3 と表示されます。

Pod と Deployment の主な違い:

  • Pod: アプリケーションの単一インスタンス
  • Deployment: 複数のレプリカを管理し、自己修復を提供します
Differences between Pod and Deployment

アプリケーションの構成を確認する

この手順では、さまざまな kubectl コマンドを使って Kubernetes のデプロイメントとポッドの構成詳細を調査して取得する方法を学びます。リソース構成をどのように調べるかを理解することは、トラブルシューティングとアプリケーションのセットアップの理解にとって重要です。

まず、前の手順で作成したポッドの YAML 構成を取得しましょう。

kubectl get pod nginx-pod -o yaml

出力例(一部):

apiVersion: v1
kind: Pod
metadata:
  name: nginx-pod
  namespace: default
  labels:
    app: nginx
spec:
  containers:
    - image: nginx:latest
      imagePullPolicy: Always
      name: nginx
      ports:
        - containerPort: 80
      resources: {}
  dnsPolicy: ClusterFirst
  restartPolicy: Always

次に、デプロイメントの構成を調べましょう。

kubectl get deployment nginx-deployment -o yaml

出力例(一部):

apiVersion: apps/v1
kind: Deployment
metadata:
  name: nginx-deployment
  namespace: default
  labels:
    app: nginx
spec:
  replicas: 3
  selector:
    matchLabels:
      app: nginx
  template:
    metadata:
      labels:
        app: nginx
    spec:
      containers:
        - name: nginx
          image: nginx:latest
          ports:
            - containerPort: 80

kubectl describe を使って、リソースに関するより詳細な情報を取得します。

kubectl describe pod nginx-pod
kubectl describe deployment nginx-deployment

describe pod の出力例(一部):

Name:         nginx-pod
Namespace:    default
Priority:     0
Node:         minikube/172.17.0.2
Start Time:   [timestamp]
Labels:       app=nginx
Annotations:  <none>
Status:       Running
IP:           172.17.0.5
Containers:
  nginx:
    Container ID:   docker://[container-id]
    Image:          nginx:latest
    Image ID:       docker-pullable://nginx@[image-digest]
    Port:           80/TCP
    Host Port:      0/TCP
    State:          Running
    Ready:          True
    Restart Count:  0
Conditions:
  Type              Status
  Initialized       True
  Ready             True
  ContainersReady   True
  PodScheduled      True

より機械読み取り可能な形式で JSON 出力も使えます。

kubectl get pod nginx-pod -o json

構成を調べる際に確認する重要な点:

  • リソースのメタデータ(名前、ラベル、名前空間)
  • コンテナ イメージとポート
  • レプリカ数(デプロイメントの場合)
  • リソースの状態と条件

アプリケーションのログを表示する

この手順では、kubectl logs を使って Kubernetes ポッドのログを表示して調査する方法を学びます。ログを表示することは、アプリケーションの動作を理解し、問題をデバッグし、アプリケーションのパフォーマンスを監視するために重要です。

まず、使用するリソースが正しいことを確認するために、利用可能なポッドを一覧表示します。

kubectl get pods

出力例:

NAME                                READY   STATUS    RESTARTS   AGE
nginx-pod                           1/1     Running   0          20m
nginx-deployment-xxx-yyy            1/1     Running   0          20m
nginx-deployment-xxx-zzz            1/1     Running   0          20m
nginx-deployment-xxx-www            1/1     Running   0          20m

特定のポッドのログを表示します。

## nginx-pod のログを表示する
kubectl logs nginx-pod

出力例:

/docker-entrypoint.sh: /docker-entrypoint.d/ は空ではないので、設定を実行します
/docker-entrypoint.sh: /docker-entrypoint.d/ 内のシェル スクリプトを探しています
/docker-entrypoint.sh: /docker-entrypoint.d/10-listen-on-ipv6-by-default.sh を起動します
...
2023/xx/xx [notice] xxxx#x: シグナル プロセスが開始されました

デプロイメントのポッドのログを表示します。

## デプロイ内の特定のポッドのログを表示する
POD_NAME=$(kubectl get pods -l app=nginx | grep nginx-deployment | head -n 1 | awk '{print $1}')
kubectl logs $POD_NAME

追加のログ表示オプションを調べます。

## ログの最後の 50 行を表示する
kubectl logs nginx-pod --tail=50

## ログをリアルタイムで追跡する
kubectl logs -f nginx-pod

ログを追跡する例:

[リアルタイムのログ出力が表示されます]

Ctrl + C を押してリアルタイムのログ表示を終了します。

複数コンテナのポッドの場合、コンテナ名を指定します。

## ポッドに複数のコンテナがある場合
kubectl logs nginx-pod -c nginx

重要なログ表示技術:

  • ログの全体の履歴を表示する
  • ログの行数を制限する
  • ログをリアルタイムで追跡する
  • 複数コンテナのポッドでコンテナを指定する

kubectl exec を使ったデバッグ

この手順では、Kubernetes ポッド内でコマンドを実行するための kubectl exec の使い方を学びます。これは、コンテナ環境のデバッグと調査に欠かせないものです。

まず、利用可能なポッドを確認します。

kubectl get pods

出力例:

NAME                                READY   STATUS    RESTARTS   AGE
nginx-pod                           1/1     Running   0          30m
nginx-deployment-xxx-yyy            1/1     Running   0          30m
nginx-deployment-xxx-zzz            1/1     Running   0          30m
nginx-deployment-xxx-www            1/1     Running   0          30m

nginx-pod 内で対話型シェルを実行します。

kubectl exec -it nginx-pod -- /bin/bash

ポッド内での対話例:

## nginx の設定を確認する
cat /etc/nginx/nginx.conf

## インストール済みのパッケージを確認する
apt update && apt list --installed

## ポッド シェルを終了する
exit

対話型シェルを終了して、シェル プロンプトに戻ることを忘れないでください。

対話型シェルに入らずに特定のコマンドを実行します。

## nginx のバージョンを確認する
kubectl exec nginx-pod -- nginx -v

## ウェブ ルート内のファイルを一覧表示する
kubectl exec nginx-pod -- ls /usr/share/nginx/html

デプロイメント ポッドの場合、特定のポッドを選択します。

## デプロイからポッド名を取得する
POD_NAME=$(kubectl get pods -l app=nginx | grep nginx-deployment | head -n 1 | awk '{print $1}')

## デプロイのポッド内でコマンドを実行する
kubectl exec -it $POD_NAME -- /bin/bash

重要な kubectl exec 技術:

  • 対話型シェルを実行する
  • 特定のコマンドを実行する
  • ポッドの内部を調査する
  • コンテナの構成をデバッグする

トラブルシューティング用に kubectl describe を使用する

この手順では、Kubernetes リソースの診断とトラブルシューティングに kubectl describe をどのように使うかを学びます。これにより、ポッド、デプロイメント、クラスタ コンポーネントの状態に関する詳細な洞察が得られます。

まず、デバッグを示すためにトラブルのあるデプロイメントを作成しましょう。

cd ~/project/k8s-manifests
nano problematic-deployment.yaml

次の内容を追加します。

apiVersion: apps/v1
kind: Deployment
metadata:
  name: debug-deployment
spec:
  replicas: 2
  selector:
    matchLabels:
      app: debug
  template:
    metadata:
      labels:
        app: debug
    spec:
      containers:
        - name: debug-container
          image: non-existent-image:latest
          ports:
            - containerPort: 80

デプロイメントを適用します。

kubectl apply -f problematic-deployment.yaml

次に、kubectl describe を使ってデプロイメントを調査します。

kubectl describe deployment debug-deployment

出力例:

Name:                   debug-deployment
Namespace:              default
CreationTimestamp:      [timestamp]
Labels:                 <none>
Annotations:            deployment.kubernetes.io/revision: 1
Selector:               app=debug
Replicas:               2 desired | 0 available | 2 total | 2 unavailable
StrategyType:           RollingUpdate
MinReadySeconds:        0
RollingUpdateStrategy:  25% max unavailable, 25% max surge
Conditions:
  Type           Status   Reason
  ----           ------   ------
  Available      False    MinimumReplicasUnavailable
  Progressing    False    ProgressDeadlineExceeded
OldReplicaSets:  <none>
NewReplicaSet:   debug-deployment-xxx (2/2 replicas created)
Events:
  Type     Reason                    Age   From                   Message
  ----     ------                    ----  ----                   -------
  Warning  FailedCreate              1m    deployment-controller  Failed to create pod
  Normal   ScalingReplicaSet         1m    deployment-controller  Scaled up replica set

ポッドの詳細を取得するには、ポッドを記述します。

kubectl describe pods -l app=debug

出力例:

Name:           debug-deployment-xxx-yyy
Namespace:      default
Priority:       0
Node:           minikube/172.17.0.2
Start Time:     [timestamp]
Labels:         app=debug
Annotations:    <none>
Status:         Pending
Conditions:
  Type           Status
  Initialized    True
  Ready          False
  PodScheduled   True
Events:
  Type     Reason                  Age   From               Message
  ----     ------                  ----  ----               -------
  Warning  FailedCreatePodSandBox  1m    kubelet            Failed to create pod sandbox
  Warning  Failed                  1m    kubelet            Failed to pull image

ノード リソースを記述します。

kubectl describe nodes minikube

重要なトラブルシューティング技術:

  • デプロイメントとポッドの状態を特定する
  • 詳細なエラー メッセージを表示する
  • リソースが実行されない原因を理解する
  • ノードとクラスタの状態を確認する

クラスター イベント (kubectl get events) を調べて、手がかりとタイムラインを特定する

この手順では、クラスタ全体のイベントを調査し、システムの活動を理解し、Kubernetes 環境全体の問題を診断するために kubectl get events をどのように使うかを学びます。

まず、すべてのクラスタ イベントを表示します。

kubectl get events

出力例:

LAST SEEN   TYPE      REASON                 OBJECT                           MESSAGE
10m         Warning   FailedCreate           deployment/debug-deployment     Failed to create pod
5m          Normal    Scheduled              pod/nginx-pod                   Successfully assigned default/nginx-pod to minikube
3m          Normal    Pulled                 pod/nginx-deployment-xxx-yyy    Container image "nginx:latest" already present on machine

名前空間でイベントをフィルタリングします。

kubectl get events -n default

より詳細なイベント表示オプションを使用します。

## イベントをリアルタイムで監視する
kubectl get events -w

## タイムスタンプでソートされたイベントを取得する
kubectl get events --sort-by='.metadata.creationTimestamp'

カスタム イベント生成シナリオを作成します。

cd ~/project/k8s-manifests
nano event-test-deployment.yaml

次の内容を追加します。

apiVersion: apps/v1
kind: Deployment
metadata:
  name: event-test
spec:
  replicas: 3
  selector:
    matchLabels:
      app: event-test
  template:
    metadata:
      labels:
        app: event-test
    spec:
      containers:
        - name: nginx
          image: nginx:latest
          resources:
            limits:
              cpu: "100m"
              memory: "50Mi"

デプロイを適用してイベントを調べます。

kubectl apply -f event-test-deployment.yaml
kubectl get events

高度なイベント フィルタリング:

## イベントの種類でフィルタリングする
kubectl get events --field-selector type=Warning

## 特定のリソースでフィルタリングする
kubectl get events --field-selector involvedObject.kind=Deployment

重要なイベント調査技術:

  • クラスタ全体のイベントを表示する
  • 名前空間でイベントをフィルタリングする
  • イベントをリアルタイムで監視する
  • 警告とエラー イベントを特定する

まとめ

この実験では、Minikube を使ってローカルの Kubernetes クラスタを起動して検証する方法を学びました。これは、ローカル マシン上で Kubernetes アプリケーションを開発およびテストするための不可欠な最初のステップです。また、YAML マニフェストを使って単純な Kubernetes アプリケーションを作成してデプロイする方法を学びました。これには、ポッドとデプロイメントの両方が含まれます。さらに、アプリケーションの構成を調べ、ログを表示し、デバッグし、トラブルシューティングするためのさまざまなコマンドを検討しました。これにより、Kubernetes アプリケーションをどのように管理および監視するかをより深く理解することができました。