Skip to content Skip to main navigation Skip to footer

Linux

Linux:Linux 系统监控、诊断工具之 IO wait

1、问题:

最近在做日志的实时同步,上线之前是做过单份线上日志压力测试的,消息队列和客户端、本机都没问题,但是没想到上了第二份日志之后,问题来了:

集群中的某台机器 top 看到负载巨高,集群中的机器硬件配置一样,部署的软件都一样,却单单这一台负载有问题,初步猜测可能硬件有问题了。

同时,我们还需要把负载有异常的罪魁祸首揪出来,到时候从软件、硬件层面分别寻找解决方案。

Linux:Linux 系统监控、诊断工具之 IO wait
Linux:Linux 系统监控、诊断工具之 IO wait

2、排查:

从 top 中可以看到 load average 偏高,%wa 很高,%us 偏低:

Linux:Linux 系统监控、诊断工具之 IO wait
Linux:Linux 系统监控、诊断工具之 IO wait

从上图我们大致可以推断 IO 遇到了瓶颈,下面我们可以再用相关的 IO 诊断工具,具体的验证排查下。

PS:如果你对 top 的用法不了解,请参考我去年写的一篇博文:linux 系统监控、诊断工具之 top 详解

常用组合方式有如下几种:

  • 用vmstat、sar、iostat检测是否是CPU瓶颈
  • 用free、vmstat检测是否是内存瓶颈
  • 用iostat、dmesg 检测是否是磁盘I/O瓶颈
  • 用netstat检测是否是网络带宽瓶颈

2.1 vmstat

vmstat命令的含义为显示虚拟内存状态(“Virtual Memor Statics”),但是它可以报告关于进程、内存、I/O等系统整体运行状态。

Linux:Linux 系统监控、诊断工具之 IO wait
Linux:Linux 系统监控、诊断工具之 IO wait
它的相关字段说明如下:

Procs(进程)

  • r: 运行队列中进程数量,这个值也可以判断是否需要增加CPU。(长期大于1)
  • b: 等待IO的进程数量,也就是处在非中断睡眠状态的进程数,展示了正在执行和等待CPU资源的任务个数。当这个值超过了CPU数目,就会出现CPU瓶颈了

Memory(内存)

  • swpd: 使用虚拟内存大小,如果swpd的值不为0,但是SI,SO的值长期为0,这种情况不会影响系统性能。
  • free: 空闲物理内存大小。
  • buff: 用作缓冲的内存大小。
  • cache: 用作缓存的内存大小,如果cache的值大的时候,说明cache处的文件数多,如果频繁访问到的文件都能被cache处,那么磁盘的读IO bi会非常小。

Swap(交换区)

  • si: 每秒从交换区写到内存的大小,由磁盘调入内存。
  • so: 每秒写入交换区的内存大小,由内存调入磁盘。

注意:内存够用的时候,这2个值都是0,如果这2个值长期大于0时,系统性能会受到影响,磁盘IO和CPU资源都会被消耗。有些朋友看到空闲内存(free)很少的或接近于0时,就认为内存不够用了,不能光看这一点,还要结合si和so,如果free很少,但是si和so也很少(大多时候是0),那么不用担心,系统性能这时不会受到影响的。

IO(输入输出)

(现在的Linux版本块的大小为1kb)

  • bi: 每秒读取的块数
  • bo: 每秒写入的块数

注意:随机磁盘读写的时候,这2个值越大(如超出1024k),能看到CPU在IO等待的值也会越大。

system(系统)

  • in: 每秒中断数,包括时钟中断。
  • cs: 每秒上下文切换数。

注意:上面2个值越大,会看到由内核消耗的CPU时间会越大。

CPU

(以百分比表示)

  • us: 用户进程执行时间百分比(user time)。us的值比较高时,说明用户进程消耗的CPU时间多,但是如果长期超50%的使用,那么我们就该考虑优化程序算法或者进行加速。
  • sy: 内核系统进程执行时间百分比(system time)。sy的值高时,说明系统内核消耗的CPU资源多,这并不是良性表现,我们应该检查原因。
  • wa: IO等待时间百分比。wa的值高时,说明IO等待比较严重,这可能由于磁盘大量作随机访问造成,也有可能磁盘出现瓶颈(块操作)。
  • id: 空闲时间百分比

从 vmstat 中可以看到,CPU大部分的时间浪费在等待IO上面,可能是由于大量的磁盘随机访问或者磁盘的带宽所造成的,bi、bo 也都超过 1024k,应该是遇到了IO瓶颈。

2.2 iostat

下面再用更加专业的磁盘 IO 诊断工具来看下相关统计数据。

Linux:Linux 系统监控、诊断工具之 IO wait
Linux:Linux 系统监控、诊断工具之 IO wait
它的相关字段说明如下:

  • rrqm/s: 每秒进行 merge 的读操作数目。即 delta(rmerge)/s
  • wrqm/s: 每秒进行 merge 的写操作数目。即 delta(wmerge)/s
  • r/s: 每秒完成的读 I/O 设备次数。即 delta(rio)/s
  • w/s: 每秒完成的写 I/O 设备次数。即 delta(wio)/s
  • rsec/s: 每秒读扇区数。即 delta(rsect)/s
  • wsec/s: 每秒写扇区数。即 delta(wsect)/s
  • rkB/s: 每秒读K字节数。是 rsect/s 的一半,因为每扇区大小为512字节。(需要计算)
  • wkB/s: 每秒写K字节数。是 wsect/s 的一半。(需要计算)
  • avgrq-sz: 平均每次设备I/O操作的数据大小 (扇区)。delta(rsect+wsect)/delta(rio+wio)
  • avgqu-sz: 平均I/O队列长度。即 delta(aveq)/s/1000 (因为aveq的单位为毫秒)。
  • await: 平均每次设备I/O操作的等待时间 (毫秒)。即 delta(ruse+wuse)/delta(rio+wio)
  • svctm: 平均每次设备I/O操作的服务时间 (毫秒)。即 delta(use)/delta(rio+wio)
  • %util: 一秒中有百分之多少的时间用于 I/O 操作,或者说一秒中有多少时间 I/O 队列是非空的。即 delta(use)/s/1000 (因为use的单位为毫秒)

可以看到两块硬盘中的 sdb 的利用率已经 100%,存在严重的 IO 瓶颈,下一步我们就是要找出哪个进程在往这块硬盘读写数据。

2.3 iotop

Linux:Linux 系统监控、诊断工具之 IO wait
Linux:Linux 系统监控、诊断工具之 IO wait

根据 iotop 的结果,我们迅速的定位到是 flume 进程的问题,造成了大量的 IO wait。

但是在开头我已经说了,集群中的机器配置一样,部署的程序也都 rsync 过去的一模一样,难道是硬盘坏了?

这得找运维同学来查证了,最后的结论是:

Sdb为双盘raid1,使用raid卡为“LSI Logic / Symbios Logic SAS1068E”,无cache。近400的IOPS压力已经达到了硬件极限。而其它机器使用的raid卡是“LSI Logic / Symbios Logic MegaRAID SAS 1078”,有256MB cache,并未达到硬件瓶颈,解决办法是更换能提供更大IOPS的机器,比如最后我们换了一台带 PERC6/i 集成RAID控制器卡的机器。需要说明的是,raid信息是在raid卡和磁盘固件里面各存一份,磁盘上的raid信息和raid卡上面的信息格式要是匹配的,否则raid卡识别不了就需要格式化磁盘。

IOPS本质上取决于磁盘本身,但是又很多提升IOPS的方法,加硬件cache、采用RAID阵列是常用的办法。如果是DB那种IOPS很高的场景,现在流行用SSD来取代传统的机械硬盘。

不过前面也说了,我们从软硬件两方面着手的目的就是看能否分别寻求代价最小的解决方案:

知道硬件的原因了,我们可以尝试把读写操作移到另一块盘,然后再看看效果: 

Linux:Linux 系统监控、诊断工具之 IO wait
Linux:Linux 系统监控、诊断工具之 IO wait

3、最后的话:另辟蹊径

其实,除了用上述专业的工具定位这个问题外,我们可以直接利用进程状态来找到相关的进程。

我们知道进程有如下几种状态:

  • D uninterruptible sleep (usually IO)
  • R running or runnable (on run queue)
  • S interruptible sleep (waiting for an event to complete)
  • T stopped, either by a job control signal or because it is being traced.
  • W paging (not valid since the 2.6.xx kernel)
  • X dead (should never be seen)
  • Z defunct (“zombie”) process, terminated but not reaped by its parent.

其中状态为 D 的一般就是由于 wait IO 而造成所谓的”非中断睡眠“,我们可以从这点入手然后一步步的定位问题:

# for x in `seq 10`; do ps -eo state,pid,cmd | grep "^D"; echo "----"; sleep 5; done
 D 248 [jbd2/dm-0-8]
 D 16528 bonnie++ -n 0 -u 0 -r 239 -s 478 -f -b -d /tmp
 ----
 D 22 [kdmflush]
 D 16528 bonnie++ -n 0 -u 0 -r 239 -s 478 -f -b -d /tmp
 ----
# 或者:
# while true; do date; ps auxf | awk '{if($8=="D") print $0;}'; sleep 1; done
 Tue Aug 23 20:03:54 CLT 2011
 root       302  0.0  0.0      0     0 ?        D    May22   2:58  _ [kdmflush]
 root       321  0.0  0.0      0     0 ?        D    May22   4:11  _ [jbd2/dm-0-8]
 Tue Aug 23 20:03:55 CLT 2011
 Tue Aug 23 20:03:56 CLT 2011
# cat /proc/16528/io
 rchar: 48752567
 wchar: 549961789
 syscr: 5967
 syscw: 67138
 read_bytes: 49020928
 write_bytes: 549961728
 cancelled_write_bytes: 0
# lsof -p 16528
 COMMAND PID USER FD TYPE DEVICE SIZE/OFF NODE NAME
 bonnie++ 16528 root cwd DIR 252,0 4096 130597 /tmp
 
 bonnie++ 16528 root 8u REG 252,0 501219328 131869 /tmp/Bonnie.16528
 bonnie++ 16528 root 9u REG 252,0 501219328 131869 /tmp/Bonnie.16528
 bonnie++ 16528 root 10u REG 252,0 501219328 131869 /tmp/Bonnie.16528
 bonnie++ 16528 root 11u REG 252,0 501219328 131869 /tmp/Bonnie.16528
 bonnie++ 16528 root 12u REG 252,0 501219328 131869 /tmp/Bonnie.16528
# df /tmp
 Filesystem 1K-blocks Used Available Use% Mounted on
 /dev/mapper/workstation-root 7667140 2628608 4653920 37% /
# fuser -vm /tmp
        USER        PID ACCESS COMMAND
 /tmp:  db2fenc1   1067 ....m db2fmp
        db2fenc1   1071 ....m db2fmp
        db2fenc1   2560 ....m db2fmp
        db2fenc1   5221 ....m db2fmp

4、Refer:[1] Troubleshooting High I/O Wait in Linux —— A walkthrough on how to find processes that are causing high I/O Wait on Linux Systems

[2] 理解Linux系统负荷

[3] 24 iostat, vmstat and mpstat Examples for Linux Performance Monitoring

[4] vmstat vmstat命令

[5] Linux vmstat命令实战详解

[6] 影响Linux服务器性能的因素

[7] linux磁盘IO查看iostat,vmstat

[8] What Process is using all of my disk IO

[9] Linux Wait IO Problem

[10] Tracking Down High IO Wait in Linux

[11] 磁盘IOPS计算与测量

[12] [DOC]磁盘性能指标—IOPS – Huawei

[13] RAID卡

 

来源:http://my.oschina.net/leejun2005/blog/355915

Linux:使用 smartmontools 查看硬盘的健康状态

要说Linux用户最不愿意看到的事情,莫过于在毫无警告的情况下发现硬盘崩溃了。诸如RAID备份和存储技术可以在任何时候帮用户恢复数据,但为预防硬件突然崩溃造成数据丢失所花费的代价却是相当可观的,特别是在用户从来没有提前考虑过在这些情况下的应对措施时。

为了避免遇到这种困境,用户可以试用一款叫做smartmontools的软件包程序,它通过使用自我监控(Self-Monitoring)、分析(Analysis)和报告(Reporting)三种技术(缩写为S.M.A.R.T或SMART)来管理和监控存储硬件。如今大部分的ATA/SATA、SCSI/SAS和固态硬盘都搭载内置的SMART系统。SMART的目的是监控硬盘的可靠性、预测磁盘故障和执行各种类型的磁盘自检。smartmontools由smartctl和smartd两部分工具程序组成,它们一起为Linux平台提供对磁盘退化和故障的高级警告。

Linux:使用 smartmontools 查看硬盘的健康状态
Linux:使用 smartmontools 查看硬盘的健康状态

这篇文章会描述Linux上smartmontools的安装和配置方法。

安装Smartmontools

由于smartmontools在大部分Linux发行版的基本软件库中都可用,所以安装很方便。

Debian和其衍生版:

# aptitude install smartmontools

基于Red Hat的发行版:

# yum install smartmontools

使用Smartctl检测硬盘的健康状况

首先,使用下面的命令列出和系统相连的硬盘:

# ls -l /dev | grep -E 'sd|hd'

输出结果和下图类似:

Linux:使用 smartmontools 查看硬盘的健康状态
Linux:使用 smartmontools 查看硬盘的健康状态

其中sdX代表分配给机器上对应硬盘上的设备名。

如果想要显示出某个指定硬盘的信息(比如设备模式、S/N、固件版本、大小、ATA版本/修订号、SMART功能的可用性和状态),在运行smartctl命令时添加”–info”选项,并按如下所示指定硬盘的设备名。

在本例中,选择/dev/sda。

# smartctl --info /dev/sda
Linux:使用 smartmontools 查看硬盘的健康状态
Linux:使用 smartmontools 查看硬盘的健康状态

尽管最开始可能不会注意到ATA(译者注:硬盘接口技术)的版本信息,但当需要替换硬盘时它确实是最重要的因素之一。每一代ATA版本都保持向下兼容。例如,老的ATA-1或ATA-2设备可以正常工作在ATA-6和ATA-7接口上,但反过来就不行了。在设备版本和接口版本两者不匹配的情况下,它们会按照两者中版本较小的规范来运行。也就是说,在这种情况下,需要替换硬盘时,ATA-7硬盘是最安全的选择。

可以通过这个命令来检测某个硬盘的健康状况:

# smartctl -s on -a /dev/sda

在这个命令中,”-s on”标志开启指定设备上的SMART功能。如果/dev/sda上已开启SMART支持,那就省略它。

硬盘的SMART信息包含很多部分。其中,”READ SMART DATA”部分显示出硬盘的整体健康状况。

=== START OF READ SMART DATA SECTION ===
SMART overall-health self-assessment rest result: PASSED

这个测试的结果是PASSED或FAILED。后者表示即将出现硬件故障,所以需要开始备份这块磁盘上的重要数据!

下一个需要关注的地方是SMART属性表,如下所示。

Linux:使用 smartmontools 查看硬盘的健康状态
Linux:使用 smartmontools 查看硬盘的健康状态

基本上,SMART属性表列出了制造商在硬盘中定义好的属性值,以及这些属性相关的故障阈值。这个表由驱动固件自动生成和更新。

  • ID:属性ID,通常是一个1到255之间的十进制或十六进制的数字。
  • ATTRIBUTE_NAME:硬盘制造商定义的属性名。
  • FLAG:属性操作标志(可以忽略)。
  • VALUE:这是表格中最重要的信息之一,代表给定属性的标准化值,在1到253之间。253意味着最好情况,1意味着最坏情况。取决于属性和制造商,初始化VALUE可以被设置成100或200.
  • WORST:所记录的最小VALUE。
  • THRESH:在报告硬盘FAILED状态前,WORST可以允许的最小值。
  • TYPE:属性的类型(Pre-fail或Oldage)。Pre-fail类型的属性可被看成一个关键属性,表示参与磁盘的整体SMART健康评估(PASSED/FAILED)。如果任何Pre-fail类型的属性故障,那么可视为磁盘将要发生故障。另一方面,Oldage类型的属性可被看成一个非关键的属性(如正常的磁盘磨损),表示不会使磁盘本身发生故障。
  • UPDATED:表示属性的更新频率。Offline代表磁盘上执行离线测试的时间。
  • WHEN_FAILED:如果VALUE小于等于THRESH,会被设置成“FAILING_NOW”;如果WORST小于等于THRESH会被设置成“In_the_past”;如果都不是,会被设置成“-”。在“FAILING_NOW”情况下,需要尽快备份重要文件,特别是属性是Pre-fail类型时。“In_the_past”代表属性已经故障了,但在运行测试的时候没问题。“-”代表这个属性从没故障过。
  • RAW_VALUE:制造商定义的原始值,从VALUE派生。

这时候你可能会想,“是的,smartctl看起来是个不错的工具,但我更想知道如何避免手动运行的麻烦。”如果能够以指定的间隔运行,同时又能通知我测试结果,那不是更好吗?”

好消息是,这个功能已经有了。是smartd发挥作用的时候了!

来源:http://xmodulo.com/check-hard-disk-health-linux-smartmontools.html

Linux:使用n2n配置二层点对点VPN

n2n是一个二层点对点虚拟专用网(VPN),它允许用户在网络层面而非应用层面开发典型的P2P应用功能。这就意味着,用户可以获得本地IP可见性(如,属于同一个n2n网络的两台PC可以互相ping通),以及不管他们现在身处哪个网络,只要有相同的网络IP地址就可以访问到。简言之,就像OpenVPN将SSL从应用(如,用于部署https协议)搬到了网络协议一样,n2n将P2P从应用搬到了网络层面。

Linux:使用n2n配置二层点对点VPN
Linux:使用n2n配置二层点对点VPN

n2n主要功能

n2n是一个基于P2P协议的加密的二层专用网。

加密使用开放协议部署在边缘节点,它使用用户定义的加密钥匙:你自己控制安全,而不用授权给公司,而Skype或Hamachi却是要的。

各个n2n用户可以同时属于多个网络(或者社区)。

它拥有在反向通信方向(如,从外部到内部)穿越NAT和防火墙的能力,因此可以到达n2n节点,即使运行在一个专用网中。防火墙不再是IP层面掌控通信的障碍。

n2n网络并不意味着它是独立的,它可以在n2n和非n2n网络间路由通信。

n2n架构基于两个组件

超级节点:它在启动时用于边缘节点或用于达到对称防火墙后面的节点。对于这些节点,该应用主要是一个目录暂存器和包路由器,而不是直接通信。

边缘节点:安装在用户PC的应用程序,它允许构建n2n网络。实际上,各个边缘节点创建一个tun/tap设备,该设备是n2n网络的进入点。

安装n2n到Ubuntu

打开终端并运行以下命令

$ sudo apt-get install subversion build-essential libssl-dev
$ svn co https://svn.ntop.org/svn/ntop/trunk/n2n
$ cd n2n/n2n_v2
$ make
$ sudo make install

使用n2n配置P2P VPN

首先,我们需要配置一个超级节点和任意数量的边缘节点。

决定将超级节点放在哪个地方。假设你将它放到了主机a.b.c.d的xyw端口上。

决定使用何种密码加密来保证数据安全。假设你使用密码encryptme。

决定你想要使用的网络名称。假设你将它命名为mynetwork。注意,你可以使用超级节点/边缘节点来处理多个网络,不仅仅只有一个哦。

决定在边缘节点上使用什么IP地址。假设你使用10.1.2.0/24。

启动应用:

配置超级节点

supernode -l xyw

配置边缘节点

在各个边缘节点,使用以下命令来连接到P2P VPN。

sudo edge -a 10.1.2.1 -c mynetwork -k encryptme -l a.b.c.d:xyw
sudo edge -a 10.1.2.2 -c mynetwork -k encryptme -l a.b.c.d:xyw

现在来测试你的n2n网络

edge node1> ping 10.1.2.2
edge node2> ping 10.1.2.1

Windows n2n VPN客户端(N2N边缘图形界面)

你可以从这里下载N2N边缘图形界面。

N2N边缘图形界面是一个基本的安装器和用于点对点‘n2n VPN解决方案’的GUI配置界面。

Linux:使用n2n配置二层点对点VPN
Linux:使用n2n配置二层点对点VPN

via: http://www.ubuntugeek.com/configuring-layer-two-peer-to-peer-vpn-using-n2n.html

作者:ruchi 译者:GOLinux 校对:wxy

本文由 LCTT 原创翻译,Linux中国 荣誉推出

来源:https://linux.cn/article-4469-1.html

Linux:在 Linux 上使用 eCryptFS 加密文件和目录

作为罪犯,你需要为自己的身份保密;而作为中情局成员,你同样也需要为自己的身份保密。但是,你却不是他们其中的任何一员,你只是不想其他人查探到你的金融数据、家庭照片、尚未出版的手稿,或者记录着你能发家致富的最初想法的私密笔记。

我时常听到有人告诉我“我只是个微不足道的人,没人会查探我”或者“我没有什么东西要隐藏的。”好吧,告诉你我的想法,即便我没有什么要隐藏的,或者我也可以公开我带着狗的孩子的照片,那我也有权利不这么去做,也有权利来保护我的隐私。

加密类型

我们主要有两种加密文件和目录的方法。一种是文件系统级别的加密,在这种加密中,你可以选择性地加密某些文件或者目录(如,/home/alice)。对我而言,这是个十分不错的方法,你不需要为了启用或者测试加密而把所有一切重新安装一遍。然而,文件系统级别的加密也有一些缺点。例如,许多现代应用程序会缓存(部分)文件你硬盘中未加密的部分中,比如交换分区、/tmp和/var文件夹,而这会导致隐私泄漏。

另外一种方式,就是所谓的全盘加密,这意味着整个磁盘都会被加密(可能除了主引导记录外)。全盘加密工作在物理磁盘级别,写入到磁盘的每个比特都会被加密,而从磁盘中读取的任何东西都会在运行中解密。这会阻止任何潜在的对未加密数据的未经授权的访问,并且确保整个文件系统中的所有东西都被加密,包括交换分区或任何临时缓存数据。

可用的加密工具

在Linux中要实施加密,有几个可供选择的工具。在本教程中,我打算介绍其中一个:eCryptFS,一个用户空间文件系统加密工具。下面提供了一个Linux上可用的加密工具摘要供您参考。

文件系统级别加密

  • EncFS:尝试加密的最简单方式之一。EncFS工作在基于FUSE的伪文件系统上,所以你只需要创建一个加密文件夹并将它挂载到某个文件夹就可以工作了。
  • eCryptFS:一个POSIX兼容的加密文件系统,eCryptFS工作方式和EncFS相同,所以你必须挂载它。

磁盘级别加密

  • Loop-AES:最古老的磁盘加密方法。它真的很快,并且适用于旧系统(如,2.0内核分支)。
  • DMCrypt:最常见的磁盘加密方案,支持现代Linux内核。
  • CipherShed:已停止的TrueCrypt磁盘加密程序的一个开源分支。

