実行中の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 nodekubectl 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}

例として、実行中のCassandra Podからログを見るには、次のように実行します。

kubectl exec cassandra -- cat /var/log/cassandra/system.log

例えばkubectl exec-i-t引数を使って、端末に接続されたシェルを実行することができます:

kubectl exec -it cassandra -- sh

詳しくは、実行中のコンテナへのシェルを取得するを参照してください。

エフェメラルコンテナによるデバッグ

FEATURE STATE: 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でプロセス名前空間の共有を有効にしないため、指定する必要があります。

新しく作成されたエフェメラルコンテナの状態は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:/#

デバッグが終わったら、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.
/ #

これで、ファイルシステムのパスのチェックやコンテナコマンドの手動実行などのタスクを実行するために使用できる対話型シェルが完成しました。

デバッグが終わったら、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フラグを使用して適用できます。 使用可能なスタティックプロファイルは以下の通りです:

ProfileDescription
legacyv1.22と互換性を保つプロパティのセット
general各デバッグシナリオに対応する汎用的なプロパティのセット
baselinePodSecurityStandard baseline policy に準拠したプロパティのセット
restrictedPodSecurityStandard restricted policyに準拠したプロパティのセット
netadminネットワーク管理者権限を含むプロパティのセット
sysadminシステム管理者(root)権限を含むプロパティのセット

例えば、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

カスタムプロファイルの適用

FEATURE STATE: Kubernetes v1.31 [beta]

デバッグに使用するコンテナのspecをYAMLまたはJSON形式でカスタムプロファイルとして定義し、--customフラグを使用して適用できます。

例えば、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
最終更新 December 15, 2024 at 6:24 PM PST: Merge pull request #49087 from Arhell/es-link (2c4497f)