2014年11月27日星期四

Linux下进程管理工具之(三):glances

本邮件内容由第三方提供,如果您不想继续收到该邮件,可 点此退订
Linux下进程管理工具之(三):glances  阅读原文»

Linux下进程管理工具之(三):glances

实验环境:

CentOS release 6.6 (Final) 一台

IP地址:172.16.249.230

glances是一款用于 Linux、BSD 的开源命令行系统监视工具,它使用 Python 语言开发,能够监视 CPU、负载、内存、磁盘 I/O、网络流量、文件系统、系统温度等信息。本文介绍glances的使用方法和技巧,帮助 Linux 系统管理员了解掌握服务器性能。

.glances简介

glances 可以为 Unix Linux 性能专家提供监视和分析性能数据的功能,其中包括:

CPU 使用率

内存使用情况

内核统计信息和运行队列信息

磁盘 I/O 速度、传输和读/写比率

文件系统中的可用空间

磁盘适配器

网络 I/O 速度、传输和读/写比率

页面空间和页面速度

消耗资源最多的进程

计算机信息和系统资源

glances 工具可以在用户的终端上实时显示重要的系统信息,并动态地对其进行更新。这个高效的工具可以工作于任何终端屏幕。另外它并不会消耗大量的 CPU 资源,通常低于百分之二。glances 在屏幕上对数据进行显示,并且每隔两秒钟对其进行更新。您也可以自己将这个时间间隔更改为更长或更短的数值。glances 工具还可以将相同的数据捕获到一个文件,便于以后对报告进行分析和绘制图形。输出文件可以是电子表格的格式 (.csv) 或者 html 格式。

.glances安装

两种方法安装 glances

通常可以有两种方法安装 glances

第一种是通过编译源代码的方式,这种方法比较复杂另外可能会遇到软件包依赖性问题。

第二种是使用特定的软件包管理工具来安装 glances,这种方法比较简单。

本文使用后者,需要说明的是在 CentOS 特定的软件包管理工具来安装。glances 要首先配置 EPEL repo,然后安装 glances

如果既想获得 RHEL 的高质量、高性能、高可靠性,又需要方便易用(关键是免费)的软件包更新功能,那么 Fedora Project 推出的 EPELExtra Packages for Enterprise Linux http://fedoraproject.org/wiki/EPEL)正好适合你。它是由 Fedora 社区打造,为 RHEL 及衍生发行版如 CentOSScientific Linux 等提供高质量软件包的项目。装上了 EPEL,就像在 Fedora 上一样,可以通过 yum install package-name,随意安装软件。安装使用 EPEL 非常简单:

首先找出离你最近的镜像源网站:

http://mirrors.fedoraproject.org/publiclist/EPEL/6/x86_64/

wKioL1R1vyDR9VUVAAJrkesPqK4032.jpg

选择北京的那个哦!

  #wgethttp://mirrors.yun-idc.com/epel/RPM-GPG-KEY-EPEL-6  #rpm --importRPM-GPG-KEY-EPEL-6  #rm -fRPM-GPG-KEY-EPEL-6  #vi/etc/yum.repos.d/epel.repo  [epel]  name=EPEL RPMRepository for Red Hat Enterprise Linux  baseurl=http://mirrors.yun-idc.com/epel/6/$basearch/  gpgcheck=1  enabled=0  

.glances的使用方法

glances 是一个命令行工具包括如下命令选项:

  -b:显示网络连接速度 Byte/ 秒   -B @IP|host :绑定服务器端 IP 地址或者主机名称   -c @IP|host:连接 glances 服务器端   -C file:设置配置文件默认是 /etc/glances/glances.conf   -d:关闭磁盘 I/O 模块   -e:显示传感器温度   -f file:设置输出文件(格式是 HTML 或者 CSV)   -m:关闭挂载的磁盘模块   -n:关闭网络模块   -p PORT:设置运行端口默认是 61209   -P password:设置客户端 / 服务器密码   -s:设置 glances 运行模式为服务器   -t sec:设置屏幕刷新的时间间隔,单位为秒,默认值为 2 秒,数值许可范围:1~32767   -h : 显示帮助信息   -v : 显示版本信息  