eCryptFS基础

Linux:在 Linux 上使用 eCryptFS 加密文件和目录
Linux:在 Linux 上使用 eCryptFS 加密文件和目录

eCrypFS是一个基于FUSE的用户空间加密文件系统,在Linux内核2.6.19及更高版本中可用(作为encryptfs模块)。eCryptFS加密的伪文件系统是挂载到当前文件系统顶部的。它可以很好地工作在EXT文件系统家族和其它文件系统如JFS、XFS、ReiserFS、Btrfs,甚至是NFS/CIFS共享文件系统上。Ubuntu使用eCryptFS作为加密其家目录的默认方法,ChromeOS也是。在eCryptFS底层,默认使用的是AES算法,但是它也支持其它算法,如blowfish、des3、cast5、cast6。如果你是通过手工创建eCryptFS设置,你可以选择其中一种算法。

就像我所的,Ubuntu让我们在安装过程中选择是否加密/home目录。好吧,这是使用eCryptFS的最简单的一种方法。

Linux:在 Linux 上使用 eCryptFS 加密文件和目录
Linux:在 Linux 上使用 eCryptFS 加密文件和目录

Ubuntu提供了一个用户友好的工具集,通过eCryptFS可以让我们的生活更轻松,但是在Ubuntu安装过程中启用eCryptFS只创建了一个指定的预配置的设置。所以,如果默认的设置不适合你的需求,你需要进行手工设置。在本教程中,我将介绍如何在主流Linux发行版上手工设置eCryptFS

eCryptFS的安装

Debian,Ubuntu或其衍生版:

$ sudo apt-get install ecryptfs-utils

注意,如果你在Ubuntu安装过程中选择加密家目录,eCryptFS应该已经安装了。

CentOS, RHEL or Fedora:

# yum install ecryptfs-utils

Arch Linux:

$ sudo pacman -S ecryptfs-utils

在安装完包后,加载eCryptFS内核模块当然会是一个很好的实践:

$ sudo modprobe ecryptfs

配置eCryptFS

现在,让我们开始加密一些目录,运行eCryptFS配置工具:

$ ecryptfs-setup-private
Linux:在 Linux 上使用 eCryptFS 加密文件和目录
Linux:在 Linux 上使用 eCryptFS 加密文件和目录

它会要求你输入登录密码和挂载密码。登录密码和你常规登录的密码一样,而挂载密码用于派生一个文件加密主密钥。这里留空可以生成一个(复杂的),这样会更安全。登出然后重新登录。

你会注意到,eCryptFS默认在你的家目录中创建了两个目录:Private和.Private。~/.Private目录包含有加密的数据,而你可以在~/Private目录中访问到相应的解密后的数据。在你登录时,~/.Private目录会自动解密并映射到~/Private目录,因此你可以访问它。当你登出时,~/Private目录会自动卸载,而~/Private目录中的内容会加密回到~/.Private目录。

eCryptFS怎么会知道你拥有~/.Private目录,并自动将其解密到~/Private目录而不需要我们输入密码呢?这就是eCryptFS的PAM模块捣的鬼,它为我们提供了这项便利服务。

如果你不想让~/Private目录在登录时自动挂载,只需要在运行ecryptfs-setup-private工具时添加“–noautomount”选项。同样,如果你不想要~/Private目录在登出后自动卸载,也可以自动“–noautoumount”选项。但是,那样后,你需要自己手工挂载或卸载~/Private目录:

$ ecryptfs-mount-private ~/.Private ~/Private
$ ecryptfs-umount-private ~/Private

你可以来验证一下.Private文件夹是否被挂载,运行:

$ mount
Linux:在 Linux 上使用 eCryptFS 加密文件和目录
Linux:在 Linux 上使用 eCryptFS 加密文件和目录

现在,我们可以开始把任何敏感文件放进~/Private文件夹里头了,它们会在我们登出时自动被加密并锁在~/.Private文件内。

所有这一切看起来是那么得神奇。这主要是ecryptfs-setup-private工具让一切设置变得简单。如果你想要深究一点,对eCryptFS指定的方面进行设置,那么请转到官方文档

结尾

综上所述,如果你十分关注你的隐私,最好是将基于eCryptFS文件系统级别的加密和全盘加密相结合。切记,只进行文件加密并不能保证你的隐私不受侵犯。


via: http://xmodulo.com/encrypt-files-directories-ecryptfs-linux.html

作者:Christopher Valerio 译者:GOLinux 校对:wxy

本文由 LCTT 原创翻译,Linux中国 荣誉推出

来源:https://linux.cn/article-4470-1.html

Linux:如何从Ubuntu的声音菜单中移除音乐播放器

自从2010年首次出现,Ubuntu 的声音菜单已经被证明是Unity 桌面上的最流行的独有特性之一。

把音乐播放器与音量控制程序集成到一个标准的界面里是一种看起来很聪明的做法,这样就不用到处找声音相关的各种程序。人们不禁要问,为什么其它操作系统没有效仿这种做法!

臃肿

尽管它看起来很方便,但是这个小应用当前存在一个问题:很多播放器都堆在一起,像一个组合音响一样。也许你用得着,但是你安装的所有的媒体播放器都挤在这里,这会让人看着很累赘和反感。

我将要打赌,当你读到这里时,一定发现上面的截图看起来很熟悉!不要担心,dconf-editor可以解决它。

从Ubuntu 声音菜单中移除播放器

第一部分: 基础知识

最快速和最简单地从声音菜单中移除播放器的方法就是卸载相关的应用程序。但这是极端的方式,我的意思是指你也许想要保留应用程序,但是不需要它集成到菜单里面。

只删除播放器但是保留我们需要的应用程序,我们用到一个看起来令人惊讶的工具叫“dconf-editor”。

你可能已经安装了,如果没有安装的话,那么你从Ubuntu软件中心找出。

一旦安装完毕,找到Unity Dash并打开。打开的时候不要惊慌;你没有到2002年,它确实是这种古老的样子。

使用右侧菜单栏,你需要从导航到 com > canonical > indicator > sound.下面的面板将会出现。

双击“interested-media-players”旁的闭括号,并删除你希望从声音菜单里移除掉的播放器,但需要保留方括号中,且不要删除任何需要保留的逗号或者单引号。

举个例子,我移除掉这些

rhythmbox.desktop’, ‘pithos.desktop’, ‘clementine.desktop’,

这样就好留了一行如下:

['tomahawk.desktop']

现在,当我再打开声音菜单时,我只看到Tomahawk:

第二部分:黑名单

等等!还不能关闭dconf-editor。尽管上面的步骤看起来把事情处理得干净利落,但是一些播放器在打开时会立即重新加载到声音菜单。为了避免重复这个过程,将它们添加到blacklisted-media-player中。

记得每个在括号里的播放器都用逗号分隔多个条目。他们也必须在方括号内,所以在退出之前请务必仔细检查。

最终结果如下:


via: http://www.omgubuntu.co.uk/2014/11/remove-players-ubuntu-sound-menu

作者:Joey-Elijah Sneddon 译者:disylee 校对:wxy

本文由 LCTT 原创翻译,Linux中国 荣誉推出

来源:https://linux.cn/article-4473-1.html

Linux:你值得拥有 —— 25 个 Linux 性能监控工具

一段时间以来,我们在网上向读者介绍了如何为Linux以及类Linux操作系统配置多种不同的性能监控工具。在这篇文章中我们将罗列一系列使用最频繁的性能监控工具,并对介绍到的每一个工具提供了相应的简介链接,大致将其划分为两类,基于命令行的和提供图形化接口的。

基于命令行的性能监控工具

1. dstat – 多类型资源统计工具

该命令整合了vmstatiostatifstat三种命令。同时增加了新的特性和功能可以让你能及时看到各种的资源使用情况,从而能够使你对比和整合不同的资源使用情况。通过不同颜色和区块布局的界面帮助你能够更加清晰容易的获取信息。它也支持将信息数据导出到cvs格式文件中,从而用其他应用程序打开,或者导入到数据库中。你可以用该命令来监控cpu,内存和网络状态随着时间的变化

Linux:你值得拥有 —— 25 个 Linux 性能监控工具
Linux:你值得拥有 —— 25 个 Linux 性能监控工具

2. atop – 相比top更好的ASCII码体验

这个使用ASCII码显示方式的命令行工具是一个显示所有进程活动的性能监控工具。它可以展示每日的系统日志以进行长期的进程活动分析,并高亮显示过载的系统使用资源。它包含了CPU,内存,交换空间,磁盘和网络层的度量指标。所有这些功能只需在终端运行atop即可。

# atop

当然你也可以使用交互界面来显示数据并进行排序。

Linux:你值得拥有 —— 25 个 Linux 性能监控工具
Linux:你值得拥有 —— 25 个 Linux 性能监控工具

3. Nmon – 类Unix系统的性能监控

Nmon是Nigel’s Monitor缩写,它最早开发用来作为AIX的系统监控工具。如果使用在线模式,可以使用光标键在屏幕上操作实时显示在终端上的监控信息。使用捕捉模式能够将数据保存为CSV格式,方便进一步的处理和图形化展示。

Linux:你值得拥有 —— 25 个 Linux 性能监控工具
Linux:你值得拥有 —— 25 个 Linux 性能监控工具

更多的信息参考使用nmon进行性能监控的文章。

4. slabtop – 显示内核slab缓存信息

这个应用能够显示缓存分配器是如何管理Linux内核中缓存的不同类型的对象。这个命令类似于top命令,区别是它的重点是实时显示内核slab缓存信息。它能够显示按照不同排序条件来排序显示缓存列表。它同时也能够显示一个slab层信息的统计信息的题头。举例如下:

# slabtop --sort=a
# slabtop -s b
# slabtop -s c
# slabtop -s l
# slabtop -s v
# slabtop -s n
# slabtop -s o

更多的信息参考监控内核slab缓存的文章。

5. sar – 性能监控和瓶颈检查

sar 命令可以将操作系统上所选的累积活动计数器内容信息输出到标准输出上。其基于计数值和时间间隔参数的审计系统,会按照指定的时间间隔输出指定次数的监控信息。如果时间间隔参数为设置为0,那么sar命令将会显示系统从开机到当时时刻的平均统计信息。有用的命令如下:

# sar -u 2 3
# sar -u -f /var/log/sa/sa05
# sar -P ALL 1 1
# sar -r 1 3
# sar -W 1 3

6. Saidar – 简单的统计监控工具

Saidar是一个简单轻量的系统信息监控工具。虽然它无法提供大多性能报表,但是它能够通过一个简单明了的方式显示最有用的系统运行状况数据。你可以很容易地看到运行时间、平均负载、CPU、内存、进程、磁盘和网络接口统计信息。

Usage: saidar [-d delay] [-c] [-v] [-h]
-d 设置更新时间(秒)
-c 彩色显示
-v 显示版本号
-h 显示本帮助
Linux:你值得拥有 —— 25 个 Linux 性能监控工具
Linux:你值得拥有 —— 25 个 Linux 性能监控工具

7. top – 经典的Linux任务管理工具

作为一个广为人知的Linux工具,top是大多数的类Unix操作系统任务管理器。它可以显示当前正在运行的进程的列表,用户可以按照不同的条件对该列表进行排序。它主要显示了系统进程对CPU和内存的使用状况。top可以快速检查是哪个或哪几个进程挂起了你的系统。你可以在这里看到top使用的例子。 你可以在终端输入top来运行它并进入到交互模式:

交互模式的一些快捷操作:
    全局命令: <回车/空格> ?, =, A, B, d, G, h, I, k, q, r, s, W, Z
    统计区的命令: l, m, t, 1
    任务区的命令:
         外观: b, x, y, z 内容: c, f, H, o, S, u 大小: #, i, n 排序: <, >, F, O, R
    色彩方案: , a, B, b, H, M, q, S, T, w, z, 0 - 7
    窗口命令:  -, _, =, +, A, a, G, g, w
Linux:你值得拥有 —— 25 个 Linux 性能监控工具
Linux:你值得拥有 —— 25 个 Linux 性能监控工具

8. Sysdig – 系统进程的高级视图

Sysdig是一个能够让系统管理员和开发人员以前所未有方式洞察其系统行为的监控工具。其开发团队希望改善系统级的监控方式,通过提供关于存储,进程,网络和内存子系统的统一有序以及粒度可见的方式来进行错误排查,并可以创建系统活动记录文件以便你可以在任何时间轻松分析。

简单例子:

# sysdig proc.name=vim
# sysdig -p"%proc.name %fd.name" "evt.type=accept and proc.name!=httpd"
# sysdig evt.type=chdir and user.name=root
# sysdig -l
# sysdig -L
# sysdig -c topprocs_net
# sysdig -c fdcount_by fd.sport "evt.type=accept"
# sysdig -p"%proc.name %fd.name" "evt.type=accept and proc.name!=httpd"
# sysdig -c topprocs_file
# sysdig -c fdcount_by proc.name "fd.type=file"
# sysdig -p "%12user.name %6proc.pid %12proc.name %3fd.num %fd.typechar %fd.name" evt.type=open
# sysdig -c topprocs_cpu
# sysdig -c topprocs_cpu evt.cpu=0
# sysdig -p"%evt.arg.path" "evt.type=chdir and user.name=root"
# sysdig evt.type=open and fd.name contains /etc
Linux:你值得拥有 —— 25 个 Linux 性能监控工具
Linux:你值得拥有 —— 25 个 Linux 性能监控工具

更多的信息参考:如何利用sysdig改善系统层次的监控和错误排查

来源:https://linux.cn/article-4481-1.html

Linux:迁移LVM分区到新的逻辑卷/驱动器(第六部分)

这是我们正在进行的LVM系列的第六部分。在本文中,我们将为大家展示怎样在线将现存的逻辑卷迁移到其它新的驱动器。在开始之前,我想要先来介绍一下LVM迁移及其特性。

Linux:迁移LVM分区到新的逻辑卷/驱动器(第六部分)
Linux:迁移LVM分区到新的逻辑卷/驱动器(第六部分)

LVM存储迁移

什么是LVM迁移?

LVM迁移是LVM众多优秀特性之一,通过它,我们可以迁移逻辑卷到一个新的磁盘而不会丢失数据,也不用关机操作。该特性的功能是将数据从旧磁盘移动到新磁盘。通常,我们只是在一些磁盘发生错误时,才将数据从一个磁盘迁移到另外一个磁盘存储。

迁移特性

  • 将逻辑卷从一个磁盘移动到另一个磁盘。
  • 我们可以使用任何类型的磁盘,如SATA、SSD、SAS、SAN storage iSCSI或者FC。
  • 在线迁移磁盘,而且数据不会丢失。

在LVM迁移中,我们将交换各个卷、文件系统以及位于已有的存储中的数据。例如,如果我们有一个单一逻辑卷,它已经映射到了物理卷,而该物理卷是一个物理硬盘驱动器。

现在,如果我们需要升级服务器存储为SSD硬盘驱动器,我们首先需要考虑什么?重新格式化磁盘?不!我们不必重新格式化服务器,LVM可以选择将这些旧的SATA驱动器上的数据迁移到新的SSD驱动器上。在线迁移将会支持任何类型的磁盘,不管是本地驱动器,还是SAN或者光纤通道都可以。

我的服务器设置

操作系统:  CentOS 6.5 Final
IP地址:   192.168.0.224
系统主机名:  lvmmig.tecmintlocal.com

步骤1: 检查当前驱动器

1.假设我们已经有一个名为“vdb”的虚拟驱动器,它已经被映射到了其中一个逻辑卷“tecmint_lv”。现在,我们想要迁移“vdb”这个逻辑卷到其它某个新的存储设备中。在开始之前,首先在下面所示的fdisk和lvs命令的帮助下验证该虚拟驱动器。

# fdisk -l | grep vd
# lvs
Linux:迁移LVM分区到新的逻辑卷/驱动器(第六部分)
Linux:迁移LVM分区到新的逻辑卷/驱动器(第六部分)

检查逻辑卷磁盘

步骤2: 检查新添加的驱动器

2.在我们确认了现存驱动器后,现在是时候来将新的SSD驱动器连接到系统并在fdisk命令的帮助下验证新添加的驱动器了。

# fdisk -l | grep dev
Linux:迁移LVM分区到新的逻辑卷/驱动器(第六部分)
Linux:迁移LVM分区到新的逻辑卷/驱动器(第六部分)

检查新添加的驱动器

注意:你看到上面屏幕中的内容了吗?新的驱动器已经被成功添加了,其名称为“/dev/sda”。

步骤3: 检查当前逻辑和物理卷

3.现在,让我们开始创建物理卷、卷组和逻辑卷以用于迁移。在创建卷时,确保检查/mnt/lvm挂载点下的当前逻辑卷的数据。用以下命令来列出挂载点并检查数据。

# df -h
# cd /mnt/lvm
# cat tecmint.txt
Linux:迁移LVM分区到新的逻辑卷/驱动器(第六部分)
Linux:迁移LVM分区到新的逻辑卷/驱动器(第六部分)

检查逻辑卷数据

注意:出于演示的目的,我们已经在/mnt/lvm挂载点下创建了两个文件,我们将在线将这些数据迁移到新的驱动器中。

4.在迁移之前,确保对确认与物理卷相关的逻辑卷和卷组名称,并且确认哪个物理卷用于容纳该卷组和逻辑卷。

# lvs
# vgs -o+devices | grep tecmint_vg
Linux:迁移LVM分区到新的逻辑卷/驱动器(第六部分)
Linux:迁移LVM分区到新的逻辑卷/驱动器(第六部分)

确认逻辑卷名称

注意:看到上面屏幕中的内容了吗?“vdb”容纳了卷组tecmint_vg

步骤4: 创建新物理卷

5.在在我们新添加的SSD驱动器中创建物理卷之前,我们需要使用fdisk来定义分区。在创建分区时,别忘了修改分区类型为LVM(8e)。

# pvcreate /dev/sda1 -v
# pvs
Linux:迁移LVM分区到新的逻辑卷/驱动器(第六部分)
Linux:迁移LVM分区到新的逻辑卷/驱动器(第六部分)

创建物理卷

6.接下来,使用‘vgextend命令’来添加新创建的物理卷到现存卷组tecmint_vg。

# vgextend tecmint_vg /dev/sda1
# vgs
Linux:迁移LVM分区到新的逻辑卷/驱动器(第六部分)
Linux:迁移LVM分区到新的逻辑卷/驱动器(第六部分)

添加物理卷

7.要获得卷组的完整信息列表,请使用‘vgdisplay’命令。

# vgdisplay tecmint_vg -v
Linux:迁移LVM分区到新的逻辑卷/驱动器(第六部分)
Linux:迁移LVM分区到新的逻辑卷/驱动器(第六部分)

列出卷组信息

注意:在上面屏幕中,我们可以看到在输出结果的结束处,我们的PV已经添加到了卷组中。

8.如果我们需要知道更多关于哪些设备被映射的信息,请使用‘dmsetup’依赖命令。

# lvs -o+devices
# dmsetup deps /dev/tecmint_vg/tecmint_lv

在上面的结果中,有个1个依赖(PV)或(驱动器),而这里17被列出了。如果你想要检查设备,那些关联的有着主、次设备号的驱动器,以确认,使用下面的命令。

# ls -l /dev | grep vd
Linux:迁移LVM分区到新的逻辑卷/驱动器(第六部分)
Linux:迁移LVM分区到新的逻辑卷/驱动器(第六部分)

列出设备信息

注意:在上面的命令中,我们可以看到主设备号是252,次设备号是17,它连接到了vdb1。希望你理解了上面命令的输出。

来源:http://www.tecmint.com/lvm-storage-migration/#comment-331336

Linux:为什么我要竖向对齐程序代码

Linux:为什么我要竖向对齐程序代码
Linux:为什么我要竖向对齐程序代码

最近在HackerNews上Linux内核编码风格讨论非常热闹。

讨论的进行中,我的一个回复触发了另外一场关于是否应该竖向对齐代码的口水仗。我坚持我的观点!下面让我来解释一下为什么要竖向对齐。

为什么要竖向对齐代码?

举一个简单的例子:

int robert_age = 32;
int annalouise_age = 25;
int bob_age = 250;
int dorothy_age = 56;

相较而言,下面的写法更易读:

int robert_age     = 32;
int annalouise_age = 25;
int bob_age        = 250;
int dorothy_age    = 56;

只要用眼睛一扫,我们就能发现”bob_age”数字异常。我可以去轻松的识别这些变量都是数字,不需要拿眼睛一个个对比。

这种编码风格并不是被广泛接受。所以,我需要解释一些这种风格的好处。

代码的可读性

90%的编程活动是为了解决问题。另外90%是用来理解代码是如何解决问题的。

阅读代码跟阅读小说没多大区别。我们希望作者能把他的想法写明白,不需要陈词滥调长篇累牍,但同时要遵守所使用的语言的语法。

事实上,Linux内核编码风格里十分强调这一点。你给变量的命名同它的作用同等重要。

看一下下面的这段代码:

var thinG=doIt(thestuff,MORE_sTuff); /* LOL! */

就算你是十分解这段代码,你读起它来也十分费劲。

var totalBill = apply_tax(initialBill, taxRate);

通过给予变量有意义的命名,空格,大小写区分,我们能让这段代码更清晰。这意味着接手我们的代码的下一位程序员能更容易的理解它。

为什么要使用Monospace字体?

关于代码编辑器应该使用monospace字体还是proportional字体的争论,从未停息也不会停息,两派人各有所好。

有些异教徒会告诉你proportional 字体最好的——忽略这些人吧。

最终是为可读性。什么方法能最简单的帮助我们理解代码?所以IDE才会有代码高亮配色,这样你就能轻松的分辨“foo”究竟是一个函数,是一个变量,是一个常量,还是一个注释。只要是能帮助我们理解代码的东西都是好东西!

编辑器的问题

有趣的是,我遇到的很多批评的声音不是说代码竖向对齐的好坏,而是批评我的代码编辑器不行。

你这样做会破坏使用diff对比版本差异时的可读性和有效性。比如,本来只是一行是有一个变量有bug,你能为了对齐变量改动了很多行,影响了查看关键修改处。也有能够忽略空格的diff技术,但至少你这样做得不偿失。Andreas van Cranenburgh

…还有…

假如说,你有50行代码要竖向对齐,你把所有的值对对齐距离最远的那一行,而增加一个更大距离的行,你需要修改50行。我就遇到过这样的问题,最终发现这样做是错误的。scrollaway

他们说的是对的——在某些情况下。但关键是他们不会使用更好工具。

我记得Elastic Tabstops提供的一个技巧——如何自动对齐代码块:

Linux:为什么我要竖向对齐程序代码
Linux:为什么我要竖向对齐程序代码

正确的工具能轻松的完成这样的任务。计算机就是用来为我们干这些枯燥、重复的事情的-CPU的工作很廉价,我们可以“浪费”CPU的工作来让我们的代码更清晰可读。

Linux 内核代码中还有大量例子能说明竖向对齐代码能让代码更适合人类阅读。

