日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

简化 Pod 故障诊断:kubectl-debug 介绍

發布時間:2023/12/4 编程问答 34 豆豆
生活随笔 收集整理的這篇文章主要介紹了 简化 Pod 故障诊断:kubectl-debug 介绍 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.


背景


容器技術的一個最佳實踐是構建盡可能精簡的容器鏡像。但這一實踐卻會給排查問題帶來麻煩:精簡后的容器中普遍缺失常用的排障工具,部分容器里甚至沒有 shell (比如 FROM scratch )。在這種狀況下,我們只能通過日志或者到宿主機上通過 docker-cli 或 nsenter 來排查問題,效率很低。Kubernetes 社區也早就意識到了這個問題,在 16 年就有相關的 Issue Support for troubleshooting distroless containers[1] 并形成了對應的 Proposal[2]。遺憾的是,由于改動的涉及面很廣,相關的實現至今還沒有合并到 Kubernetes 上游代碼中。而在 一個偶然的機會下(PingCAP 一面要求實現一個 kubectl 插件實現類似的功能),我開發了 kubectl-debug[2]:通過啟動一個安裝了各種排障工具的容器,來幫助診斷目標容器。
工作原理


我們先不著急進入 Quick Start 環節。kubectl-debug 本身非常簡單,因此只要理解了它的工作原理,你就能完全掌握這個工具,并且還能用它做 debug 之外的事情。
我們知道,容器本質上是帶有 Cgroup 資源限制和 Namespace 隔離的一組進程。因此,我們只要啟動一個進程,并且讓這個進程加入到目標容器的各種 Namespace 中,這個進程就能 “進入容器內部”(注意引號),與容器中的進程”看到”相同的根文件系統、虛擬網卡、進程空間了——這也正是 docker exec 和 kubectl exec 等命令的運行方式。
現在的狀況是,我們不僅要 “進入容器內部”,還希望帶一套工具集進去幫忙排查問題。那么,想要高效管理一套工具集,又要可以跨平臺,最好的辦法就是把工具本身都打包在一個容器鏡像當中。接下來,我們只需要通過這個”工具鏡像”啟動容器,再指定這個容器加入目標容器的的各種 namespace,自然就實現了 “攜帶一套工具集進入容器內部”。事實上,使用 docker-cli 就可以實現這個操作:
export TARGET_ID=666666666 # 加入目標容器的 network, pid 以及 ipc namespace docker run -it --network=container:$TARGET_ID --pid=container:$TARGET_ID --ipc=container:$TARGET_ID busybox
這就是 kubectl-debug 的出發點:用工具容器來診斷業務容器 。背后的設計思路和 sidecar 等模式是一致的:每個容器只做一件事情。
具體到實現上,一條 kubectl debug命令背后是這樣的:

步驟分別是:
  • 插件查詢 ApiServer:demo-pod 是否存在,所在節點是什么

  • ApiServer 返回 demo-pod 所在所在節點

  • 插件請求在目標節點上創建 Debug Agent Pod

  • Kubelet 創建 Debug Agent Pod

  • 插件發現 Debug Agent 已經 Ready,發起 debug 請求(長連接)

  • Debug Agent 收到 debug 請求,創建 Debug 容器并加入目標容器的各個 Namespace 中,創建完成后,與 Debug 容器的 tty 建立連接


  • 接下來,客戶端就可以開始通過 5,6 這兩個連接開始 debug 操作。操作結束后,Debug Agent 清理 Debug 容器,插件清理 Debug Agent,一次 Debug 完成。效果如下圖:

    開始使用


    Mac 可以直接使用 brew 安裝:
    brew install aylei/tap/kubectl-debug
    所有平臺都可以通過下載 binary 安裝:
    export PLUGIN_VERSION=0.1.1 # linux x86_64 curl -Lo kubectl-debug.tar.gz https://github.com/aylei/kubectl-debug/releases/download/v${PLUGIN_VERSION}/kubectl-debug_${PLUGIN_VERSION}_linux_amd64.tar.gz # macos curl -Lo kubectl-debug.tar.gz https://github.com/aylei/kubectl-debug/releases/download/v${PLUGIN_VERSION}/kubectl-debug_${PLUGIN_VERSION}_darwin_amd64.tar.gz tar -zxvf kubectl-debug.tar.gz kubectl-debug sudo mv kubectl-debug /usr/local/bin/
    Windows 用戶可以在 Release 頁面[4]進行下載。
    下載完之后就可以開始使用 debug 插件:
    kubectl debug target-pod --agentless --port-forwardkubectl 從 1.12 版本之后開始支持從 PATH 中自動發現插件。1.12 版本之前的 kubectl 不支持這種插件機制,但也可以通過命令名 kubectl-debug 直接調用。可以參考項目的中文 README[5]來獲得更多文檔和幫助信息。
    典型案例


    基礎排障
    kubectl debug 默認使用 nicolaka/netshoot[6] 作為默認的基礎鏡像,里面內置了相當多的排障工具,包括:
    使用 iftop 查看容器網絡流量:
    ? ~ kubectl debug demo-pod root @ / [2] ? → iftop -i eth0 interface: eth0 IP address is: 10.233.111.78 MAC address is: 86:c3:ae:9d:46:2b # (圖片略去)
    使用 drill 診斷 DNS 解析:
    root @ / [3] ? → drill -V 5 demo-service ;; ->>HEADER<<- opcode: QUERY, rcode: NOERROR, id: 0 ;; flags: rd ; QUERY: 1, ANSWER: 0, AUTHORITY: 0, ADDITIONAL: 0 ;; QUESTION SECTION: ;; demo-service. IN A ;; ANSWER SECTION: ;; AUTHORITY SECTION: ;; ADDITIONAL SECTION: ;; Query time: 0 msec ;; WHEN: Sat Jun 1 05:05:39 2019 ;; MSG SIZE rcvd: 0 ;; ->>HEADER<<- opcode: QUERY, rcode: NXDOMAIN, id: 62711 ;; flags: qr rd ra ; QUERY: 1, ANSWER: 0, AUTHORITY: 1, ADDITIONAL: 0 ;; QUESTION SECTION: ;; demo-service. IN A ;; ANSWER SECTION: ;; AUTHORITY SECTION: . 30 IN SOA a.root-servers.net. nstld.verisign-grs.com. 2019053101 1800 900 604800 86400 ;; ADDITIONAL SECTION: ;; Query time: 58 msec ;; SERVER: 10.233.0.10 ;; WHEN: Sat Jun 1 05:05:39 2019 ;; MSG SIZE rcvd: 121
    使用 tcpdump 抓包:
    root @ / [4] ? → tcpdump -i eth0 -c 1 -Xvv tcpdump: listening on eth0, link-type EN10MB (Ethernet), capture size 262144 bytes 12:41:49.707470 IP (tos 0x0, ttl 64, id 55201, offset 0, flags [DF], proto TCP (6), length 80) demo-pod.default.svc.cluster.local.35054 > 10-233-111-117.demo-service.default.svc.cluster.local.8080: Flags [P.], cksum 0xf4d7 (incorrect -> 0x9307), seq 1374029960:1374029988, ack 1354056341, win 1424, options [nop,nop,TS val 2871874271 ecr 2871873473], length 28 0x0000: 4500 0050 d7a1 4000 4006 6e71 0ae9 6f4e E..P..@.@.nq..oN 0x0010: 0ae9 6f75 88ee 094b 51e6 0888 50b5 4295 ..ou...KQ...P.B. 0x0020: 8018 0590 f4d7 0000 0101 080a ab2d 52df .............-R. 0x0030: ab2d 4fc1 0000 1300 0000 0000 0100 0000 .-O............. 0x0040: 000e 0a0a 08a1 86b2 ebe2 ced1 f85c 1001 .............\.. 1 packet captured 11 packets received by filter 0 packets dropped by kernel
    訪問目標容器的根文件系統:
    容器技術(如 Docker)利用了 /proc 文件系統提供的 /proc/{pid}/root/ 目錄實現了為隔離后的容器進程提供單獨的根文件系統(root filesystem)的能力(就是 chroot 一下)。當我們想要訪問 目標容器的根文件系統時,可以直接訪問這個目錄:
    root @ / [5] ? → tail -f /proc/1/root/log_ Hello, world!
    這里有一個常見的問題是 free top 等依賴 /proc 文件系統的命令會展示宿主機的信息,這也是容器化過程中開發者需要適應的一點(當然了,各種 runtime 也要去適應,比如臭名昭著的 Java 8u121 以及更早的版本不識別 cgroups 限制[7]問題就屬此列)。
    診斷 CrashLoopBackoff
    排查 CrashLoopBackoff 是一個很麻煩的問題,Pod 可能會不斷重啟, kubectl exec 和 kubectl debug 都沒法穩定進行排查問題,基本上只能寄希望于 Pod 的日志中打印出了有用的信息。為了讓針對 CrashLoopBackoff 的排查更方便, kubectl-debug 參考 oc debug 命令,添加了一個 --fork 參數。當指定 --fork 時,插件會復制當前的 Pod Spec,做一些小修改, 再創建一個新 Pod:
    • 新 Pod 的所有 Labels 會被刪掉,避免 Service 將流量導到 fork 出的 Pod 上

    • 新 Pod 的 ReadinessProbe 和 LivnessProbe 也會被移除,避免 kubelet 殺死 Pod

    • 新 Pod 中目標容器(待排障的容器)的啟動命令會被改寫,避免新 Pod 繼續 Crash


    接下來,我們就可以在新 Pod 中嘗試復現舊 Pod 中導致 Crash 的問題。為了保證操作的一致性,可以先 chroot 到目標容器的根文件系統中:
    ? ~ kubectl debug demo-pod --fork root @ / [4] ? → chroot /proc/1/root root @ / [#] ? → ls bin entrypoint.sh home lib64 mnt root sbin sys tmp var dev etc lib media proc run srv usr root @ / [#] ? → ./entrypoint.sh # 觀察執行啟動腳本時的信息并根據信息進一步排障
    結尾的碎碎念


    kubectl-debug 一開始只是 PingCAP 在面試時出的 homework,第一版完成在去年年底。當時整個項目還非常粗糙,不僅文檔缺失,很多功能也都有問題:
    • 不支持診斷 CrashLoopBackoff 中的 Pod

    • 強制要求預先安裝一個 Debug Agent 的 DaemonSet

    • 不支持公有云(節點沒有公網 IP 或公網 IP 因為防火墻原因無法訪問時,就無法 debug)

    • 沒有權限限制,安全風險很大


    而讓我非常興奮的是,在我無暇打理項目的情況下,隔一兩周就會收到 Pull Request 的通知郵件,一直到今天,大部分影響基礎使用體驗的問題都已經被解決, kubectl-debug 也發布了 4 個版本(0.0.1, 0.0.2, 0.1.0, 0.1.1)。尤其要感謝 @tkanng,TA 在第一個 PR 時還表示之前沒有寫過 Go, 而在 0.1.1 版本中已經是這個版本絕大部分 feature 的貢獻者,解決了好幾個持續很久的 issue,感謝!
    最后再上一下項目地址:https://github.com/aylei/kubectl-debug
    假如在使用上或者對項目本身有任何問題,歡迎提交 issue,也可以在 文章評論區留言討論。
    相關鏈接:
  • https://github.com/kubernetes/kubernetes/issues/27140

  • https://github.com/kubernetes/community/blob/master/contributors/design-proposals/node/troubleshoot-running-pods.md

  • https://github.com/aylei/kubectl-debug

  • https://github.com/aylei/kubectl-debug/releases/tag/v0.1.1

  • https://github.com/aylei/kubectl-debug/blob/master/docs/zh-cn.md

  • https://github.com/nicolaka/netshoot

  • https://blog.softwaremill.com/docker-support-in-new-java-8-finally-fd595df0ca54


  • 原文鏈接:https://aleiwu.com/post/kubectl-debug-intro/

    .NET社區新聞,深度好文,歡迎訪問公眾號文章匯總?http://www.csharpkit.com?


    創作挑戰賽新人創作獎勵來咯,堅持創作打卡瓜分現金大獎

    總結

    以上是生活随笔為你收集整理的简化 Pod 故障诊断:kubectl-debug 介绍的全部內容,希望文章能夠幫你解決所遇到的問題。

    如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。