轻量级 Linux 桌面发行版 CrunchBang

这周拿到一台新笔记本,很久没摸过 PC 忽然发现自己彻底 out 了。开机预装的是 Windows 8,界面飞来飞去,想看看配置不知道怎么去控制面板,花了两分钟没找到关机菜单,直接电源长按强制关机,重启后准备安装 Linux,发现现在流行什么 UEFI,无法装 Linux,一顿搜索发现需要在 BIOS 里换成 Legacy …

朋友推荐的 CrunchBang 用了几天感觉非常棒,这才是一个系统应该有的嘛,轻量级、不过分占用资源,界面低调简洁,默认软件都已经精心挑选,装完系统后立刻可用(对于我的需求来说),不需要 “安装完 … 后必做的10件事”,…,相信有类似喜好(minimalism & simplicity)的 Linux 爱好者都会喜欢。

安装完后的桌面:

crunchbang linux

CrunchBang 是一款基于 Debian GNU/Linux、使用 Openbox 作为窗口管理器的轻量级 Linux 桌面发行版。界面看上去简洁、优雅,符合个人喜好;系统符合轻量级的要求,占用资源少、速度快;软件选择上偏向轻量级,默认安装好的软件多是自己常用的,省了自己安装和配置的时间;细节上 CrunchBang 处理也很到位,桌面已经配置好 SYSTEM INFO(有人喜欢在桌面或者任务栏看到系统资源占用情况),桌面还有个 SHORTCUT KEYS 用来帮助新手记住一些常用快捷键。按照自己使用电脑的习惯,CrunchBang 安装完后就基本可用,无线网络、外接显示器、打印机、多窗口、Google Chrome 浏览器、Terminal 分屏显示等等这些我要用到的统统默认,无需更多配置,简直就是 “我” 的发行版。

Chrome 浏览器和 Terminal:

crunchbang linux

近距离看菜单和背景,个人挺喜欢的风格:

crunchbang linux

有个小问题就是选择安装英文版系统的话不会默认安装中文字体,这样中文网页打开看到的是方块,所以想看中文的话需要安装个中文字体:

$ sudo apt-get update
$ sudo apt-get install ttf-wqy-microhei

安装和使用系统监控工具 Glances

Glances 是前几天网上闲逛的时候发现的一款 “新” 系统监控工具,尽管现在监控工具有很多选择,Glances 还是有些值得关注的,和那些常用的老牌监控工具比起来,比如 top/vmstat/iostat 只能监控本机系统,Glances 可以监控本机也可以通过客户端服务器模式监控其他机器;Glances 提供了基于 XML/RPC 的 API 便于其他程序调用,可编程;Glances 可以将数据输出保存到 csv 或 html 格式的文件方便其他程序处理(报告或绘制图形)。

Glances 是用 Python 开发的,使用 psutil 库来采集系统数据,在用户的终端上实时动态的显示重要的系统数据和变化。显示的数据包括:CPU、内存、磁盘、网络等使用情况,内核、运行队列、负载、I/O 状态、消耗资源最多的进程等等。

安装

Glance 支持 Linux, Mac OS X, FreeBSD, Windows 等多个系统,安装也很方便。在 Ubuntu 上安装:

$ sudo apt-get update
$ sudo apt-get install python-pip build-essential python-dev

$ sudo pip install glances

在 CentOS 6.x 上安装:

$ su root
# rpm -ivh http://fr2.rpmfind.net/linux/epel/6/x86_64/epel-release-6-7.noarch.rpm
# yum install python-pip python-devel
# pip-python install glances

在 FreeBSD 上安装:

# pkg_add -r py27-glances
或者
# cd /usr/ports/sysutils/py-glances/
# make install clean

使用

Glances 可以单机使用,也可以客户端-服务器模式多机使用。单机使用很简单,直接运行就可以了:

$ glances