竖向对齐代码并不是在所有情况下都适用——但对于大多数情况,它的好处是大大的。

代码是我们表达我们的思想的媒介。如果你的工具使得理解这些思想更困难,那说明工具需要改变,而不是我们。

来源:http://www.techug.com/why-i-vertically-align-my-code

Linux:李纳斯法则:只要有足够多的眼球,就可让所有bug浮现

开放源代码运动的主要领导者、最为大众所知道(并最具争议性)的黑客——埃里克·雷蒙(Eric Steven Raymond)在他1999年出版的讨论软件工程方法的著名文集《大教堂和市集》中首次描述了这样一个精彩的观点:

只要足够多的眼球关注,就可让所有软件缺陷浮现。

更正式地来说即是:

只要有足够的测试员及共同开发者,所有软件缺陷都会在很短时间内被发现,而且能够很容易被解决。

他以开源操作系统Linux之父李纳斯·托瓦兹(Linus Torvalds)的名字来命名它,以此向李纳斯致敬:李纳斯法则(Linus’s_Law)。

Linux:李纳斯法则:只要有足够多的眼球,就可让所有bug浮现
Linux:李纳斯法则:只要有足够多的眼球,就可让所有bug浮现

把代码呈现给多个开发人员,让大家一起判断代码是否合格,这就是最简单的软件代码审查形式。各种研究和试验都反复的验证了代码审查(形式不限)在发现软件bug和安全漏洞中的有效性,证明代码审查要比软件测试效果好的多。

在关于软件工程方法的《事实与谬论(Facts and Fallacies)》一书中,作者Robert Glass将这条定律描述为开源运动的”真经(mantra)”,但同时认为这条定律并不准确,因为缺乏足够的支持证据,并且有研究发现,遗漏的bug数并不跟审查的人数之间存在线性的变化。更准确的说,当审查人数在2-4个人之间时,效果最佳,增加更多的审查者对消除bug比例的影响不大。一些非开源的专业开发人员,他们虽然提倡在软件开发者执行严格的、独立的代码分析,但同时用有限的人手进行深度的代码审查——而不是强调”眼球“的数量。

以著名的心脏出血(Heartbleed)bug为例——非常重要的开源软件中的一个很肤浅的bug——2年多的时间里没有人能够发现,要知道,全世界上百万台服务器都在使用含有这个bug的OpenSSL软件。但雷蒙对于心脏出血(Heartbleed)这个案例有不同意见,他认为虽然OpenSSL使用广泛,但事实上”没有任何的眼球“注意了它的源代码。

在2001年出版的《黑客伦理与信息时代的精神》(The Hacker Ethic And the Spirit of th Information Age)里,李纳斯在其为此书做的序言中,自己定义了另外一个李纳斯定律”黑客行为的动机是什么?——李纳斯法则(Linus’s_Law)“:

人类所有的动机可分为递进的三种类型 — 生存(survival)、社会生活(social life)、娱乐(entertainment)。

“黑客”是已经超越利用计算机谋生存而进入后面两个阶段的人。计算机本身就是娱乐。黑客坚信没有比这更高的动力阶段。

来源:http://www.techug.com/linuss-law

Linux:Shell 脚本基础 – 使用 if 语句进行条件检测

Bourne Shell 的 if 语句和大部分编程语言一样 – 检测条件是否真实,如果条件为真,shell 会执行这个 if 语句指定的代码块,如果条件为假,shell 就会跳过 if 代码块,继续执行之后的代码。

Linux:Shell 脚本基础 - 使用 if 语句进行条件检测
Linux:Shell 脚本基础 – 使用 if 语句进行条件检测

if 语句的语法:

if [ 判断条件 ]
then
        command1
        command2
        ……..
        last_command
fi

Example:

#!/bin/bash
number=150
if [ $number -eq 150 ]
then
    echo "Number is 150"
fi

if-else 语句:

除了标准的 if 语句之外,我们还可以加入 else 代码块来扩展 if 语句。这么做的主要目的是:如果 if 条件为真,执行 if 语句里的代码块,如果 if 条件为假,执行 else 语句里的代码块。

语法:

if [ 判断条件 ]
then
       command1
       command2
       ……..
       last_command
else
       command1
       command2
       ……..
       last_command
fi

Example:

#!/bin/bash
number=150
if [ $number -gt 250 ]
then
    echo "Number is greater"
else
    echo "Number is smaller"
fi

If..elif..else..fi 语句 (简写的 else if)

Bourne Shell 的 if 语句语法中,else 语句里的代码块会在 if 条件为假时执行。我们还可以将 if 语句嵌套到一起,来实现多重条件的检测。我们可以使用 elif 语句(else if 的缩写)来构建多重条件的检测。

语法 :

if [ 判断条件1 ]
then
       command1
       command2
       ……..
       last_command
elif [ 判断条件2 ]
then
        command1
        command2
        ……..
        last_command
else
command1
command2
……..
last_command
fi

Example :

#!/bin/bash
number=150
if [ $number -gt 300 ]
then
    echo "Number is greater"
elif [ $number -lt 300 ]
then
    echo "Number is Smaller"
else
    echo "Number is equal to actual value"
fi

多重 if 语句 :

If 和 else 语句可以在一个 bash 脚本里相互嵌套。关键词 “fi” 表示里层 if 语句的结束,所有 if 语句必须使用 关键词 “fi” 来结束。

基本 if 语句的嵌套语法

if [ 判断条件1 ]
then
        command1
        command2
        ……..
        last_command
else
if [ 判断条件2 ]
then
        command1
        command2
        ……..
        last_command
else
        command1
        command2
         ……..
         last_command
      fi
fi

Example:

#!/bin/bash
number=150
if [ $number -eq 150 ]
then
   echo "Number is 150"
else
if [ $number -gt 150 ]
then
    echo "Number is greater"
else
    echo "'Number is smaller"
   fi
fi

via: http://www.linuxtechi.com/shell-scripting-checking-conditions-with-if/

作者:Pradeep Kumar 译者:ThomazL 校对:wxy

本文由 LCTT 原创翻译,Linux中国 荣誉推出

来源:https://linux.cn/article-4489-1.html

Linux:Linux 系统中使用 logwatch 监控日志文件

Linux 操作系统和许多应用程序会创建特殊的文件来记录它们的运行事件,这些文件通常被称作“日志”。当要了解操作系统或第三方应用程序的行为或进行故障排查时,这些系统日志或特定的应用程序日志文件是必不可少的的工具。但是,日志文件并没有您们所谓的“清晰”或“容易”这种程度的可读性。手工分析原始的日志文件简直是浪费时间,并且单调乏味。出于这个原因,对于系统管理员来说,发现任何一款能把原始的日志文件转换成更人性化的记录摘要的工具,将会受益无穷。

Linux:Linux 系统中使用 logwatch 监控日志文件
Linux:Linux 系统中使用 logwatch 监控日志文件

logwatch 是一款用 Perl 语言编写的开源日志解析分析器。它能对原始的日志文件进行解析并转换成结构化格式的文档,也能根据您的使用情况和需求来定制报告。logwatch 的主要目的是生成更易于使用的日志摘要,并不是用来对日志进行实时的处理和监控的。正因为如此,logwatch 通常被设定好时间和频率的自动定时任务来调度运行或者是有需要日志处理的时候从命令行里手动运行。一旦日志报告生成,logwatch 可以通过电子邮件把这报告发送给您,您可以把它保存成文件或者直接显示在屏幕上。

Logwatch 报告的详细程度和报告覆盖范围是完全可定制化的。Logwatch 的日志处理引擎也是可扩展的,从某种意义上来说,如果您想在一个新的应用程序中使用 logwatch 功能的话,只需要为这个应用程序的日志文件编写一个日志处理脚本(使用 Perl 语言),然后挂接到 logwatch 上就行。

logwatch 有一点不好的就是,在它生成的报告中没有详细的时间戳信息,而原来的日志文件中是存在的。您只能知道被记录下来的一段时间之内的特定事件,如果想要知道精确的时间点的信息,就不得不去查看原日志文件了。

安装 Logwatch

在 Debian 系统或其派生的系统上:

# aptitude install logwatch

在基于 Red Hat 的发布系统上:

# yum install logwatch

配置 Logwatch

安装时,主要的配置文件(logwatch.conf)被放到 /etc/logwatch/conf 目录中。此文件(默认是空的)定义的设置选项会覆盖掉定义在 /usr/share/logwatch/default.conf/logwatch.conf 文件中的系统级设置。

在命令行中,启动 logwatch, 如果不带参数的话,将会使用 /etc/logwatch/conf/logwatch.conf 文件中定义的选项。但,只要一指定参数,它们就会覆盖 /etc/logwatch/conf/logwatch.conf 文件中的任意默认/自定义设置。

这篇文章里,我们会编辑 /etc/logwatch/conf/logwatch.conf 文件来对一些默认的设置项做些个性化设置。

Detail = 

“Detail” 配置指令控制着 logwatch 报告的详细程度。它可以是个正整数,也可以是分别代表着10、5和0数字的 High、Med、Low 几个选项。

MailTo = youremailaddress@yourdomain.com

如果您让把一份 logwatch 的报告邮件给您,就要使用 “MailTo” 这个配置指令。要把一份报告发送给多个用户,只需要把他们的邮件地址用空格格开,然后配置上去。但是,您需要在 logwatch 运行的服务器上配置好本地邮件传输代理(MTA)如,sendmail、 Postfix 等,这个配置指令项才能起作用。

Range = 

“Range” 配置指令定义了生成 logwatch 报告的时间段信息。这个指令通常可选的值是 Yesterday、Today、All。当作用了“Rang = All”时,“Archive = yes” 这个指令项也必须配置上,那么所有的已存档的日志文件 (比如,/var/log/maillog、/var/log/maillog.X 或 /var/log/maillog.X.gz 文件)都会被处理到。

除了这些通用的 range 值,您也可以使用复杂点的选择值,如下所示:

  • Range = “2 hours ago for that hour”
  • Range = “-5 days”
  • Range = “between -7 days and -3 days”
  • Range = “since September 15, 2014”
  • Range = “first Friday in October”
  • Range = “2014/10/15 12:50:15 for that second”

要使用上面例子中自由形式的 range,您需要从 CPAN(注:Comprehensive Perl Archive Network) 上下载安装 Perl 的 Date::Manip 模块。关于 CPAN 模块的安装说明,请请参阅此帖

Service = 
Service = 
. . .

“Service” 选项指定想要监控的一个或多个服务。在 /usr/share/logwatch/scripts/services 目录下列出的服务都能被监控,它们已经涵盖了重要的系统服务(例如:pam,secure,iptables,syslogd 等),也涵盖了一些像 sudo、sshd、http、fail2ban、samba等主流的应用服务。如果您想添加新的服务到列表中,得编写一个相应的日志处理 Perl 脚本,并把它放在这个目录中。

如果这个选项要用来选择特定的服务话,您需要把 /usr/share/logwatch/default.conf/logwatch.conf 文件中的 “Service = All ” 这一行注释掉。

Format = 

“Format” 配置指令定义了一份 logwatch 报告的格式(比如 text 或者 HTML)。

Output = 

“Output” 配置指令定义生成的 logwatch 报告要发送的目的地。它能被保存成文件(file),生成电子邮件(mail)或者是直接在屏幕上显示(stdout)。

用 Logwatch 来分析日志文件

要弄明白怎么使用 logwatch 来分析日志文件,可以参考下面的 logwatch.conf 文件例子:

Detail = High
MailTo = youremailaddress@yourdomain.com
Range = Today
Service = http
Service = postfix
Service = zz-disk_space
Format = html
Output = mail

使用这些设置,logwatch 将会处理三个应用服务(http、postfix 和 zz-disk_space)当天产生的日志,生成一份非常详细的 HTML 格式报告,然后邮件给您。

如果您不想个性化 /etc/logwatch/conf/logwatch.conf,您可以不修改此文件让其默认,然后在命令行里运行如下所示的命令。也会得到同样的输出。

# logwatch --detail 10 --mailto youremailaddress@yourdomain.com --range today --service http --service postfix --service zz-disk_space --format html --output mail

电子邮件发送的报告样子如图示:

Linux:Linux 系统中使用 logwatch 监控日志文件
Linux:Linux 系统中使用 logwatch 监控日志文件

这份电子邮件头部包含指向导航到报告细节的链接,在每个选中的服务细节,也会有“返回顶部”的链接。

接收人很少的情况下您可能会使用电子邮件发送报告这个选项。其它情况下,您可能会把让其生成为 HTML 格式的报告,这样每个想看这份报告的人都可以从网络共享里看到。只需要把上面例子中的配置做些修改就可以实现:

Detail = High
Range = Today
Service = http
Service = postfix
Service = zz-disk_space
Format = html
Output = file
Filename = /var/www/html/logs/dev1.html

同样的,也可以在命令行中运行如下的命令。

# logwatch --detail 10 --range today --service http --service postfix --service zz-disk_space --format html --output file --filename /var/www/html/logs/dev1.html

最后,让我们使用 cron 来配置 logwatch 的定时执行任务。下面的例子中,将会在每个工作日的下午 12:15 分运行 logwatch 调度任务。

# crontab -e

15 12 * * 1,2,3,4,5 /sbin/logwatch

希望这会有所帮助。欢迎到社区发表评论或分享自己的心得和体会!


via: http://xmodulo.com/monitor-log-file-linux-logwatch.html

作者:Gabriel Cánepa 译者:runningwater 校对:wxy

本文由 LCTT 原创翻译,Linux中国 荣誉推出

来源:https://linux.cn/article-4490-1.html

Linux:一些关于Java的句子

本文并没有什么新鲜的。我只是收集了一些不太重要的语句,但这些语句可能对初级程序员来说很重要。也就是些无聊的旧东西。

如果以下的这些你都知道的话,那么你比Java的了解已经超过了对一个平常的家庭主妇的了解。我不知道清楚所有的这些是否是有意义的。即使不知道其中的一些特性,你照样也可以成为一个相当不错的Java程序员。然而,本文中许多的新信息可能表明你还有很大的发展空间。

Java中有四种不同的访问类型(而不是三种)

这四种类型包括:private, package private (包访问权限,无修饰符,又叫default, 译者注)。如果你在类中定义一个元素时并不加任何访问类型修饰符,它将被默认设置为包访问权限(package private),而不是public或者protected。

Linux:一些关于Java的句子
Linux:一些关于Java的句子

Java有四个级别的访问类型。

从另一方面来说,如果在接口中,你不指定方法的访问修饰符,那么它将是public类型的。你也可以显式地指定它为public类型, 但这并不符合SONAR(一个开源代码质量管理平台,译者注)的代码质量管理思想。

Linux:一些关于Java的句子
Linux:一些关于Java的句子

访问类型是传递的

我的“在Java中允许选择性的在接口的方法中写public”的观点是一个技术错误。

同样你也可在接口的字段前写final,甚至是static。这说明这些字段可以是非静态或非final吗?不是的,接口中的字段中总是final和static的。

Protected和package private是不一样的

Package private(或者default)访问类型可以使得相同包(package)下其他类能够访问这些字段或方法。保护类型(protected)的方法和字段可以被相同包下的类使用(这和package private是一样的),同时它也可以被其他类使用,只要那个类继承了这个包含这些protected方法或字段的类。

Protected是可传递的

如果有三个包a、b、c,每个包都分别包含A、B、C类,而且B继承A,C继承B,那么C可以访问A中的protected字段和方法。

package a;
public class A {
    protected void a() {
    }
}
package b;
import a.A;
public class B extends A {
    protected void b() {
        a();
    }
}
package c;
import b.B;
public class C extends B {
    protected void c() {
        a();
    }
}

接口不能定义protected方法

很多人认为可以在接口中定义protected方法。如果你这么做的话,编译器很快就会毫不留情地给你报错。顺便说下,这也就是我为什么认为允许public关键字在接口中是一个技术错误,它会让人觉得还可以写其他访问类型似的。

Linux:一些关于Java的句子
Linux:一些关于Java的句子

private是一种新的public

如果你还想在一个接口的方法中声明protected方法,你可能还不理解封装的含义。

此private非彼private

私有变量和方法在编译单元内是可见的。如果这听起来太神秘的话,换种说法:几乎就是在同一个Java文件中。这比“在它们被定义的类中”听起来好理解些。它们在同一编译单元的类和接口中也是可见的。嵌套类可以看到类中封装的私有字段和方法。然而,当前封闭类也可以看到该类下任何深度下类中的私有方法和字段。

package a;
class Private {
    private class PrivateInPrivate {
        private Object object;
    }
    Object m() {
        return new PrivateInPrivate().object;
    }
}

后者并不广为人知,事实上也很少有用到。

Private是类的访问级别而不是对象

如果你可以访问一个变量或方法,那么不管它属于哪个对象你都可以访问它。如果this.a可以访问到,那another.a也可以访问到,只要它们是同一个类的实例。同一个类的实例对象可以随意调用其他实例的变量或方法。不过这样的代码一般都没有意义。现实生活中异常是equals()(由Eclipse生成, 15 – 18行):

package a;
public class PrivateIsClass {
    private Object object;
    @Override
    public boolean equals(Object obj) {
        if (this == obj)
            return true;
        if (obj == null)
            return false;
        if (getClass() != obj.getClass())
            return false;
        PrivateIsClass other = (PrivateIsClass) obj;
        if (object == null) {
            if (other.object != null)
                return false;
        } else if (!object.equals(other.object))
            return false;
        return true;
    }
}

静态(static)类可能有很多实例

Linux:一些关于Java的句子
Linux:一些关于Java的句子

访问类型不是对象级别的而是类级别的。

那些不支持有任何实例的类,通常被称为实用工具类。它们只包含静态字段和静态方法以及唯一的不被该类的任何静态方法调用的私有构造函数。在Java 8中也可以有这样的一个野兽(这个词翻译不通,译者注)在接口中实现,因为Java 8的接口可以有静态方法。我不觉得我们应该使用这个特性而不是实用工具类。我也不完全确信我们应该使用实用工具类。

静态类总是在另一个类或接口中。它们是嵌套类。他们是静态的,就像静态方法不能访问类的实例方法和字段一样,静态内部类也不能访问嵌入类的实例方法和字段。这是因为内部类没有嵌入类实例的引用(或者说是指针,如果你喜欢这么叫的话)。内部类(内部类,也即非静态嵌套类, 译者注),而非静态嵌套类, 没有嵌入类的一个实例,它是无法被创建的。每个内部类的实例都具有嵌入类实例的一个引用,因此一个内部类可以访问嵌入类的实例方法和字段。

因为这个原因,要是没有外部类的一个实例,你就不能创建一个内部类。当然,如果是当前对象,也就是this的话,你就可以不需要指定它。在这种情况下你可以使用new, 在这种情况下,也就是this.new的简式。在一个静态的环境中,例如从一个静态方法,你必须指定内部类应该创建哪个封闭类的实例。见第10行:

package a;
class Nesting {
    static class Nested {}
    class Inner {}
    void method(){
        Inner inner = new Inner();
    }
    static void staticMethod(){
        Inner inner = new Nesting().new Inner();
    }
}

匿名类只能访问final变量

Variable has to be effective final

变量必须是有效的final

当一个匿名类被定义在一个方法中,它可以访问局部变量如果该变量是final的。但这说的有点模糊。它们不得不声明成final,他们还必须是有效final。这也是Java 8中发布的一些特性。你不需要声明这些变量为final型,但它们仍然必须是有效的final。

Java 8 does not require final, only effective final

Java 8并不要求final,只要求有效final。

为什么你需要对一些东西声明final,当它被检查必须是这样的。就像方法的参数。它们也必须是final的。你说这不是Java所必须的吗?嗯,你是对的。这只是一个良好的编程风格所必须的。


via: http://www.javacodegeeks.com/2014/11/some-sentences-about-java.html

作者:Peter Verhas 译者:a598799539 校对:wxy

本文由 LCTT 原创翻译,Linux中国 荣誉推出

来源:https://linux.cn/article-4491-1.html

Linux:使用 smem 可视化显示Linux内存使用情况

物理内存不足对Linux桌面系统和服务器系统的性能影响都很大。当你的计算机变慢时,要做的第一件事就是释放内存。尤其是在多用户环境以及执行关键任务的服务器环境下,内存消耗会变得更加关键,因为多个用户和应用线程会同时竞争更多的内存空间。

Linux:使用 smem 可视化显示Linux内存使用情况
Linux:使用 smem 可视化显示Linux内存使用情况

如果要监测系统内各种资源的使用情况(比如说CPU或内存),图形化显示是一种高效的方法,通过图形界面可以快速分析各用户和进程的资源消耗情况。本教程将给大家介绍在linux下图形化分析内存使用情况的方法,使用到命令行工具是smem.

物理内存使用情况: RSS 、 PSS 和 USS

由于Linux使用到了虚拟内存(virtual memory),因此要准确的计算一个进程实际使用的物理内存就不是那么简单。 只知道进程的虚拟内存大小也并没有太大的用处,因为还是无法获取到实际分配的物理内存大小。

  • RSS(Resident set size),使用top命令可以查询到,是最常用的内存指标,表示进程占用的物理内存大小。但是,将各进程的RSS值相加,通常会超出整个系统的内存消耗,这是因为RSS中包含了各进程间共享的内存。
  • PSS(Proportional set size)会更准确一些,它将共享内存的大小进行平均后,再分摊到各进程上去。
  • USS(Unique set size )是PSS中自己的部分,它只计算了进程独自占用的内存大小,不包含任何共享的部分。

安装Smem

smem是一个能够生成多种内存耗用报告的命令行工具,它从/proc文件系统中提取各进程的PSS/USS信息,并进行汇总输出。它还内建了图表的生成能力,所以能够方便地分析整个系统的内存使用情况。

在Debian, Ubuntu 或 Linux Mint 上安装smem

$ sudo apt-get install smem

在Fedora 或 CentOS/RHEL上安装Smem

在CentOS/RHEL上,你首先得启用EPEL仓库。

$ sudo yum install smem python-matplotlib

使用smem检查内存使用情况

你可以在非特权模式下使用smem,它能够显示当前用户运行的所有进程的内存使用情况,并按照PSS的大小进行排序。

$ smem
Linux:使用 smem 可视化显示Linux内存使用情况
Linux:使用 smem 可视化显示Linux内存使用情况

如有你想得到整个系统中所有用户的内存使用情况,就需要使用root权限来运行smem。

$ sudo smem
Linux:使用 smem 可视化显示Linux内存使用情况
Linux:使用 smem 可视化显示Linux内存使用情况

也可以按用户维度来输出报告:

$ sudo smem -u
Linux:使用 smem 可视化显示Linux内存使用情况
Linux:使用 smem 可视化显示Linux内存使用情况

smem提供了以下选项来对输出结果进行筛选,支持按映射方式(mapping)、进程和用户三个维度的筛选:

  • -M <正则表达式>
  • -P <正则表达式>
  • -U <正则表达式>

想了解smem更多的使用方式,可以查询用户手册(man page)。

