はじめに
前回の実験では、ログとイベントに焦点を当てました。これらは最初のシグナルとなりますが、時には実行中のコンテナを直接調査したり、ターミナルから一時的にサービスへアクセスしたりする必要が生じます。Kubernetes には、そのための一般的なツールとして kubectl exec と kubectl port-forward が用意されています。
この実験では、小規模な Web アプリケーションをデプロイし、kubectl exec を使って Pod 内のファイルやプロセスを調査し、kubectl port-forward を使ってサービスへの一時的なローカル接続を開く方法を学びます。ワークフローは意図的にシンプルにしているため、アプリケーションの複雑さに惑わされることなく、デバッグ技術そのものに集中できます。
デバッグ用名前空間の準備
このステップでは、exec とポートフォワードの練習用にクリーンな名前空間を準備します。
/home/labex/project から開始します。アプリケーションのマニフェストはこのディレクトリに保持します。
mkdir -p /home/labex/project
cd /home/labex/project
Kubernetes API サーバーに到達可能か確認します。VM が起動した直後でノードの準備ができていない場合は、数秒待ってから再度コマンドを実行してください。
kubectl get nodes --request-timeout=5s
期待される出力例:
NAME STATUS ROLES AGE VERSION
labex-v135 Ready control-plane ... v1.35...
クラスターのネットワーク用 Pod が「Ready」になるまで待ちます。ポートフォワードは API サーバーへの接続を使用しますが、アプリケーションには健全な Pod とサービスが必要です。
kubectl wait --namespace kube-system --for=condition=Ready pod -l k8s-app=calico-node --timeout=120s
期待される出力:
pod/calico-node-... condition met
ckad-prep-debug という名前の名前空間を作成し、現在の名前空間として設定します。
kubectl create namespace ckad-prep-debug
kubectl config set-context --current --namespace=ckad-prep-debug
現在の名前空間を確認します。
kubectl config view --minify --output 'jsonpath={..namespace}'; echo
期待される出力:
ckad-prep-debug
小規模な Web アプリケーションのデプロイ
このステップでは、調査およびアクセス対象となるシンプルなアプリケーションをデプロイします。
この Pod は index.html ファイルを作成し、ポート 8080 で BusyBox の httpd を実行します。debug-web という名前のサービスが、クラスター内の Pod をポート 80 で公開します。kubectl port-forward は Pod だけでなくサービスもターゲットにできるため、サービスを含めています。
debug-web.yaml を作成します。
cat > debug-web.yaml <<'EOF'
apiVersion: apps/v1
kind: Deployment
metadata:
name: debug-web
spec:
replicas: 2
selector:
matchLabels:
app: debug-web
template:
metadata:
labels:
app: debug-web
spec:
terminationGracePeriodSeconds: 0
containers:
- name: web
image: busybox:1.36
command:
- /bin/sh
- -c
- |
mkdir -p /www
echo "debug-web-ready" > /www/index.html
httpd -f -p 8080 -h /www
ports:
- containerPort: 8080
readinessProbe:
httpGet:
path: /
port: 8080
initialDelaySeconds: 1
periodSeconds: 2
---
apiVersion: v1
kind: Service
metadata:
name: debug-web
spec:
selector:
app: debug-web
ports:
- port: 80
targetPort: 8080
EOF
マニフェストを適用し、デプロイメントの完了を待ちます。
kubectl apply -f debug-web.yaml
kubectl rollout status deployment/debug-web --timeout=120s
期待される出力例:
deployment.apps/debug-web created
service/debug-web created
deployment "debug-web" successfully rolled out
Pod とサービスを調査します。
kubectl get pods -l app=debug-web
kubectl get service debug-web
2 つの実行中 Pod と ClusterIP サービスが表示されるはずです。
debug-web-... 1/1 Running
debug-web ClusterIP
exec を使用した実行中コンテナの調査
このステップでは、kubectl exec を使用してアプリケーション Pod 内でコマンドを実行します。
kubectl exec は、Pod が実行中であるものの、コンテナ内部で何が起きているかを確認する必要がある場合に便利です。これはログの代わりになるものではなく、通常のデプロイメント中に隠れた手動修正を行うために使用すべきではありません。デバッグのワークフローにおいては、コンテナ内部からファイル、プロセス、環境変数、ローカルネットワークの挙動を確認するのに役立ちます。
Pod 名をシェル変数に格納します。
POD_NAME="$(kubectl get pods -l app=debug-web -o jsonpath='{.items[0].metadata.name}')"
echo "$POD_NAME"
Pod 名が 1 つ出力されます。
debug-web-...
コンテナ内で hostname を実行します。Kubernetes はコンテナのホスト名を Pod 名から設定するため、出力は Pod 名と一致するはずです。
kubectl exec "$POD_NAME" -- hostname
期待される出力:
debug-web-...
コンテナ内で実行中のプロセスを一覧表示します。
kubectl exec "$POD_NAME" -- ps
httpd プロセスが含まれているはずです。
PID USER TIME COMMAND
... root ... httpd -f -p 8080 -h /www
Web サーバーが提供しているファイルを読み取ります。
kubectl exec "$POD_NAME" -- cat /www/index.html
期待される出力:
debug-web-ready
最後に、同じコンテナ内から Web サーバーをテストします。
kubectl exec "$POD_NAME" -- wget -qO- http://127.0.0.1:8080
期待される出力:
debug-web-ready
ポートフォワードを使用したサービスのテスト
このステップでは、kubectl port-forward を使用してターミナルからサービスにアクセスします。
ポートフォワードは、ローカルポートからクラスター内の Pod やサービスへの一時的なトンネルを作成します。サービスのタイプを変更したり、Ingress を作成したり、外部アクセスを開放したりすることなく、迅速にデバッグできるため非常に便利です。フォアグラウンドで実行される kubectl port-forward コマンドは停止するまで実行され続けるため、この実験ではバックグラウンドで起動し、テスト後に停止させます。
ローカルポート 18080 からサービスポート 80 へのポートフォワードを開始します。ターミナルを使い続けられるよう、出力を /tmp/debug-web-port-forward.log に書き込みます。
kubectl port-forward service/debug-web 18080:80 > /tmp/debug-web-port-forward.log 2>&1 &
PF_PID=$!
sleep 3
cat /tmp/debug-web-port-forward.log
期待される出力例:
Forwarding from 127.0.0.1:18080 -> 8080
ローカルの転送ポート経由でリクエストを送信します。
wget -qO- http://127.0.0.1:18080
期待される出力:
debug-web-ready
バックグラウンドのポートフォワードプロセスを停止します。ローカルポートが使用中のままにならないよう、このクリーンアップは重要です。
kill "$PF_PID"
wait "$PF_PID" 2>/dev/null || true
ポートフォワードのログに接続が処理された記録があるか確認します。
cat /tmp/debug-web-port-forward.log
期待される出力例:
Handling connection for 18080
まとめ
実用的な 2 つのデバッグツールを練習しました。kubectl exec を使用して、実行中のコンテナのホスト名、プロセス、ファイル、およびローカルホストの HTTP レスポンスを調査しました。また、kubectl port-forward を使用して ClusterIP サービスへの一時的なローカル接続を作成し、ターミナルからテストを行い、バックグラウンドの転送プロセスをクリーンに停止させました。