客户端-服务器模式稍微复杂一点,需要在一台机器上以服务器模式启动 glances -s,另外一台机器以客户端模式连接 glances -c. 比如在有两台机器 A 和 B 都装了 glances,要想在 A 上看 B 上的 glances 的话需要事先在 B 上用服务器模式启动 glances(假设 B 的 IP 地址是 192.168.2.22):

$ glances -s

然后再从 A(客户端)用 Glances 访问 B(服务器):

$ glances -c 192.168.2.22

编程

Glances 和其他一堆老牌系统监控工具相比其突出优点在于提供 XML-RPC API,可编程。使用 Glances 提供的 API,我们可以通过编程轻松获取(我们想要的)数据。比如下面的是一个打印系统信息的简单 Python 脚本:

$ vi test.py
#!/usr/bin/python
import xmlrpclib

s = xmlrpclib.ServerProxy('http://192.168.2.22:61209')
print s.getSystem()

运行上面这个脚本:

$ python test.py
{"linux_distro": "Ubuntu 12.04", "platform": "64bit", "os_name": "Linux", "hostname": "vpsee.com", "os_version": "3.2.0-23-virtual"}

Glances 的界面:
docker desktop

Linux 性能监测:工具

一个完整运行的 Linux 系统包括很多子系统(介绍CPUMemoryIONetwork,…),监测和评估这些子系统是性能监测的一部分。我们往往需要宏观的看整个系统状态,也需要微观的看每个子系统的运行情况。幸运的是,我们不必重复造轮子,监控这些子系统都有相应的工具可用,这些经过时间考验、随 Unix 成长起来、简单而优雅的小工具是我们日常 Unix/Linux 工作不可缺少的部分。

下面这张图片很好的总结了 Linux 各个子系统以及监控这些子系统所需要的工具,如果你对 Linux 系统管理(sysadmin & devops)感兴趣、想入门的话,可以从这张图开始慢慢了解和熟悉各个工具。对于熟练的 Linux 屌丝,这张图你应该能问答自如。(图片来自:Linux Performance Analysis and Tools,幻灯片也很精彩,建议对照阅读。)

linux performance analysis and tools

Linux 性能监测:介绍
Linux 性能监测:CPU
Linux 性能监测:Memory
Linux 性能监测:IO
Linux 性能监测:Network

解决 /dev/null is not a character device! 问题

昨天我们一个客户无法 ssh 到他的 VPS,但是可以 ping 通。从控制台上看没有异常,登陆进去后发现 ssh 服务没有启动,企图启动(重启)这个服务时报错 /dev/null is not a character device!:

# /etc/init.d/ssh restart
Restarting OpenBSD Secure Shell server: sshd failed!
/dev/null is not a character device!.

解决办法是,删除 /dev/null 后重建一个字符设备:

# rm -f /dev/null
# mknod /dev/null c 1 3

然后启动(重启)ssh 就可以了:

# /etc/init.d/ssh restart
Restarting OpenBSD Secure Shell server: sshd.

用 NetHogs 监控 Linux 每个进程的网络使用情况

有时候我们客户会发现服务器或 VPS 网络慢,进一步发现大量带宽被占用,一些客户到这里为止就不知道怎么办了。有什么简单办法能找出哪个程序(或者进程)占用了带宽呢?Linux 监控流量的小工具不少,如 iftop, iptraf, ifstat, darkstat, bwm-ng, vnstat 等,大都是统计和监控网卡流量的。今天介绍的 NetHogs 有点特别,可以监控每个进程的网络带宽占用情况。

在 Ubuntu/Debian 上安装 nethogs:

$ sudo apt-get install nethogs

在 CentOS/RHEL 上安装 nethogs:

# yum install nethogs

运行 nethogs:

# nethogs

# nethogs eth0

nethogs

ssh_exchange_identification: Connection closed by remote host 可能的问题

今天 ssh 登陆一台服务器的时候报错:

$ ssh vpsee@172.16.38.200
ssh_exchange_identification: Connection closed by remote host