使用smem图形化显示内存使用情况

图形化的报告使用起来会更加方便快捷。smem支持两种格式的图形显示方式:直方图和饼图。

下面是一些图形化显示的实例。

下面的命令行会基于PSS/RSS值,生成直方图,以用户alice为例。

$ sudo smem --bar name -c "pss uss" -U alice
Linux:使用 smem 可视化显示Linux内存使用情况
Linux:使用 smem 可视化显示Linux内存使用情况

这个例子会生成一张饼图,图中显示了系统中各进程的PSS内存使用量:

$ sudo smem --pie name -c "pss"
Linux:使用 smem 可视化显示Linux内存使用情况
Linux:使用 smem 可视化显示Linux内存使用情况

概括来说,smem是一个方便易用的内存分析工具。利用smem的格式化输出,你可以对内存使用报告进行自动化分析,并执行一些自动化的处理措施。如果你还知道其他的一些优秀的内存检测工具,请在留言区告诉我。


via: http://xmodulo.com/visualize-memory-usage-linux.html

作者:Dan Nanni 译者:coloka 校对:wxy

本文由 LCTT 原创翻译,Linux中国 荣誉推出

来源:https://linux.cn/article-4492-1.html

Linux:如何不使用DBCA在Oracle 11中删除数据库

本文简短的教程,将会向你展示如何不使用DBCA(数据库配置助手)在Oracle 11中删除数据库。

Linux:如何不使用DBCA在Oracle 11中删除数据库
Linux:如何不使用DBCA在Oracle 11中删除数据库

1- 导入数据库的SID,如果没有定义的话

export ORACLE_SID=database

2- 以操作系统认证连接数据库

[oracle@Oracle11 ~]$ sqlplus / as sysdba
SQL*Plus: Release 11.2.0.1.0 Production on Mon Dec 1 17:38:02 2014
Copyright (c) 1982, 2009, Oracle. All rights reserved.
Connected to an idle instance.

3- 启动数据库实例

SQL> startup
ORACLE instance started.
Total System Global Area 3340451840 bytes
Fixed Size 2217952 bytes
Variable Size 1828718624 bytes
Database Buffers 1493172224 bytes
Redo Buffers 16343040 bytes
Database mounted.
Database opened.

4- 关闭数据库

SQL> shutdown immediate;
Database closed.
Database dismounted.
ORACLE instance shut down.

5- 启动独占模式

SQL> startup mount exclusive restrict
ORACLE instance started.
Total System Global Area 3340451840 bytes
Fixed Size 2217952 bytes
Variable Size 1828718624 bytes
Database Buffers 1493172224 bytes
Redo Buffers 16343040 bytes
Database mounted.

6- 删除数据库

SQL> drop database;

Database dropped. Disconnected from Oracle Database 11g Enterprise Edition Release 11.2.0.1.0 - 64bit Production With the Partitioning, OLAP, Data Mining and Real Application Testing options

完成!


via: http://www.unixmen.com/drop-database-oracle-11-without-using-dcba/

作者:M.el Khamlichi 译者:VicYu/Vic020 校对:wxy

本文由 LCTT 原创翻译,Linux中国 荣誉推出

来源:https://linux.cn/article-4493-1.html

Linux:如何在Linux下使用rsync

对于各种组织和公司,数据对他们是最重要的,即使对于电子商务,数据也是同样重要的。Rsync是一款通过网络备份重要数据的工具/软件。它同样是一个在类Unix和Window系统上通过网络在系统间同步文件夹和文件的网络协议。Rsync可以复制或者显示目录并复制文件。Rsync默认监听TCP 873端口,通过远程shell如rsh和ssh复制文件。Rsync必须在远程和本地系统上都安装。

Linux:如何在Linux下使用rsync
Linux:如何在Linux下使用rsync

rsync的主要好处是:

速度:最初会在本地和远程之间拷贝所有内容。下次,只会传输发生改变的块或者字节。

安全:传输可以通过ssh协议加密数据。

低带宽:rsync可以在两端压缩和解压数据块。

语法:

#rsysnc [options] source path destination path

示例: 1 – 启用压缩

[root@localhost /]# rsync -zvr /home/aloft/ /backuphomedir
building file list ... done
.bash_logout
.bash_profile
.bashrc
sent 472 bytes received 86 bytes 1116.00 bytes/sec
total size is 324 speedup is 0.58

上面的rsync命令使用了-z来启用压缩,-v是可视化,-r是递归。上面在本地的/home/aloft/和/backuphomedir之间同步。

示例: 2 – 保留文件和文件夹的属性

[root@localhost /]# rsync -azvr /home/aloft/ /backuphomedir
building file list ... done
./
.bash_logout
.bash_profile
.bashrc
sent 514 bytes received 92 bytes 1212.00 bytes/sec
total size is 324 speedup is 0.53

上面我们使用了-a选项,它保留了所有人和所属组、时间戳、软链接、权限,并以递归模式运行。

示例: 3 – 同步本地到远程主机

root@localhost /]# rsync -avz /home/aloft/ azmath@192.168.1.4:192.168.1.4:/share/rsysnctest/
Password:
building file list ... done
./
.bash_logout
.bash_profile
.bashrc
sent 514 bytes received 92 bytes 1212.00 bytes/sec
total size is 324 speedup is 0.53

上面的命令允许你在本地和远程机器之间同步。你可以看到,在同步文件到另一个系统时提示你输入密码。在做远程同步时,你需要指定远程系统的用户名和IP或者主机名。

示例: 4 – 远程同步到本地

[root@localhost /]# rsync -avz azmath@192.168.1.4:192.168.1.4:/share/rsysnctest/ /home/aloft/
Password:
building file list ... done
./
.bash_logout
.bash_profile
.bashrc
sent 514 bytes received 92 bytes 1212.00 bytes/sec
total size is 324 speedup is 0.53

上面的命令同步远程文件到本地。

示例: 5 – 找出文件间的不同

[root@localhost backuphomedir]# rsync -avzi /backuphomedir /home/aloft/
building file list ... done
cd+++++++ backuphomedir/
>f+++++++ backuphomedir/.bash_logout
>f+++++++ backuphomedir/.bash_profile
>f+++++++ backuphomedir/.bashrc
>f+++++++ backuphomedir/abc
>f+++++++ backuphomedir/xyz
sent 650 bytes received 136 bytes 1572.00 bytes/sec
total size is 324 speedup is 0.41

上面的命令帮助你找出源地址和目标地址之间文件或者目录的不同。

示例: 6 – 备份

rsync命令可以用来备份linux。

你可以在cron中使用rsync安排备份。

0 0 * * * /usr/local/sbin/bkpscript &> /dev/null

vi /usr/local/sbin/bkpscript
rsync -avz -e ‘ssh -p2093′ /home/test/ root@192.168.1.150:/oracle/data/

via: http://linoxide.com/how-tos/rsync-copy/

作者:Bobbin Zachariah 译者:geekpi 校对:wxy

本文由 LCTT 原创翻译,Linux中国 荣誉推出

来源:https://linux.cn/article-4503-1.html

Linux:systemd的运行级别与服务管理命令简介

Linux:systemd的运行级别与服务管理命令简介
Linux:systemd的运行级别与服务管理命令简介

从很久很久以前我们就在使用静态运行级别。而systemd提供了更为动态灵活的机制,来管控你的系统。

在开始介绍systemd命令前,让我们先简单的回顾一下历史。在Linux世界里,有一个很奇怪的现象,一方面Linux和自由软件(FOSS)在不断的向前推进,另一方面人们对这些变化却不断的抱怨。这就是为什么我要在此稍稍提及那些反对systemd所引起的争论的原因,因为我依然记得历史上有不少类似的争论:

  • 软件包(Pacakge)是邪恶的,因为真正的Linux用户会从源码构建他所想要的的一切,并严格的管理系统中安装的软件。
  • 解析依赖关系的包管理器是邪恶的,真正的Linux用户会手动解决这些该死的依赖关系。
  • apt-get总能把事情干好,所以只有Yum是邪恶的。
  • Red Hat简直就是Linux中的微软。
  • 好样的,Ubuntu!
  • 滚蛋吧,Ubuntu!

诸如此类…就像我之前常常说的一样,变化总是让人沮丧。这些该死的变化搅乱了我的工作流程,这可不是一件小事情,任何业务流程的中断,都会直接影响到生产力。但是,我们现在还处于计算机发展的婴儿期,在未来的很长的一段时间内将会持续有快速的变化和发展。想必大家应该都认识一些因循守旧的人,在他们的心里,商品一旦买回家以后就是恒久不变的,就像是买了一把扳手、一套家具或是一个粉红色的火烈鸟草坪装饰品。就是这些人,仍然在坚持使用Windows Vista,甚至还有人在使用运行Windows 95的老破烂机器和CRT显示器。他们不能理解为什么要去换一台新机器。老的还能用啊,不是么?

这让我回忆起了我在维护老电脑上的一项伟大的成就,那台破电脑真的早就该淘汰掉。从前我有个朋友有一台286的老机器,安装了一个极其老的MS-DOS版本。她使用这台电脑来处理一些简单的任务,比如说约会、日记、记账等,我还用BASIC给她写了一个简单的记账软件。她不用关注任何安全更新,是这样么?因为它压根都没有联网。所以我会时不时给她维修一下电脑,更换电阻、电容、电源或者是CMOS电池什么的。它竟然还一直能用。它那袖珍的琥珀CRT显示器变得越来越暗,在使用了20多年后,终于退出了历史舞台。现在我的这位朋友,换了一台运行Linux的老Thinkpad,来干同样的活。

前面的话题有点偏题了,下面抓紧时间开始介绍systemd。

运行级别 vs. 状态

SysVInit使用静态的运行级别来构建不同的启动状态,大部分发布版本中提供了以下5个运行级别:

  • 单用户模式(Single-user mode)
  • 多用户模式,不启动网络服务(Multi-user mode without network services started)
  • 多用户模式,启动网络服务(Multi-user mode with network services started)
  • 系统关机(System shutdown)
  • 系统重启(System reboot)

对于我来说,使用多个运行级别并没有太大的好处,但它们却一直在系统中存在着。 不同于运行级别,systemd可以创建不同的状态,状态提供了灵活的机制来设置启动时的配置项。这些状态是由多个unit文件组成的,状态又叫做启动目标(target)。启动目标有一个清晰的描述性命名,而不是像运行级别那样使用数字。unit文件可以控制服务、设备、套接字和挂载点。参考下/usr/lib/systemd/system/graphical.target,这是CentOS 7默认的启动目标:

[Unit]
Description=Graphical Interface
Documentation=man:systemd.special(7)
Requires=multi-user.target
After=multi-user.target
Conflicts=rescue.target
Wants=display-manager.service
AllowIsolate=yes
[Install]
Alias=default.target

现在再看看unit文件长什么样? 我来给大家找个例子。 unit文件存放在下面的两个目录下:

  • /etc/systemd/system/
  • /usr/lib/systemd/system/

我们可以修改第一个目录中的文件来进行自定义配置,而第二个目录中的文件是包安装时保存的备份。/etc/systemd/system/的优先级高于/usr/lib/systemd/system/。不错,用户优先级高于机器。下面是Apache Web server的unit文件:

[Unit]
Description=The Apache HTTP Server
After=network.target remote-fs.target nss-lookup.target
[Service]
Type=notify
EnvironmentFile=/etc/sysconfig/httpd
ExecStart=/usr/sbin/httpd/ $OPTIONS -DFOREGROUND
ExecReload=/usr/sbin/httpd $OPTIONS -k graceful
ExecStop=/bin/kill -WINCH ${MAINPID}
KillSignal=SIGCONT
PrivateTmp=true
[Install]
WantedBy=multi.user.target

就算是对于新手而言,上面的文件也是非常简单易懂的。这可比SysVInit的init文件要简单多了,为了便于比较,下面截取了/etc/init.d/apache2的一个片段:

SCRIPTNAME="${0##*/}"
SCRIPTNAME="${SCRIPTNAME##[KS][0-9][0-9]}"
if [ -n "$APACHE_CONFDIR" ] ; then
    if [ "${APACHE_CONFDIR##/etc/apache2-}" != "${APACHE_CONFDIR}" ] ; then
            DIR_SUFFIX="${APACHE_CONFDIR##/etc/apache2-}"
    else
            DIR_SUFFIX=

整个文件一共有410行。

你可以检查unit文件的依赖关系,我常常被这些复杂的依赖关系给吓到:

$ systemctl list-dependencies httpd.service

cgroups

cgroups,或者叫控制组,在Linux内核里已经出现好几年了,但直到systemd的出现才被真正使用起来。The kernel documentation中是这样描述cgroups的:“控制组提供层次化的机制来管理任务组,使用它可以聚合和拆分任务组,并管理任务组后续产生的子任务。”换句话说,它提供了多种有效的方式来控制、限制和分配资源。systemd使用了cgroups,你可以便捷的查看它,使用下面的命令可以展示你系统中的整个cgroup树:

$ systemd-cgls

你可以使用ps命令来进行查看cgroup树:

$ ps xawf -eo pid,user,cgroup,args

常用命令集

下面的命令行展示了如何为守护进程重新装载配置文件,注意不是systemd服务文件。 使用这个命令能够激活新的配置项,且尽可能少的打断业务进程,下面以Apache为例:

# systemctl reload httpd.service

重新装载服务文件(service file)需要完全停止和重新启动服务。如果服务挂死了,用下面的命令行可以恢复它:

# systemctl restart httpd.service

你还可以用一个命令重启所有的守护进程。这个命令会重新装载所有守护进程的unit文件,然后重新生成依赖关系树:

# systemctl daemon-reload

在非特权模式下,你也可以进行重启、挂起、关机操作:

$ systemctl reboot
$ systemctl suspend
$ systemctl poweroff

按照惯例,最后给大家介绍一些systemd的学习材料。Here We Go Again, Another Linux Init: Intro to systemdUnderstanding and Using Systemd 是不错的入门材料,这两份文档里会链接到更多其他资源。


via: http://www.linux.com/learn/tutorials/794615-systemd-runlevels-and-service-management

作者:Carla Schroder 译者:coloka 校对:wxy

本文由 LCTT 原创翻译,Linux中国 荣誉推出

来源:https://linux.cn/article-4505-1.html

Linux:DevOps系统的变迁

Linux:DevOps系统的变迁
Linux:DevOps系统的变迁

一、DevOps的起源和发展历程

在过去的几十年里,为了按时交付软件产品和服务,大家越来越意识到,对于传统把开发和运营割裂开的做法,不适合现代产品和服务开发的需求。于是,把 开发和运营作为整体来看待的DevOps工程思想逐步深入人心,随之也逐步有了对DevOps系统的需求,希望能有个平台或工具来统一支持开发和运营的交 付工作及之后的环境管理工作,即需要一系列的持续集成,持续交付,自动化部署,自动化测试监控,自动化伸缩,自动化恢复系统,以提升开发测试运营过程中的 部署效率,简化开发测试运维过程的管理,降低交付风险,降低沟通成本及运营成本。

Linux:DevOps系统的变迁
Linux:DevOps系统的变迁

从广义来讲,不管是云管理平台工具(比如RightScale),还是各种PaaS平台(CloudFoundry,Heroku etc.),还是自动化部署工具比如Chef、Puppet和Ansible等,其本质上都是DevOps系统的一部分,都是为了解决在开发过程的交付环 节问题和交付后的运营管理问题,即

  • 在开发和测试过程中,帮助开发测试人员搭建和管理环境,以便在变更后部署变更以测试;
  • 在运营和支持过程中,帮助运营支持人员升级系统,扩展重建恢复系统,在升级后能够持续地掌握系统整体和各个栈的状态,从各个层面监控系统,伸缩系统,恢复系统。

这些年,随着云计算和容器技术的进步,以及产品业务对IT能力的需求推动,DevOps系统发展越来越快,其角色和概念也越来越清晰和独立。回顾其 发展的路径和变迁的过程,我们认为基本可以分为三代:基于物理机或独立虚拟机的部署时代,基于IaaS可编程资源的部署时代和基于容器的部署时代。随着这 三代的改进,DevOps系统的整体能力越来越强。下面我们首先看一下各代DevOps系统的特点和能力,之后再对DevOps系统进行更进一步的分类, 以帮助我们选择合适的DevOps系统。

二、DevOps的变迁及其关键使能技术

1. 基于物理机/独立虚机的部署时代

这是第一代DevOps系统,特点是静态配置 + 人工协调 + 仅应用部分自动部署。

在搭建整个应用系统的过程中,首先需要在DevOps系统外创建运行应用所需的资源环境(如主机,网络,存储等),DevOps系统对这部分没有控 制,只负责在资源环境搭建好后自动化部署应用,资源环境的搭建与之后的应用部署过程是割裂开来的,需要人为的手工协调控制,即等资源环境搭建好后,由人控 制时机,等待资源环境准备好后再手工修改配置(如各种主机IP地址,登陆密码Key信息),然后手工运行自动化脚本工具,如 Shell,Python,Ruby脚本,进行应用的安装部署升级,而且之后当增加或减少节点后,也由人来手工运行自动化脚本来配置系统,不能实现包括资 源环境创建或节点变更到应用部署的整个过程的一键部署,即集群感知 + 自动协调控制 + 动态配置 + 全栈自动化。

Linux:DevOps系统的变迁
Linux:DevOps系统的变迁

目前,可以说大多数的DevOps系统仍然停留在这个阶段,由于DevOps系统没有实现资源环境创建的自动化与基于集群感知的协调自动化,那么这个阶段的DevOps系统的能力会造成以下几个影响和后果:

  • 创建系统资源环境效率低、耗时、风险高,特别是创建复杂的系统组件多结构复杂时;
  • 创建系统资源环境过程需要专门的网络工程师、系统工程师,不能够实现开发测试运维人员自助服务,系统越复杂,沟通成本越大,开发运维过程管理也越复杂;
  • 创建整个系统需要网络工程师,系统工程师,开发人员的共同参与和合作,系统组件越多结构越复杂,沟通成本越大,开发运维过程管理也越复杂,费时费力,协调麻烦,风险高且易出错;
  • 当系统资源环境变更时,如在增加减少主机后,由人来手工协调控制,人为手工静态配置部署升级所需IP,登陆密码或Key等信息,造成变更过程风险高且效率低,特别是系统庞大和复杂时;
  • 交付过程风险高,开发测试产品各个环境不统一,经常出现在一个环境里运行正常,另外一个环境不正常的现象

这里需要提的一点就是,尽管很多组织已经在使用IaaS(如阿里云)创建虚拟机搭建应用系统所需资源环境,但是并没有实现集群感知,系统整套环境创 建的自动化,仍然停留在半自动化的阶段(例如,先启动一组包年包月虚拟机后,然后手工配置部署脚本所需IP地址,登陆密码,登陆密钥等信息,然后手工运行 自动化脚本部署),所以这种方式仍然属于第一代的DevOps系统。同时,这也是国内大多数组织DevOps的现状,其自动化和效率的改进空间巨大。

2. 基于IaaS的部署时代

这是第二代DevOps系统,特点是集群感知 + 自动协调控制 + 动态配置 + 全栈自动化。

借助于云计算IaaS资源的可编程特性,这一代的DevOps系统实现了集群感知,自动协调控制,动态配置,全栈自动化,即实现了从创建环境到部署 安装应用组件整个过程的一键创建和部署,并且在创建后的阶段,能够实现集群感知(Cluster-Aware),即自动根据环境的变更,自动部署和配置系 统。举个例子,某网站业务量增长需要扩容时,当人为添加Web计算节点后,能够自动在新添加Web虚拟机启动后安装Web组件,并将各个虚拟机Web服务 注册配置到负载均衡服务中,当收缩时,自动移除,这个过程不需要人为的协调控制,DevOps系统能够根据集群的变化自动地配置集群。

Linux:DevOps系统的变迁
Linux:DevOps系统的变迁

目前,做到这个层面DevOps系统还是比较少的,由于这个阶段的DevOps系统自动化管理覆盖了环境的创建变更,应用组件部署自动化,以及环境 创建,集群感知和应用组件部署的各个过程自动化协调控制,那么这个阶段的DevOps系统相比第一代会给开发和运维工作带来以下非常巨大的改进:

  • 开发测试运维人员能够自助创建环境和部署系统,系统越复杂,沟通成本减少越多,开发运维过程管理复杂性风险减少越多,比如只能由有专门知识的工程师做,如果工程师在需要的时候不可用,就很麻烦;
  • 创建环境和部署效率高,自动化,快速,所需时间少,风险低;
  • 当系统资源环境变更时,如伸缩时,在增加减少主机后,能够实现集群感知,动态配置集群,提高变更过程效率且降低风险,特别是系统组件多庞大和复杂时;
  • 能够按需快速创建环境满足各种测试,演示,上线扩容需要
  • 能够按需创建启动关闭开发测试环境,节约成本
  • 能够提高开发测试和交付的效率

3. 基于容器的部署时代

这是第三代DevOps系统,特点是在第二代基础上,又增加了应用跨云可迁移性(基于容器技术)。

借助于云计算IaaS资源的可编程特性以及Linux容器技术,不仅实现了集群感知,自动化协调,动态配置和全栈自动化,而且实现了应用跨云可迁移 性和弹性伸缩,消除了开发,测试,生产环境的不一致,使应用不会被锁定在某个IaaS上,让所有的基础设施服务IaaS及物理机都变成通用的资源池,还可 以提高资源利用率,这给IT的开发建设和运营带来了更多更大的想象空间,这也是Docker,Kubernetes现在很火的原因。

举个例子: 如果我们想把一套服务从AWS迁移到Azure上,那么,我们将不得不从头开始创建一组虚拟机镜像及虚拟机,并配置安装系统或应用的组件,如果系统复杂庞 大的话,这个过程仍然会耗费很多的时间和人工,并且依赖于某些具备这个知识的工程师,但是如果有容器技术及相关容器工具的支持,那么这个过程会变成一个非 常快速简单的过程,变成在目标云如Azure上自动启动需要的标准虚拟机,然后下载容器镜像,配置启动容器,配置相关DNS等,真正实现方便的跨云迁移, 和弹性动态的伸缩服务。

再举个例子,目前Google开源的容器管理系统Kubernetes可以说得到了工业界的广泛认同和支持,当我们已经做好应用系统的Docker images后,那么只要在各个不同的IaaS上有支持Docker的环境,如Kubernetes集群,那么我们就能在不同的IaaS上快速方便的迁移 应用系统,或者扩容,下图展示了基于FIT2CLOUD的跨云部署和管理解决方案,我们希望未来用户可以使用FIT2CLOUD在多个不同的IaaS上创 建Kubernetes集群,通过Kubernetes管理和部署应用系统。之后,我们会有新文章来分享FIT2CLOUD是如何创建和运维 Kunerbetes集群的。

Linux:DevOps系统的变迁
Linux:DevOps系统的变迁

