Upgrade to Pro
— share decks privately, control downloads, hide ads and more …
Speaker Deck
Speaker Deck
PRO
Sign in
Sign up
for free
Debugging Applications in Kubernetes
Takashi Kusumi
March 08, 2018
Technology
16
3.1k
Debugging Applications in Kubernetes
Kubernetes Meetup Tokyo #10
2018.03.08
https://k8sjp.connpass.com/event/76816/
Takashi Kusumi
March 08, 2018
Tweet
Share
More Decks by Takashi Kusumi
See All by Takashi Kusumi
tksm
6
1.1k
tksm
6
1k
tksm
2
1.1k
tksm
0
270
tksm
5
2k
tksm
0
1.2k
tksm
1
8.1k
tksm
2
2.4k
tksm
9
2.4k
Other Decks in Technology
See All in Technology
ido_kara_deru
1
170
syoshie
1
700
free_world21
0
110
pakio
0
140
pohjus
0
3.3k
hololab
0
290
dena_tech
0
200
mizzy
3
150
go5paopao
9
1.9k
900groove
2
570
hiroyaiizuka
0
210
dena_tech
0
240
Featured
See All Featured
jonyablonski
19
1.2k
mthomps
38
2.3k
bermonpainter
342
26k
bkeepers
408
58k
myddelton
109
11k
holman
461
280k
tmm1
61
9.5k
eileencodes
113
25k
pedronauck
652
110k
brad_frost
157
6.5k
chriscoyier
779
240k
aarron
257
36k
Transcript
Kubernetes Meetup Tokyo #10 2018/03/08 Takashi Kusumi <tkusumi@zlab.co.jp> Debugging Applications
in Kubernetes
Kubernetes でのデバッグの悩み ▶ Pod や Service にクラスタ外からアクセスできない ▶ コンテナにデバッグツールが⼊っていない +
tcpdump や strace など使い慣れたツールを使いたい + ⼀⽅コンテナのサイズは最⼩にしたい 2 # NH 96566-KB First Computer "Bug", 1945
アジェンダ ▶ kubectl でのデバッグの基本 + kubectl (run | logs |
exec | port-forward | cp | top) ▶ Pod と Linux 名前空間 ▶ デバッグツールが含まれない場合 ▶ 将来⼊りそうな便利機能 + kubectl debug、PodShareProcessNamespace 3
kubectl でのデバッグの基本
デバッグに使える kubectl のサブコマンド 5 run Pod をコマンドだけで作成する logs コンテナのログを表⽰する exec
コンテナ内の任意コマンドを実⾏する port-forward コンテナ内にポートフォワードする cp コンテナとローカルの間でファイルを転送する top Pod や Node の利⽤状況を表⽰する
kubelet の Debugging handler 6 Controller Master scheduler etcd apiserver
Node kubectl kubelet kube-proxy container runtime debugging handler kubelet kube-proxy container runtime debugging handler kubelet ͷ --enable-debugging-handlers ͰઃఆՄɻσϑΥϧτtrue exec ͷ߹ kubelet ͷ API Λར༻ port: 10250 exec ͷ߹ SPDY ʹ upgrade
kubectl run 7 クラスタ内から Pod や Service にアクセスしたいときに最適 # Pod
を立ち上げシェルをアタッチして操作する $ kubectl run -it --rm --restart=Never debug --image alpine /bin/sh # 必要に応じてツールをインストール (Pod 内のシェル) (pod) $ apk add --update curl # DNS サービスディスカバリを使って Service にアクセス (pod) $ curl http://mynginx/ # 終了すると Pod も削除される (--rm --restart=Never) (pod) $ exit
--serviceaccount オプション 8 ServiceAccount の権限周りのデバッグに便利 # ServiceAccount を指定して起動 $ kubectl
run -it --restart=Never --rm \ --serviceaccount robot \ --image gcr.io/google_containers/hyperkube:v1.9.3 \ debug # 実際に kubectl で権限を確認 (pod) $ kubectl get pods
--overrides オプション 9 overrides オプションを使うと JSON で値の上書きが可能 run のオプションで指定できないフィールドも全て設定できる #
ノードを指定して Pod をデプロイする $ kubectl run --overrides ' {"spec": {"nodeName": "$NODE_NAME"}} ' -it --rm --restart=Never debug --image alpine
ホストの Docker を操作 ☠ 10 $ kubectl run -it --rm
--restart=Never --overrides ' { "spec": { "nodeName": "$NODE_NAME", "containers": [ { "name": "docker", "image": "docker", "stdin": true, "tty": true, "command": ["/bin/sh"], "securityContext": {"capabilities": {"add": ["SYS_PTRACE"]}}, "volumeMounts": [ {"name": "docker-sock", "mountPath": "/var/run/docker.sock"} ] } ], "volumes": [ {"name": "docker-sock", "hostPath": {"path": "/var/run/docker.sock"}} ] } } ' mydocker --image docker # ホストの Docker ソケットをマウントして操作
kubectl logs 11 # Pod のログを表示する $ kubectl logs <POD_NAME>
# tail -f 相当 $ kubectl logs -f <POD_NAME> # 1時間以内のログをタイムスタンプ付きで表示 $ kubectl logs --since --timestamp 1h <POD_NAME> # Deployment の Pod の一つ目だけのログを表示 $ kubectl logs deploy/<DEPLOY_NAME>
wercker/stern 12 複数の Pod のログをまとめて表⽰できる便利ツール https://github.com/wercker/stern
kubectl exec 13 # 任意コマンドの実行。オプションを使いたい場合は -- を置く $ kubectl exec
nginx-3272110360-n2dq6 -- ls -l # シェルをインタラクティブ操作 $ kubectl exec -it nginx-3272110360-n2dq6 -- /bin/sh # コンテナ内に tcpdump をインストール (コンテナ内シェル) (pod) $ apt-get update && apt-get install -y tcpdump # コンテナ内で tcpdump を実行 (pod) $ tcpdump -i any -X コンテナ内の任意コマンドを実⾏する
kubectl port-forward 14 コンテナ内のポートをフォーワードする ローカルのみ listen しているポートにもアクセスできる # ローカルの 8080
ポートをコンテナの 80 に転送 $ kubectl port-forward <POD_NAME> 8080:80 Forwarding from 127.0.0.1:8080 -> 80 # コンテナの 80 をランダムなローカルポートに転送 $ kubectl port-forward <POD_NAME> :80 Forwarding from 127.0.0.1:53706 -> 80
v1.10 で Service / Deploy 指定もサポート 15 # ローカルの 8443
ポートを Service の 443 に転送 $ kubectl port-forward svc/<SVC_NAME> 8443:443 # Deploy を指定して 5000 ポートと 6000 ポートを転送 $ kubectl port-forward deployment/<DEPLOY_NAME> 5000 6000 kubectl 側で Service / Deploy のセレクタを使って 最初の Pod を選択しているので分散されるわけではない
kubectl top nodes 16 ノードの CPU, メモリ使⽤量が簡単に⾒える $ kubectl top
nodes NAME CPU(cores) CPU% MEMORY(bytes) MEMORY% node-cqkj6 88m 1% 3298Mi 20% node-fgq9d 110m 1% 3776Mi 23% node-kg2r6 99m 1% 3461Mi 21% node-4nqgg 1568m 19% 20297Mi 33% node-jrwj2 66m 0% 7631Mi 12% node-pkzhd 84m 1% 5219Mi 8% node-trtr2 91m 1% 6779Mi 11%
kubectl top pods 17 Pod の CPU, メモリ使⽤量が簡単に⾒える $ kubectl
top pods -n kube-system NAME CPU(cores) MEMORY(bytes) alertmanager-2731826431-5bwb9 0m 7Mi prometheus-2216016132-84s23 1428m 19879Mi default-http-backend-462227202-0wlrn 0m 3Mi grafana-2108099539-0c2dk 0m 27Mi heapster-629638580-xcw2v 3m 65Mi kube-dns-4058640398-92363 1m 36Mi kube-state-metrics-4210456282-m9d2v 2m 49Mi
Pod と Linux 名前空間
Linux 名前空間と Pod 19 名前空間 分離対象 Pod 内 IPC 共有メモリやセマフォ等によるプロセス間通信
(IPC) 共有 Network ネットワークデバイス、IP アドレスネット等のネットワーク 共有 Mount マウントポイント 分離 PID プロセス ID 分離 User ユーザ ID とグループ ID (UID, GID) 共有 UTS ホスト名とドメイン名 分離 Cgroup cgroup のルートディレクトリ 共有 *後述
Pod と pause コンテナ 20 pause Container A Container B
ڞ༗͢Δ໊લۭؒ pause ίϯςφ͕อ࣋ # 別のコンテナ($C)の名前空間 # 使って起動する $ docker run -it \ —pid container:$C \ —ipc container:$C \ —network container:$C \ # 起動するコンテナイメージ ubuntu Pod
See also: Ian さんの Pause コンテナの記事 21 https://www.ianlewis.org/en/almighty-pause-container
/proc/[pid]/ns で実際に⾒てみる 22 $ sudo ls -l /proc/15627/ns total 0
... cgroup -> cgroup:[4026531835] ... ipc -> ipc:[4026532337] ... mnt -> mnt:[4026532335] ... net -> net:[4026532340] ... pid -> pid:[4026532338] ... user -> user:[4026531837] ... uts -> uts:[4026532336] $ sudo ls -l /proc/15784/ns total 0 ... cgroup -> cgroup:[4026531835] ... ipc -> ipc:[4026532337] ... mnt -> mnt:[4026532442] ... net -> net:[4026532340] ... pid -> pid:[4026532549] ... user -> user:[4026531837] ... uts -> uts:[4026532443] pause ίϯςφ (pid 15627) nginx ίϯςφ (pid 15784)
デバッグには Network, PID の共有が便利 ▶ Network 名前空間 + tcpdump, netstat
▶ PID 名前空間 (Pod 内では分離されている) + ps, strace, kill (シグナル) + /proc/[pid]/root でファイルシステムにもアクセスできる 23
PID がマウントするルート: /proc/[pid]/root ▶ /proc/[pid]/root でその PID がマウントしているルートが⾒れる ▶ PID
名前空間を共有していればアクセス可能 + デバッグ対象にシェルが含まれない場合に便利 24 $ docker run -it \ --pid container:$CONTAINER_ID \ # PID 名前空間を共有 alpine # 任意のコンテナイメージ # /proc/[pid]/root で PID を共有したコンテナのファイルを見れる (pod) $ ls /proc/1/root/ Dockerfile dashboard dev etc ...
デバッグツールが含まれない場合
コンテナにツールが含まれない場合 26 Mount Network PID 備考 Pod にパッケージをインストール ⼀番⼿軽 デバッグ⽤イメージを作成
開発中に便利 デバッグ⽤サイドカーを⼊れる パッケージマネージャーが ない場合に便利 docker run で名前空間を共有 ※1 scratch イメージも対応可能 ※1 /proc/[PID]/root 経由でファイルにアクセス可能
docker run で他のコンテナと名前空間を共有 27 $ docker run -it \ --pid
container:$CONTAINER_ID \ # PID 名前空間 --network container:$CONTAINER_ID \ # ネットワーク名前空間 --privileged \ # strace などを利用したい場合 alpine # 任意のコンテナイメージ # 共有したコンテナのプロセスが見える (シグナルや strace も可能) (pod) $ ps PID USER TIME COMMAND 1 root 0:04 /dashboard --port=9090 ... # /proc 経由で共有したコンテナのファイルも見れる (pod) $ ls /proc/1/root/ Dockerfile dashboard dev etc ...
scratch-debugger 28 scratch イメージに busybox シェルを差し込むスクリプト
将来⼊りそうな便利機能
Debug Containers #277 ▶ k8s v1.7くらいからマイルストーンに⼊っている機能 + 最近も v1.10 ->
v1.11 にずれ込んだ ▶ 最近開発が進んだので v1.11 に期待 30 # Pod 上でデバッグコンテナを起動 $ kubectl debug target-pod # イメージ等を指定して起動 $ kubectl debug -c debug-shell --image=debian target-pod -- bash
Configurable Pod Process Namespace Sharing #495 31 ▶ Pod 間の
PID 名前空間の共有を設定可能にする機能 ▶ v1.10 でα機能として⼊る予定 + pod.spec.securityContext.shareProcessNamespace
まとめ
まとめ ▶ デバッグの基本 + kubectl (run | logs | exec
| port-forward | cp | top) ▶ デバッグツールが含まれない場合 + パッケージージインストール or docker で名前空間を共有 + PID 空間を共有すると /proc/[pid]/root でファイルも⾒れる ▶ kubectl debug に期待 33
We are hiring! bit.ly/zlab-careers