実行中のPodのデバッグ
このページでは、ノード上で動作している(またはクラッシュしている)Podをデバッグする方法について説明します。
始める前に
-
あなたのPodは既にスケジュールされ、実行されているはずです。Podがまだ実行されていない場合は、アプリケーションのトラブルシューティングから始めてください。
-
いくつかの高度なデバッグ手順では、Podがどのノードで動作しているかを知り、そのノードでコマンドを実行するためのシェルアクセス権を持っていることが必要です。
kubectl
を使用する標準的なデバッグ手順の実行には、そのようなアクセスは必要ではありません。
kubectl describe pod
を使ってpodの詳細を取得
この例では、先ほどの例と同様に、Deploymentを使用して2つのpodを作成します。
apiVersion: apps/v1
kind: Deployment
metadata:
name: nginx-deployment
spec:
selector:
matchLabels:
app: nginx
replicas: 2
template:
metadata:
labels:
app: nginx
spec:
containers:
- name: nginx
image: nginx
resources:
limits:
memory: "128Mi"
cpu: "500m"
ports:
- containerPort: 80
以下のコマンドを実行して、Deploymentを作成します:
kubectl apply -f https://k8s.io/examples/application/nginx-with-request.yaml
deployment.apps/nginx-deployment created
以下のコマンドでPodの状態を確認します:
kubectl get pods
NAME READY STATUS RESTARTS AGE
nginx-deployment-1006230814-6winp 1/1 Running 0 11s
nginx-deployment-1006230814-fmgu3 1/1 Running 0 11s
kubectl describe pod
を使うと、これらのPodについてより多くの情報を得ることができます。
例えば:
kubectl describe pod nginx-deployment-1006230814-6winp
Name: nginx-deployment-1006230814-6winp
Namespace: default
Node: kubernetes-node-wul5/10.240.0.9
Start Time: Thu, 24 Mar 2016 01:39:49 +0000
Labels: app=nginx,pod-template-hash=1006230814
Annotations: kubernetes.io/created-by={"kind":"SerializedReference","apiVersion":"v1","reference":{"kind":"ReplicaSet","namespace":"default","name":"nginx-deployment-1956810328","uid":"14e607e7-8ba1-11e7-b5cb-fa16" ...
Status: Running
IP: 10.244.0.6
Controllers: ReplicaSet/nginx-deployment-1006230814
Containers:
nginx:
Container ID: docker://90315cc9f513c724e9957a4788d3e625a078de84750f244a40f97ae355eb1149
Image: nginx
Image ID: docker://6f62f48c4e55d700cf3eb1b5e33fa051802986b77b874cc351cce539e5163707
Port: 80/TCP
QoS Tier:
cpu: Guaranteed
memory: Guaranteed
Limits:
cpu: 500m
memory: 128Mi
Requests:
memory: 128Mi
cpu: 500m
State: Running
Started: Thu, 24 Mar 2016 01:39:51 +0000
Ready: True
Restart Count: 0
Environment: <none>
Mounts:
/var/run/secrets/kubernetes.io/serviceaccount from default-token-5kdvl (ro)
Conditions:
Type Status
Initialized True
Ready True
PodScheduled True
Volumes:
default-token-4bcbi:
Type: Secret (a volume populated by a Secret)
SecretName: default-token-4bcbi
Optional: false
QoS Class: Guaranteed
Node-Selectors: <none>
Tolerations: <none>
Events:
FirstSeen LastSeen Count From SubobjectPath Type Reason Message
--------- -------- ----- ---- ------------- -------- ------ -------
54s 54s 1 {default-scheduler } Normal Scheduled Successfully assigned nginx-deployment-1006230814-6winp to kubernetes-node-wul5
54s 54s 1 {kubelet kubernetes-node-wul5} spec.containers{nginx} Normal Pulling pulling image "nginx"
53s 53s 1 {kubelet kubernetes-node-wul5} spec.containers{nginx} Normal Pulled Successfully pulled image "nginx"
53s 53s 1 {kubelet kubernetes-node-wul5} spec.containers{nginx} Normal Created Created container with docker id 90315cc9f513
53s 53s 1 {kubelet kubernetes-node-wul5} spec.containers{nginx} Normal Started Started container with docker id 90315cc9f513
ここでは、コンテナ(複数可)とPodに関する構成情報(ラベル、リソース要件など)や、コンテナ(複数可)とPodに関するステータス情報(状態、準備状況、再起動回数、イベントなど)を確認できます。
コンテナの状態は、Waiting(待機中)、Running(実行中)、Terminated(終了)のいずれかです。状態に応じて、追加の情報が提供されます。ここでは、Running状態のコンテナについて、コンテナがいつ開始されたかが表示されています。
Readyは、コンテナが最後のReadiness Probeに合格したかどうかを示す。(この場合、コンテナにはReadiness Probeが設定されていません。Readiness Probeが設定されていない場合、コンテナは準備が完了した状態であるとみなされます)。
Restart Countは、コンテナが何回再起動されたかを示します。この情報は、再起動ポリシーが「always」に設定されているコンテナのクラッシュループを検出するのに役立ちます。
現在、Podに関連する条件は、二値のReady条件のみです。これは、Podがリクエストに対応可能であり、マッチングするすべてのサービスのロードバランシングプールに追加されるべきであることを示します。
最後に、Podに関連する最近のイベントのログが表示されます。このシステムでは、複数の同一イベントを圧縮して、最初に見られた時刻と最後に見られた時刻、そして見られた回数を示します。"From"はイベントを記録しているコンポーネントを示し、"SubobjectPath"はどのオブジェクト(例: Pod内のコンテナ)が参照されているかを示し、"Reason"と "Message"は何が起こったかを示しています。
例: Pending Podsのデバッグ
イベントを使って検出できる一般的なシナリオは、どのノードにも収まらないPodを作成した場合です。例えば、Podがどのノードでも空いている以上のリソースを要求したり、どのノードにもマッチしないラベルセレクターを指定したりする場合です。例えば、各(仮想)マシンが1つのCPUを持つ4ノードのクラスター上で、(2つではなく)5つのレプリカを持ち、500ではなく600ミリコアを要求する前のDeploymentを作成したとします。この場合、Podの1つがスケジュールできなくなります。(なお、各ノードではfluentdやskydnsなどのクラスターアドオンPodが動作しているため、もし1000ミリコアを要求した場合、どのPodもスケジュールできなくなります)
kubectl get pods
NAME READY STATUS RESTARTS AGE
nginx-deployment-1006230814-6winp 1/1 Running 0 7m
nginx-deployment-1006230814-fmgu3 1/1 Running 0 7m
nginx-deployment-1370807587-6ekbw 1/1 Running 0 1m
nginx-deployment-1370807587-fg172 0/1 Pending 0 1m
nginx-deployment-1370807587-fz9sd 0/1 Pending 0 1m
nginx-deployment-1370807587-fz9sdのPodが実行されていない理由を調べるには、保留中のPodに対してkubectl describe pod
を使用し、そのイベントを見てみましょう
kubectl describe pod nginx-deployment-1370807587-fz9sd
Name: nginx-deployment-1370807587-fz9sd
Namespace: default
Node: /
Labels: app=nginx,pod-template-hash=1370807587
Status: Pending
IP:
Controllers: ReplicaSet/nginx-deployment-1370807587
Containers:
nginx:
Image: nginx
Port: 80/TCP
QoS Tier:
memory: Guaranteed
cpu: Guaranteed
Limits:
cpu: 1
memory: 128Mi
Requests:
cpu: 1
memory: 128Mi
Environment Variables:
Volumes:
default-token-4bcbi:
Type: Secret (a volume populated by a Secret)
SecretName: default-token-4bcbi
Events:
FirstSeen LastSeen Count From SubobjectPath Type Reason Message
--------- -------- ----- ---- ------------- -------- ------ -------
1m 48s 7 {default-scheduler } Warning FailedScheduling pod (nginx-deployment-1370807587-fz9sd) failed to fit in any node
fit failure on node (kubernetes-node-6ta5): Node didn't have enough resource: CPU, requested: 1000, used: 1420, capacity: 2000
fit failure on node (kubernetes-node-wul5): Node didn't have enough resource: CPU, requested: 1000, used: 1100, capacity: 2000
ここでは、理由 FailedScheduling
(およびその他の理由)でPodのスケジュールに失敗したという、スケジューラーによって生成されたイベントを見ることができます。このメッセージは、どのノードでもPodに十分なリソースがなかったことを示しています。
この状況を修正するには、kubectl scale
を使用して、4つ以下のレプリカを指定するようにDeploymentを更新します。(あるいは、1つのPodを保留にしたままにしておいても害はありません。)
kubectl describe pod
の最後に出てきたようなイベントは、etcdに永続化され、クラスターで何が起こっているかについての高レベルの情報を提供します。
すべてのイベントをリストアップするには、次のようにします:
kubectl get events
しかし、イベントは名前空間に所属することを忘れてはいけません。つまり、名前空間で管理されているオブジェクトのイベントに興味がある場合(例: 名前空間 my-namespace
のPods で何が起こったか)、コマンドに名前空間を明示的に指定する必要があります。
kubectl get events --namespace=my-namespace
すべての名前空間からのイベントを見るには、--all-namespaces
引数を使用できます。
kubectl describe pod
に加えて、(kubectl get pod
で提供される以上の)Podに関する追加情報を得るためのもう一つの方法は、-o yaml
出力形式フラグを kubectl get pod
に渡すことです。これにより、kubectl describe pod
よりもさらに多くの情報、つまりシステムが持っているPodに関するすべての情報をYAML形式で得ることができます。ここでは、アノテーション(Kubernetesのシステムコンポーネントが内部的に使用している、ラベル制限のないキーバリューのメタデータ)、再起動ポリシー、ポート、ボリュームなどが表示されます。
kubectl get pod nginx-deployment-1006230814-6winp -o yaml
apiVersion: v1
kind: Pod
metadata:
annotations:
kubernetes.io/created-by: |
{"kind":"SerializedReference","apiVersion":"v1","reference":{"kind":"ReplicaSet","namespace":"default","name":"nginx-deployment-1006230814","uid":"4c84c175-f161-11e5-9a78-42010af00005","apiVersion":"extensions","resourceVersion":"133434"}}
creationTimestamp: 2016-03-24T01:39:50Z
generateName: nginx-deployment-1006230814-
labels:
app: nginx
pod-template-hash: "1006230814"
name: nginx-deployment-1006230814-6winp
namespace: default
resourceVersion: "133447"
uid: 4c879808-f161-11e5-9a78-42010af00005
spec:
containers:
- image: nginx
imagePullPolicy: Always
name: nginx
ports:
- containerPort: 80
protocol: TCP
resources:
limits:
cpu: 500m
memory: 128Mi
requests:
cpu: 500m
memory: 128Mi
terminationMessagePath: /dev/termination-log
volumeMounts:
- mountPath: /var/run/secrets/kubernetes.io/serviceaccount
name: default-token-4bcbi
readOnly: true
dnsPolicy: ClusterFirst
nodeName: kubernetes-node-wul5
restartPolicy: Always
securityContext: {}
serviceAccount: default
serviceAccountName: default
terminationGracePeriodSeconds: 30
volumes:
- name: default-token-4bcbi
secret:
secretName: default-token-4bcbi
status:
conditions:
- lastProbeTime: null
lastTransitionTime: 2016-03-24T01:39:51Z
status: "True"
type: Ready
containerStatuses:
- containerID: docker://90315cc9f513c724e9957a4788d3e625a078de84750f244a40f97ae355eb1149
image: nginx
imageID: docker://6f62f48c4e55d700cf3eb1b5e33fa051802986b77b874cc351cce539e5163707
lastState: {}
name: nginx
ready: true
restartCount: 0
state:
running:
startedAt: 2016-03-24T01:39:51Z
hostIP: 10.240.0.9
phase: Running
podIP: 10.244.0.6
startTime: 2016-03-24T01:39:49Z
例: ダウン/到達不可能なノードのデバッグ
例えば、ノード上で動作しているPodのおかしな挙動に気付いたり、Podがノード上でスケジュールされない原因を探ったりと、デバッグ時にノードのステータスを見ることが有用な場合があります。Podと同様に、kubectl describe node
やkubectl get node -o yaml
を使ってノードの詳細情報を取得することができます。例えば、ノードがダウンした場合(ネットワークから切断された、またはkubeletが死んで再起動しないなど)に表示される内容は以下の通りです。ノードがNotReadyであることを示すイベントに注目してください。また、Podが実行されなくなっていることにも注目してください(NotReady状態が5分続くと、Podは退避されます)。
kubectl get nodes
NAME STATUS ROLES AGE VERSION
kubernetes-node-861h NotReady <none> 1h v1.13.0
kubernetes-node-bols Ready <none> 1h v1.13.0
kubernetes-node-st6x Ready <none> 1h v1.13.0
kubernetes-node-unaj Ready <none> 1h v1.13.0
kubectl describe node kubernetes-node-861h
Name: kubernetes-node-861h
Role
Labels: kubernetes.io/arch=amd64
kubernetes.io/os=linux
kubernetes.io/hostname=kubernetes-node-861h
Annotations: node.alpha.kubernetes.io/ttl=0
volumes.kubernetes.io/controller-managed-attach-detach=true
Taints: <none>
CreationTimestamp: Mon, 04 Sep 2017 17:13:23 +0800
Phase:
Conditions:
Type Status LastHeartbeatTime LastTransitionTime Reason Message
---- ------ ----------------- ------------------ ------ -------
OutOfDisk Unknown Fri, 08 Sep 2017 16:04:28 +0800 Fri, 08 Sep 2017 16:20:58 +0800 NodeStatusUnknown Kubelet stopped posting node status.
MemoryPressure Unknown Fri, 08 Sep 2017 16:04:28 +0800 Fri, 08 Sep 2017 16:20:58 +0800 NodeStatusUnknown Kubelet stopped posting node status.
DiskPressure Unknown Fri, 08 Sep 2017 16:04:28 +0800 Fri, 08 Sep 2017 16:20:58 +0800 NodeStatusUnknown Kubelet stopped posting node status.
Ready Unknown Fri, 08 Sep 2017 16:04:28 +0800 Fri, 08 Sep 2017 16:20:58 +0800 NodeStatusUnknown Kubelet stopped posting node status.
Addresses: 10.240.115.55,104.197.0.26
Capacity:
cpu: 2
hugePages: 0
memory: 4046788Ki
pods: 110
Allocatable:
cpu: 1500m
hugePages: 0
memory: 1479263Ki
pods: 110
System Info:
Machine ID: 8e025a21a4254e11b028584d9d8b12c4
System UUID: 349075D1-D169-4F25-9F2A-E886850C47E3
Boot ID: 5cd18b37-c5bd-4658-94e0-e436d3f110e0
Kernel Version: 4.4.0-31-generic
OS Image: Debian GNU/Linux 8 (jessie)
Operating System: linux
Architecture: amd64
Container Runtime Version: docker://1.12.5
Kubelet Version: v1.6.9+a3d1dfa6f4335
Kube-Proxy Version: v1.6.9+a3d1dfa6f4335
ExternalID: 15233045891481496305
Non-terminated Pods: (9 in total)
Namespace Name CPU Requests CPU Limits Memory Requests Memory Limits
--------- ---- ------------ ---------- --------------- -------------
......
Allocated resources:
(Total limits may be over 100 percent, i.e., overcommitted.)
CPU Requests CPU Limits Memory Requests Memory Limits
------------ ---------- --------------- -------------
900m (60%) 2200m (146%) 1009286400 (66%) 5681286400 (375%)
Events: <none>
kubectl get node kubernetes-node-861h -o yaml
apiVersion: v1
kind: Node
metadata:
creationTimestamp: 2015-07-10T21:32:29Z
labels:
kubernetes.io/hostname: kubernetes-node-861h
name: kubernetes-node-861h
resourceVersion: "757"
uid: 2a69374e-274b-11e5-a234-42010af0d969
spec:
externalID: "15233045891481496305"
podCIDR: 10.244.0.0/24
providerID: gce://striped-torus-760/us-central1-b/kubernetes-node-861h
status:
addresses:
- address: 10.240.115.55
type: InternalIP
- address: 104.197.0.26
type: ExternalIP
capacity:
cpu: "1"
memory: 3800808Ki
pods: "100"
conditions:
- lastHeartbeatTime: 2015-07-10T21:34:32Z
lastTransitionTime: 2015-07-10T21:35:15Z
reason: Kubelet stopped posting node status.
status: Unknown
type: Ready
nodeInfo:
bootID: 4e316776-b40d-4f78-a4ea-ab0d73390897
containerRuntimeVersion: docker://Unknown
kernelVersion: 3.16.0-0.bpo.4-amd64
kubeProxyVersion: v0.21.1-185-gffc5a86098dc01
kubeletVersion: v0.21.1-185-gffc5a86098dc01
machineID: ""
osImage: Debian GNU/Linux 7 (wheezy)
systemUUID: ABE5F6B4-D44B-108B-C46A-24CCE16C8B6E
Podログを調べます
まず、影響を受けるコンテナのログを見ます。
kubectl logs ${POD_NAME} ${CONTAINER_NAME}
コンテナが以前にクラッシュしたことがある場合、次のコマンドで以前のコンテナのクラッシュログにアクセスすることができます:
kubectl logs --previous ${POD_NAME} ${CONTAINER_NAME}
container execによるデバッグ
もしcontainer imageがデバッグユーティリティを含んでいれば、LinuxやWindows OSのベースイメージからビルドしたイメージのように、kubectl exec
で特定のコンテナ内でコマンドを実行することが可能です:
kubectl exec ${POD_NAME} -c ${CONTAINER_NAME} -- ${CMD} ${ARG1} ${ARG2} ... ${ARGN}
備考:
-c ${CONTAINER_NAME}
は省略可能です。コンテナを1つだけ含むPodの場合は省略できます。例として、実行中のCassandra Podからログを見るには、次のように実行します。
kubectl exec cassandra -- cat /var/log/cassandra/system.log
例えばkubectl exec
の-i
と-t
引数を使って、端末に接続されたシェルを実行することができます:
kubectl exec -it cassandra -- sh
詳しくは、実行中のコンテナへのシェルを取得するを参照してください。
エフェメラルコンテナによるデバッグ
Kubernetes v1.25 [stable]
エフェメラルコンテナは、コンテナがクラッシュしたり、コンテナイメージにデバッグユーティリティが含まれていないなどの理由でkubectl exec
が不十分な場合に、対話的にトラブルシューティングを行うのに便利です(ディストロレスイメージの場合など)。
エフェメラルコンテナを使用したデバッグ例
実行中のPodにエフェメラルコンテナを追加するには、kubectl debug
コマンドを使用することができます。
まず、サンプル用のPodを作成します:
kubectl run ephemeral-demo --image=registry.k8s.io/pause:3.1 --restart=Never
このセクションの例では、デバッグユーティリティが含まれていないpause
コンテナイメージを使用していますが、この方法はすべてのコンテナイメージで動作します。
もし、kubectl exec
を使用してシェルを作成しようとすると、このコンテナイメージにはシェルが存在しないため、エラーが表示されます。
kubectl exec -it ephemeral-demo -- sh
OCI runtime exec failed: exec failed: container_linux.go:346: starting container process caused "exec: \"sh\": executable file not found in $PATH": unknown
代わりに、kubectl debug
を使ってデバッグ用のコンテナを追加することができます。
引数に-i
/--interactive
を指定すると、kubectl
は自動的にエフェメラルコンテナのコンソールにアタッチされます。
kubectl debug -it ephemeral-demo --image=busybox:1.28 --target=ephemeral-demo
Defaulting debug container name to debugger-8xzrl.
If you don't see a command prompt, try pressing enter.
/ #
このコマンドは新しいbusyboxコンテナを追加し、それにアタッチします。--target
パラメーターは、他のコンテナのプロセス名前空間をターゲットにします。これはkubectl run
が作成するPodでプロセス名前空間の共有を有効にしないため、指定する必要があります。
備考:
--target
パラメーターはContainer Runtimeでサポートされている必要があります。サポートされていない場合、エフェメラルコンテナは起動されないか、ps
が他のコンテナ内のプロセスを表示しないように孤立したプロセス名前空間を使用して起動されます。新しく作成されたエフェメラルコンテナの状態はkubectl describe
を使って見ることができます:
kubectl describe pod ephemeral-demo
...
Ephemeral Containers:
debugger-8xzrl:
Container ID: docker://b888f9adfd15bd5739fefaa39e1df4dd3c617b9902082b1cfdc29c4028ffb2eb
Image: busybox
Image ID: docker-pullable://busybox@sha256:1828edd60c5efd34b2bf5dd3282ec0cc04d47b2ff9caa0b6d4f07a21d1c08084
Port: <none>
Host Port: <none>
State: Running
Started: Wed, 12 Feb 2020 14:25:42 +0100
Ready: False
Restart Count: 0
Environment: <none>
Mounts: <none>
...
終了したらkubectl delete
を使ってPodを削除してください:
kubectl delete pod ephemeral-demo
Podのコピーを使ったデバッグ
Podの設定オプションによって、特定の状況でのトラブルシューティングが困難になることがあります。
例えば、コンテナイメージにシェルが含まれていない場合、またはアプリケーションが起動時にクラッシュした場合は、kubectl exec
を実行してトラブルシューティングを行うことができません。
このような状況では、kubectl debug
を使用してデバッグを支援するために設定値を変更したPodのコピーを作ることができます。
新しいコンテナを追加しながらPodをコピーします
新しいコンテナを追加することは、アプリケーションは動作しているが期待通りの動作をせず、トラブルシューティングユーティリティをPodに追加したい場合に便利です。
例えば、アプリケーションのコンテナイメージはbusybox
上にビルドされているが、busybox
に含まれていないデバッグユーティリティが必要な場合があります。このシナリオはkubectl run
を使ってシミュレーションすることができます。
kubectl run myapp --image=busybox:1.28 --restart=Never -- sleep 1d
このコマンドを実行すると、myapp
のコピーにmyapp-debug
という名前が付き、デバッグ用の新しいUbuntuコンテナが追加されます。
kubectl debug myapp -it --image=ubuntu --share-processes --copy-to=myapp-debug
Defaulting debug container name to debugger-w7xmf.
If you don't see a command prompt, try pressing enter.
root@myapp-debug:/#
備考:
-
kubectl debug
は--container
フラグでコンテナ名を選択しない場合、自動的にコンテナ名を生成します。 -
i
フラグを指定すると、デフォルトでkubectl debug
が新しいコンテナにアタッチされます。これを防ぐには、--attach=false
を指定します。セッションが切断された場合は、kubectl attach
を使用して再接続することができます。 -
--share-processes
を指定すると、このPod内のコンテナが、Pod内の他のコンテナのプロセスを参照することができます。この仕組みについて詳しくは、Pod内のコンテナ間でプロセス名前空間を共有するを参照してください。
デバッグが終わったら、Podの後始末をするのを忘れないでください。
kubectl delete pod myapp myapp-debug
Podのコマンドを変更しながらコピーします
例えば、デバッグフラグを追加する場合や、アプリケーションがクラッシュしている場合などでは、コンテナのコマンドを変更すると便利なことがあります。
アプリケーションのクラッシュをシミュレートするには、kubectl run
を使用して、すぐに終了するコンテナを作成します:
kubectl run --image=busybox:1.28 myapp -- false
kubectl describe pod myapp
を使用すると、このコンテナがクラッシュしていることがわかります:
Containers:
myapp:
Image: busybox
...
Args:
false
State: Waiting
Reason: CrashLoopBackOff
Last State: Terminated
Reason: Error
Exit Code: 1
kubectl debug
を使うと、コマンドをインタラクティブシェルに変更したこのPodのコピーを作成することができます。
kubectl debug myapp -it --copy-to=myapp-debug --container=myapp -- sh
If you don't see a command prompt, try pressing enter.
/ #
これで、ファイルシステムのパスのチェックやコンテナコマンドの手動実行などのタスクを実行するために使用できる対話型シェルが完成しました。
備考:
-
特定のコンテナのコマンドを変更するには、そのコンテナ名を
--container
で指定する必要があります。そうしなければ、指定したコマンドを実行するための新しいコンテナを、kubectl debug
が代わりに作成します。 -
-i
フラグは、デフォルトでkubectl debug
がコンテナにアタッチされるようにします。これを防ぐには、--attach=false
を指定します。セッションが切断された場合は、kubectl attach
を使用して再接続することができます。
デバッグが終わったら、Podの後始末をするのを忘れないでください:
kubectl delete pod myapp myapp-debug
コンテナイメージを変更してPodをコピーします
状況によっては、動作不良のPodを通常のプロダクション用のコンテナイメージから、デバッグビルドや追加ユーティリティを含むイメージに変更したい場合があります。
例として、kubectl run
を使用してPodを作成します:
kubectl run myapp --image=busybox:1.28 --restart=Never -- sleep 1d
ここで、kubectl debug
を使用してコピーを作成し、そのコンテナイメージをubuntu
に変更します:
kubectl debug myapp --copy-to=myapp-debug --set-image=*=ubuntu
--set-image
の構文は、kubectl set image
と同じcontainer_name=image
の構文を使用します。*=ubuntu
は、全てのコンテナのイメージをubuntu
に変更することを意味します。
デバッグが終わったら、Podの後始末をするのを忘れないでください:
kubectl delete pod myapp myapp-debug
ノード上のシェルによるデバッグ
いずれの方法でもうまくいかない場合は、Podが動作しているノードを探し出し、ホストの名前空間で動作するデバッグ用のPodを作成します。
ノード上でkubectl debug
を使って対話型のシェルを作成するには、以下を実行します:
kubectl debug node/mynode -it --image=ubuntu
Creating debugging pod node-debugger-mynode-pdx84 with container debugger on node mynode.
If you don't see a command prompt, try pressing enter.
root@ek8s:/#
ノードでデバッグセッションを作成する場合、以下の点に注意してください:
kubectl debug
はノードの名前に基づいて新しいPodの名前を自動的に生成します。- ノードのルートファイルシステムは
/host
にマウントされます。 - コンテナはホストのIPC、Network、PIDネームスペースで実行されますが、特権は付与されません。そのため、ホスト上のプロセス情報の参照や、
chroot /host
の実行に失敗する場合があります。 - 特権が必要な場合は手動でPodを作成するか、
--profile=sysadmin
を使用してください。
デバッグが終わったら、Podの後始末をするのを忘れないでください:
kubectl delete pod node-debugger-mynode-pdx84
デバッグプロファイルを使用したPodやNodeのデバッグ
kubectl debug
でノードやPodをデバッグする場合、デバッグ用のPod、エフェメラルコンテナ、またはコピーされたPodにデバッグプロファイルを適用できます。
デバッグプロファイルを適用することで、securityContextなど特定のプロパティが設定され、
さまざまなシナリオに適応できるようになります。
デバッグプロファイルにはスタティックプロファイルとカスタムプロファイルの2種類があります。
スタティックプロファイルの適用
スタティックプロファイルは事前に定義されたプロパティの組み合わせで構成され、--profile
フラグを使用して適用できます。
使用可能なスタティックプロファイルは以下の通りです:
Profile | Description |
---|---|
legacy | v1.22と互換性を保つプロパティのセット |
general | 各デバッグシナリオに対応する汎用的なプロパティのセット |
baseline | PodSecurityStandard baseline policy に準拠したプロパティのセット |
restricted | PodSecurityStandard restricted policyに準拠したプロパティのセット |
netadmin | ネットワーク管理者権限を含むプロパティのセット |
sysadmin | システム管理者(root)権限を含むプロパティのセット |
備考:
もし--profile
を指定しない場合、デフォルトでlegacy
プロファイルが使用されます。
legacy
プロファイルは将来的に廃止される予定であるため、general
プロファイルなどの他のプロファイルを使用することを推奨します。例えば、myapp
という名前のPodを作成し、デバッグを行います:
kubectl run myapp --image=busybox:1.28 --restart=Never -- sleep 1d
エフェメラルコンテナを使用して、Podをデバッグします。
エフェメラルコンテナに特権が必要な場合は、sysadmin
プロファイルを使用できます:
kubectl debug -it myapp --image=busybox:1.28 --target=myapp --profile=sysadmin
Targeting container "myapp". If you don't see processes from this container it may be because the container runtime doesn't support this feature.
Defaulting debug container name to debugger-6kg4x.
If you don't see a command prompt, try pressing enter.
/ #
コンテナで次のコマンドを実行して、エフェメラルコンテナプロセスのケーパビリティを確認します:
/ # grep Cap /proc/$$/status
...
CapPrm: 000001ffffffffff
CapEff: 000001ffffffffff
...
この結果は、sysadmin
プロファイルを適用したことで、エフェメラルコンテナプロセスに特権が付与されていることを示しています。
詳細はコンテナにケーパビリティを設定するを参照してください。
エフェメラルコンテナが特権コンテナであることは、次のコマンドからも確認できます:
kubectl get pod myapp -o jsonpath='{.spec.ephemeralContainers[0].securityContext}'
{"privileged":true}
確認が終わったらPodを削除します:
kubectl delete pod myapp
カスタムプロファイルの適用
Kubernetes v1.32 [stable]
デバッグに使用するコンテナのspecをYAMLまたはJSON形式でカスタムプロファイルとして定義し、--custom
フラグを使用して適用できます。
備考:
カスタムプロファイルはコンテナのspecの変更のみをサポートしていますが、name
, image
, command
, lifecycle
および volumeDevices
フィールドの変更は許可されません。
また、Podのspecの変更もサポートされていません。例えば、myapp
という名前のPodを作成します:
kubectl run myapp --image=busybox:1.28 --restart=Never -- sleep 1d
YAMLまたはJSON形式でカスタムプロファイルを作成します。
ここでは、custom-profile.yaml
という名前のYAML形式のファイルを作成します:
env:
- name: ENV_VAR_1
value: value_1
- name: ENV_VAR_2
value: value_2
securityContext:
capabilities:
add:
- NET_ADMIN
- SYS_TIME
次のコマンドを実行することで、エフェメラルコンテナにカスタムプロファイルを適用し、Podをデバッグします:
kubectl debug -it myapp --image=busybox:1.28 --target=myapp --profile=general --custom=custom-profile.yaml
Podにカスタムプロファイルが適用された状態のエフェメラルコンテナが追加されたことを確認できます:
kubectl get pod myapp -o jsonpath='{.spec.ephemeralContainers[0].env}'
[{"name":"ENV_VAR_1","value":"value_1"},{"name":"ENV_VAR_2","value":"value_2"}]
kubectl get pod myapp -o jsonpath='{.spec.ephemeralContainers[0].securityContext}'
{"capabilities":{"add":["NET_ADMIN","SYS_TIME"]}}
確認が終わったらPodを削除します:
kubectl delete pod myapp
Feedback
Was this page helpful?
Glad to hear it! Please tell us how we can improve.
Sorry to hear that. Please tell us how we can improve.