glances 工作界面如下图:

wKioL1R1v1nQddA4AASAcnx6v2E580.jpg

glances 工作界面的说明:

上图的上部是 CPU Load(负载)、Mem(内存使用)、 Swap(交换分区)的使用情况。在上图的中上部是网络接口

右边大部分是Processes(进程)的使用情况。通常包括如下字段:

   VIRT: 虚拟内存大小   RES: 进程占用的物理内存值   %CPU:该进程占用的 CPU 使用率   %MEM:该进程占用的物理内存和总内存的百分比   PID: 进程 ID 号   USER: 进程所有者的用户名  NI: 进程优先级   S: 进程状态,其中 S 表示休眠,R 表示正在运行,Z 表示僵死状态。   TIME+: 该进程启动后占用的总的 CPU 时间   IO_R 和 IO_W: 进程的读写 I/O 速率  NAME: 进程名称  

图的下部是磁盘 I/O 的使用情况和磁盘挂载分区的使用状况。

另外 glances 可以使用交互式的方式运行该工具,用户可以使用如下快捷键:

  h :显示帮助信息   q :离开程序退出   c :按照 CPU 实时负载对系统进程进行排序   m :按照内存使用状况对系统进程排序   i:按照 I/O 使用状况对系统进程排序   p:按照进程名称排序   d :显示磁盘读写状况   w :删除日志文件   l :显示日志   s:显示传感器信息   f :显示系统信息   1 :轮流显示每个 CPU 内核的使用情况(次选项仅仅使用在多核 CPU 系统)  

.glances的高级应用

glances 的结果输出方法

glances 输出HTML 格式文件,需要一个HTTP服务器。

首先安装相关软件包

[root@LinuxHosthtml]# yum install python-jinja2

[root@LinuxHost~]# glances -f /usr/local/nginx/html/ -o html

下面可以使用 Chrom 浏览器输入网址: http://localhost/usr/local/nginx/html/glances.html,结果如图

wKioL1R1v6CRWHd1AAGIbupUNjk481.jpg

继iptables之后的新一代包过滤框架是nftables  阅读原文»

继iptables之后的新一代包过滤框架是nftables

夜已深然未央,准备接着讲述有关Netfilter的故事,行文有点松散,由于未打草稿,有点随意识而流,一气呵成不知是自夸还是自嘲,权当小时候写的日 记吧,自幼喜欢每天写日记,中学时更是以退士为名折腾了几箱子抄本,前几年由于喝酒就改为周记了,现在意识到了生命短暂,时间甚是不够用,不能在迷迷糊糊 中得过且过,就准备把自己知道的关于Linux网络的东西一点一滴记录下来,本来想继续行文于纸上,然而发现在个人电脑智能手机时代,很多字早就不会写 了...上回没有说完关于iptables的故事,本文继续...

一.nftables前传-iptables之弊端

iptables几乎是无人不知无人不晓,人们被圈入了框框也就觉得任何事情都是理所当然,但我例外,和其他很多事情一样,在这个领域,我依然做并且乐于做那个"被排除的人"。
iptables的诸多弊端已经不能再视而不见,然而只有很少的人看到了这些,大多数的人作为使用者,仅仅是使用罢了。在此我不会吐嘈很多了。以下的弊端来自nftables的宣传文档,但是即使是在国外,也引发了超级多的争论:
1.iptables框架在内核态知道的太多,以至于产生了大量的代码冗余。
这一点是显而易见的,比如对于TCP和UDP而言,取sport,dport没有什么不同,但是iptables却使用了两套代码,这只是一个例子,类似的还有很多。
2.iptables的rule结构设计不合理。
这是要着重说明的。

1.iptables的结构

iptables由表,链,规则组成,其中规则又由match,target组成。如下面的结构所示:
Table{
Chain[
Rule
(match,match,match,...)
->target,
Rule
(match,match,match,...)
->target,
...
],
Chain[
...
],
...
}