上面这一节中我们介绍了不同时代的DevOps系统的特点和能力,那么是不是我们直接选择能力最强的第三代DevOps系统就可以了吗? 是不是选一种DevOps系统就通杀了呢? 答案是否定的,每种DevOps系统都不是银弹,都需要我们根据要管理的系统的需求来选择合适的DevOps系统或工具,在接下来的一节,我们来回答这个 问题。

三、如何选择适合自己的DevOps系统?

目前DevOps系统可以说五花八门非常多,功能上差别大,适用场景也不同,那么我们究竟该如何选择合适的DevOps系统呢? 这里我们建议一种基于目标系统分类的选择方法。我们根据要管理的目标应用或系统类型来分类,对于目标系统,我们可以将其首先分为三大类,即IaaS服务系 统,PaaS服务系统,应用系统,应用系统又可以分为简单的Web应用系统,复杂的分布式系统,那么有了这个分类,我们选择DevOps系统和工具就会相 对容易和明确一些。

1. IaaS服务系统

由于IaaS系统的创建,本身就是基于物理机创建的,所以对于这类的系统,其适用的DevOps系统或工具就是Shell,Chef, Puppet及IaaS服务提供商自身开发的自动化运维管理系统,只能选用第一代的基于物理机的DevOps系统。

2. PaaS服务系统

如果一个PaaS不是部署在IaaS之上,从本质上说这不是一个PaaS,因为其不具备弹性和自动伸缩。真正的PaaS系统是部署在IaaS上,为 开发测试运维人员来提供服务,那么其适用的DevOps工具就可以选用 RightScale,Scalr,Cloudformation,Opsworks和FIT2CLOUD这类第二代基于IaaS可编程资源的 DevOps系统,当然也可以选择第三代基于容器的DevOps系统,只是第三代的目前还在发展中,还不如第二代成熟。

3. 简单的Web应用系统

对于简单的Web应用系统,突出的特点就是应用的结构简单,比如只包含一个Web组件及数据库,缓存,或一些常见的中间件服务等,没有包含非常多的 分布式组件,那么对于这类的系统可以选择容器类的传统PaaS,即CloudFoundry,Heroku,OpenShift等。

4. 复杂的分布式应用系统

对于复杂的分布式应用系统,无法使用容器类PaaS来管理,只能通过自定义的DevOps工具或系统,或者使用云管理 RightScale,Scalr,Cloudformation,Opsworks,FIT2CLOUD这类工具的某种或某种组合,即第二代基于 IaaS可编程资源的DevOps系统,也可以选择第三代基于容器的DevOps系统。因为这类工具给用户提供了对IaaS主机更大的控制权,且提供了各 个部署过程中的回调接口,实现了集群感知及各个部署过程的自动协调控制,即全栈自动化。

以上是我们对DevOps系统变迁的一些思考,大家通过微博和我们进行讨论,我们的微博是:@fit2cloud

来源:http://blog.fit2cloud.com/2014/12/14/devops-system-evolution.html

Linux:Linux中使用rsync——文件和目录排除列表

rsync是一个十分有用,而且十分流行的linux工具。它用于备份和恢复文件,也用于对比和同步文件。我们已经在前面的文章讲述了如何在Linux下使用rsync,而今天我们将增加一些更为有用的rsync使用技巧。

Linux:Linux中使用rsync——文件和目录排除列表
Linux:Linux中使用rsync——文件和目录排除列表

排除文件和目录列表

有时候,当我们做大量同步的时候,我们可能想要从同步的文件和目录中排除一个文件和目录的列表。一般来说,像设备文件和某些系统文件,或者像临时文件或者缓存文件这类占据不必要磁盘空间的文件是不合适同步的,这类文件是我们需要排除的。

首先,让我们创建一个名为“excluded”的文件(当然,你想取什么名都可以),然后将我们想要排除的文件夹或文件写入该文件,一行一个。在我们的例子中,如果你想要对根分区进行完整的备份,你应该排除一些在启动时创建的设备目录和放置临时文件的目录,列表看起来像下面这样:

rsync excluded

然后,你可以运行以下命令来备份系统:

$ sudo rsync -aAXhv --exclude-from=excluded / /mnt/backup

rsync exclude file

从命令行排除文件

你也可以从命令行直接排除文件,该方法在你要排除的文件数量较少,并且在你想要将它写成脚本或加到crontab中又不想脚本或cron依赖于另外一个文件运行时十分有用。

例如,如果你想要同步/var到一个备份目录,但是你不想要包含cache和tmp这些通常不会有重要内容的文件夹,你可以使用以下命令:

$ sudo rsync -aAXhv --exclude={"/var/cache","/var/tmp"} /var /home/adrian/var

rsync exclude

该命令易于在脚本或cron中使用,也不会依赖其它文件。


via: http://linoxide.com/linux-command/exclude-files-rsync-examples/

作者:Adrian Dinu 译者:GOLinux 校对:wxy

本文由 LCTT 原创翻译,Linux中国 荣誉推出

来源:https://linux.cn/article-4504-1.html

Linux:24条 Docker 建议

TES GLOBAL,我们已经爱上Docker并从Docker的0.8版本开始就在生产环境中使用它。我们的很多开发者都参加了在DockerCon欧洲上的培训。下面是我们总结的一些tips,希望可以帮到已经有Docker基础的同学。

Linux:24条 Docker 建议
Linux:24条 Docker 建议

1. CLI

1.1 美化docker ps的输出

将Docker ps的输出通过管道到less -S,这样表格式的行就不会被折叠。

docker ps - a | less -S

1.2 刷新日志

docker的日志不会即时刷新,除非你使用了-F选项:

docker logs <containerid> -F

1.3 从docker inspect中获取一个单一的值

docker inspect默认会输出大量的JSON格式的数据。你可以用jq,来得到某一特定键的值。或者你可以使用内置的go模板功能:

最后一个docker容器现在运转正常吗?

docker inspect --format '{{.State.Running}}' $(docker ps -lq)

1.4 使用docker exec而不是sshd 或者 nsenter

如果你查看过Docker的发行版你会你会很清楚这个小技巧。exec在是在1.3版本中添加的新功能,可以让你在容器里面运行一个新的进程。这样你就不必运行sshd或者在主机上安装nscenter。

2. Dockerfiles

2.1 docker build支持git仓库

你不但可以从本地的Dockerfile中创建Docker镜像,你还可以简单的给docker build指定一个仓库的URL,然后docker build会为你做完余下的事情。

2.2 没有软件包列表

默认的镜像(如Ubuntu)是不包含软件包列表的,目的是让镜像体积更小。因此需要在任何的基础的Dockerfile中需要使用apt-get update。

2.3 留意软件包的版本

注意软件包的安装,因为这些命令也是会缓存起来的。意味着如果你清空了缓存,你可能会得到不同的版本;或者如果缓存长期不更新,你可能不会得到最新的安全更新。

2.4 小体积的基础镜像

在Docker Hub上有一个官方的真正零体积的Docker镜像,它的名字叫做scratch。所以如果你有这种需求,可以让你的镜像从零开始。而大多数的情况下,你最好还是从busybox开始,其大小只有2.5M。

2.5 FROM默认会获取最新的

如果在FROM关键字后你没有指定一个版本的tag,那么默认就会获取最新的。请注意这点,并确保尽可能的指定一个特定的版本。

2.6 shell或者是exec模式

在Dockerfile中可以通过两种方式来指定命令(如CMD RUN等)。如果你仅仅写下命令那么Docker会将其包裹在sh -c命令中执行。你也可以写成一个字符串数组的形式。数组的写法不需要依赖容器中的shell,因为其会使用go的exec。Docker的开发者建议使用后一种方式。

2.7 ADD vs COPY

ADD和COPY都能在创建容器的时候添加本地的文件。但是ADD有一些额外的魔力,如添加远程的文件、unzip或者untar一些文件包等。使用ADD之前请了解这种差别。

2.8 WORKDIR和ENV

每个命令都会创建一个新的临时镜像并在新的shell中运行,所以如果你在Dockerfile中不能运行 cd 或者export =。使用WORKDIR在多个命令中设置工作目录并使用ENV来设置环境变量。

2.9 CMD和ENTRYPOINT

CMD是当一个镜像在运行时默认会执行的命令。默认的ENTRYPOINT是/bin/sh -c,然后CMD会以参数的形式被传入。我们可以在Dockerfile中覆盖ENTRYPOINT以让我们的容器像在接受命令行参数(默认的参数在Dockerfile中的CMD指定)。

Dockerfile中

ENTRYPOINT /bin/ls
CMD ["-a"]

我们覆盖了命令行但是netrypoint仍然是ls

docker run training/ls -l

2.10 将ADD置于末尾

如果文件发生改变,ADD会让缓存失效。不要在Dockerfile中添加经常变化的东西,以避免让缓存失效。将你的代码放在最后,将库和依赖放在最前。对于Node.js的应用来说,这意味着将package.json放在前面,运行nmp install然后添加你的代码。

3. Docker的网络

Docker有一个内置的IP池,用来指定容器的ip地址。它对外是不可见的,通过桥接的网口可以访问到。

3.1 查找端口的映射

docker run接收显式的端口映射作为参数,或者你可以通过-P选项来映射所有的端口。第二种做法的好处是能防止冲突。可以通过以下命令查找指定的端口:

docker port containerID portNumber

或者

docker inspect --format '{{.NetworkSettings.Ports}}' 
containerID

3.2 容器的IP地址

每一个容器都拥有自己属于私有网段的IP地址(默认是172.17.0.0/16)。IP可能会在重启的时候发生变化,如果你想知道其地址,可以用:

docker inspect --format '{{.NetworkSettings.IPAddress}}' containerID

Docker会尝试检查冲突,在需要的情况下会使用不同的网段的地址。

3.3 接管主机的网络

docker run –net=host能重用网络。但是请不要这么做。

4. 卷(volume)

一个绕过目录或者单一文件写时复制(copy-on-write)的文件系统,接近零负载(绑定挂载)。

4.1 卷的内容在docker commit的时候不会被保存

在镜像建立后写入你的卷没有太多的意义。

4.2 卷默认是可读可写的

但是有一个:ro的标志。

4.3 卷和容器是分开存在的

卷只要有一个容器使用他们就会存在。可以在容器之间通过–volumes-from选项共享。

4.4 挂载你的docker.sock

你可以仅仅挂载docker.sock就能让你的容器访问到Docker的API。然后你可以在该容器中运行Docker的命令。这样容器甚至还可以杀死自己,在一个容器里面运行一个Docker的守护者进程是没有必要的。

5. 安全

5.1 以root身份运行Docker

Docker API能给root的访问权限,因为你可以将/映射成一个卷,然后读或者写。或者你可以通过–net host接管宿主机的网络。不要暴露Docker API如果你需要请使用TLS。

5.2 Dockerfile中的USER

默认下Docker可以以root的身份运行任何命令,但是你可以使用USER。Docker没有用户的命名空间,因此容器将用户看作是宿主机上的用户。但是仅仅是UID因而你需要在容器里面添加该用户。

5.3 使用TLS操作Docker API

Docker 1.3版本添加了对TLS的支持。他们使用手动的验证机制:客户端和服务端都有一个Key。把Key看做是root用户的密码。从1.3版本开始,Boot2docker默认使用TLS并且会为你生成key。

另外生成Key需要OpenSSL 1.0.1以上版本的支持,然后Docker daemon进程需要加上–tls-verify选项运行,Docker会使用安全的端口(2376)。

来源:http://dockerone.com/article/59

Linux:手把手教你在 CoreOS 上构建你的第一个应用

【编者的话】作者以自己的Mac笔记本为例,介绍了如何在CoreOS上安装WordPress应用,没有过多的理论解释,全部是实战类教程,推荐想快速了解CoreOS的同学阅读。

我相信你一定听说过CoreOS,但是你是否真正在它上面部署过一个应用了?可能很多人都没有部署过。在CoreOS上构建一个应用是非常困难且令人沮丧的(译者注:frustrating,用了这个词,看来确实难)。因为文档比较散乱,并且你不得不在开始之前学习所有相关的技术,包括etcd、systemd、Docker。如果你和我一样比较懒惰,只是想试试CoreOS而不想小题大做,那么让我来帮你吧。接下来我们将会在CoreOS上创建一个简单的WordPress应用以及MySQL数据库。

Screen-Shot-2014-03-25-at-2.13_.49-PM_.png

如果你使用的是Mac,可以通过安装命令行工具来控制CoreOS

fleetctl 和 etcdctl 是原生的控制CoreOS集群的工具,安装步骤如下:

$ brew install go etcdctl $ git clone https://github.com/coreos/fleet.git
$ cd fleet
$ ./build
$ mv bin/fleetctl /usr/local/bin/

安装一个本地的CoreOS集群,并运行

Vagrant是非常简单的。

$ git clone https://github.com/CenturyLinkLabs/coreos-vagrant $ cd coreos-vagrant/cluster
$ vagrant up --provision

现在你的笔记本上有一个由最小的3个CoreOS系统组成的集群。简单极了,现在让我们使用fleetctl来检查下。

$ fleetctl list-machines MACHINE IP METADATA
09fd0a88... 10.0.2.15 -
77763947... 10.0.2.15 -
f31c383c... 10.0.2.15 -

太棒了,跑起来了。

使用fleet在CoreOS集群上部署应用

现在你有一个CoreOS集群了。接下来fleetctl命令可以让你在CoreOS集群节点上部署应用,但要用fleet写服务文件。当然,不需要你自己来写。你可以用简单的YAML格式来生成服务(service)文件。

$ sudo gem install bundler fig2coreos
$ cat fig.yml

web:
image: ctlc/wordpress
ports:
- 80:80
environment:
DB_USER: root
DB_PASSWORD: qa1N76pWAri9
links:
- db
db:
image: ctlc/mysql
ports:
- 3306:3306
environment:
MYSQL_DATABASE: wordpress
MYSQL_ROOT_PASSWORD: qa1N76pWAri9

$ fig2coreos myapp fig.yml coreos-files
$ cd coreos-files
$ ls
db-discovery.1.service
db.1.service
web-discovery.1.service
web.1.service 

fleetctl客户端工具使用etcd的键值存储来确定它要访问的服务器以及访问集群中有etcd服务端运行的服务器。下面是如何在CoreOS集群中部署你的应用。

$ fleetctl start db.1.service
$ fleetctl list-units
UNIT        LOAD    ACTIVE  SUB DESC        MACHINE
db.1.service    loaded  active  running Run db_1    9c008961.../10.0.2.15
$ fleetctl start web.1.service
$ fleetctl list-units
UNIT        LOAD    ACTIVE  SUB DESC        MACHINE
db.1.service    loaded  active  running Run db_1    9c008961.../10.0.2.15
web.1.service   loaded  active  running Run web_1   9c008961.../10.0.2.15 

现在你的程序运行起来了,但是服务还没有注册到etcd。幸运的是,fig2coreos已经为我们自动生成服务文件。

$ fleetctl start db-discovery.1.service
$ fleetctl start web-discovery.1.service
$ fleetctl list-units
UNIT            LOAD    ACTIVE  SUB DESC        MACHINE
db-discovery.1.service  loaded  active  running Announce db_1   9c008961.../10.0.2.15
db.1.service        loaded  active  running Run db_1    9c008961.../10.0.2.15
web-discovery.1.service loaded  active  running Announce web_1  9c008961.../10.0.2.15
web.1.service       loaded  active  running Run web_1   9c008961.../10.0.2.15
$ etcdctl ls --recursive
/services
/services/web
/services/web/web_1
/services/db
/services/db/db_1
$ etcdctl get /services/web/web_1
{ "host": "core-03", "port": 80, "version": "52c7248a14" }
$ etcdctl get /services/db/db_1
{ "host": "core-03", "port": 3306, "version": "52c7248a14" }

部署完成

就这样,搞定了。在Vagrant 1.5使用Vagrant Cloud账号,你可以访问你的WordPress应用。如下图:

$ cd ~/coreos-vagrant/cluster/

找出哪个机器监听着你的80端口:

$ etcdctl get /services/web/web_1
{ "host": "core-03", "port": 80, "version": "52c7248a14" }
$ vagrant share core-03 --http 80
==> core-03: Detecting network information for machine...
core-03: Local machine address: 192.168.65.2
core-03: Local HTTP port: 80
core-03: Local HTTPS port: disabled
==> core-03: Checking authentication and authorization...
==> core-03: Creating Vagrant Share session...
core-03: Share will be at: quick-iguana-4689
==> core-03: Your Vagrant Share is running! Name: quick-iguana-4689
==> core-03: URL: http://quick-iguana-4689.vagrantshare.com

Screen-Shot-2014-03-25-at-1.58_.16-PM_.png

结论

现在你可以用CoreOS做很多事情,但至少现在你已经做完基本的工作了,如果你打算在生产环境使用多主机的Coreos集群。需要你在系统中增加ambassador容器。事实上,你可以通过ambassador容器连接etc服务器,我们将会在下周发表另外一篇博文。

来源:http://dockerone.com/article/66

Linux:机器学习领域的几种主要学习方式

学习方式

根据数据类型的不同,对一个问题的建模有不同的方式。在机器学习或者人工智能领域,人们首先会考虑算法的学习方式。在机器学习领域,有几种主要 的学习方式。将算法按照学习方式分类是一个不错的想法,这样可以让人们在建模和算法选择的时候考虑能根据输入数据来选择最合适的算法来获得最好的结果。

监督式学习:

Linux:机器学习领域的几种主要学习方式
Linux:机器学习领域的几种主要学习方式

在监督式学习下,输入数据被称为“训练数据”,每组训练数据有一个明确的标识或结果,如对防垃圾邮件系统中“垃圾邮件”“非垃圾邮件”,对手写 数字识别中的“1“,”2“,”3“,”4“等。在建立预测模型的时候,监督式学习建立一个学习过程,将预测结果与“训练数据”的实际结果进行比较,不断 的调整预测模型,直到模型的预测结果达到一个预期的准确率。监督式学习的常见应用场景如分类问题和回归问题。常见算法有逻辑回归(Logistic Regression)和反向传递神经网络(Back Propagation Neural Network)

非监督式学习:

Linux:机器学习领域的几种主要学习方式
Linux:机器学习领域的几种主要学习方式

在非监督式学习中,数据并不被特别标识,学习模型是为了推断出数据的一些内在结构。常见的应用场景包括关联规则的学习以及聚类等。常见算法包括Apriori算法以及k-Means算法。

半监督式学习:

Linux:机器学习领域的几种主要学习方式
Linux:机器学习领域的几种主要学习方式

在此学习方式下,输入数据部分被标识,部分没有被标识,这种学习模型可以用来进行预测,但是模型首先需要学习数据的内在结构以便合理的组织数据 来进行预测。应用场景包括分类和回归,算法包括一些对常用监督式学习算法的延伸,这些算法首先试图对未标识数据进行建模,在此基础上再对标识的数据进行预 测。如图论推理算法(Graph Inference)或者拉普拉斯支持向量机(Laplacian SVM.)等。

强化学习:

在这种学习模式下,输入数据作为对模型的反馈,不像监督模型那样,输入数据仅仅是作为一个检查模型对错的方式,在强化学习下,输入数据直接反馈 到模型,模型必须对此立刻作出调整。常见的应用场景包括动态系统以及机器人控制等。常见算法包括Q-Learning以及时间差学习(Temporal difference learning)

在企业数据应用的场景下, 人们最常用的可能就是监督式学习和非监督式学习的模型。 在图像识别等领域,由于存在大量的非标识的数据和少量的可标识数据, 目前半监督式学习是一个很热的话题。 而强化学习更多的应用在机器人控制及其他需要进行系统控制的领域。

算法类似性

根据算法的功能和形式的类似性,我们可以把算法分类,比如说基于树的算法,基于神经网络的算法等等。当然,机器学习的范围非常庞大,有些算法很 难明确归类到某一类。而对于有些分类来说,同一分类的算法可以针对不同类型的问题。这里,我们尽量把常用的算法按照最容易理解的方式进行分类。

回归算法

Linux:机器学习领域的几种主要学习方式
Linux:机器学习领域的几种主要学习方式

回归算法是试图采用对误差的衡量来探索变量之间的关系的一类算法。回归算法是统计机器学习的利器。在机器学习领域,人们说起回归,有时候是指一 类问题,有时候是指一类算法,这一点常常会使初学者有所困惑。常见的回归算法包括:最小二乘法(Ordinary Least Square),逻辑回归(Logistic Regression),逐步式回归(Stepwise Regression),多元自适应回归样条(Multivariate Adaptive Regression Splines)以及本地散点平滑估计(Locally Estimated Scatterplot Smoothing)

基于实例的算法

基于实例的算法常常用来对决策问题建立模型,这样的模型常常先选取一批样本数据,然后根据某些近似性把新数据与样本数据进行比较。通过这种方式 来寻找最佳的匹配。因此,基于实例的算法常常也被称为“赢家通吃”学习或者“基于记忆的学习”。常见的算法包括 k-Nearest Neighbor(KNN), 学习矢量量化(Learning Vector Quantization, LVQ),以及自组织映射算法(Self-Organizing Map , SOM)

正则化方法

Linux:机器学习领域的几种主要学习方式
Linux:机器学习领域的几种主要学习方式

正则化方法是其他算法(通常是回归算法)的延伸,根据算法的复杂度对算法进行调整。正则化方法通常对简单模型予以奖励而对复杂算法予以惩罚。常 见的算法包括:Ridge Regression, Least Absolute Shrinkage and Selection Operator(LASSO),以及弹性网络(Elastic Net)。

决策树学习

决策树算法根据数据的属性采用树状结构建立决策模型, 决策树模型常常用来解决分类和回归问题。常见的算法包括:分类及回归树(Classification And Regression Tree, CART), ID3 (Iterative Dichotomiser 3), C4.5, Chi-squared Automatic Interaction Detection(CHAID), Decision Stump, 随机森林(Random Forest), 多元自适应回归样条(MARS)以及梯度推进机(Gradient Boosting Machine, GBM)

贝叶斯方法

Linux:机器学习领域的几种主要学习方式
Linux:机器学习领域的几种主要学习方式

贝叶斯方法算法是基于贝叶斯定理的一类算法,主要用来解决分类和回归问题。常见算法包括:朴素贝叶斯算法,平均单依赖估计(Averaged One-Dependence Estimators, AODE),以及Bayesian Belief Network(BBN)。

基于核的算法

Linux:机器学习领域的几种主要学习方式
Linux:机器学习领域的几种主要学习方式

基于核的算法中最着名的莫过于支持向量机(SVM)了。 基于核的算法把输入数据映射到一个高阶的向量空间, 在这些高阶向量空间里, 有些分类或者回归问题能够更容易的解决。 常见的基于核的算法包括:支持向量机(Support Vector Machine, SVM), 径向基函数(Radial Basis Function ,RBF), 以及线性判别分析(Linear Discriminate Analysis ,LDA)等。

聚类算法

Linux:机器学习领域的几种主要学习方式
Linux:机器学习领域的几种主要学习方式

