Container及其内部进程监控剖析
目前市场上的虚拟化技术种类很多,例如moby(docker)、LXC、RKT等等。在带来方便应用部署和资源充分利用的好处的同时,如何监控相应Container及其内部应用进程成为运维人员不可避免遇到的新情况。UAV.Container从虚拟化技术的基础原理和Linux操作系统的内核特性出发,得到Container容器和内部进程的各维度监控数据,使无论是虚拟机或物理机运维人员,还是业务运维人员角度,都能得到合适的监控维度。
虚拟化技术从基础原理上主要是cgroups、namespace和file system的应用,而操作系统作为cgroup和namespace根节点,无论在container里启动何种应用,从内核角度上来说,肯定在操作系统有其一定的特征和表现形式。我们需要做的就是对这些特征做加工处理,以得到相应的监控数据。
下面我们以docker技术举例,其他虚拟化技术类似。
一、Container ID
Container ID是一个Container的唯一标识。从容器监控的角度我们需要能得到该进程在哪个Container里运行。在操作系统层面,进程的cgroup的挂载情况就能有所体现。如图所示,我们在一个ID为3411554ff684的Container内部跑一个Tomcat进程。
由于Container的pid namespace是操作系统的pid namespace的子namespace,那么该进程在操作系统级也应该有相应的pid,用docker top命令验证一下:
该容器内进程在宿主机上的进程号为1848。接下来进入/proc/1848/cgroup下看看该进程的cgroup挂载情况
从cgroup文件里清楚的显示了实现了该容器的虚拟化技术、Container ID和此container的资源挂载路径,对比一下这里面显示的Container ID,和创建Container时的ID完全相同。这也验证了通过扫描宿主机进程的cgroup信息可以获得Container ID。这样就将pid和Container ID做了关联。
二、CPU
虽然cgroup管控了该cgroup下所有进程的CPU使用情况,但从操作系统的角度上,不论进程是否隶属于某个子cgroup下,仍然是共用宿主机的CPU。所以监控宿主机上该进程的CPU就能得到进程的CPU监控指标。
Linux上常用的CPU监控命令是top。top对CPU监控的原理是在time1时刻获取CPU从启动时的累计总时间countAll1和busy总时间countBusy1,再到time2时刻获取CPU总时间countAll2和busy总时间countBusy2,最后用busy的时间差值减去总时间的差值得到了在time1到time2这个时间段内机器CPU的占用情况。也就是:
CPU占用率(%) = (countBusy2 - countBusy1)/(countAll2 - countAll1) * 100
进程同理,在两个时刻分别得到每个进程的busy总时间countProcBusy1和countProcBusy2,则得到进程CPU占用率:
进程CPU占用率(%) = (countProcBusy2 - countProcBusy1)/(countProcAll2 - countProcAll1)*100
宿主机从启动开始的CPU总时间片可以从/proc/stat下获取:
第一行是总的CPU使用情况,具体参数的意思:
所以,选择当前为time1,3秒后为time2,countAll = user + nice + system + idle + iowait + irq + softirq + stealstolean + guest + guest_nice。countBusy为countAll减去idle的值,这样上面第一个公式的所有需要的值就齐了,可以直接计算。
第二行、第三行是每个逻辑CPU的使用情况,这里记下有两个逻辑CPU,CPU的逻辑核数与CPU显示模式irix和solaris有关。
接下来是countProcBusy的计算,进程的CPU时间片位于/proc/$pid/stat下,如图所示:
这个文件里面体现了很多进程的相关信息。其中第14、15、16、17个参数与CPU有关。
所以,countProcBusy = utime + stime + cutime + cstime,该值包括其所有线程的cpu时间。而countProcAll2-countProcAll1=3s,通过两个时刻的countProcBusy和countProcAll,进程CPU的占用率就能得到了。
其中需要注意的问题有两点:
1) jiffies实际上指的是内核时钟使用的节拍总数,所以这里的jiffies需要换算成秒才能应用上面的除法公式。
2) 刚刚我们谈到CPU显示模式irix和solaris,简单来说irix模式就是机器有N个逻辑CPU,CPU显示上限就是N*100%,solaris模式就是不管机器有多少逻辑CPU,CPU显示上限就是100%,而/proc/$pid/stat显示的是计算了所有逻辑CPU时间的,所以两种显示方式意味着计算方法稍有差异,solaris模式的结果需要在上面进程CPU占用率公式基础之上除以逻辑核数。
三、内存
进程内存的监控有两个维度的数据:一是物理占用内存大小,二是进程内存占用百分比的大小。
进程内存占用率(%) = 进程物理内存占用大小 / 宿主机总内存大小 * 100
与CPU类似,/proc/$pid/status文件记录了进程物理内存使用情况,其中VmRSS即为该进程目前所占实际物理内存的大小。
/proc/meminfo文件下记录了机器内存占用情况,这个文件很长,截取其中的一部分展示一下,MemTotal就是宿主机总内存大小:
这样,这个进程的物理内存占用和机器总内存就都得到了,相应的进程内存的占用率也就得到了。
四、磁盘IO
磁盘IO获取也很简单,/proc/$pid/io已经帮我们把这个进程的io情况记录下来了,但是与CPU类似,io文件里存的也是该进程从启动到现在的io总量,那么:
磁盘I/O(bytes/秒) = (time2时刻I/O – time1时刻I/O) / (time2 – time1)
其中的read_bytes和write_bytes分别为该进程从启动到目前为止的读取字节数和写入字节数,分别取2个时刻的值,根据上面的公式,就得到了该进程的磁盘IO。
五、端口号和连接数
由于Network Namespace对网络做了隔离,所以如果进程在Container内部运行,该进程的端口信息也应该是进程本身监听的端口号,而不是真正实际对外的端口,而Container内外端口的映射机制是由应用的虚拟化技术本身控制的,这就避免不了与实现容器的虚拟化技术打交道了,那么问题就转化成获取容器内进程本身监听的端口了。
/proc/$pid/net/tcp(tcp6,udp,udp6)就对端口号和连接数做了相应的历史记录。这些文件格式都类似,以tcp6举例
解释几个关键的key:
因为st = 0A代表listen,所以从其中挑选出st = 0A的数据,取出对应的inode号,这里这个inode号是socket号,则问题转换为了这个进程是否还存在这个socket号代表的socket。在/proc/$pid/fd下有该进程所有的fd(file descriptor),截取一段举个例子。
每个文件描述符后面的软链实际上就是打开的文件,以socket开头的就是这个进程打开的socket,在中括号中间的部分就是socket号。拿着这个socket号和上面tcp6里获得的inode号做一个匹配,如果对应上,那么tcp6里的st = 0A的端口就是这个进程监听的。至于容器内外端口的映射,这就需要根据应用的虚拟化技术的映射方法来获取了。连接数计算与端口扫描是同理的,区别只在于需要对st = 01(establish)进行扫描计数累加。
六、总结
- 上面的方法将容器内所有进程的CPU、内存、磁盘IO、端口号和连接数都拿到了。根据Container ID就可以对不同的Container的对应数据做加和,就获得了Container级的监控数据。
- 在容器内的进程是通过在操作系统级别反映出的pid和Container ID的对应关系来关联的。这样就可以通过读取/proc下的文件来获取监控数据。
参考文档:
http://elixir.free-electrons.com/linux/v3.10/ident
作者:周新宇
低调大师中文资讯倾力打造互联网数据资讯、行业资源、电子商务、移动互联网、网络营销平台。
持续更新报道IT业界、互联网、市场资讯、驱动更新,是最及时权威的产业资讯及硬件资讯报道平台。
转载内容版权归作者及来源网站所有,本站原创内容转载请注明来源。
- 上一篇
在CentOS 7系统里如何使用465端口发送邮件
环境:CentOS 7准备产品:阿里云服务器 (https://www.aliyun.com/product/ecs)阿里云企业邮箱账户( https://wanwang.aliyun.com/mail/) 过程: 1.编辑 /etc/mail.rc 文件内容,追加以下内容(请替换其中的登录用户和密码值): set smtp="smtps://smtp.mxhichina.com:465" set smtp-auth=login set smtp-auth-user="sales@vfutai.xxx" set smtp-auth-password="Ni-De-Mi-Ma" set ssl-verify=ignore set nss-config-dir=/etc/pki/nssdb 2.发信测试(请替换其中的回信、收信地址和标题): echo message3 | mail -v -r "sales@vfutai.xxx" -s "This is the subject" dongshan3@foxmail.xxx 3.执行命令后,显示发信成功。收件人邮箱中,有信 看到上图,说明已...
- 下一篇
使用阿里云容器服务部署Bookinfo示例
Bookinfo应用介绍 Bookinfo是一个样例应用,用来演示多种 Istio 特性,它由四个单独的微服务构成: productpage:productpage微服务会调用details和reviews两个微服务,用来生成页面。 details:这个微服务包含了书籍的信息。 reviews:这个微服务包含了书籍相关的评论。它还会调用ratings微服务。 ratings:ratings微服务中包含了由书籍评价组成的评级信息。 reviews微服务有 3 个版本: v1 版本不会调用ratings服务。 v2 版本会调用ratings服务,并使用 1 到 5 个黑色星形图标来显示评分信息。 v3 版本会调用ratings服务,并使用 1 到 5 个红色星形图标来显示评分信息。 下图展示了这个应用的端到端架构 部署应用 部署istio 登录容器服务控制台,左侧导航中选择服务网格-Istio管理,选择需要安装Istio的集群,使用默认配置点击部署Istio 成功部署Istio后,可以看到下方Sidecar 自动注入设置。选择一个命名空间,开启Sidecar自动注入 完成后可以看到isti...
相关文章
文章评论
共有0条评论来说两句吧...
文章二维码
点击排行
推荐阅读
最新文章
- Jdk安装(Linux,MacOS,Windows),包含三大操作系统的最全安装
- CentOS7编译安装Cmake3.16.3,解决mysql等软件编译问题
- CentOS7,CentOS8安装Elasticsearch6.8.6
- Linux系统CentOS6、CentOS7手动修改IP地址
- SpringBoot2全家桶,快速入门学习开发网站教程
- SpringBoot2整合MyBatis,连接MySql数据库做增删改查操作
- Docker使用Oracle官方镜像安装(12C,18C,19C)
- CentOS关闭SELinux安全模块
- CentOS8安装Docker,最新的服务器搭配容器使用
- 设置Eclipse缩进为4个空格,增强代码规范