2.iptables的规则匹配执行流程

iptables的规则是按照配置顺序顺序匹配的,在每一张表的每一个链上依次匹配每一条规则,在每一条规则依次匹配每一个match,全部匹配的match执行该规则的target,由target决定:a.继续匹配下一条规则
b.对数据包做一些修改
c.跳转到其它的链(即开始从该链依次匹配该链上的每一条规则)
d.返回引发跳转的链(即继续匹配跳转前的链的下一条规则)
e.丢弃数据包
f.接收数据包(即不再继续往下匹配,直接返回)
g.记录日志
h....

整个iptables框架执行的流程如下:

  循环1:          static breakrule = 0;          遍历一个chain的每一条rule {          nomatch = 0;          循环2:遍历一条rule的每一个match {                          result = rule->match[curr](skb, info);                          if(result != MATCH) {                                  nomatch = 1;                                  break;                          }          }          if (nomatch == 1) {                  continue该chain的下一条rule;          }          result = rule->target(skb, info);          if (result == DROP) {                  break丢弃数据包          } else if (result == ACCEPT) {                  break接受数据包          } else if (result == GOTO) {                  breakrule = rule;                  跳转到相应的chain,执行循环1          } else if (result == RETURN) {                  break返回调用chain,执行其breakrule的下一条rule          } ...  }  

看了上述的代码就基本知道了iptables的命令实现,程序员能做的就是扩展iptables的功能,具体的做法有两个:写一个match以及写一个target。除此之外,程序员就没辙了,剩下的就看使用者的想象力了...
通过上面的流程,可以发现,包过滤的流程最终要落实到规则匹配,而过滤的动作最终落实到了该规则的target,前面的所有的match匹配返回结果就是0或者非0表示是否匹配,只有所有的match均匹配,才会执行target。这就决定了下面几件事:
a.如果你想实现多个target,就不得不写多条规则
比如实现log和drop,那么就要写两条规则,或者扩展一个LOG_and_DROP target,前者影响效率,后者需要编程。你很在乎性能,同时你又不是程序员不懂编程,你就抓狂了...
b.你可以写一个match,在里面偷偷摸摸做一点事情,但是外部不知道
这一切太不正规了,你可以在一个match里面把一个数据包的校验码改掉,也可以在里面做log,做NAT什么的,但是iptables的框架的本意虽不允许你这么做但是又没有阻止你的行为。
我们可以在iptables执行流的一个细节(上述的流程中未画出)中看到另一个细节,即iptables在match中仅仅确定"是否匹配"真的已经很 不够,就连代码都设计得很勉强。如果你看ipt_do_table这个核心函数,会发现一个控制变量名叫hotdrop,这个变量是干什么的呢?按照注释 的意思是:

  @hotdrop:    drop packet if we had inspection problems  

这 个hotdrop作为传出参数传入每一个match回调函数,用于在match内部指示将一个数据包丢弃。这就暴露出了设计的不足,丢弃一个数据包不是 target要做的吗?一个match的职责是抉择该数据包是否匹配,干嘛要指示丢弃它呢?这不是越级么?这只是一个细节,你可以说出一千个理由表明它是 合理的,但是它却是丑陋的!