单看这个错误信息没有啥用,因为可能有多种情况都会导致这一信息,多数时候用 ssh -vvvvv 也 debug 不到啥有用的东西出来。一般来说有这么几种情况和解决办法:

1、检查 /etc/hosts.deny 和 /etc/hosts.allow 里面是否屏蔽了某些帐户;
2、删除 ~/.ssh/known_hosts 里面的相关服务器条目试一下;
3、Debian 上 /var/run/sshd/ 的所属问题导致 SSH 不能启动
4、在某些发行版上升级 glibc 或 openssl 等软件包以后需要重启一下 sshd;
5、由于 ssh 试探或者 ssh 连结数太多,/etc/ssh/sshd_config 里面的 MaxStartups 默认参数配置不够用;
6、欢迎补充 …

这里遇到的就是“情况5”,控制台直接登陆服务器后检查 /var/log/secure 发现大量未经授权和失败的连接,典型的 ssh brute force 试探导致。先看一下帮助文件,看看 MaxStartups 10:30:60 是啥意思:

# man sshd_config
...
     MaxStartups
             ...
         Alternatively, random early drop can be enabled by specifying the
         three colon separated values “start:rate:full” (e.g. "10:30:60").
         sshd(8) will refuse connection attempts with a probability of
         “rate/100” (30%) if there are currently “start” (10) unauthenti-
         cated connections.  The probability increases linearly and all con-
         nection attempts are refused if the number of unauthenticated con-
         nections reaches “full” (60).
...

MaxStartups 默认设置是 10:30:60,意思是从第10个连接开始以30%的概率(递增)拒绝新连接,直到连接数达到60为止,可能因为 ssh ddos/brute force 触发了这个 MaxStartups 设置。根据当前 ssh 连接用户和服务器情况解决办法是,把这个值加大、在 /etc/hosts.allow 里只加上授权用户、或者使用 DenyHosts, Fail2ban 等工具屏蔽掉攻击源。

在 Ubuntu 上安装 NX 服务器

远程登陆 Linux 图形桌面有很多方式,比如使用 RFB (Remote Frame Buffer) 协议的各种 VNC 工具,TightVNC, UltraVNC, Xvnc 等,使用 NX 的 NoMachine, freenx, neatx 等。NX 通过 X11 调用来通信,比 VNC 这种通过截图似的通信要快的多,而且安全(通过 ssh),更适合在网速不高(相比局域网来说)的 Internet 上应用。如果你想在 VPS 上使用 Linux 图形界面的话,使用 NX 是一个比 VNC 好得多的方案。

安装 NX 服务器

到 NoMachine 官网下载 nxserver 4.0 到 Ubuntu 后直接安装就可以了,不需要其他的依赖包,这个比以前的 3.5 版本清晰多了,3.5 版本的 NX 服务器要装 nxnode, nxserver, nxclient,这三个名字很混淆人:

$ wget http://64.34.173.142/download/4.0/Linux/S/nxserver_4.0.181-7_i386.deb
$ sudo dpkg -i nxserver_4.0.181-7_i386.deb

安装 NX 客户端

在 Mac 上下载 nx 客户端 nxplayer 4.0 后安装,需要注意的是,nxplayer 是 nxclient 的下一代版本,目前还是预览版,因为 Mac OS X 10.8 上不能使用旧版本的 nx 客户端(nxclient-3.5.0-7.pkg),安装后不能启动,所以这里只能用 nxplayer 预览版。

$ wget http://64.34.173.142/download/4.0/MacOSX/nxplayer-4.0.181-7.dmg

测试

安装完毕后,在 Mac 上启动一个 nxplayer 连接 Linux 上的 nxserver:

nxplayer session

成功连接后输入用户名和密码就能进入 Ubuntu 桌面了:

nxplayer session

使用 Fabric 批量执行服务器任务