聚类,就像回归一样,有时候人们描述的是一类问题,有时候描述的是一类算法。聚类算法通常按照中心点或者分层的方式对输入数据进行归并。所以的 聚类算法都试图找到数据的内在结构,以便按照最大的共同点将数据进行归类。常见的聚类算法包括 k-Means算法以及期望最大化算法(Expectation Maximization, EM)。

关联规则学习

关联规则学习通过寻找最能够解释数据变量之间关系的规则,来找出大量多元数据集中有用的关联规则。常见算法包括 Apriori算法和Eclat算法等。

人工神经网络

Linux:机器学习领域的几种主要学习方式
Linux:机器学习领域的几种主要学习方式

人工神经网络算法模拟生物神经网络,是一类模式匹配算法。通常用于解决分类和回归问题。人工神经网络是机器学习的一个庞大的分支,有几百种不同 的算法。(其中深度学习就是其中的一类算法,我们会单独讨论),重要的人工神经网络算法包括:感知器神经网络(Perceptron Neural Network), 反向传递(Back Propagation), Hopfield网络,自组织映射(Self-Organizing Map, SOM)。学习矢量量化(Learning Vector Quantization, LVQ)

深度学习

深度学习算法是对人工神经网络的发展。 在近期赢得了很多关注, 特别是 百度也开始发力深度学习后, 更是在国内引起了很多关注。  在计算能力变得日益廉价的今天,深度学习试图建立大得多也复杂得多的神经网络。很多深度学习的算法是半监督式学习算法,用来处理存在少量未标识数据的大 数据集。常见的深度学习算法包括:受限波尔兹曼机(Restricted Boltzmann Machine, RBN), Deep Belief Networks(DBN),卷积网络(Convolutional Network), 堆栈式自动编码器(Stacked Auto-encoders)。

降低维度算法

Linux:机器学习领域的几种主要学习方式
Linux:机器学习领域的几种主要学习方式

像聚类算法一样,降低维度算法试图分析数据的内在结构,不过降低维度算法是以非监督学习的方式试图利用较少的信息来归纳或者解释数据。这类算法 可以用于高维数据的可视化或者用来简化数据以便监督式学习使用。常见的算法包括:主成份分析(Principle Component Analysis, PCA),偏最小二乘回归(Partial Least Square Regression,PLS), Sammon映射,多维尺度(Multi-Dimensional Scaling, MDS),  投影追踪(Projection Pursuit)等。

集成算法

集成算法用一些相对较弱的学习模型独立地就同样的样本进行训练,然后把结果整合起来进行整体预测。集成算法的主要难点在于究竟集成哪些独立的较 弱的学习模型以及如何把学习结果整合起来。这是一类非常强大的算法,同时也非常流行。常见的算法包括:Boosting, Bootstrapped Aggregation(Bagging), AdaBoost,堆叠泛化(Stacked Generalization, Blending),梯度推进机(Gradient Boosting Machine, GBM),随机森林(Random Forest)。

来源:http://www.smartcitychina.cn/zhyy/2014-12/3985.html

Linux:Docker 容器初体验

在本文中,我们将迈出使用Docker的第一步,学习第一个Docker容器。本章还会介绍如何与Docker进行交互的基本知识。

Linux:Docker 容器初体验
Linux:Docker 容器初体验

1 确保Docker已经就绪

首先,我们会查看Docker是否能正常工作,然后学习基本的Docker的工作流:创建并管理容器。我们将浏览容器的典型生命周期:从创建、管理到停止,直到最终删除。

第一步,查看docker程序是否存在,功能是否正常,如代码清单3-1所示。

代码清单3-1 查看docker程序是否正常工作

$ sudo docker info
Containers: 0
Images: 0
Storage Driver: aufs
 Root Dir: /var/lib/docker/aufs
 Dirs: 144