弄清楚历史总是能明白更多,这绝对是一句真话,但是恰恰是专业化阻止了大多数的程序员去读历史,哪怕是IT的历史。最好的历史资料就是原著,Netfilter的历史不长,从Linux 2.3.15内核版本被引入至今,不会像老子庄子那样被篡改地体无完肤。
我们当然要看iptables被引入的那段历史。
iptables被引入旨在替掉ipchains,因为当时ipchains的维护者Rusty Russell认识到它拥有诸多的弊端。总的说来,弊端有两个,其它的都是由这两个而发:
a.内核的firewall框架仅仅设置了3个检查点,即input,forward,output,对于环回包以及indev,outdev的控制力很弱;
b.代码写死,匹配项固定,没有可扩展性。
问 题就在这里的b。针对问题a,Rusty Russell提出了Netfilter的设计,精心设计了5个HOOK点,解决了几乎所有的控制点的问题,特别是OUTPUT点的设计顶级绝妙,它被安 放在路由之后,原因在于Linux协议栈的路由操作之后才会给出完整的过滤匹配项,比如源IP地址,出口设备等,路由之后的OUTPUT同时给了调用者再 次路由的权限。FORWARD和INPUT作为路由的二分,同时保持了无用功最少化,因为如果你没有打开ip_forward选项,即便不是INPUT的 数据包也不会进入FORWARD,如果根本就没有找到路由,则既不会到达INPUT,也不会到达FORWARD。对于PREROUTING而言,它可以通 过conntrack区分本地环回流量和网卡进入流量...不管怎么说,这是内核的工作,这个Netfilter的设计十分完美,至今依然被使用。
对于问题b,Rusty Russell提出了iptables,它是一个高度可扩展的框架,也就是从此时起,iptables拥有了match/target配对的扩展方式,每 当需要扩展的时候,每一个match/target除了有用户态的lib之外,还有用内核态的支持,它将ipchains时代的固定匹配模式变成了可以自 己编程扩展的了。
针对ipchains的弊端,Rusty Russell可谓是给出了完美的解决方案,然而仅此而已!任何一个来自同一作者的新的框架几乎均是为了解决上一个框架的弊端的,iptables作为一 个新秀,在获得欢呼的时候,不会有人去考虑它的弊端,任何事情都是这样,不是吗?
iptables的弊端是被逐步发现的,Rusty Russell作为ipchains和iptables的共同作者,它对待后者取代前者的态度永远都是保守的,一个全新的框架需要另一个人或者团队来提 出,而不可能出现在Rusty Russell本人手里以及iptables团队的内部。
针对Netfilter,Rusty写了大量的文档,均在Netfilter网站上可以找到:http://people.netfilter.org/rusty/unreliable-guides/不可否认,这些都是珍贵的第一手资料,对于我们理解Netfilter,可能没有比这些更好的了。任何人都可以从这些原著中找到"XX为何会这样"这种问题的蛛丝马迹,同时它们也是指导你如何改进现有框架的明灯。

三.nftables登场

鉴于iptables的诸多缺点(其实并不是缺点,但是match/target配对的扩展方式导致了开发者延伸了劣势,最终将其确定为缺点),nftables旨在一个个地改进它们。首先是两个问题:a.如何使用一种统一的方式来解析数据包
在这个问题的解决上,u32 match给了作者思路
b.如何执行多个action
事 实上,是iptables的matches/target配对的方式限制了开发者的思路。为何非要区分match和target呢?iptables框架 的执行流程限制了match的结果就是个布尔型,所有的动作都在target中执行,如果去掉了这个限制,将整个流程都开放给开发者,那就灵活多了。 nftables就在这样的背景下登场了。事实证明,nftables做的比修正弊端更多,走的更远。
首先nftables采用了"虚拟机解释字节码"的方式,使一条rule真的成了"为一个数据包做一些事情"这样灵活的命令,而去掉了"匹配所有的 match之后执行一个target"这样的限制。虚拟机执行字节码的方式早就被BPF采用了,我们熟知的tcpdump抓包程序就是利用的它来过滤的数 据包。我们来看一下nftables框架的执行流程:

  循环1:          static breakrule = 0;          遍历一个chain的每一条rule {          nomatch = 0;          reg[MAX]          循环2:遍历一条rule的每一个expression {                          void rule->expression[curr]->operations->expr(skb, info, reg)                          if(reg[VERDICT] != CONTINUE) {                                  break;                          }          }          if (reg[VERDICT] == CONTINUE) {                  continue该chain的下一条rule;          } else if (reg[VERDICT] == DROP) {                  break丢弃数据包          } else if (reg[VERDICT] == ACCEPT) {                  break接受数据包          } else if (reg[VERDICT] == GOTO) {                  breakrule = rule;  

阅读更多内容

没有评论:

发表评论