我们的服务器和虚拟机的环境配置都由 puppet 管理,但有时候需要临时执行某些任务和操作,比如同时更换500台服务器的密码、同时更新或者重启500台虚拟机、在特定几台服务器上添加或者一个用户、上传一个特定文件/脚本到1000台服务器等等。这些任务用 Puppet 可以做,但是不是最简洁的办法。我们需要一种工具能完成大量服务器上的批量操作,并且要简单可编程,Fabric 就是这样一个基于 Python 的服务器批量管理库/工具,Fabric 使用 ssh(通过 paramiko 库)在多个服务器上批量执行任务,我们只需要用 Python 编写这些任务脚本并指定要执行这些任务的服务器就可以了。

Fabric 依赖 paramiko,所以需要安装这两个:

$ sudo pip install fabric
$ sudo pip install paramiko

编写一个简单的 Fabric 例子,在1台服务器上打印系统信息(uname -s):

$ vi fabfile.py
#!/usr/bin/python

from fabric.api import run

def host_os():
    run('uname -s')

在 vpsee.com 这台主机(host)上使用 root 帐户执行上面的任务 host_os:

$ fab -H root@vpsee.com host_os
[root@vpsee.com] Executing task 'host_os'
[root@vpsee.com] run: uname -s
[root@vpsee.com] Login password for 'root': 
[root@vpsee.com] out: Linux

Done.
Disconnecting from root@vpsee.com... done.

来看一个更复杂点的例子,在多个服务器(grid00, grid02, …, grid05)上更换 root 密码(假设原密码是 root),注意加上 @parallel,这样任务是并行执行的,在大量服务器上会快很多:

#!/usr/bin/python
# -*- coding: utf-8 -*-
from fabric.api import *
import string
from random import choice
import socket
import paramiko

env.user = 'root'
env.password = 'root'
env.hosts = [ 'grid00', 'grid01', 'grid02', 'grid03', 'grid04', 'grid05']

@task
@parallel
def passwd(user, passwd=False):
    with settings(hide('running', 'stdout', 'stderr'), warn_only=True):
        if isup(env.host):
            if not passwd:
                passwd = genpass()
            sudo("echo -e '%s\n%s' | passwd %s" % (passwd, passwd, user))

def genpass(length=10):
    return ''.join(choice(string.ascii_letters + string.digits) for _ in range(length))

def isup(host):
    print 'connecting host: %s' % host
    timeout = socket.getdefaulttimeout()
    socket.setdefaulttimeout(1)
    up = True
    try:
        paramiko.Transport((host, 22))
    except Exception, e:
        up = False
        print '%s down, %s' % (host, e)
    finally:
        socket.setdefaulttimeout(timeout)
        return up

使用 fab -l 查看我们刚编写的 fabfile.py 里面的可用命令,这个命令就是那个函数名 def passwd(user, passwd=False):

$ fab -l
Available commands:

    passwd

使用这个命令批量更换 grid00-grid05 的 root 密码为 test,passwd 传递参数的时候接冒号,并且用户名和密码参数用逗号隔开:

$ fab passwd:root,test
[grid00] Executing task 'passwd'
[grid01] Executing task 'passwd'
[grid02] Executing task 'passwd'
[grid03] Executing task 'passwd'
[grid04] Executing task 'passwd'
[grid05] Executing task 'passwd'
connecting host: grid05
connecting host: grid04
connecting host: grid02
connecting host: grid03
connecting host: grid01
connecting host: grid00

Done.

Fabric 的强大之处在于可以用 Python 编写各种任务(函数),这些任务可以指定到任何服务器上(通过 ssh),非常适合管理大量服务器、批量处理任务。另外 Fabric 工作方式非常简单容易理解,就是简单的 ssh 而已,没有内幕没有架构,不像其他工具什么客户端服务器端、什么中间代码、什么 DSL 领域专属语言(嗯,说的就是 puppet, chef)。Fabric 使用起来只需要懂点 Python 就可以了,不需要学命令、api、框架之类的。我们喜欢简单、容易理解的工具。

释放 Linux 系统预留的硬盘空间

