在平常kubernetes的運維中,常常遇到pod的網絡問題,如pod間網絡不通,或者端口不通,更復雜的,須要在容器裏面抓包分析才能定位。而kubertnets的場景,pod使用的鏡像通常都是儘可能精簡,不少都是基於alpine基礎鏡像製做的,於是pod內沒有ping,telnet,nc,curl命令,更別說tcpdump這種複雜的工具了。除了在容器或者鏡像內直接安裝這些工具這種最原始的法子,咱們探討下其餘法子。linux
項目地址 kubect debug,https://github.com/aylei/kubectl-debugios
kubectl-debug
是一個簡單的 kubectl 插件,可以幫助你便捷地進行 Kubernetes 上的 Pod 排障診斷。背後作的事情很簡單: 在運行中的 Pod 上額外起一個新容器,並將新容器加入到目標容器的 pid
, network
, user
以及 ipc
namespace 中,這時咱們就能夠在新容器中直接用 netstat
, tcpdump
這些熟悉的工具來解決問題了, 而舊容器能夠保持最小化,不須要預裝任何額外的排障工具。操做流程能夠參見官方項目地址文檔。git
一條 kubectl debug命令背後是這樣的github
步驟分別是:docker
接下來,客戶端就能夠開始經過 5,6 這兩個鏈接開始 debug 操做。操做結束後,Debug Agent 清理 Debug 容器,插件清理 Debug Agent,一次 Debug 完成。bash
有2種進入pod 所在net ns的方式,前提都是須要登陸到pod所在宿主機,且須要找出pod對應的容器ID或者名字。網絡
獲取pod對應容器的ID或者name運維
pid="$(docker inspect -f '{{.State.Pid}}' <container_name | uuid>)" #替換爲環境實際的容器名字或者uuid
建立容器對應netnsssh
ip netns會到/var/run/netns目錄下尋找network namespace,把容器進程中netns鏈接到這個目錄中後,ip netns纔會感知到curl
$ sudo mkdir -p /var/run/netns #docker默認不會建立這個連接,須要手動建立,這時候執行ip netns,就應當看到連接過來的network namespace $ sudo ln -sf /proc/$pid/ns/net "/var/run/netns/<container_name|uuid>"
執行ip netns <<container_name|uuid > bash,進入容器ns
ip netns exec <container_name|uuid> bash
執行telnet,tcpdump等命令,此時執行ip a或者ifconfig,只能看到容器自己的IP
以下圖,執行ifconfig,只看到容器自己的IP,此時執行telnet,tcpdump等於直接在容器內操做
nsenter爲util-linux裏面的一個工具,除了進入容器net ns,還支持其餘不少操做,能夠查看官方文檔。
pid="$(docker inspect -f '{{.State.Pid}}' <container_name | uuid>)" nsenter -t $pid -n /bin/bash tcpdump -i eth0 -nn #此時利用宿主機的tcpdump執行抓包操做,等於在容器內抓包