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.4k
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
Unit Testing for Prometheus Rules
tksm
6
1.7k
Z Lab の教育への取組 / Cloud Native Education Efforts at Z Lab
tksm
6
1.1k
Recap: Securing Kubernetes with Admission Controllers
tksm
2
1.2k
Istio Mutual TLS
tksm
0
400
Kubernetes with Prometheus
tksm
5
2.1k
Kubernetes v1.7 の主な変更点 / Kubernetes v1.7 features
tksm
0
1.3k
kubectl apply の仕組み / How kubectl apply works
tksm
1
8.8k
Prometheus による Kubernetes モニタリングの基礎 / Kubernetes monitoring with Prometheus
tksm
2
2.6k
Kubernetes の認証・認可と RBAC
tksm
9
2.6k
Other Decks in Technology
See All in Technology
読者のことを考えて書いてみよう / Write with your reader in mind
line_developers
PRO
3
360
ソフトウェアテストで参考にしている67のモノ #scrumniigata / 67 things for software testing
kyonmm
PRO
1
500
Data-Driven Healthcare - Techplay
kotaroito
0
110
5分で完全理解するGoのiota
uji
3
2.1k
LIFF Deep Dive 2022
line_developers
PRO
1
430
スクラムマスターの「観察」スキルを掘り下げる / Scrum Fest Niigata 2022
ama_ch
0
690
失敗を経験したあなたへ〜建設的なインシデントの振り返りを行うために実践するべきこと〜
nobuakikikuchi
0
190
[SRE NEXT 2022]メルカリグループにおけるSREs
srenext
0
280
我々はなぜテストをするのか?
kawaguti
PRO
0
540
CTOのためのQAのつくりかた #scrumniigata / SigSQA How to create QA for CTOs and VPoEs
caori_t
0
300
Dagu | オンプレ向けワークフローエンジン(WebUI 同梱)
yohamta
0
180
LINEスタンプの実例紹介 小さく始める障害検知・対応・振り返りの 改善プラクティス
line_developers
PRO
3
1.7k
Featured
See All Featured
Java REST API Framework Comparison - PWX 2021
mraible
PRO
11
4.6k
Adopting Sorbet at Scale
ufuk
63
7.5k
The MySQL Ecosystem @ GitHub 2015
samlambert
238
11k
Navigating Team Friction
lara
175
11k
Scaling GitHub
holman
451
140k
Art, The Web, and Tiny UX
lynnandtonic
280
17k
VelocityConf: Rendering Performance Case Studies
addyosmani
316
22k
A Tale of Four Properties
chriscoyier
149
20k
GitHub's CSS Performance
jonrohan
1020
410k
Automating Front-end Workflow
addyosmani
1351
200k
Statistics for Hackers
jakevdp
781
210k
Producing Creativity
orderedlist
PRO
333
37k
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