大多数文件系统都会保留一部分空间留作紧急情况时用(比如硬盘空间满了),这样能保证有些关键应用(比如数据库)在硬盘满的时候有点余地,不致于马上就 crash,给监控系统和管理员一点时间去察觉。不过有时候这部分预留的硬盘空间不用的话有点浪费。如何释放这部分系统预留的空间呢?

在 Linux ext2/ext3/ext4 文件系统上通常默认预留5%的硬盘空间,如果硬盘是 4TB 的话就意味着有 200GB 的空间就这样浪费了,我们可以通过 tune2fs 来改变5%的默认设置,比如只预留1%的空间。可不可以设成0%呢?当然可以,但是不推荐。

查看当前硬盘空间情况:

# df -h
Filesystem            Size  Used Avail Use% Mounted on
/dev/mapper/vg_cloud22-lv_root
                       32G  1.1G   30G   4% /
tmpfs                  24G     0   24G   0% /dev/shm
/dev/sda1             485M   68M  392M  15% /boot
/dev/mapper/vg_cloud22-lv_home
                      3.2G   70M  2.9G   3% /home
/dev/sdd1            1008G  161G  797G  17% /var/cloud

调整 /dev/sdd1,只预留1%的空间:

# tune2fs -m 1 /dev/sdd1
tune2fs 1.41.12 (17-May-2010)
Setting reserved blocks percentage to 1% (2684381 blocks)

调整后查看释放后的硬盘空间,发现多出了 838-797=41GB 的空间:

# df -h
Filesystem            Size  Used Avail Use% Mounted on
/dev/mapper/vg_cloud22-lv_root
                       32G  1.1G   30G   4% /
tmpfs                  24G     0   24G   0% /dev/shm
/dev/sda1             485M   68M  392M  15% /boot
/dev/mapper/vg_cloud22-lv_home
                      3.2G   70M  2.9G   3% /home
/dev/sdd1            1008G  161G  838G  17% /var/cloud

如果硬盘被塞满了,想清理硬盘那是另外一回事,可以参考:什么吃掉了我的硬盘?

/dev/null 的另类用法

/dev/null 是个黑洞,进去的东西永远出不来,在脚本编程的时候经常会用它(空设备文件)来屏蔽标准或错误输出(stdout 或 stderr),比如 command > /dev/null 2>&1 把 command 执行的结果(标准输出和错误输出)全部重定向到 /dev/null,也就是在控制台上不回显任何输出。

今天发现我们的 Graphite 监控服务器硬盘空间不够了(因为监控日志体积日益增加),一些不必要的日志占据了不少硬盘,比如 graphite 里面的 console.log,一般来说日志配置都在相关的配置文件里,在 graphite 的配置文件里找了一圈居然没找到如何关闭 console.log 日志配置(有其他日志的配置选项,但是没有 console.log 这个日志的关闭选项),难道要写个 cron 定期清理 console.log?一个更好的办法是把 console.log 这个连接到 /dev/null(如果确定以后不需要查看 console.log 的话),这样 graphite 写到 console.log 就永远的消失了,对现在的系统和配置不会有任何影响,甚至连 graphite 服务都不用重启,下面的脆香米兄的评论是对的,graphite 正在操作 console.log,简单改变文件名称并没有更改已打开的文件句柄,所以需要重启 carbon-cache.py.

# cd /opt/graphite/storage/log/carbon-cache/carbon-cache-a/

# ls -l
total 1811016
-rw-r--r-- 1 root     root     1360161601 Aug  6 15:18 console.log

# /opt/graphite/bin/carbon-cache.py stop

# mv console.log console.log.bak
# ln -s /dev/null console.log

# /opt/graphite/bin/carbon-cache.py start

# ls -l
total 1811032
lrwxrwxrwx 1 root     root              9 Aug  6 15:18 console.log -> /dev/null
-rw-r--r-- 1 root     root     1360178736 Aug  6 15:18 console.log.bak