Execution Driver: native-0.1
Kernel Version: 3.8.0-29-generic
Registry: [https://index.docker.io/v1/]

在这里我们调用了docker可执行程序的info命令,该命令会返回所有容器和镜像(镜像即是Docker用来构建容器的“构建块”)的数量、Docker使用的执行驱动和存储驱动(execution and storage driver),以及Docker的基本配置。

在前面几章我们已经介绍过,Docker是基于客户端-服务器构架的。它有一个docker程序,既能作为客户端,也可以作为服务器端。作为客户端时,docker程序向Docker守护进程发送请求(如请求返回守护进程自身的信息),然后再对返回来的请求结果进行处理。

2 运行我们的第一个容器

现在,让我们尝试启动第一个Docker容器。我们可以使用docker run命令创建容器,如代码清单3-2所示。docker run命令提供了Docker容器的创建到启动的功能,在本书中我们也会使用该命令来创建新容器。

代码清单3-2 创建第一个容器

$ sudo docker run -i -t ubuntu /bin/bash
Pulling repository ubuntu from https://index.docker.io/v1
Pulling image 8dbd9e392a964056420e5d58ca5cc376ef18e2de93b5cc90e868a1bbc8318c1c (precise) from ubuntu
Pulling 8dbd9e392a964056420e5d58ca5cc376ef18e2de93b5cc90e868a1bbc8318c1c metadata
Pulling 8dbd9e392a964056420e5d58ca5cc376ef18e2de93b5cc90e868a1bbc8318c1c fs layer
Downloading 58337280/? (n/a)
Pulling image b750fe79269d2ec9a3c593ef05b4332b1d1a02a62b4accb2c21d589ff2f5f2dc (quantal) from ubuntu
Pulling image 27cf784147099545 () from ubuntu
root@fcd78e1a3569:/#

{提示}官方文档列出了完整的Docker命令列表,你也可以使用docker help获取这些命令。此外,你还可以使用Docker的man页(即执行man docker-run)。

代码清单3-3所示命令的输出结果非常丰富,下面我们来逐条解析。

代码清单3-3 docker run命令

$ sudo docker run -i -t ubuntu /bin/bash

首先,我们告诉Docker执行docker run命令,并指定了-i和-t两个命令行参数。-i标志保证容器中STDIN是开启的,尽管我们并没有附着到容器中。持久的标准输入是交互式shell的“半边天”,-t标志则是另外“半边天”,它告诉Docker为要创建的容器分配一个伪tty终端。这样,新创建的容器才能提供一个交互式shell。若要在命令行下创建一个我们能与之进行交互的容器,而不是一个运行后台服务的容器,则这两个参数已经是最基本的参数了。

{提示}官方文档上列出了docker run命令的所有标志,此外还可以用命令docker help run查看这些标志。或者,也可以用Docker的man页(也就是执行man docker-run命令)。

接下来,我们告诉Docker基于什么镜像来创建容器,示例中使用的是ubuntu镜像。ubuntu镜像是一个常备镜像,也可以称为“基础”(base)镜像,它由Docker公司提供,保存在Docker HubRegistry上。

你可以用 ubuntu 基础镜像(以及类似的 fedora、debian、centos等镜像)为基础,在你选择的操作系统上构建自己的镜像。这里,我们基于此基础镜像启动了一个容器,并且没有对容器进行任何改动。

那么,在这一切的背后又都发生了什么呢?首先Docker会检查本地是否存在ubuntu镜像,如果本地还没有该镜像的话,那么Docker就会连接官方维护的Docker Hub Registry,查看Docker Hub中是否有该镜像。Docker一旦找到该镜像,就会下载该镜像并将其保存到本地宿主机中。

随后,Docker在文件系统内部用这个镜像创建了一个新容器。该容器拥有自己的网络、IP地址,以及一个用来和宿主机进行通信的桥接网络接口。最后,我们告诉Docker在新容器中要运行什么命令,在本例中我们在容器中运行/bin/bash命令启动了一个Bash shell。

当容器创建完毕之后,Docker就会执行容器中的/bin/bash命令,这时我们就可以看到容器内的shell了,就像代码清单3-4所示。

代码清单3-4 第一个容器的shell

root@f7cbdac22a02:/#

{注意}在第4章中,我们将会看到如何构建自己的镜像并基于该镜像创建容器的基础知识。

3 使用第一个容器

现在,我们已经以root用户登录到了新容器中,容器的IDf7cbdac22a02“,乍“看起来有些令人迷惑的字符串。这是一个完整的Ubuntu系统,你可以用它来做任何事情。下面我们就来研究一下这个容器。首先,我们可以获取该容器的主机名,如代码清单3-5所示。

代码清单3-5 检查容器的主机名

root@f7cbdac22a02:/# hostname
f7cbdac22a02

可以看到,容器的主机名就是该容器的ID。我们再来看看/etc/hosts文件,如代码清单3-6所示。

代码清单3-6 检查容器的/etc/hosts文件

root@f7cbdac22a02:/# cat /etc/hosts
172.17.0.4  f7cbdac22a02
127.0.0.1 localhost
::1 localhost ip6-localhost ip6-loopback
fe00::0 ip6-localnet
ff00::0 ip6-mcastprefix
ff02::1 ip6-allnodes
ff02::2 ip6-allrouters

Docker以在hosts文件中为该容器的IP地址添加了一条主机配置项。我们再来看看容器的网络配置情况,如代码清单3-7所示。

代码清单3-7 检查容器的接口

root@f7cbdac22a02:/# ip a
1: lo:  mtu 1500 qdisc noqueue state UNKNOWN group default
    link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
    inet 127.0.0.1/8 scope host lo
    inet6 ::1/128 scope host
       valid_lft forever preferred_lft forever
899: eth0:  mtu 1500 qdisc pfifo_fast state UP group default qlen 1000
    link/ether 16:50:3a:b6:f2:cc brd ff:ff:ff:ff:ff:ff
    inet 172.17.0.4/16 scope global eth0
    inet6 fe80::1450:3aff:feb6:f2cc/64 scope link
       valid_lft forever preferred_lft forever

我们可以看到,这里有lo的环回接口,还有IP为172.17.0.4的标准eth0网络接口,和普通宿主机是完全一样的。我们还可以查看容器中运行的进程,如代码清单3-8所示。

代码清单3-8 检查容器的进程

root@f7cbdac22a02:/# ps -aux
USER       PID %CPU %MEM    VSZ   RSS TTY      STAT START   TIME COMMAND
root         1  0.0  0.0  18156  1936 ?        Ss   May30   0:00 /bin/bash
root        21  0.0  0.0  15568  1100 ?        R+   02:38   0:00 ps -aux

接下来我们要干些什么呢?安装一个软件包怎么样?如代码清单3-9所示。

代码清单3-9 在第一个容器中安装软件包

root@f7cbdac22a02:/# apt-get update && apt-get install vim

通过上述命令,我们就在容器中安装了Vim软件。

你可以继续在容器中做任何自己想做的事情。当所有工作都结束时,输入exit,就可以返回到Ubuntu宿主机的命令行提示符了。

这个容器现在怎样了?容器现在已经停止运行了!只有在指定的/bin/bash命令处于运行状态的时候,我们容器也才会相应地处于运行状态。一旦退出容器,/bin/bash命令也就结束了,这时容器也随之停止了运行。

但容器仍然是存在的,我们可以用docker ps -a命令查看当前系统中容器的列表

默认情况下,当执行docker ps命令时,只能看到正在运行的容器。如果指定-a标志,选项的话,那么docker ps命令会列出所有容器,包括正在运行的和已经停止的。

{提示}你也可以为docker ps命令指定-l标志,该选项会列出最后一次运行的容器,包括正在运行和已经停止的。

从该命令的输出结果中我们可以看到关于这个容器的很多有用信息:ID、用于创建该容器的镜像、容器最后执行的命令、创建时间以及容器的退出状态(在上面的例子中,退出状态是0,因为容器是通过正常的exit命令退出的)。我们还可以看到,每个容器都有一个名称。

{注意}有三种方式可以指代唯一容器:短UUID(如f7cbdac22a02)、长UUID(如f7cbdac22a02e03c9438c729345e54db9d20cfa2ac1fc3494b6eb60872e74778)或者名称(如gray_cat)。

来源:http://www.jianshu.com/p/26f15063de7d

Linux:90后CEO的开源心得:Github 2500 star是如何炼成的

Linux:90后CEO的开源心得:Github 2500 star是如何炼成的
Linux:90后CEO的开源心得:Github 2500 star是如何炼成的

如果你是一名iOS开发者同时还是Github的重度使用者,那么你多半见过这个项目:PNChart,一个提供带动画的图表控件。截止到目前为止,PNChart在Github上的star数已经超过2500,是一个备受开发者喜爱的iOS第三方开源库。那么,你知道它的第一作者其实是国人、90后,并且已经有自己的公司了吗?

这个人就是周楷雯,除了PNChart,最近他还开源了Waver,一个类似Siri中的声波效果库。当记者联系他表达采访意愿后,他表示“如果能为开源发展贡献一份力量那再好不过了”,非常热心。

下面就让我们听他来分享一下,如何打造一个成功的iOS开源项目。

CocoaChina:非常感谢您能和大家分享自己的宝贵经验。首先请您简单介绍一下自己,以及您是如何开始现在的事业的?

Kevin:Hi 我是 Kevin,92 年出生,因为觉得做产品是有趣的事情,所以 2011 年开始着手学习编程、设计,并且开始尝试进行iOS开发。不过学习是件漫长的事情,我发现用漫长的时间去学习无穷无尽的模式和 API 是件挺悲哀的事情,所以本着生有涯而学无涯的精神,我按照自己想做的事情去学习需要的技能,无分深浅。

接下来的一年其实过得特别快,时间似乎快变成是按照月来计算的,每天都有很多要学的新东西。终于 2012年 5 月份我发布了第一款独立作品 Piner ,之后 2014 年 5 月份组建立了 Catch 团队,前段时间发布了我们的第一款产品 秒视,总的来说,和有趣的人做有趣的事情、创造一些有价值的产品、并鼓舞一些人,这些是我当下的事业。

CocoaChina:请介绍一下您的开源项目,您为何会参与开源?

Kevin:PNChart 是我 2013 年的时候重写 Piner 那款产品而做的,因为对动画和设计有着比较高的要求,发布后迅速聚集了大量 Star,并连续两周在 Github趋势的Objective-C语言分类排名第一,至今已经有很多国际友人做了贡献,以至于我想加点新功能都得重新读一遍,并修修他们留给我的 坑(笑)。

说到开源,其实和我有着很深的渊源,甚至影响了我的人生轨迹。 2007 年的时候我开始使用 Ubuntu,2009 年的时候开始使用 Twitter,而上面早期的朋友也都是使用 Linux 的,所以虽然软件匮乏,但是大家相互鸡汤,精神世界还是很丰富的,同时我转战于Gimp、Blender,以及各种Linux发行版之间,也参与了 Ubuntu Tweak的设计。

我一开始完全是个开源愤青,以完全使用开源产品为荣,鄙视一切不开源的东西。比较讽刺的是当我从 Linux 世界淘到第一桶金后,我就转移到了 Mac 平台,不是有句段子这么说的嘛,Linux 用户有钱就买 Mac。不过开源依旧是流淌在我血液里的东西,只不过对其的理解,从单纯的全部使用开源产品,转化成了知识的分享。在这个过程中我发现比较痛苦的一件事 是,你总是需要走过前人走过的路,去趟过那些坑,然后实现别人很早之前就已经实现的事情。如果牛人都可以记录下自己的心得为后来人开路,那么我想编程和开 发不会像现在这么令人望而却步,开源对人类而言会有更高的价值。

就 PNChart 来说,满足每个产品的需求是不可能的,但是我希望至少你在写这类控件的时候,有个东西可以帮你节省一些力气,我相信开源的价值就是打破这些知识壁垒,不让知识束之高阁。

CocoaChina: 您认为iOS开发有哪些方向适合做开源项目?

Kevin: 我觉得其实iOS的开源项目就像积木,使用开源项目的过程就是将这些积木一块一块的搭起来。做iOS方向的开源,开发积木块就可以,比如现在的一些热门 iOS开源项目,网络模块AFNetworking,图像模块GPUImage,以及交互小控件之类的,都属于这个范畴。不过最主要的当然还是做一个你用 得到的模块。高度整合的开发框架我觉得实用性不大,iOS 的更新很容易破坏掉这些东西,应用的跨iOS版本升级时擦屁股是很累的。

CocoaChina: 能否讲讲如何打造一个成功的开源项目,您觉得有哪些关键要素?

Kevin: 我觉得,最重要的是项目本身需要满足广泛的需求,在我开发PNChart之前没有什么既能动画,又能漂亮的iOS图表库,大家都没有,所以我做了一个,结 果大家很喜欢。其次是需要传播,到各类控件中心或代码库发发帖子,然后写个 Blog介绍一下。这两个是很重要的,因为根据长尾理论,这类符合刚需的东西在很长的时间内大家都需要,你的项目容易被找到,就更容易形成二次传播。

CocoaChina: 前不久CocoaPods宣布达成100万下载,已有6000+第三方库,您觉得iOS开源是否是一个趋势?

Kevin:开源在 Github 流行以来已经成为一种名片一样的东西,多写写开源的东西很有益身心的,能让你感受到纯粹的编程以外的事情,可能也能约炮,这个我只是推论,呵呵。

CocoaChina: 您认为开源的流行对iOS开发会有哪些影响?

Kevin:影响分为两方面,正面和负面,负面无非是一些人搭搭积木就说自己会编程了,工程质量降低。不过这是团队管理的事情,和开源与 iOS 没关系。正面当然很多了,消除知识壁垒比较有意义。 

CocoaChina:在国内参与iOS开源的人您知道的有哪些呢?私下里是否有交流?国内iOS开源的形势如何?

Kevin:国内参与开源的太多啦,私下肥皂也是捡的不少,不过我比较熟悉的是 Lex,我们一起共事过一段时间,他是一位比我优秀的开发者和交互设计者,做了很多有趣的开源模块,但是考虑到他已经当爹了,但是我还年轻,所以未来我还是比较看好我自己。

还有人见人爱的 Onevcat,前段时间还开源了 Swift 相关的知识,《Swift 100 Tips》。

以及国内 iOS 开发的领袖人物唐巧,最近也分享了Objective-C相关的知识, 《iOS 开发进阶》,我写下这段文字的时候,他应该正准备下午一点签售。

其 实我把开源看做是一个像小桥流水一样的事情,做好自己喜欢的事情,把能模块化的东西抽离出来,做成开源模块,优秀的人都在做这样的事情。说到底,开源是知 识的开源,不是代码的开源,商业化并不是开源的对立面,相反,很多商业公司集合了一群最牛逼的人做出来伟大的开源产品。

CocoaChina:做iOS开源项目是否与公司内的开发相矛盾?如何避免或化解开源项目与公司项目的冲突?

Kevin: 因为我是老板,所以主要是内心的斗争,to be or not to be 的问题,我是开源呢,还是不开源呢,私心总是会有的,并且常常排在第一位。但是需要明白的是,无论做什么产品,核心的竞争力不是那几段代码,而是团队的赋 予这个产品的灵魂。做过开源的人运营公司就懂这个道理,没做过的你可以跟他布道开源的好处,但千万别擅自将属于公司项目的代码开源,否则后果可能会很严 重。总的来说,这个还是看缘分的。

以上就是本次采访的全部内容,感谢来自Kevin的分享。

来源:http://www.cocoachina.com/programmer/20141224/10747.html

Linux:Linux有问必答:如何在CentOS上安装phpMyAdmin

问题:我正在CentOS上运行一个MySQL/MariaDB服务,并且我想要通过网络接口来用phpMyAdmin来管理数据库。在CentOS上安装phpMyAdmin的最佳方法是什么?

phpMyAdmin是一款以PHP为基础,基于Web的MySQL/MariaDB数据库管理工具。虽然已经存在着一些诸如Adminer的轻量级数据库管理工具, 但是phpMyAdmin还是更加广泛应用于网站管理员之中来进行各种MySQL/MariaDB的管理任务。它支持几乎所有MySQL数据库/表的相关操作,比如浏览、创建、复制、删除、重命名、更改,还有MySQL用户/权限管理和数据库导入/导出。以下就是如何在CentOS 6或7上安装phpMyAdmin

Linux:Linux有问必答:如何在CentOS上安装phpMyAdmin
Linux:Linux有问必答:如何在CentOS上安装phpMyAdmin

前提

在CentOS上安装phpMyAdmin,你第一步需要架设一台Web服务器(如Apache或nginx),安装好MySQL/MariaDB数据库和PHP。根据你的偏好和需求,你可以从LAMPLEMP中选择一种安装。

另一个要求是允许在你的CentOS上安装EPEL库。如果你还没设置过请猛戳这里

在CentOS6或7上安装phpMyAdmin

一旦你设置了EPEL库,你就能轻松地用以下命令安装phpMyAdmin了。

在CentOS 7上:

$ sudo yum install phpmyadmin

在CentOS 7上:

$ sudo yum install phpmyadmin php-mcrypt

在CentOS 7上配置phpMyAdmin

默认情况下,CentOS 7上的phpMyAdmin只允许从回环地址(127.0.0.1)访问。为了能远程连接,你需要改动它的配置。

用文本编辑器打开phpMyAdmin的配置文件(路径:/etc/httpd/conf.d/phpMyAdmin.conf),找出并注释掉带有”Require ip XXXX”字样的代码行。会有四处这样的代码行,用”Require all granted”取而代之。重新改动过的配置文件如下所示。

$ sudo vi /etc/httpd/conf.d/phpMyAdmin.conf

. . . . .

   AddDefaultCharset UTF-8
   
     # Apache 2.4
     
       #Require ip 127.0.0.1
       #Require ip ::1
       Require all granted
     
   
   
     # Apache 2.2
     Order Deny,Allow
     Deny from All
     Allow from 127.0.0.1
     Allow from ::1
   


   
     # Apache 2.4
     
       #Require ip 127.0.0.1
       #Require ip ::1
       Require all granted
     
   
   
     # Apache 2.2
     Order Deny,Allow
     Deny from All
     Allow from 127.0.0.1
     Allow from ::1
   

. . . . .

最后,重启httpd使改动生效。

$ sudo systemctl restart httpd

在CentOS 6上配置phpMyAdmin

默认情况下,CentOS 6上的phpMyAdmin是禁止从每个IP地址访问的。为了能远程连接,你需要改动它的配置。

用文本编辑器打开phpMyAdmin的配置文件(路径:/etc/httpd/conf.d/phpMyAdmin.conf),找出并注释掉”Deny from all”字样的代码行。然后把”Allow from 127.0.0.1″字样的代码行改成”Allow from 0.0.0.0″。重新改动过的配置文件如下所示。

$ sudo vi /etc/httpd/conf.d/phpmyadmin.conf


  Order Deny,Allow
#  Deny from all
  Allow from 0.0.0.0

下一步是将phpMyAdmin的配置文件用blowfish加密工具加密。这一步需要加密cookie里的密码来作为基于cookie的部分认证。

用文本编辑器打开如下路径所示的文件并且用blowfish设置一个随机密码,如下所示。

$ sudo vi /usr/share/phpmyadmin/config.inc.php

$cfg['blowfish_secret'] = 'kd5G}d33aXDc50!'; /* YOU MUST FILL IN THIS FOR COOKIE AUTH! */

最后,重启httpd使改动生效。

$ sudo service httpd restart

测试phpMyAdmin

测试phpMyAdmin是否设置成功,访问这个页面:http:///phpmyadmin

Linux:Linux有问必答:如何在CentOS上安装phpMyAdmin
Linux:Linux有问必答:如何在CentOS上安装phpMyAdmin

你应该能通过Web界面来记录下任何MySQL用户(比如root)和管理MySQL/MariaDB的数据库/表。

Linux:Linux有问必答:如何在CentOS上安装phpMyAdmin
Linux:Linux有问必答:如何在CentOS上安装phpMyAdmin

疑难解答

这里有一些在CentOS上安装phpMyAdmin的过程中遇到的一些问题解决方法。

  1. 当你在浏览器里尝试连接phpMyAdmin页面的时候,你看到”403 Forbidding”错误:

    You don’t have permission to access /phpMyAdmin on this server.

    发生这种错误是因为phpMyAdmin默认阻止了IP地址远程连接。要修复这种错误,你需要编辑它的配置文件来允许远程连接。具体操作见上。

  2. 当你连接phpMyAdmin页面时,你看见”The configuration file now needs a secret passphrase (blowfish_secret).”信息,并且你无法登录。

    要修复这种错误,你需要编辑 /usr/share/phpmyadmin/config.inc.php 这个文件来添加一个随机的blowfish密码,然后重启httpd,如下所示。

    $cfg['blowfish_secret'] = 'kd5G}d33aXDc50!'; /* YOU MUST FILL IN THIS FOR COOKIE AUTH! */
    

    $ sudo service httpd restart (CentOS 6)
    $ sudo systemctl restart httpd (CentOS 7)
    
  3. 当你连接phpMyAdmin页面时,你看见”Cannot load mcrypt extension. Please check your PHP configuration”错误信息。

    要修复这种错误,要安装下面这个包:

    $ sudo yum install php-mcrypt
    

    然后重启httpd:

    $ sudo service httpd restart (CentOS 6)
    $ sudo systemctl restart httpd (CentOS 7)
    

via: http://ask.xmodulo.com/install-phpmyadmin-centos.html

译者:ZTinoZ 校对:wxy

本文由 LCTT 原创翻译,Linux中国 荣誉推出

来源:https://linux.cn/article-4526-1.html

Linux:十个 SCP 传输命令例子

Linux系统管理员应该很熟悉CLI环境,因为通常在Linux服务器中是不安装GUI的。SSH可能是Linux系统管理员通过远程方式安全管理服务器的最流行协议。在SSH命令中内置了一种叫SCP的命令,用来在服务器之间安全传输文件。

Linux:十个 SCP 传输命令例子
Linux:十个 SCP 传输命令例子

以下命令可以解读为:用“username account”“拷贝 source file name”到“destination host”上的“destination folder”里。

SCP命令的基本语法

scp source_file_name username@destination_host:destination_folder

SCP命令有很多可以使用的参数,这里指的是每次都会用到的参数。

用-v参数来提供SCP进程的详细信息

不带参数的基本SCP命令会在后台拷贝文件,除非操作完成或者有错误出现,否则用户在界面上是看不到任何提示信息的。你可以用“-v”参数来在屏幕上打印出调试信息,这能帮助你调试连接、认证和配置的一些问题。

pungki@mint ~/Documents $ scp -v Label.pdf mrarianto@202.x.x.x:.

部分输出

Executing: program /usr/bin/ssh host 202.x.x.x, user mrarianto, command scp -v -t .
OpenSSH_6.0p1 Debian-3, OpenSSL 1.0.1c 10 May 2012
debug1: Reading configuration data /etc/ssh/ssh_config
debug1: /etc/ssh/ssh_config line 19: Applying options for *
debug1: Connecting to 202.x.x.x [202.x.x.x] port 22.
debug1: Connection established.
debug1: Host '202.x.x.x' is known and matches the RSA host key.
debug1: Found key in /home/pungki/.ssh/known_hosts:1
debug1: ssh_rsa_verify: signature correct
debug1: Next authentication method: password
mrarianto@202.x.x.x's password:
debug1: Authentication succeeded (password).
Authenticated to 202.x.x.x ([202.x.x.x]:22).
Sending file modes: C0770 3760348 Label.pdf
Sink: C0770 3760348 Label.pdf
Label.pdf 100% 3672KB 136.0KB/s 00:27
Transferred: sent 3766304, received 3000 bytes, in 65.2 seconds
Bytes per second: sent 57766.4, received 46.0
debug1: Exit status 0

从源文件获取修改时间、访问时间和模式

-p”参数会帮到把预计的时间和连接速度会显示在屏幕上。

pungki@mint ~/Documents $ scp -p Label.pdf mrarianto@202.x.x.x:.

部分输出

mrarianto@202.x.x.x's password:
Label.pdf 100% 3672KB 126.6KB/s 00:29

用-C参数来让文件传输更快

有一个参数能让传输文件更快,就是“-C”参数,它的作用是不停压缩所传输的文件。它特别之处在于压缩是在网络传输中进行,当文件传到目标服务器时,它会变回压缩之前的原始大小。

来看看这些命令,我们使用一个93 Mb的单一文件来做例子。

pungki@mint ~/Documents $ scp -pv messages.log mrarianto@202.x.x.x:.

部分输出

Executing: program /usr/bin/ssh host 202.x.x.x, user mrarianto, command scp -v -p -t .
OpenSSH_6.0p1 Debian-3, OpenSSL 1.0.1c 10 May 2012
debug1: Reading configuration data /etc/ssh/ssh_config
debug1: /etc/ssh/ssh_config line 19: Applying options for *
debug1: Connecting to 202.x.x.x [202.x.x.x] port 22.
debug1: Connection established.
debug1: identity file /home/pungki/.ssh/id_rsa type -1
debug1: Found key in /home/pungki/.ssh/known_hosts:1
debug1: ssh_rsa_verify: signature correct
debug1: Trying private key: /home/pungki/.ssh/id_rsa
debug1: Next authentication method: password
mrarianto@202.x.x.x's password:
debug1: Authentication succeeded (password).
Authenticated to 202.x.x.x ([202.x.x.x]:22).
debug1: Sending command: scp -v -p -t .
File mtime 1323853868 atime 1380425711
Sending file timestamps: T1323853868 0 1380425711 0
messages.log 100% 93MB 58.6KB/s 27:05
Transferred: sent 97614832, received 25976 bytes, in 1661.3 seconds
Bytes per second: sent 58758.4, received 15.6
debug1: Exit status 0

不用“-C”参数来拷贝文件,结果用了1661.3秒,你可以比较下用了“-C”参数之后的结果。

pungki@mint ~/Documents $ scp -Cpv messages.log mrarianto@202.x.x.x:.

部分输出

Executing: program /usr/bin/ssh host 202.x.x.x, user mrarianto, command scp -v -p -t .
OpenSSH_6.0p1 Debian-3, OpenSSL 1.0.1c 10 May 2012
debug1: Reading configuration data /etc/ssh/ssh_config
debug1: /etc/ssh/ssh_config line 19: Applying options for *
debug1: Connecting to 202.x.x.x [202.x.x.x] port 22.
debug1: Connection established.
debug1: identity file /home/pungki/.ssh/id_rsa type -1
debug1: Host '202.x.x.x' is known and matches the RSA host key.
debug1: Found key in /home/pungki/.ssh/known_hosts:1
debug1: ssh_rsa_verify: signature correct
debug1: Next authentication method: publickey
debug1: Trying private key: /home/pungki/.ssh/id_rsa
debug1: Next authentication method: password
mrarianto@202.x.x.x's password:
debug1: Enabling compression at level 6.
debug1: Authentication succeeded (password).
Authenticated to 202.x.x.x ([202.x.x.x]:22).
debug1: channel 0: new [client-session]
debug1: Sending command: scp -v -p -t .
File mtime 1323853868 atime 1380428748
Sending file timestamps: T1323853868 0 1380428748 0
Sink: T1323853868 0 1380428748 0
Sending file modes: C0600 97517300 messages.log
messages.log 100% 93MB 602.7KB/s 02:38
Transferred: sent 8905840, received 15768 bytes, in 162.5 seconds
Bytes per second: sent 54813.9, received 97.0
debug1: Exit status 0
debug1: compress outgoing: raw data 97571111, compressed 8806191, factor 0.09
debug1: compress incoming: raw data 7885, compressed 3821, factor 0.48

看到了吧,压缩了文件之后,传输过程在162.5秒内就完成了,速度是不用“-C”参数的10倍。如果你要通过网络拷贝很多份文件,那么“-C”参数能帮你节省掉很多时间。

有一点我们需要注意,这个压缩的方法不是适用于所有文件。当源文件已经被压缩过了,那就没办法再压缩很多了。诸如那些像.zip.rarpictures.iso的文件,用“-C”参数就没什么意义。

选择其它加密算法来加密文件

SCP默认是用“AES-128”加密算法来加密传输的。如果你想要改用其它加密算法来加密传输,你可以用“-c”参数。我们来瞧瞧。

pungki@mint ~/Documents $ scp -c 3des Label.pdf mrarianto@202.x.x.x:.
mrarianto@202.x.x.x's password:
Label.pdf 100% 3672KB 282.5KB/s 00:13

上述命令是告诉SCP3des algorithm来加密文件。要注意这个参数是“-c”(小写)而不是“-C“(大写)。

限制带宽使用

还有一个很有用的参数是“-l”参数,它能限制使用带宽。如果你为了拷贝很多文件而去执行了一份自动化脚本又不希望带宽被SCP进程耗尽,那这个参数会非常管用。

pungki@mint ~/Documents $ scp -l 400 Label.pdf mrarianto@202.x.x.x:.
mrarianto@202.x.x.x's password:
Label.pdf 100% 3672KB 50.3KB/s 01:13

在“-l”参数后面的这个400值意思是我们给SCP进程限制了带宽为50 KB/秒。有一点要记住,带宽是以千比特/秒 (kbps)表示的,而8 比特等于1 字节

因为SCP是用千字节/秒 (KB/s)计算的,所以如果你想要限制SCP的最大带宽只有50 KB/s,你就需要设置成50 x 8 = 400

指定端口

通常SCP是把22作为默认端口。但是为了安全起见SSH 监听端口改成其它端口。比如说,我们想用2249端口,这种情况下就要指定端口。命令如下所示。

pungki@mint ~/Documents $ scp -P 2249 Label.pdf mrarianto@202.x.x.x:.
mrarianto@202.x.x.x's password:
Label.pdf 100% 3672KB 262.3KB/s 00:14

确认一下写的是大写字母“P”而不是“p“,因为“p”已经被用来保留源文件的修改时间和模式(LCTT 译注:和 ssh 命令不同了)。

递归拷贝文件和文件夹

有时我们需要拷贝文件夹及其内部的所有文件/子文件夹,我们如果能用一条命令解决问题那就更好了。SCP用“-r”参数就能做到。

pungki@mint ~/Documents $ scp -r documents mrarianto@202.x.x.x:.
mrarianto@202.x.x.x's password:
Label.pdf 100% 3672KB 282.5KB/s 00:13
scp.txt 100% 10KB 9.8KB/s 00:00

拷贝完成后,你会在目标服务器中找到一个名为“documents”的文件夹,其中就是所拷贝的所有文件。“documents”是系统自动创建的文件夹。

禁用进度条和警告/诊断信息

如果你不想从SCP中看到进度条和警告/诊断信息,你可以用“-q”参数来静默它们,举例如下。

pungki@mint ~/Documents $ scp -q Label.pdf mrarianto@202.x.x.x:.
mrarianto@202.x.x.x's password:
pungki@mint ~/Documents $

正如你所看到的,在你输入密码之后,没有任何关于SCP进度的消息反馈。进度完成后,你也看不到任何提示。

用SCP通过代理来拷贝文件

代理服务器经常用于办公环境,SCP自然是没有经过代理方面的配置的。当你的环境正在使用代理,那么你就必须要“告诉”SCP与代理关联起来。

场景如下:代理的地址是10.0.96.6,端口是8080。该代理还实现了用户认证功能。首先,你需要创建一个“~/.ssh/config”文件,其次把以下命令输入进该文件。

ProxyCommand /usr/bin/corkscrew 10.0.96.6 8080 %h %p ~/.ssh/proxyauth

接着你需要创建一个同样包括以下命令的“~/.ssh/proxyauth”文件。

myusername:mypassword

然后你就可以像往常一样使用SCP了。

请注意corkscrew可能还没有安装在你的系统中。在我的Linux Mint中,我需要首先先用标准Linux Mint安装程序来安装它。

$ apt-get install corkscrew

对于其它的一些基于yum安装的系统,用户能用以下的命令来安装corkscrew。

# yum install corkscrew

还有一点就是因为“~/.ssh/proxyauth”文件中以明文的格式包含了你的“用户名”和“密码”,所以请确保该文件只能你来查看。

选择不同的ssh_config文件

对于经常在公司网络和公共网络之间切换的移动用户来说,一直改变SCP的设置显然是很痛苦的。如果我们能放一个保存不同配置的ssh_config文件来匹配我们的需求那就很好了。

以下是一个简单的场景

代理是被用来在公司网络但不是公共网络并且你会定期切换网络时候使用的。

pungki@mint ~/Documents $ scp -F /home/pungki/proxy_ssh_config Label.pdf
mrarianto@202.x.x.x:.
mrarianto@202.x.x.x's password:
Label.pdf 100% 3672KB 282.5KB/s 00:13

默认情况下每个用户会把“ssh_config”文件放在“~/.ssh/config“路径下。用兼容的代理创建一个特定的“ssh_config”文件,能让你切换网络时更加方便容易。

当你处于公司网络时,你可以用“-F”参数,当你处于公共网络时,你可以忽略掉“-F”参数。

以上就是关于SCP的全部内容了,你可以查看SCPman页面来获取更多内容,请随意留下您的评论及建议。


via: http://www.tecmint.com/scp-commands-examples/

作者:Pungki Arianto 译者:ZTinoZ 校对:wxy

本文由 LCTT 原创翻译,Linux中国 荣誉推出

来源:https://linux.cn/article-4527-1.html

Linux:当MySQL数据库遭到攻击篡改后,使用备份和binlog进行数据恢复

本文主要描述了MySQL遭到攻击篡改数据,利用从库的备份和主库的Binlog进行不完全恢复。 

Linux:当MySQL数据库遭到攻击篡改后,使用备份和binlog进行数据恢复
Linux:当MySQL数据库遭到攻击篡改后,使用备份和binlog进行数据恢复

一、发现问题

今天是2014-09-26,开发大清早就说昨晚数据库遭到了攻击。数据库中某文章表的文章内容字段遭到篡改,全部改成了同一篇文章。

通过查看日制 发现 数据是在 2014-09-25 21:53:57 遭到篡改。

所有的内容全部被改成了如下:

Linux:当MySQL数据库遭到攻击篡改后,使用备份和binlog进行数据恢复
Linux:当MySQL数据库遭到攻击篡改后,使用备份和binlog进行数据恢复

我把文章贴出来,先谴责一下,很可能是某旅游社的人为了打广告 雇人干的。

二、解决方法

这个库我们是每天凌晨备份,保留30天的备份。主库的Binlog保留时间为7天。

因此很容易想到的方法是将从库2014-09-25凌晨的备份拿出来恢复,然后通过主库的Binlog通过时间段来筛选出凌晨至2014-09-25 21:53:56的所有更改,之后的数据,经业务确认,可以舍弃掉。或者后面再通过其他方法慢慢将这部分数据找出来。但是当务之急,是立马恢复数据库。

三、找备份及时间点

在备份的从库上检查备份:

crontab -l 
#0 3 * * * /data/opdir/mysqlbak/backup_mysqldump.sh 6084 >> /data/opdir/mysqlbak/6084/mysql-bakup.log 2>&1

发现备份任务让注释了

查看备份文件:

[root@localhost 6084]# ll
total 128
drwxr-xr-x 2 root root 4096 Aug 25 03:13 20140825
drwxr-xr-x 2 root root 4096 Aug 26 03:13 20140826
drwxr-xr-x 2 root root 4096 Aug 27 03:13 20140827
drwxr-xr-x 2 root root 4096 Aug 28 03:13 20140828
drwxr-xr-x 2 root root 4096 Aug 29 03:13 20140829
drwxr-xr-x 2 root root 4096 Aug 30 03:13 20140830
drwxr-xr-x 2 root root 4096 Aug 31 03:13 20140831
drwxr-xr-x 2 root root 4096 Sep  1 03:13 20140901
drwxr-xr-x 2 root root 4096 Sep  2 03:13 20140902
drwxr-xr-x 2 root root 4096 Sep  3 03:13 20140903
drwxr-xr-x 2 root root 4096 Sep  4 03:13 20140904
drwxr-xr-x 2 root root 4096 Sep  5 03:13 20140905
drwxr-xr-x 2 root root 4096 Sep  6 03:13 20140906
drwxr-xr-x 2 root root 4096 Sep  7 03:13 20140907
drwxr-xr-x 2 root root 4096 Sep  8 03:13 20140908
drwxr-xr-x 2 root root 4096 Sep  9 03:13 20140909
drwxr-xr-x 2 root root 4096 Sep 10 03:13 20140910
drwxr-xr-x 2 root root 4096 Sep 11 03:13 20140911
drwxr-xr-x 2 root root 4096 Sep 12 03:13 20140912
drwxr-xr-x 2 root root 4096 Sep 13 03:13 20140913
drwxr-xr-x 2 root root 4096 Sep 14 03:13 20140914
drwxr-xr-x 2 root root 4096 Sep 15 03:13 20140915
drwxr-xr-x 2 root root 4096 Sep 16 03:13 20140916
drwxr-xr-x 2 root root 4096 Sep 17 03:13 20140917
drwxr-xr-x 2 root root 4096 Sep 18 03:14 20140918
drwxr-xr-x 2 root root 4096 Sep 19 03:14 20140919
drwxr-xr-x 2 root root 4096 Sep 20 03:13 20140920
drwxr-xr-x 2 root root 4096 Sep 21 03:13 20140921
drwxr-xr-x 2 root root 4096 Sep 22 03:14 20140922
drwxr-xr-x 2 root root 4096 Sep 23 18:33 20140923
-rw-r--r-- 1 root root 5475 Sep 23 18:33 mysql-bakup.log

备份只到20140923日,下午18:33分。

备份日志最后一段截取:

tail -n 5 mysql-bakup.log 
deleting backup of 30 days ago -- 20140824 
2014-09-23 18:19:12 begin backup ...
20140824 deleted OK 
2014-09-23 18:33:43 end backup ...

因为这些表是在从库备份的,而且表都是MyiSAM的表。查看备份脚本,是先Stop Slave之后,才开始备份,因此从备份脚本输出的日志中找到备份开始的时间是:

2014-09-23 18:19:12

通过:

Drwxr-xr-x 2 root root 4096 Sep 23 18:33 20140923

可看到结束时间是:2014-09-23 18:33:00

现在考虑到底是以备份开始的时间:2014-09-23 18:19:12 为Start-DateTime还是以2014-09-23 18:33:00 为Start-DateTime。

前面 提到备份脚本是从库进行备份的,是在2014-09-23 18:19:12开始的,在这个时刻备份开始,执行了Stop Slave;因此整个备份的状态反映的是从库2014-09-23 18:19:12 这个时间的状态。而且通过监控可以看到在这个时间点,从库的延迟为0,因此可以认为这个备份就是 主库在这个时间的备份

NOTES: 

(有人可能会因为从库上有Binlog,从库也会接受主库的Binlog之类的机制而造成混淆。这里要结合我们具体的备份方式和恢复方式来看,以选出正确的时间点。)

前面提到通过日志查到遭到篡改的时间为:2014-09-25 21:53:57,因此可以将2014-09-25 21:53:56作为Stop-DateTime

因此Binlog命令应该是这样:

mysqlbinlog --database=[db_name] --start-datetime='2014-09-23 18:19:12' --stop-datetime='2014-09-25 21:53:56' [binlog_name] > binlog_name0000x.sql 

四、具体的恢复操作

清楚了这些,具体的操作就简单了:

1.从备份机拷贝备份:

scp <备份机IP>:/data/MySQLbak/20140923/20140923.db_name.gz <恢复测试机IP>:/data/opdir/20140926

2.恢复测试机 解压:

gunzip 20140923.db_name.gz

3.恢复测试机导入(测试恢复库中之前没有db_name这个库):

mysql -uroot -pxxxxxx -S /tmp/mysql.sock < 20140923.db_name

4.将主库的Binlog拷贝到恢复测试机:

查看主库Binlog

-rw-rw---- 1 mysql mysql  87669492 Sep 23 00:00 mysql-bin.000469
-rw-rw---- 1 mysql mysql 268436559 Sep 23 04:20 mysql-bin.000470
-rw-rw---- 1 mysql mysql 268435558 Sep 23 17:32 mysql-bin.000471
-rw-rw---- 1 mysql mysql  37425262 Sep 24 00:00 mysql-bin.000472
-rw-rw---- 1 mysql mysql 137389819 Sep 25 00:00 mysql-bin.000473
-rw-rw---- 1 mysql mysql 147386521 Sep 26 00:00 mysql-bin.000474

 我们需要的Binlog时间段为:2014-09-23 18:28:00 至 2014-09-25 21:53:56 因此只需要:

-rw-rw---- 1 mysql mysql 37425262 Sep 24 00:00 mysql-bin.000472
-rw-rw---- 1 mysql mysql 137389819 Sep 25 00:00 mysql-bin.000473
-rw-rw---- 1 mysql mysql 147386521 Sep 26 00:00 mysql-bin.000474

将这3个Binlog  Copy过去:

scp mysql-bin.000472 <恢复测试机IP>:/data/opdir/20140926 
scp mysql-bin.000473 <恢复测试机IP>:/data/opdir/20140926 
scp mysql-bin.000474 <恢复测试机IP>:/data/opdir/20140926

5.使用MySQLBinlog 生成SQL脚本:

mysqlbinlog --database=[db_name] --start-datetime='2014-09-23 18:19:12' --stop-datetime='2014-09-25 21:53:56' mysql-bin.000472 > 472.SQL
mysqlbinlog --database=[db_name] --start-datetime='2014-09-23 18:19:12' --stop-datetime='2014-09-25 21:53:56' mysql-bin.000473 > 473.SQL
mysqlbinlog --database=[db_name] --start-datetime='2014-09-23 18:19:12' --stop-datetime='2014-09-25 21:53:56' mysql-bin.000474 > 474SQL

6.Binlog生成的SQL脚本导入:

待20140923.db_name导入到恢复测试库之后,将MySQLBinlog生成的SQL脚本导入到数据库中:

mysql -uroot -pxxxxxx -S /tmp/mysql.sock db_name < 472.sql 
mysql -uroot -pxxxxxx -S /tmp/mysql.sock db_name < 473.sql 
mysql -uroot -pxxxxxx -S /tmp/mysql.sock db_name < 474.sql

7.导入完成后检查数据正确性:

大致看一下数据的情况,然后可以通过时间字段来看一下情况:

mysql> select max(createtime),max(updatetime) from table_name;
+-----------------+-----------------+
| max(createtime) | max(updatetime) |
+-----------------+-----------------+
|      1411648043 |      1411648043 |
+-----------------+-----------------+
1 row in set (0.00 sec)

时间差不多为 晚上20:27了

这个判断,作为DBA,查看部分数据,只能起到辅助作用,具体的需要 到底是否OK,需要业务开发的人来判断。

经过业务开发确认后,即可将该数据导出后,再导入到线上主库中。

8、将该库导出,并压缩:

mysqldump -uroot -pxxxxxx -S /tmp/mysql.sock -q db_name table_name > table_name.sql 

压缩:

gzip table_name.sql

scp 到主库 (复制的时候,请将网络因素考虑进去,确认不会占用过多带宽而影响其他线上业务)

9.恢复测试的数据导入到线上主库中:

线上主库操作:

操作之前,最好让开发把应用业务那段先暂停,否则可能会影响导入。比如这个表示MyISAM的,应用那边如果不听有update进来,就会阻塞数据导入。

a、主库将原始被篡改的表改名:(不要上来就drop,先rename,后续确认没问题了再考虑drop,因为很多问题不是一瞬间就能全部反映上来的)

rename table_name to old_table_name;

b、解压:

gunzip -d table_name.sql.gz

c、导入新表数据:

mysql -uroot -pxxxxxx -S /tmp/mysql.sock db_name < table_name.sql

后面就需要开发来进一步验证数据是否 OK 了。 验证没问题后,再启动应用程序。

来源:http://blog.itpub.net/26355921/viewspace-1281757/

Linux:使用 Go 语言实现优雅的服务器重启

Go被设计为一种后台语言,它通常也被用于后端程序中。服务端程序是GO语言最常见的软件产品。在这我要解决的问题是:如何干净利落地升级正在运行的服务端程序。

Linux:使用 Go 语言实现优雅的服务器重启
Linux:使用 Go 语言实现优雅的服务器重启

目标:

  • 不关闭现有连接:例如我们不希望关掉已部署的运行中的程序。但又想不受限制地随时升级服务。

  • socket连接要随时响应用户请求:任何时刻socket的关闭可能使用户返回’连接被拒绝’的消息,而这是不可取的。

  • 新的进程要能够启动并替换掉旧的。

原理

在基于Unix的操作系统中,signal(信号)是与长时间运行的进程交互的常用方法.

  • SIGTERM: 优雅地停止进程

  • SIGHUP: 重启/重新加载进程 (例如: nginx, sshd, apache)

如果收到SIGHUP信号,优雅地重启进程需要以下几个步骤:

  1. 服务器要拒绝新的连接请求,但要保持已有的连接。

  2. 启用新版本的进程

  3. 将socket“交给”新进程,新进程开始接受新连接请求

  4. 旧进程处理完毕后立即停止。

停止接受连接请求

服务器程序的共同点:持有一个死循环来接受连接请求:

for {
  conn, err := listener.Accept()
  // Handle connection
}

跳出这个循环的最简单方式是在socket监听器上设置一个超时,当调用listener.SetTimeout(time.Now())后,listener.Accept()会立即返回一个timeout err,你可以捕获并处理: 

for {
  conn, err := listener.Accept()
  if err != nil {
    if nerr, ok := err.(net.Err); ok && nerr.Timeout() {
       fmt.Println(“Stop accepting connections”)
       return
    }
  }
}

注意这个操作与关闭listener有所不同。这样进程仍在监听服务器端口,但连接请求会被操作系统的网络栈排队,等待一个进程接受它们。 

启动新进程

Go提供了一个原始类型ForkExec来产生新进程.你可以与这个新进程共享某些消息,例如文件描述符或环境参数。

execSpec := &syscall.ProcAttr{  Env:   os.Environ(),  Files: []uintptr{os.Stdin.Fd(), os.Stdout.Fd(), os.Stderr.Fd()},}fork, err := syscall.ForkExec(os.Args[0], os.Args, execSpec)[…]

 你会发现这个进程使用完全相同的参数os.Args启动了一个新进程。 

发送socket到子进程并恢复它

正如你先前看到的,你可以将文件描述符传递到新进程,这需要一些UNIX魔法(一切都是文件),我们可以把socket发送到新进程中,这样新进程就能够使用它并接收及等待新的连接。

但fork-execed进程需要知道它必须从文件中得到socket而不是新建一个(有些兴许已经在使用了,因为我们还没断开已有的监听)。你可以按任何你希望的方法来,最常见的是通过环境变量或命令行标志。

listenerFile, err := listener.File()
if err != nil {
  log.Fatalln("Fail to get socket file descriptor:", err)
}
listenerFd := listenerFile.Fd()
// Set a flag for the new process start process
os.Setenv("_GRACEFUL_RESTART", "true")
execSpec := &syscall.ProcAttr{
  Env:   os.Environ(),
  Files: []uintptr{os.Stdin.Fd(), os.Stdout.Fd(), os.Stderr.Fd(), listenerFd},
}
// Fork exec the new version of your server
fork, err := syscall.ForkExec(os.Args[0], os.Args, execSpec)

 然后在程序的开始处:

var listener *net.TCPListener
if os.Getenv("_GRACEFUL_RESTART") == "true" {
  // The second argument should be the filename of the file descriptor
  // however, a socker is not a named file but we should fit the interface
  // of the os.NewFile function.
  file := os.NewFile(3, "")
  listener, err := net.FileListener(file)
  if err != nil {
    // handle
  }
  var bool ok
  listener, ok = listener.(*net.TCPListener)
  if !ok {
    // handle
  }
} else {
  listener, err = newListenerWithPort(12345)
}

文件描述没有被随机的选择为3,这是因为uintptr的切片已经发送了fork,监听获取了索引3。留意隐式声明问题

最后一步,等待旧服务连接停止

到此为止,就这样,我们已经将其传到另一个正在正确运行的进程,对于旧服务器的最后操作是等其连接关闭。由于标准库里提供了sync.WaitGroup结构体,用go实现这个功能很简单。

每次接收一个连接,在WaitGroup上加1,然后,我们在它完成时将计数器减一:

for {
  conn, err := listener.Accept()
  wg.Add(1)
  go func() {
    handle(conn)
    wg.Done()
  }()
}

至于等待连接的结束,你仅需要wg.Wait(),因为没有新的连接,我们等待wg.Done()已经被所有正在运行的handler调用。

Bonus: 不要无限制等待,给定限量的时间

timeout := time.NewTimer(time.Minute)
wait := make(chan struct{})
go func() {
  wg.Wait()
  wait <- struct{}{}
}()
select {
case <-timeout.C:
  return WaitTimeoutError
case <-wait:
  return nil
}

完整的示例

这篇文章中的代码片段都是从这个完整的示例中提取的:https://github.com/Scalingo/go-graceful-restart-example

结论

socket传递配合ForkExec使用确实是一种无干扰更新进程的有效方式,在最大时间上,新的连接会等待几毫秒——用于服务的启动和恢复socket,但这个时间很短。

这篇文章是我#周五技术系列的一部分,下这个周不会有新的更新了,大家圣诞节快乐。

链接:

来源:http://www.oschina.net/translate/graceful-server-restart-with-go

Linux:深入浅出Docker(一):Docker核心技术预览

【编者按】Docker是PaaS供应商dotCloud开源的一个基于LXC 的高级容器引擎,源代码托管在 GitHub 上, 基于Go语言开发并遵从Apache 2.0协议开源。Docker提供了一种在安全、可重复的环境中自动部署软件的方式,它的出现拉开了基于云计算平台发布产品方式的变革序幕。

1. 背景

1.1. 由PaaS到Container

2013年2月,前Gluster的CEO Ben Golub和dotCloud的CEO Solomon Hykes坐在一起聊天时,Solomon谈到想把dotCloud内部使用的Container容器技术单独拿出来开源,然后围绕这个技术开一家新公司提供技术支持。28岁的Solomon在使用python开发dotCloud的PaaS云时发现,使用 LXC(Linux Container) 技术可以打破产品发布过程中应用开发工程师和系统工程师两者之间无法轻松协作发布产品的难题。这个Container容器技术可以把开发者从日常部署应用的繁杂工作中解脱出来,让开发者能专心写好程序;从系统工程师的角度来看也是一样,他们迫切需要从各种混乱的部署文档中解脱出来,让系统工程师专注在应用的水平扩展、稳定发布的解决方案上。他们越深入交谈,越觉得这是一次云技术的变革,紧接着在2013年3月Docker 0.1发布,拉开了基于云计算平台发布产品方式的变革序幕。

1.2 Docker简介

Linux:深入浅出Docker(一):Docker核心技术预览
Linux:深入浅出Docker(一):Docker核心技术预览

Docker 是 Docker.Inc 公司开源的一个基于 LXC技术之上构建的Container容器引擎, 源代码托管在 GitHub 上, 基于Go语言并遵从Apache2.0协议开源。 Docker在2014年6月召开DockerConf 2014技术大会吸引了IBM、Google、RedHat等业界知名公司的关注和技术支持,无论是从 GitHub 上的代码活跃度,还是Redhat宣布在RHEL7中正式支持Docker, 都给业界一个信号,这是一项创新型的技术解决方案。 就连 Google 公司的 Compute Engine 也支持 docker 在其之上运行, 国内“BAT”先锋企业百度Baidu App Engine(BAE)平台也是以Docker作为其PaaS云基础

Linux:深入浅出Docker(一):Docker核心技术预览
Linux:深入浅出Docker(一):Docker核心技术预览

Docker产生的目的就是为了解决以下问题:

1) 环境管理复杂: 从各种OS到各种中间件再到各种App,一款产品能够成功发布,作为开发者需要关心的东西太多,且难于管理,这个问题在软件行业中普遍存在并需要直接面对。Docker可以简化部署多种应用实例工作,比如Web应用、后台应用、数据库应用、大数据应用比如Hadoop集群、消息队列等等都可以打包成一个Image部署。如图所示:

Linux:深入浅出Docker(一):Docker核心技术预览
Linux:深入浅出Docker(一):Docker核心技术预览

2) 云计算时代的到来: AWS的成功, 引导开发者将应用转移到云上, 解决了硬件管理的问题,然而软件配置和管理相关的问题依然存在 (AWS cloudformation是这个方向的业界标准, 样例模板可参考这里)。Docker的出现正好能帮助软件开发者开阔思路,尝试新的软件管理方法来解决这个问题。

3) 虚拟化手段的变化: 云时代采用标配硬件来降低成本,采用虚拟化手段来满足用户按需分配的资源需求以及保证可用性和隔离性。然而无论是KVM还是Xen,在 Docker 看来都在浪费资源,因为用户需要的是高效运行环境而非OS, GuestOS既浪费资源又难于管理, 更加轻量级的LXC更加灵活和快速。如图所示:

Linux:深入浅出Docker(一):Docker核心技术预览
Linux:深入浅出Docker(一):Docker核心技术预览

4) LXC的便携性: LXC在 Linux 2.6 的 Kernel 里就已经存在了,但是其设计之初并非为云计算考虑的,缺少标准化的描述手段和容器的可便携性,决定其构建出的环境难于分发和标准化管理(相对于KVM之类image和snapshot的概念)。Docker就在这个问题上做出了实质性的创新方法。

1.3 Docker的Hello World

以Fedora 20作为主机为例,直接安装docker-io:

$ sudo yum -y install docker-io

启动docker后台Daemon:

$ sudo systemctl start docker

跑我们第一个Hello World容器:

$ sudo docker run -i -t fedora /bin/echo hello world
Hello world

可以看到在运行命令行后的下一行会打印出经典的Hello World字符串。

来源:http://www.infoq.com/cn/articles/docker-core-technology-preview

Linux:深入浅出Docker(二):Docker命令行探秘

Linux:深入浅出Docker(二):Docker命令行探秘
Linux:深入浅出Docker(二):Docker命令行探秘

1. Docker命令行

Docker官方为了让用户快速了解Docker,提供了一个交互式教程,旨在帮助用户掌握Docker命令行的使用方法。但是由于Docker技术的快速发展,此交互式教程已经无法满足Docker用户的实际使用需求,所以让我们一起开始一次真正的命令行学习之旅。首先,Docker的命令清单可以通过运行docker ,或者 docker help 命令得到:

$ sudo docker

Linux:深入浅出Docker(二):Docker命令行探秘
Linux:深入浅出Docker(二):Docker命令行探秘

在Docker容器技术不断演化的过程中,Docker的子命令已经达到34个之多,其中核心子命令(例如:run)还会有复杂的参数配置。笔者通过结合功能和应用场景方面的考虑,把命令行划分为4个部分,方便我们快速概览Docker命令行的组成结构:

功能划分

命令

环境信息相关

  1. info
  2. version

系统运维相关

  1. attach
  2. build
  3. commit
  4. cp
  5. diff
  6. export
  7. images
  8. import / save / load
  9. inspect
  10. kill
  11. port
  12. pause / unpause
  13. ps
  14. rm
  15. rmi
  16. run
  17. start / stop / restart
  18. tag
  19. top
  20. wait

日志信息相关

  1. events
  2. history
  3. logs

Docker Hub服务相关

  1. login
  2. pull / push
  3. search

1.1 参数约定

单个字符的参数可以放在一起组合配置,例如

docker run -t -i --name test busybox sh 

可以用这样的方式等同:

docker run -ti --name test busybox sh

1.2 Boolean

Boolean参数形式如: -d=false。注意,当你声明这个Boolean参数时,比如 docker run -d=true,它将直接把启动的Container挂起放在后台运行。

1.3 字符串和数字

参数如 –name=“” 定义一个字符串,它仅能被定义一次。同类型的如-c=0 定义一个数字,它也只能被定义一次。

1.4 后台进程

Docker后台进程是一个常驻后台的系统进程,值得注意的是Docker使用同一个文件来支持客户端和后台进程,其中角色切换通过-d来实现。这个后台进程是用来管理容器的,使用Docker –help可以得到更详细的功能参数配置, 如下图:

Linux:深入浅出Docker(二):Docker命令行探秘
Linux:深入浅出Docker(二):Docker命令行探秘

Docker后台进程参数清单如下表:

参数

解释

–api-enable-cors=false

开放远程API调用的 CORS 头信息。这个接口开关对想进行二次开发的上层应用提供了支持。

-b, –bridge=””

挂载已经存在的网桥设备到 Docker 容器里。注意,使用 none 可以停用容器里的网络。

–bip=””

使用 CIDR 地址来设定网络桥的 IP。注意,此参数和 -b 不能一起使用。

-D, –debug=false

开启Debug模式。例如:docker -d -D

-d, –daemon=false

开启Daemon模式。

–dns=[]

强制容器使用DNS服务器。例如: docker -d –dns 8.8.8.8

–dns-search=[]

强制容器使用指定的DNS搜索域名。例如: docker -d –dns-search example.com

-e, –exec-driver=”native”

强制容器使用指定的运行时驱动。例如:docker -d -e lxc

-G, –group=”docker”

在后台运行模式下,赋予指定的Group到相应的unix socket上。注意,当此参数 –group 赋予空字符串时,将去除组信息。

-g, –graph=”/var/lib/docker”

配置Docker运行时根目录

-H, –host=[]

在后台模式下指定socket绑定,可以绑定一个或多个 tcp://host:port, unix:///path/to/socket, fd://* 或 fd://socketfd。例如:

$ docker -H tcp://0.0.0.0:2375 ps 或者

$ export DOCKER_HOST=”tcp://0.0.0.0:2375″$ docker ps

–icc=true

启用内联容器的通信。

–ip=”0.0.0.0″

容器绑定IP时使用的默认IP地址

–ip-forward=true

启动容器的 net.ipv4.ip_forward

–iptables=true

启动Docker容器自定义的iptable规则

–mtu=0

设置容器网络的MTU值,如果没有这个参数,选用默认 route MTU,如果没有默认route,就设置成常量值 1500。

-p, –pidfile=”/var/run/docker.pid”

后台进程PID文件路径。

-r, –restart=true

重启之前运行中的容器

-s, –storage-driver=””

强制容器运行时使用指定的存储驱动,例如,指定使用devicemapper, 可以这样:

docker -d -s devicemapper

–selinux-enabled=false

启用selinux支持

–storage-opt=[]

配置存储驱动的参数

–tls=false

启动TLS认证开关

–tlscacert=”/Users/dxiao/.docker/ca.pem”

通过CA认证过的的certificate文件路径

–tlscert=”/Users/dxiao/.docker/cert.pem”

TLS的certificate文件路径

–tlskey=”/Users/dxiao/.docker/key.pem”

TLS的key文件路径

–tlsverify=false

使用TLS并做后台进程与客户端通讯的验证

-v, –version=false

显示版本信息

注意,其中带有[] 的启动参数可以指定多次,例如

$ docker run -a stdin -a stdout -a stderr -i -t ubuntu /bin/bash

来源:http://www.infoq.com/cn/articles/docker-command-line-quest

Linux:深入浅出Docker(三):Docker开源之路

1. 背景

Linux:深入浅出Docker(三):Docker开源之路
Linux:深入浅出Docker(三):Docker开源之路

Docker从一开始的概念阶段就致力于使用开源驱动的方式来发展,它的成功缘于国外成熟的开源文化氛围,以及可借鉴的社区运营经验。通过本文详细的介绍,让大家可以全面了解一个项目亦或者一项技术是如何通过开源的方式发展起来的。为了更准确的描述Docker的社区状况,请先看一份来自Docker官方的数据:

Linux:深入浅出Docker(三):Docker开源之路
Linux:深入浅出Docker(三):Docker开源之路

图中数据的看点有:

  1. 超过500个代码贡献者。代码的贡献者在社区发展过程中是非常重要的催化剂,它会不断加快产品迭代的速度,让项目更快的交付到最终用户的手里。
  2. 20个全职开发。一般的开源项目一般都不会有如此多的全职开发人员,但是Docker却有20个全职开发人员来驱动一个社区项目。这也从侧面证明了国外公司对开源项目的支持力度,以至于一家初创公司都舍得投入20个全职开发来推动开源技术的发展。
  3. 超过8000个创建在GitHub上的Docker相关项目。通过这个规模可以看到围绕Docker可以使用的项目已经非常丰富。
  4. Docker技术聚会。30个国家超过90个城市举办超过250个Docker技术聚会,这样的技术聚会还在不断增加,Docker技术爱好者可以在线申请承办此类技术聚会。
  5. 50万次的boot2docker下载。boot2docker为Docker官方推荐客户端,50万次也代表当前潜在的用户群体。
Linux:深入浅出Docker(三):Docker开源之路
Linux:深入浅出Docker(三):Docker开源之路

Docker公司目前正式员工50多名,由开源老手Ben Golub(前GlusterFS CEO)主持运营。现在主要有以下几个赢利点:

  1. 印有蓝鲸的T恤和贴纸的品牌价值
  2. 通过Docker Hub服务提供SaaS的分发服务
  3. 提供Docker技术支持和培训

通过了解Docker的社区现状和公司的运营状况,可以发现其在运营的方式上并没有什么特别的地方。除了支付公司员工的正常开支外,它并没有像一般商业公司那样在推广上投入很多资金。Docker在推广上主要是将开源社区和社交网络作为基础推广平台,结合全球范围的Docker技术聚会,形成了良好的良性的客户互动和口口相传的品牌效应。在Docker的开源历程中,通过分析观察用户社区、源代码管理、合作伙伴的生态圈这三种形式,梳理出一套实践经验的案例,方便大家参考学习。

2. 用户社区维护

Docker技术首先考虑的是在技术社区里通过各种渠道来找到它的用户,而当前最流行的技术社交网络不是Twitter,而是GitHub。所以Docker第一步是向GitHub上提交自己的代码开始吸引自己的用户的。我们总说万事开头难,那么Docker的第一个Commit应该是什么,它是否需要包括测试、用户文档、用户开发指南、设计理念等一系列的文档和代码呢?如果参照常规的开源项目,它们都考虑的都很周到,完善的代码文档结构会让用户第一眼就知道这是一个成熟的项目,我们只要用就可以了。但Docker公司却不按套路出牌,第一个Commit仅包括6个主文件:

Linux:深入浅出Docker(三):Docker开源之路
Linux:深入浅出Docker(三):Docker开源之路

没有README,没有开发环境指南,开始阶段用户无法有效的了解Docker项目。但是,这其实也是对的,因为在一个小众的开源项目的初期,很难吸引到社区用户来为它贡献代码。在接下来的很长一段时间,Docker主要是由Docker之父Solomon Hykes开发维护。在没有社区用户参与的情况下,他每天不分昼夜地提交代码,也许是为了生活,也许是为了爱好,Solomon Hykes在拼命的实现心中那个目标:让LXC创建的容器更容易使用。用当下时髦的那句话讲就是不忘初衷。

Linux:深入浅出Docker(三):Docker开源之路
Linux:深入浅出Docker(三):Docker开源之路

从 Solomon Hykes 贡献代码的趋势图,我们可以看到只有保证项目的活跃度(持续贡献代码)那么项目才有可能获得用户的认可和关注。试想,“三天打鱼,两天晒网”的开源项目会给用户怎么样的感觉?作者都不专注,用户怎么可能忠实?这种投入,并不是偶然性的,这是国外业界的开源文化,非常值得我们学习。

在代码贡献的同时,Docker.io的主站也在2013年的5月30日第一次提交到GitHub。这距离第一行代码提交到GitHub已经有5个月。总体来看,Docker从一开始仅仅是一个很酷的想法,到真正完成并可以对外发布版本,也是经历了小半年之久。开源的意义并不像国内大多数厂商发布开源项目一样,一定要在内部应用的很成功才发布到技术社区。我们通过以上数据,可以很容易的看出来,它一定是一个长期的、持续的过程。你越专注的投入,你的项目越有可能成功。

当然,如果仅仅Docker只在GitHub上提供代码来吸引用户,那也不会是最佳的实践。在网站建立后的下一步,它开始在全球各大城市的技术聚会上推广介绍Docker。Docker技术在全球推广的方法是通过线下的技术聚会,外加社交网络媒体传播才得到流行的。Docker官网通过发布“创建Docker技术聚会指南”,引导Docker技术的爱好者自发申请承办技术聚会。Docker官网主要通过类似Twitter、Docker周报、用户论坛等渠道,及时的把每个城市即将开始的技术聚会时间和联系人发布出来,就可以把Docker的技术推广做下去。并且这种形式的最大好处是口碑相传,其长尾效应的结果是Docker技术开始在当地的技术圈得到关注。像这样的技术聚会,一般都在30到200人之间,对于商业项目的推广是无法参照这样推广的。但这种形式就像一颗种子散落在城市中间,一旦有人介绍Docker技术到这个城市的技术圈,就会有更多的用户去GitHub上关注Docker的项目进展。

来源:http://www.infoq.com/cn/articles/docker-open-source-road