ubuntu 自动挂载工具_容器诊断工具集合

前言

随着微服务架构和云计算的普及,越来越多企业的应用都上了云,不仅是云基础设施 IaaS ,如 kubernetes 等 PaaS 项目也是越来越热门。但新的技术会带来新的架构复杂,同时也会使排查问题更加困难,因此很多运维和开发同学都觉得用平时用的顺手的工具和手段在容器里排查问题不好使了。工欲善其事必先利其器,正是由于这样的情况,所以我们排查容器问题的时候,需要引入新的工具和手段。

容器基础

在学习工具的使用前,我们首先需要简单的了解下容器的原理。假如一台机器是一间房子,那么进程就是住在里面的一个个的人,在单体应用的时代,所有人都住在一间房子里,而容器技术就是通过一些手段把这些人都隔开,让每个人都以为自己住上有独卫(网络,IPC,namespace 等资源)的单间。而这些隔离和限制的主要使用的如下技术:

  • cgroups 资源限制

  • namespace 资源隔离

  • rootfs 文件系统隔离

在单体应用的时代,所有的进程都在同一个命名空间里,且启动的进程都没有隔离命名空间,那么自然调试工具进程也在同一个命名空间,也就可以 debug 其他进程。而容器技术由于分割成一个个的小房间,如果想要查看单个房间的情况,虽然在大管家(宿主机)的上帝视角一样可以看到, 但为了减少干扰并更加符合我们平时的使用习惯,我们就需要进入到房间(命名空间)里面查看。

例如我们可以通过 docker inspect CONTAINER_ID 获取到某个容器资源隔离的文件的地址,如下"SandboxKey": "/var/run/docker/netns/50def85bf6e2"就是。

@ubuntu ➜ k8s-debug  docker inspect 0dde03166e02
...
"SandboxKey": "/var/run/docker/netns/50def85bf6e2",
"SecondaryIPAddresses": null,
"SecondaryIPv6Addresses": null,
"EndpointID": "7faa1e764317cdfadf7f31b7ed2fecff62b458211f79fadb3362c8e22755f326",
"Gateway": "172.17.0.1",
...

而容器的诊断工具就是自带了部分调试工具的镜像,并能根据容器 ID 帮我们自动地进入到房间(网络,IPC 命名空间等)。在初步了解了容器的原理后,我们便可进入工具的介绍了。

netshoot

首先介绍的第一个工具是netshoot,netshoot 的自我定位就是容器网络诊断的瑞士军刀,简单来说,netshoot 其实就是一个装满了各种工具的镜像,他用起来也很简单。

  • 执行docker run -it --net container: nicolaka/netshoot 就行,这里的--net是 docker 命令指定该容器要联结到哪个容器的网络命名空间

  • 如果要进入宿主机的命名空间则指定--net host就行了

  • 如果要诊断 docker NIC设备的网络 情况,则可以用工具nsenter进入NIC 设备的命名空间排查,后面我会介绍这个工具

另外,如果是在 kubernetes 里面,我们可以通过执行kubectl run test-lab --generator=run-pod/v1 --rm -i --tty --overrides='{"spec": {"hostNetwork": true}}' --image nicolaka/netshoot -- /bin/bash 这个命令进入宿主机的网络。别怕这个命令长,我来一一解释下这条命令的各个选项的作用

  • kubectl run test_lab --generator=pod/v1 --rm -i --tty意思是创建一个一次性的名叫test_lab的 Pod 资源并且使用标准输入输出交互

  • --overrides='{"spec": {"hostNetwork": true}}'意思是使用宿主机网络,具体哪台宿主机要看这个 Pod 调度到哪个节点。

  • --image nicolaka/netshoot指定 Pod 的镜像

  • -- 这是 bash 的内置命令选项,是标志命令的结束的意思,举个例子:如果我想要在文件里用grep搜索-v字符串,grep -v filename-v会被视为选项,但我如果使用grep -- -v filename那么就可以正常搜索了

演示

下面我来演示几个例子:

  1. 使用 tcpdump 抓容器的包并拷贝 pcap 文件出来,便于用 wireshark 分析

    @ubuntu ➜ k8s-debug  mkdir -p /tmp/netshoot
    @ubuntu ➜ k8s-debug docker ps
    CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
    0dde03166e02 jumpserver/jms_all:1.5.4 "entrypoint.sh" 3 weeks ago Up 3weeks ... mystifying_williamson
    @ubuntu ➜ k8s-debug docker run -it -v /tmp/netshoot:/tmp --net container:0dde03166e02 nicolaka/netshoot
    Welcome to Netshoot! (github.com/nicolaka/netshoot)
    root @ /
    [1] → tcpdump -nn -i any -w /tmp/pkg.pcap
    [2] → exit

    具体命令使用与之前的差不多,只不过把宿主机上的/tmp/netshoot目录 bind-mount 到了容器的/tmp目录

  2. 有时候我们还需要调试 bridge 或者 overlay 网络,可以使用 nsenter,nsenter 可以进入任何命名空间

    @ubuntu ➜ ~  docker network ls
    NETWORK ID NAME DRIVER SCOPE
    ...
    0ipu2p43c6jh ingress overlay swarm
    697402c52a87 none null local
    @ubuntu ➜ ~ docker run -it --rm -v /var/run/docker/netns:/var/run/docker/netns --privileged=true nicolaka/netshoot
    Welcome to Netshoot! (github.com/nicolaka/netshoot)
    root @ /
    [1] ? → ls /var/run/docker/netns/
    1-0ipu2p43c6 50def85bf6e2 83f9ffa847d7 default ingress_sbox
    root @ /var/run/docker/netns
    [6] ? → nsenter --net=/var/run/docker/netns/1-0ipu2p43c6 sh
    root @ /run/docker/netns
    [#] ? → ifconfig
    br0 Link encap:Ethernet HWaddr 02:61:F2:E4:26:3B
    inet addr:10.255.0.1 Bcast:10.255.255.255 Mask:255.255.0.0
    UP BROADCAST RUNNING MULTICAST MTU:1450 Metric:1
    ...
    vxlan0 Link encap:Ethernet HWaddr 02:61:F2:E4:26:3B
    UP BROADCAST RUNNING MULTICAST MTU:1450 Metric:1
    RX packets:0 errors:0 dropped:0 overruns:0 frame:0
    TX packets:0 errors:0 dropped:0 overruns:0 carrier:0
    collisions:0 txqueuelen:0
    RX bytes:0 (0.0 B) TX bytes:0 (0.0 B)
    root @ /run/docker/netns
    [#] ? → bridge fdb show br0
    33:33:00:00:00:01 dev br0 self permanent
    01:00:5e:00:00:01 dev br0 self permanent
    02:61:f2:e4:26:3b dev vxlan0 master br0 permanent
    ...

    上面的命令首先我们是进入了1-0ipu2p43c6的命名空间,即那个叫 ingress 的 overlay 网络,然后可以通过查看这个 NIC 设备上的fdb 表

  3. 我们也可以通过挂载 docker 的 unix sock 文件查看容器的 metrics

    docker run -it --rm -v /var/run/docker.sock:/var/run/docker.sock nicolaka/netshoot ctop

    如下图所示13482284ba59b2499f3aefc6ac9dbfea.png

netshoot 工具非常强大,还有很多功能可以自行去探索,netshoot上有详细的说明。

docker-debug

上面介绍的 netshoot 主要定位于 docker 网络的诊断,从名字就可以看出来。而我们现在介绍的工具 docker-debug可以说是 netshoot 的升级版,他不仅可以进入目标容器的网络命名空间,还可以进入 pid,user,filesystem,ipc 的命名空间,所以我们可以操作的空间就更大了。话不多说,我们开始演示。

安装

首先我们要下载 docker-debug 的二进制文件

@ubuntu ➜ docker-debug  wget docker-debug https://github.com/zeromake/docker-debug/releases/download/0.6.2/docker-debug-linux-amd64 -O docker-debug
@ubuntu ➜ docker-debug chmod +x docker-debug
@ubuntu ➜ docker-debug mv docker-debug /usr/bin
@ubuntu ➜ docker-debug docker-debug info
Version: 0.6.2
Platform: TravisLinux
Commit: cf4cc41
Time: 2019-06-20 05:40:52 +0000

然后我赋予了文件执行权限并移动到/usr/bin目录下,如果执行docker-debug info看到有正确输出,则说明安装成功了

使用

使用就很简单了,首先我们获取到容器的名字或者容器 ID

@ubuntu ➜ docker-debug  docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
0dde03166e02 jumpserver/jms_all:1.5.4 "entrypoint.sh" 3 weeks ago Up 3 weeks ... mystifying_williamson

然后执行docker-debug COMMAND就可以了

@ubuntu ➜ docker-debug  docker-debug 0dde03166e02 bash
bash-5.0# netstat -lntp
Active Internet connections (only servers)
Proto Recv-Q Send-Q Local Address Foreign Address State PID/Program name
...
tcp 0 0 0.0.0.0:8080 0.0.0.0:* LISTEN 52/python3.6
tcp 0 0 0.0.0.0:8081 0.0.0.0:* LISTEN 110/java
...
bash-5.0# ifconfig
eth0 Link encap:Ethernet HWaddr 02:42:AC:11:00:02
inet addr:172.17.0.2 Bcast:172.17.255.255 Mask:255.255.0.0
UP BROADCAST RUNNING MULTICAST MTU:1500 Metric:1
RX packets:32776325 errors:0 dropped:0 overruns:0 frame:0
...
bash-5.0# ls /mnt/container/
anaconda-post.log dev lib mnt root srv usr
bin etc lib64 opt run sys var
config home media proc sbin tmp

我们可以看到已经进入了目标容器的 ipc,network,filesystem,pid 的命名空间了,而目标容器的root则挂载在了/mnt/container目录下。此外,我们还可以通过设置 docker-debug 在~/.docker-debug/config.toml的配置文件使用自定义的诊断镜像

version = "0.6.1"
image = "nicolaka/netshoot:latest"
mount_dir = "/mnt/container"
timeout = 10000000000
config_default = "default"

[config]
[config.default]
host = "unix:///var/run/docker.sock"
tls = false
cert_dir = ""
cert_password = ""

其他就不做过多介绍了

kubectl-debug

在介绍了 docker 的 debug 的工具后,我们了解了容器诊断工具的原理和使用,接下来我们要学习 kubernetes 的容器诊断工具。虽然 kubernetes 上也可以用我上面介绍的那些工具,但 kubernetes 上的容器毕竟运行在不同的 node 上,用起来就不太方便,所以就要用到 kubectl-debug 这个工具了。

kubectl-debug 其实就是一个 kubectl 的插件,他的原理和 docker 容器诊断工具大同小异。kubectl-debug 可以帮我们在 某个 Pod 的节点上起一个容器,并将这个容器加入到目标容器的pid,network,user,icp 的命名空间。kubectl-debug 架构主要可以分为两部分:

  • 客户端:kubectl-debug 二进制文件

  • 服务端:agent 容器

客户端通过控制 node 上的 agent 服务端与容器运行时通信,从而启动一个容器并进入到指定 Pod 的命名空间,可以说 agent 就是一个 debug 容器与客户端之间的中继。而从 kubectl-debug 的工作模式来看,可以分为两种模式:

  • 非常驻服务端:agentless

  • 常驻服务端: DaemonSet

简单来说就是 agentless 模式只有在每次 kubectl-debug 进行调试 Pod 的时候才会启动一个 agent 服务端,调试完成后自动清理 agent,此模式的优点是不那么占用 kubernetes 集群资源,而 DaemonSet 模式就是在每个节点上都会常驻一个 DaemonSet 的 agent, 好处就是启动快。此外针对 node 节点无法直接访问的情况,kubectl-debug 还有一个 port-forward 模式,这里就不多介绍了。

由于 kubectl-debug 可能还不太完善,agentless 模式我这里用不了,所以我用的是 DaemonSet 模式,下面开始演示。

安装客户端

安装过程和 docker-debug 差不多

  1. 下载二进制文件: wget https://github.com/aylei/kubectl-debug/releases/download/v0.1.0/kubectl-debug_0.1.0_linux_amd64.tar.gz -O kubectl-debug.tar.gz

  2. 解压文件: tar -zxvf kubectl-debug.tar.gz kubectl-debug

安装 agent 服务端

  1. 下载 DaemonSet 的 yaml 文件:wget -f https://raw.githubusercontent.com/aylei/kubectl-debug/master/scripts/agent_daemonset.yml

  2. 修改agent_daemonset.yml 文件

      ...
    18 hostNetwork: true # 需要加上 hostNetwork: true,hostPort:10027 才会生效
    19 hostPID: true
    20 tolerations:
    21 - key: node-role.kubernetes.io/master
    22 effect: NoSchedule
    23 containers:
    24 - name: debug-agent
    25 image: aylei/debug-agent:v0.1.1 # 老版本镜像有问题,使用 v0.1.1新版本
    ...
    39 ports:
    40 - containerPort: 10027
    41 hostPort: 10027
    ...
  3. 创建 DaemonSet:kubectl apply -f agent_daemonset.yaml, 接下来我们可以看到每个节点上都创建了 debug-agent 的 DaemonSet,并且宿主机上都监听了10027端口。

     root @ master ➜  k8s-debug   kubectl get pods
    NAME READY STATUS RESTARTS AGE
    debug-agent-5gfk6 1/1 Running 0 22h
    ...
    root @ master ➜ k8s-debug netstat -lntp | grep 10027
    tcp6 0 0 :::10027 :::* LISTEN 15510/debug-agent
  4. 执行命令kubectl-debug 就可以进行调试了

    root @ master ➜  k8s-debug  kubectl get pods
    NAME READY STATUS RESTARTS AGE
    licai-gwapi-77465b4c66-hdjlb 1/1 Running 0 3d
    ...
    root @ master ➜ k8s-debug kubectl-debug licai-gwapi-77465b4c66-hdjlb --agentless=false --port-forward=false
    pulling image nicolaka/netshoot:latest...
    ...
    bash-5.0# ps -ef | grep java
    1 root 23:24 /usr/local/openjdk-8/bin/java -Djava.util.logging.config.file=/usr/local/tomcat/conf/logging.properties...
    192 root 0:00 grep java
    bash-5.0# exit
    exit
    root @ master ➜ k8s-debug

    我们可以看到已经进入了目标容器的命名空间了,而kubectl-debug 客户端正是与每个 node 上的 10027 端口通信来控制 agent 对 Pod 的调试。

除了这些之外,kubectl-debug 还有很多配置可以自定义,kubectl-debug页面也有详细的介绍,至此从 docker 到 kubernetes 的调试工具介绍完成了。


欢迎关注运维自研堂订阅号,运维自研堂是一个技术分享平台,主要是运维自动化开发:linux、python、django、saltstack、tornado、bootstrap、redis、golang、docker、etcd、k8s、ci/cd、devops等经验分享。

  • 容器平台自动化CI/CD流水线实操

  • 云原生语义化 CI/CD最佳实践

  • 【提速500%】让Drone飞起来

  • 小孩子也能看懂的kubernetes教程

  • 谷歌开源 Kubernetes 原生 CI/CD 构建框架 Tekton

  • 架构师是怎么炼成的

  • IPv6时代对业务的挑战

  • 如何打造一个安全稳定高效的容器云平台

  • 深入理解无服务器架构(Faas/Serverless)

  • CI/CD 场景价值

  • 云原生架构及设计原则

  • Jira与Zabbix结合

  • 【Zabbix】告警事件归档与提取

  • 【HMonitor】Zabbix告警管理平台

  • Zabbix 告警收敛

  • Zabbix v3.0微信报警及API使用

  • zabbix v3.0安装部署及使用

  • Web权限设计

  • 搭建 kubernetes 容器编排平台

  • 区块链入门教程

  • 基于Gogs+Drone搭建的私有CI/CD平台

  • WEB架构设计心得

  • Docker与CI/CD

  • 【实战篇】Docker的CI/CD流水线实践

  • 基于 Harbor 搭建 Docker 私有镜像仓库

  • 利用helm部署应用到kubernetes

开源    创新     共享

投稿&商务合作

Mail:idevops168@163.com       QQ:785249378     微信:Idevops001

f9d7bf981b8c0dd150fda6e1e4ce5358.gif

牛人并不可怕,可怕的是牛人比我们还努力!

ae3d3cce4f4dfac5b415a00404a73545.png

长按图片,识别加入我们!

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值