Skip to content Skip to main navigation Skip to footer

Linux

Linux:既然float不能表示所有的int,那为什么在类型转换时C++将int转换成float?

问题:

代码如下:

int i = 23;
float f = 3.14;
if (i == f) // 执行某段代码

编译器会将i转换成float类型,然后比较这两个float的大小,但是float能够表示所有的int吗?为什么没有将int和float转换成double类型进行比较呢?

Linux:既然float不能表示所有的int,那为什么在类型转换时C++将int转换成float?
Linux:既然float不能表示所有的int,那为什么在类型转换时C++将int转换成float?

回答:

在整型数的演变中,当int变成unsigned时,会丢掉负数部分(有趣的是,这样的话,0u < -1就是对的了)。

和C语言中的大部分机制(在C++中得到继承)一样,就硬件操作而言,常见的算术转换应该简明易懂。C语言的发明者精通他们所使用机器上的汇编语言,他们编写的C语言对他们和像他们一样编写程序的人有直接的意义,直到使用汇编语言编写(诸如UNIX内核)的程序时。

现如今,一般来说,处理器并不具有混合类型的指令系统(如float和double相加、比较int和float,诸如此类),因为如果这样做造成芯片晶圆的巨大浪费——如果你想支持更多不同的类型,你不得不实现更多的操作码。然而,在实际中,你只有实现"add int to int"、"compare float to float"和"multiply unsigned with unsigned"等功能的常见指令,这使得优先进行算术转换变得很有必要——它们是指令系统中两种类型的映射关系,它们中的大部分很有用处。

从习惯编写低级别机器代码的编程人员的角度来说,如果有了混合类型,那么在一般情况下最有可能使用的汇编指令就是那些只需要进行最少类型转换的指令。其中,有一种特殊情况就是浮点数的转换,特别是在20世纪70年代早期,当时C语言正在被开发,计算机运行速度很慢,而浮点数的计算是通过软件完成的,所以进行转换的成本很高。这拖慢了常用算术运算的转换开发——当时只有一种操作数实现了转换(这个例外就是long到unsigned int的转换,这种转换没有任何要求,在大部分机器上都可以进行。当然并不是全部,因为总有例外情况)。

所以,编写常用的算术转换是为了完成汇编程序员在大部分时间需要做的事情:即有两种不匹配的类型,将一种转换成另一种。这也就是汇编代码所做的事情,除非有特别原因需要进行其它类型转换。对于那些习惯编写汇编代码的人来说,除非是特殊需要,才会被迫去编写一种不同的类型转换。显然,这种情况下提出编写转换是很自然的事情。虽然,你可以简单地写成这样

if((double) i < (double) f)

顺便提一下,在这个问题中有趣的是,unsigned的优先级高于int,所以把intunsigned进行比较时,最终进行的是unsigned类型的比较(开头提到的0u < -1就是这个道理)。我猜测这可能是在早些时候(计算机发展初期),当时的人们认为unsignedint在所表示的数值范围上受到的限制更小:现在还不需要符号位,所以可以使用额外的位来表示更大的数值范围。如果你觉得int可能会溢出,那么就使用unsigned好了——在使用16位表示的ints时这个担心会更明显。


via: stackoverflow

作者:wintermute 译者:KayGuoWhu 校对:wxy

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

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

Linux:监控 Linux 容器性能的命令行神器

ctop是一个新的基于命令行的工具,它可用于在容器层级监控进程。容器通过利用控制器组(cgroup)的资源管理功能,提供了操作系统层级的虚拟化环境。该工具从cgroup收集与内存、CPU、块输入输出的相关数据,以及拥有者、开机时间等元数据,并以人性化的格式呈现给用户,这样就可以快速对系统健康状况进行评估。基于所获得的数据,它可以尝试推测下层的容器技术。ctop也有助于在低内存环境中检测出谁在消耗大量的内存。

功能

ctop的一些功能如下:

  • 收集CPU、内存和块输入输出的度量值
  • 收集与拥有者、容器技术和任务统计相关的信息
  • 通过任意栏对信息排序
  • 以树状视图显示信息
  • 折叠/展开cgroup树
  • 选择并跟踪cgroup/容器
  • 选择显示数据刷新的时间窗口
  • 暂停刷新数据
  • 检测基于systemd、Docker和LXC的容器
  • 基于Docker和LXC的容器的高级特性
    • 打开/连接shell以进行深度诊断
    • 停止/杀死容器类型

安装

ctop是由Python写成的,因此,除了需要Python 2.6或其更高版本外(带有内建的光标支持),别无其它外部依赖。推荐使用Python的pip进行安装,如果还没有安装pip,请先安装,然后使用pip安装ctop。

注意:本文样例来自Ubuntu(14.10)系统

$ sudo apt-get install python-pip

使用pip安装ctop:

poornima@poornima-Lenovo:~$ sudo pip install ctop
[sudo] password for poornima:
Downloading/unpacking ctop
Downloading ctop-0.4.0.tar.gz
Running setup.py (path:/tmp/pip_build_root/ctop/setup.py) egg_info for package ctop
Installing collected packages: ctop
Running setup.py install for ctop
changing mode of build/scripts-2.7/ctop from 644 to 755
changing mode of /usr/local/bin/ctop to 755
Successfully installed ctop
Cleaning up...

如果不选择使用pip安装,你也可以使用wget直接从github安装:

poornima@poornima-Lenovo:~$ wget https://raw.githubusercontent.com/yadutaf/ctop/master/cgroup_top.py -O ctop
--2015-04-29 19:32:53-- https://raw.githubusercontent.com/yadutaf/ctop/master/cgroup_top.py
Resolving raw.githubusercontent.com (raw.githubusercontent.com)... 199.27.78.133
Connecting to raw.githubusercontent.com (raw.githubusercontent.com)|199.27.78.133|:443... connected.
HTTP request sent, awaiting response... 200 OK Length: 27314 (27K) 
Saving to: ctop
100%[======================================>] 27,314 --.-K/s in 0s
2015-04-29 19:32:59 (61.0 MB/s) - ctop saved [27314/27314]

poornima@poornima-Lenovo:~$ chmod +x ctop

如果cgroup-bin包没有安装,你可能会碰到一个错误消息,你可以通过安装需要的包来解决。

poornima@poornima-Lenovo:~$ ./ctop
[ERROR] Failed to locate cgroup mountpoints.
poornima@poornima-Lenovo:~$ sudo apt-get install cgroup-bin

下面是ctop的输出样例:

Linux:监控 Linux 容器性能的命令行神器
Linux:监控 Linux 容器性能的命令行神器

ctop屏幕

用法选项

ctop [--tree] [--refresh=] [--columns=] [--sort-col=] [--follow=] [--fold=, ...] ctop (-h | --help)

当你进入ctop屏幕,可使用上(↑)和下(↓)箭头键在容器间导航。点击某个容器就选定了该容器,按q或Ctrl+C退出该容器。

现在,让我们来看看上面列出的那一堆选项究竟是怎么用的吧。

-h / –help – 显示帮助信息

poornima@poornima-Lenovo:~$ ctop -h
Usage: ctop [options]
Options:
-h, --help show this help message and exit
--tree show tree view by default
--refresh=REFRESH Refresh display every 
--follow=FOLLOW Follow cgroup path
--columns=COLUMNS List of optional columns to display. Always includes
'name'
--sort-col=SORT_COL Select column to sort by initially. Can be changed
dynamically.

–tree – 显示容器的树形视图

默认情况下,会显示列表视图

当你进入ctop窗口,你可以使用F5按钮在树状/列表视图间切换。

–fold= – 在树形视图中折叠名为 的 cgroup 路径

该选项需要与 –tree 选项组合使用。

例子: ctop –tree –fold=/user.slice

Linux:监控 Linux 容器性能的命令行神器
Linux:监控 Linux 容器性能的命令行神器

‘ctop –fold’的输出

在ctop窗口中,使用+/-键来展开或折叠子cgroup。

注意:在写本文时,pip仓库中还没有最新版的ctop,还不支持命令行的‘–fold’选项

–follow= – 跟踪/高亮 cgroup 路径

例子: ctop –follow=/user.slice/user-1000.slice

正如你在下面屏幕中所见到的那样,带有“/user.slice/user-1000.slice”路径的cgroup被高亮显示,这让用户易于跟踪,就算显示位置变了也一样。

Linux:监控 Linux 容器性能的命令行神器
Linux:监控 Linux 容器性能的命令行神器

‘ctop –follow’的输出

你也可以使用‘f’按钮来让高亮的行跟踪选定的容器。默认情况下,跟踪是关闭的。

–refresh= – 按指定频率刷新显示,默认1秒

这对于按每用户需求来显示改变刷新率时很有用。使用‘p’按钮可以暂停刷新并选择文本。

–columns= – 限定只显示选定的列。’name’ 需要是第一个字段,其后跟着其它字段。默认情况下,字段包括:owner, processes,memory, cpu-sys, cpu-user, blkio, cpu-time

例子: ctop –columns=name,owner,type,memory

Linux:监控 Linux 容器性能的命令行神器
Linux:监控 Linux 容器性能的命令行神器

‘ctop –column’的输出

-sort-col= – 按指定的列排序。默认使用 cpu-user 排序

例子: ctop –sort-col=blkio

如果有Docker和LXC支持的额外容器,跟踪选项也是可用的:

press 'a' - 接驳到终端输出
press 'e' - 打开容器中的一个 shell
press 's' - 停止容器 (SIGTERM)
press 'k' - 杀死容器 (SIGKILL)

目前 Jean-Tiare Le Bigot 还在积极开发 ctop 中,希望我们能在该工具中见到像本地 top 命令一样的特性 🙂


via: http://linoxide.com/how-tos/monitor-linux-containers-performance/

作者:B N Poornima 译者:GOLinux 校对:wxy

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

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

Linux:iptraf:一个实用的TCP/UDP网络监控工具

iptraf是一个基于ncurses的IP局域网监控器,用来生成包括TCP信息、UDP计数、ICMP和OSPF信息、以太网负载信息、节点状态信息、IP校验和错误等等统计数据。

它基于ncurses的用户界面可以使用户免于记忆繁琐的命令行开关。

特征

  • IP流量监控器,用来显示你的网络中的IP流量变化信息。包括TCP标识信息、包以及字节计数,ICMP细节,OSPF包类型。
  • 简单的和详细的接口统计数据,包括IP、TCP、UDP、ICMP、非IP以及其他的IP包计数、IP校验和错误,接口活动、包大小计数。
  • TCP和UDP服务监控器,能够显示常见的TCP和UDP应用端口上发送的和接收的包的数量。
  • 局域网数据统计模块,能够发现在线的主机,并显示其上的数据活动统计信息。
  • TCP、UDP、及其他协议的显示过滤器,允许你只查看感兴趣的流量。
  • 日志功能。
  • 支持以太网、FDDI、ISDN、SLIP、PPP以及本地回环接口类型。
  • 利用Linux内核内置的原始套接字接口,允许它(指iptraf)能够用于各种支持的网卡上
  • 全屏,菜单式驱动的操作。

安装方法

Ubuntu以及其衍生版本

sudo apt-get install iptraf

Arch Linux以及其衍生版本

sudo pacman -S iptra

Fedora以及其衍生版本

sudo yum install iptraf

用法

如果不加任何命令行选项地运行iptraf命令,程序将进入一种交互模式,通过主菜单可以访问多种功能。

Linux:iptraf:一个实用的TCP/UDP网络监控工具
Linux:iptraf:一个实用的TCP/UDP网络监控工具

简易的上手导航菜单。

Linux:iptraf:一个实用的TCP/UDP网络监控工具
Linux:iptraf:一个实用的TCP/UDP网络监控工具

选择要监控的接口。

Linux:iptraf:一个实用的TCP/UDP网络监控工具
Linux:iptraf:一个实用的TCP/UDP网络监控工具

接口ppp0处的流量。

Linux:iptraf:一个实用的TCP/UDP网络监控工具
Linux:iptraf:一个实用的TCP/UDP网络监控工具

试试吧!


via: http://www.unixmen.com/iptraf-tcpudp-network-monitoring-utility/

作者:Enock Seth Nyamador 译者:DongShuaike 校对:wxy

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

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

Linux:理解 linux 内核的软中断

软中断介绍

把可以延迟的处理从硬中断处理程序独立出来,这样这个处理可以在开中断的情况下运行,这个处理就是软中断。可见,软中断的这种脱离可以大大缩短硬中断的响应时间,对于很多实时应用来说及其重要。

我们本文只谈软中断,至于tasklet、workqueue等我们以后再谈。我们在讲述软中断流程(参考linux kernel 4.0)时会尝试深入理解其中的各个细节之处,分享我们自己的理解(如果不正,还望指出,谢谢)。

Linux:理解 linux 内核的软中断
Linux:理解 linux 内核的软中断

(题图来自:techvark.com)

软中断数据结构的定义

软中断目前有10(由NR_SOFTIRQS定义)个,通过softirq_vec[NR_SOFTIRQS]数组来管理这些软中断,全部cpu共用。

软中断的注册

通过open_softirq()将具体的软中断处理函数和软中断编号绑定。如网络系统注册了收发包的软中断处理函数:

open_softirq(NET_TX_SOFTIRQ, net_tx_action);
open_softirq(NET_RX_SOFTIRQ, net_rx_action);

软中断的激活

每个cpu都有一个32bit的位图(即__softirq_pending)来维护本cpu上的软中断是否激活。

typedef struct {
    unsigned int __softirq_pending;
    #ifdef CONFIG_SMP
    unsigned int ipi_irqs[NR_IPI];
    #endif
} ____cacheline_aligned irq_cpustat_
irq_cpustat_t irq_stat[NR_CPUS] ____cacheline_aligned;

软中断的激活时机之一:irq_exit

irq_exit函数里可能会激活软中断,激活条件是:

不在硬中断里并且不在软中断里并且本cpu的__softirq_pending中有置位。

if (!in_interrupt() && local_softirq_pending())
    invoke_softirq();

由这个条件,我们可以知道,软中断和硬中断在这里是同等对待(在in_interrupt里)的,体现都是中断处理这一个本质。不能在硬中断里的条件,表明必须优先性,必须硬中断全部处理完,才考虑软中断;不能在软中断里的条件,表明屏蔽了软中断的嵌套。

invoke_softirq函数的处理是,要么(先唤醒ksoftirqd)将软中断交由ksoftirqd专门线程处理,要么直接调用__do_softirq即时处理(当然,即时处理要区分是在哪个栈上:是当前栈上还是在独立的软中断栈上)。

我们看看即时处理这个流程。local_softirq_pending前肯定会清除preempt_count中的硬中断位,如果此时preempt_count里没有软中断位则可以被抢占(即时关闭硬中断)。在进入到__do_softirq处理各个软中断期间,肯定是禁止抢占了。在硬(软)中断上下文里的抢占是众所周知不被允许的:会让被中断的进程执行时间不确定,也是不公平的(也就是说,不要在硬中断和软中断的处理中有调度离开的意向)。

软中断的激活时机之二:raise_softirq

网卡收包方式从非NAPI进化到NAPI方式,就充分展示了软中断的优点:把收报任务最大程度地交给软中断处理,最大程度简化硬中断处理。这种进化,我们以后再讲。

raise_softirq函数会调用__raise_softirq_irqoff函数,在指定cpu的__softirq_pending位图上置位相应的软中断。raise_softirq_irqoff函数和raise_softirq函数的区别是关中断的操作是否已经完成了。置位位图是一个竞争操作,所有硬中断里都可能做,所以得保证在关中断的情况下完成。

软中断的激活之三:ksoftirqd

每个cpu都有一个ksoftirqd线程在软中断量大时专门处理软中断:

DEFINE_PER_CPU(struct task_struct *, ksoftirqd);

ksoftirqd线程的核心函数run_ksoftirqd的(循环)处理是:关中断看本cpu的__softirq_pending的置位情况,如有则执行__do_softirqd(),执行完开中断)。这个执行很顺畅,因为是在该线程自己的栈上,不会有影响用户进程的问题。

这里有个疑问,此处以前是关抢占保护,现在是关中断的保护了(参考2012年的patch 3e339b,softirq: Use hotplugthread infrastructure)?我们的理解是:关抢占的保护方式,会让后续更多的软中断由ksoftirqd处理,不符合ksoftirqd的辅助地位。就处理软中断的地位而言,应该是irq_exit的为主,ksoftirqd的为辅。)

ksoftirqd里也可以看到,在执行软中断前是可以被抢占的,但是一旦开始执行就不能被抢占了(和上面的调度之一:irq_exit中的讲述的思想是一致的)。就是说,软中断和硬中断的处理思想是一致的:执行期间不允许发生调度!

上述不能抢占的原因其实就是类似事务性的一个原则:一旦开始不能停止。另外一个原因是,执行的是用户自定义的硬(软)中断程序,操作具有不确定性,如果让这些操作期间具有调度可能,则会脱离内核的控制范围。

软中断的激活之四:其他地方

比如netif_rx_ni(),执行do_softirq前关抢占,不能在执行软中断期间调度。

软中断的激活之五:local_bh_enable

if (unlikely(!in_interrupt() && local_softirq_pending()))
    do_softirq();

想想,如果异常和软中断有共享数据的话,异常处理走到此共享数据的临界区时需要关软中断,但不需要关硬中断。那么当走完临界区时,需要开软中断,此时就是一个激活时机(看preempt_count了,其实可能也是一个抢占时机)。

用“激活”而不是“调用”的原因是外围处理仅修改本cpu的__softirq_pending位图,最后由核心机制(比如ksoftirqd、能通过in_interrupt检查的软中断处理)真正处理,而这就是软中断的理念:让硬中断(或者其它)更快执行,所以不会采用直接调用的方式。

“激活”的原则是谁激活,谁处理,哪个cpu上的硬中断带来的软中断就由哪个cpu处理(或者说,归属cpu是软中断跟着硬中断走)。这样,充分发挥smp的优势,均衡到各个cpu上。至于硬中断和cpu之间的关系,我们以后讲到硬中断时再讨论。每个cpu维护自己的软中断机制就行了,各个cpu是互不相关的。注意,还是有相关性的:各个cpu并行处理同一类型的软中断时,该类型软中断处理需要为共享数据做保护,这是软中断可重入性需要付出的代价。

软中断核心函数处理之do_softirq

do_softirq先检查软中断重入条件:必须不在硬中断里并且不在软中断里,符合条件之后就可以开始做如下的软中断处理了:

pending = local_softirq_pending();
if (pending)
    __do_softirq();

这个处理是在关中断的保护下完成的,毕竟软中断和硬中断本质上是一样的,都是中断体系的(当然,进入到硬/软中断内部再开则另当别论了)。也可以看到,局部变量pending没有传入__do_softirq内部,所以此处仅是判断,不是使用,此处判断值和内部使用值可能有差异,位图中置位位数会少一些。

我们再深究一下这个检查条件。我们的理解是:

这个条件达到了两个效果:同一个cpu上的软中断不嵌套;嵌套硬中断中不处理软中断。就同一个cpu而言,__do_softirq函数的执行是串行的,非重入的(do_softirq函数可以说是可重入的);就多个cpu而言,__do_softirq函数是可重入的,即使是同一个类型的软中断。也就是说,软中断通过这个检查条件做到了本cpu上的软中断处理串行化,当然,多cpu之间的还是并行的,所以同一类型软中断处理还是需要保护自己的相关共享数据结构的。

软中断核心函数处理之__do_softirq

__do_softirq函数处理是尽量(虽然可能还是执行不完)执行所有被激活的软中断(由本cpu上的__softirq_pending位图标识)处理。我们分三个阶段分析。

准备处理阶段:关闭软中断(效果是让上面提到的检查条件为真,从而达到禁止本cpu上的软中断嵌套的目的)。

核心处理阶段:关硬中断,获得本cpu的__softirq_pending位图并存储起来,清空位图,开硬中断(仅在读写位图时需要关硬中断,防止其它硬中断同时操作)。执行本cpu的所有软中断(由存储起来的位图获得)。这个核心处理是个循环,最多10次(MAX_SOFTIRQ_RESTART),毕竟此时用的是用户进程的栈,不能借用太久。退出循环的条件是:总时间超出或者被抢占(开中断就会有被抢占)或者达到10次了。

结尾处理阶段:关硬中断,开软中断。

另外,如果10次循环都解决不完软中断,说明期间发生的硬中断很多,带来的额外的软中断也很多。那么就不继续影响借用的用户进程栈了,直接交给专门的ksoftirqd内核线程处理。这也就说明了循环的含义:处理软中断期间时还会进入新的硬中断,从而带进新的软中断(当然,仅仅是在本cpu的__softirq_pending上置位,不会有实际处理),所以需要反复去处理(处理的目标很明确,就是要清空本cpu上的__softirq_pending位图)。

再看看那个防止软中断嵌套的流程。关软中断中肯定有一句原子地加1的关键语句,如果当前内核路径A在该原子操作之前被另一个内核路径B打断,则B执行完硬中断和软中断后,返回到A的此处,A接着执行该原子操作,之后的软中断处理应该是空转,因为肯定已经被B处理完了。如果在该原子操作之后被B打断,则B执行完硬中断,不会执行自己的软中断而是会直接退出(因为软中断嵌套了),返回到A的此处,A接着执行,这次A除了处理自己软中断,还会额外地处理B的软中断。

对于preempt_count中的软中断位,由上述可以知道,它的作用有两个:防止软中断在单cpu上嵌套;保证了在执行软中断期间不被抢占。

最后,还得重复一句:这里讲的__do_softirq函数都是在一个cpu上的处理,多个cpu上的并行是不受任何控制的。

总结

关于中断的时序貌似很复杂,但其实都逃不过两个原则:硬中断会打断硬中断(当然是不同类型的);硬中断会打断软中断(同样地:软中断不会打断硬中断,软中断也不会打断软中断)。所有貌似复杂的时序其实都只是这两个的叠加而已。

作者:计算机学习微信公众号(jsj_xx)

来源:http://weibo.com/5577991241/Cggd9liDy

Linux:MySQL 高可用浅析

对于多数应用来说,MySQL都是作为最关键的数据存储中心的,所以,如何让MySQL提供HA服务,是我们不得不面对的一个问题。当master当机的时候,我们如何保证数据尽可能的不丢失,如何保证快速的获知master当机并进行相应的故障转移处理,都是需要我们好好思考的。这里,笔者将结合这段时间做的MySQL proxy以及toolsets相关工作,说说我们现阶段以及后续会在项目中采用的MySQL HA方案。

Linux:MySQL 高可用浅析
Linux:MySQL 高可用浅析

(题图来自:comprendrechoisir.com)

Replication

要保证MySQL数据不丢失,replication是一个很好的解决方案,而MySQL也提供了一套强大的replication机制。只是我们需要知道,为了性能考量,replication是采用的asynchronous模式,也就是写入的数据并不会同步更新到slave上面,如果这时候master当机,我们仍然可能会面临数据丢失的风险。

为了解决这个问题,我们可以使用semi-synchronous replication,semi-synchronous replication的原理很简单,当master处理完一个事务,它会等待至少一个支持semi-synchronous的slave确认收到了该事件并将其写入relay-log之后,才会返回。这样即使master当机,最少也有一个slave获取到了完整的数据。

但是,semi-synchronous并不是100%的保证数据不会丢失,如果master在完成事务并将其发送给slave的时候崩溃,仍然可能造成数据丢失。只是相比于传统的异步复制,semi-synchronous replication能极大地提升数据安全。更为重要的是,它并不慢,MHA的作者都说他们在facebook的生产环境中使用了semi-synchronous(这里),所以我觉得真心没必要担心它的性能问题,除非你的业务量级已经完全超越了facebook或者google。在这篇文章里面已经提到,MySQL 5.7之后已经使用了Loss-Less Semi-Synchronous replication,所以丢数据的概率已经很小了。

如果真的想完全保证数据不会丢失,现阶段一个比较好的办法就是使用gelera,一个MySQL集群解决方案,它通过同时写三份的策略来保证数据不会丢失。笔者没有任何使用gelera的经验,只是知道业界已经有公司将其用于生产环境中,性能应该也不是问题。但gelera对MySQL代码侵入性较强,可能对某些有代码洁癖的同学来说不合适了:-)

我们还可以使用drbd来实现MySQL数据复制,MySQL官方文档有一篇文档有详细介绍,但笔者并未采用这套方案,MHA的作者写了一些采用drdb的问题,在这里,仅供参考。

在后续的项目中,笔者会优先使用semi-synchronous replication的解决方案,如果数据真的非常重要,则会考虑使用gelera。

Monitor

前面我们说了使用replication机制来保证master当机之后尽可能的数据不丢失,但是我们不能等到master当了几分钟才知道出现问题了。所以一套好的监控工具是必不可少的。

当master当掉之后,monitor能快速的检测到并做后续处理,譬如邮件通知管理员,或者通知守护程序快速进行failover。

通常,对于一个服务的监控,我们采用keepalived或者heartbeat的方式,这样当master当机之后,我们能很方便的切换到备机上面。但他们仍然不能很即时的检测到服务不可用。笔者的公司现阶段使用的是keepalived的方式,但后续笔者更倾向于使用zookeeper来解决整个MySQL集群的monitor以及failover。

对于任何一个MySQL实例,我们都有一个对应的agent程序,agent跟该MySQL实例放到同一台机器上面,并且定时的对MySQL实例发送ping命令检测其可用性,同时该agent通过ephemeral的方式挂载到zookeeper上面。这样,我们可以就能知道MySQL是否当机,主要有以下几种情况:

  1. 机器当机,这样MySQL以及agent都会当掉,agent与zookeeper连接自然断开
  2. MySQL当掉,agent发现ping不通,主动断开与zookeeper的连接
  3. Agent当掉,但MySQL未当

上面三种情况,我们都可以认为MySQL机器出现了问题,并且zookeeper能够立即感知。agent与zookeeper断开了连接,zookeeper触发相应的children changed事件,监控到该事件的管控服务就可以做相应的处理。譬如如果是上面前两种情况,管控服务就能自动进行failover,但如果是第三种,则可能不做处理,等待机器上面crontab或者supersivord等相关服务自动重启agent。

使用zookeeper的好处在于它能很方便的对整个集群进行监控,并能即时的获取整个集群的变化信息并触发相应的事件通知感兴趣的服务,同时协调多个服务进行相关处理。而这些是keepalived或者heartbeat做不到或者做起来太麻烦的。

使用zookeeper的问题在于部署起来较为复杂,同时如果进行了failover,如何让应用程序获取到最新的数据库地址也是一个比较麻烦的问题。

对于部署问题,我们要保证一个MySQL搭配一个agent,幸好这年头有了docker,所以真心很简单。而对于第二个数据库地址更改的问题,其实并不是使用了zookeeper才会有的,我们可以通知应用动态更新配置信息,VIP,或者使用proxy来解决。

虽然zookeeper的好处很多,但如果你的业务不复杂,譬如只有一个master,一个slave,zookeeper可能并不是最好的选择,没准keepalived就够了。

Failover

通过monitor,我们可以很方便的进行MySQL监控,同时在MySQL当机之后通知相应的服务做failover处理,假设现在有这样的一个MySQL集群,a为master,b,c为其slave,当a当掉之后,我们需要做failover,那么我们选择b,c中的哪一个作为新的master呢?

原则很简单,哪一个slave拥有最近最多的原master数据,就选哪一个作为新的master。我们可以通过show slave status这个命令来获知哪一个slave拥有最新的数据。我们只需要比较两个关键字段Master_Log_File以及Read_Master_Log_Pos,这两个值代表了slave读取到master哪一个binlog文件的哪一个位置,binlog的索引值越大,同时pos越大,则那一个slave就是能被提升为master。这里我们不讨论多个slave可能会被提升为master的情况。

在前面的例子中,假设b被提升为master了,我们需要将c重新指向新的master b来开始复制。我们通过CHANGE MASTER TO来重新设置c的master,但是我们怎么知道要从b的binlog的哪一个文件,哪一个position开始复制呢?

GTID

为了解决这一个问题,MySQL 5.6之后引入了GTID的概念,即uuid:gid,uuid为MySQL server的uuid,是全局唯一的,而gid则是一个递增的事务id,通过这两个东西,我们就能唯一标示一个记录到binlog中的事务。使用GTID,我们就能非常方便的进行failover的处理。

仍然是前面的例子,假设b此时读取到的a最后一个GTID为3E11FA47-71CA-11E1-9E33-C80AA9429562:23,而c的为3E11FA47-71CA-11E1-9E33-C80AA9429562:15,当c指向新的master b的时候,我们通过GTID就可以知道,只要在b中的binlog中找到GTID为3E11FA47-71CA-11E1-9E33-C80AA9429562:15这个event,那么c就可以从它的下一个event的位置开始复制了。虽然查找binlog的方式仍然是顺序查找,稍显低效暴力,但比起我们自己去猜测哪一个filename和position,要方便太多了。

google很早也有了一个Global Transaction ID的补丁,不过只是使用的一个递增的整形,LedisDB就借鉴了它的思路来实现failover,只不过google貌似现在也开始逐步迁移到MariaDB上面去了。

MariaDB的GTID实现跟MySQL 5.6是不一样的,这点其实比较麻烦,对于我的MySQL工具集go-mysql来说,意味着要写两套不同的代码来处理GTID的情况了。后续是否支持MariaDB再看情况吧。

Pseudo GTID

GTID虽然是一个好东西,但是仅限于MySQL 5.6+,当前仍然有大部分的业务使用的是5.6之前的版本,笔者的公司就是5.5的,而这些数据库至少长时间也不会升级到5.6的。所以我们仍然需要一套好的机制来选择master binlog的filename以及position。

最初,笔者打算研究MHA的实现,它采用的是首先复制relay log来补足缺失的event的方式,但笔者不怎么信任relay log,同时加之MHA采用的是perl,一个让我完全看不懂的语言,所以放弃了继续研究。

幸运的是,笔者遇到了orchestrator这个项目,这真的是一个非常神奇的项目,它采用了一种Pseudo GTID的方式,核心代码就是这个

create database if not exists meta;
drop event if exists meta.create_pseudo_gtid_view_event;
delimiter ;;
create event if not exists
  meta.create_pseudo_gtid_view_event
  on schedule every 10 second starts current_timestamp
  on completion preserve
  enable
  do
    begin
      set @pseudo_gtid := uuid();
      set @_create_statement := concat('create or replace view meta.pseudo_gtid_view as select '', @pseudo_gtid, '' as pseudo_gtid_unique_val from dual');
      PREPARE st FROM @_create_statement;
      EXECUTE st;
      DEALLOCATE PREPARE st;
    end
;;
delimiter ;
set global event_scheduler := 1;

它在MySQL上面创建了一个事件,每隔10s,就将一个uuid写入到一个view里面,而这个是会记录到binlog中的,虽然我们仍然不能像GTID那样直接定位到一个event,但也能定位到一个10s的区间了,这样我们就能在很小的一个区间里面对比两个MySQL的binlog了。

继续上面的例子,假设c最后一次出现uuid的位置为s1,我们在b里面找到该uuid,位置为s2,然后依次对比后续的event,如果不一致,则可能出现了问题,停止复制。当遍历到c最后一个binlog event之后,我们就能得到此时b下一个event对应的filename以及position了,然后让c指向这个位置开始复制。

使用Pseudo GTID需要slave打开log-slave-update的选项,考虑到GTID也必须打开该选项,所以个人感觉完全可以接受。

后续,笔者自己实现的failover工具,将会采用这种Pseudo GTID的方式实现。

在《MySQL High Availability》这本书中,作者使用了另一种GTID的做法,每次commit的时候,需要在一个表里面记录gtid,然后就通过这个gtid来找到对应的位置信息,只是这种方式需要业务MySQL客户端的支持,笔者不很喜欢,就不采用了。

后记

MySQL HA一直是一个水比较深的领域,笔者仅仅列出了一些最近研究的东西,有些相关工具会尽量在go-mysql中实现。

更新

经过一段时间的思考与研究,笔者又有了很多心得与收获,设计的MySQL HA跟先前有了很多不一样的地方。后来发现,自己设计的这套HA方案,跟facebook这篇文章几乎一样,加之最近跟facebook的人聊天听到他们也正在大力实施,所以感觉自己方向是对了。

新的HA,我会完全拥抱GTID,比较这玩意的出现就是为了解决原先replication那一堆问题的,所以我不会考虑非GTID的低版本MySQL了。幸运的是,我们项目已经将MySQL全部升级到5.6,完全支持GTID了。

不同于fb那篇文章将mysqlbinlog改造支持semi-sync replication协议,我是将go-mysql的replication库支持semi-sync replication协议,这样就能实时的将MySQL的binlog同步到一台机器上面。这可能就是我和fb方案的唯一区别了。

只同步binlog速度铁定比原生slave要快,毕竟少了执行binlog里面event的过程了,而另外真正的slaves,我们仍然使用最原始的同步方式,不使用semi-sync replication。然后我们通过MHA监控整个集群以及进行故障转移处理。

以前我总认为MHA不好理解,但其实这是一个非常强大的工具,而且真正看perl,发现也还是看的懂得。MHA已经被很多公司用于生产环境,经受了检验,直接使用绝对比自己写一个要划算。所以后续我也不会考虑zookeeper,考虑自己写agent了。

 

来源:http://www.jianshu.com/p/cc6746ac4fc2

Linux:短 URL 系统是怎么设计的?

Linux:短 URL 系统是怎么设计的?
Linux:短 URL 系统是怎么设计的?

最烂的回答

实现一个算法,将长地址转成短地址。实现长和短一一对应。然后再实现它的逆运算,将短地址还能换算回长地址。

这个回答看起来挺完美的,然后候选人也会说现在时间比较短,如果给我时间我去找这个算法就解决问题了。但是稍微有点计算机或者信息论常识的人就能发现,这个算法就跟永动机一样,是永远不可能找到的。即使我们定义短地址是100位。那么它的变化是62的100次方。62=10数字+26大写字母+26小写字母。无论这个数多么大,他也不可能大过世界上可能存在的长地址。所以实现一一对应,本身就是不可能的。

再换一个说法来反驳,如果真有这么一个算法和逆运算,那么基本上现在的压缩软件都可以歇菜了,而世界上所有的信息,都可以压缩到100个字符。这~可能吗。

另一个很烂的回答

和上面一样,也找一个算法,把长地址转成短地址,但是不存在逆运算。我们需要把短对长的关系存到DB中,在通过短查长时,需要查DB。

怎么说呢,没有改变本质,如果真有这么一个算法,那必然是会出现碰撞的,也就是多个长地址转成了同一个短地址。因为我们无法预知会输入什么样的长地址到这个系统中,所以不可能实现这样一个绝对不碰撞的hash函数。

比较烂的回答

那我们用一个hash算法,我承认它会碰撞,碰撞后我再在后面加1,2,3不就行了。

ok,这样的话,当通过这个hash算法算出来之后,可能我们会需要做btree式的大于小于或者like查找到能知道现在应该在后面加1,2,或3,这个也可能由于输入的长地址集的不确定性。导致生成短地址时间的不确定性。同样烂的回答还有随机生成一个短地址,去查找是否用过,用过就再随机,如此往复,直到随机到一个没用过的短地址。

正确的原理

上面是几种典型的错误回答,下面咱们直接说正确的原理。

正确的原理就是通过发号策略,给每一个过来的长地址,发一个号即可,小型系统直接用mysql的自增索引就搞定了。如果是大型应用,可以考虑各种分布式key-value系统做发号器。不停的自增就行了。第一个使用这个服务的人得到的短地址是 http://xx.xx/0 第二个是 http://xx.xx/1 第11个是 http://xx.xx/a 第依次往后,相当于实现了一个62进制的自增字段即可。

几个子问题

1. 62进制如何用数据库或者KV存储来做?

其实我们并不需要在存储中用62进制,用10进制就好了。比如第10000个长地址,我们给它的短地址对应的编号是9999,我们通过存储自增拿到9999后,再做一个10进制到62进制的转换,转成62进制数即可。这个10~62进制转换,你完全都可以自己实现。

2. 如何保证同一个长地址,每次转出来都是一样的短地址

上面的发号原理中,是不判断长地址是否已经转过的。也就是说用拿着百度首页地址来转,我给一个http://xx.xx/abc 过一段时间你再来转,我还会给你一个 http://xx.xx/xyz。这看起来挺不好的,但是不好在哪里呢?不好在不是一一对应,而一长对多短。这与我们完美主义的基因不符合,那么除此以外还有什么不对的地方?

有人说它浪费空间,这是对的。同一个长地址,产生多条短地址记录,这明显是浪费空间的。那么我们如何避免空间浪费,有人非常迅速的回答我,建立一个长对短的KV存储即可。嗯,听起来有理,但是。。。这个KV存储本身就是浪费大量空间。所以我们是在用空间换空间,而且貌似是在用大空间换小空间。真的划算吗?这个问题要考虑一下。当然,也不是没有办法解决,我们做不到真正的一一对应,那么打个折扣是不是可以搞定?

这个问题的答案太多种,各有各招。这个方案最简单的是建立一个长对短的hashtable,这样相当于用空间来换空间,同时换取一个设计上的优雅(真正的一对一)。实际情况是有很多性价比高的打折方案可以用,这个方案设计因人而异了。那我就说一下我的方案吧。

我的方案是:用key-value存储,保存“最近”生成的长对短的一个对应关系。注意是“最近”,也就是说,我并不保存全量的长对短的关系,而只保存最近的。比如采用一小时过期的机制来实现LRU淘汰。

这样的话,长转短的流程变成这样:

  • 在这个“最近”表中查看一下,看长地址有没有对应的短地址
    • 有就直接返回,并且将这个key-value对的过期时间再延长成一小时
    • 如果没有,就通过发号器生成一个短地址,并且将这个“最近”表中,过期时间为1小时

所以当一个地址被频繁使用,那么它会一直在这个key-value表中,总能返回当初生成那个短地址,不会出现重复的问题。如果它使用并不频繁,那么长对短的key会过期,LRU机制自动就会淘汰掉它。

当然,这不能保证100%的同一个长地址一定能转出同一个短地址,比如你拿一个生僻的url,每间隔1小时来转一次,你会得到不同的短地址。但是这真的有关系吗?

3. 如何保证发号器的大并发高可用

上面设计看起来有一个单点,那就是发号器。如果做成分布式的,那么多节点要保持同步加1,多点同时写入,这个嘛,以CAP理论看,是不可能真正做到的。其实这个问题的解决非常简单,我们可以退一步考虑,我们是否可以实现两个发号器,一个发单号,一个发双号,这样就变单点为多点了?依次类推,我们可以实现1000个逻辑发号器,分别发尾号为0到999的号。每发一个号,每个发号器加1000,而不是加1。这些发号器独立工作,互不干扰即可。而且在实现上,也可以先是逻辑的,真的压力变大了,再拆分成独立的物理机器单元。1000个节点,估计对人类来说应该够用了。如果你真的还想更多,理论上也是可以的。

4. 具体存储如何选择

这个问题就不展开说了,各有各道,主要考察一下对存储的理解。对缓存原理的理解,和对市面上DB、Cache系统可用性,并发能力,一致性等方面的理解。

5. 跳转用301还是302

这也是一个有意思的话题。首先当然考察一个候选人对301和302的理解。浏览器缓存机制的理解。然后是考察他的业务经验。301是永久重定向,302是临时重定向。短地址一经生成就不会变化,所以用301是符合http语义的。同时对服务器压力也会有一定减少。

但是如果使用了301,我们就无法统计到短地址被点击的次数了。而这个点击次数是一个非常有意思的大数据分析数据源。能够分析出的东西非常非常多。所以选择302虽然会增加服务器压力,但是我想是一个更好的选择。

大概就是这样。

来源:http://www.zhihu.com/question/29270034

Linux:一大波你可能不知道的 Linux 网络工具

如果要在你的系统上监控网络,那么使用命令行工具是非常实用的,并且对于 Linux 用户来说,有着许许多多现成的工具可以使用,如: nethogs, ntopng, nload, iftop, iptraf, bmon, slurm, tcptrack, cbm, netwatch, collectl, trafshow, cacti, etherape, ipband, jnettop, netspeed 以及 speedometer。

鉴于世上有着许多的 Linux 专家和开发者,显然还存在其他的网络监控工具,但在这篇教程中,我不打算将它们所有包括在内。

上面列出的工具都有着自己的独特之处,但归根结底,它们都做着监控网络流量的工作,只是通过各种不同的方法。例如 nethogs 可以被用来展示每个进程的带宽使用情况,以防你想知道究竟是哪个应用在消耗了你的整个网络资源; iftop 可以被用来展示每个套接字连接的带宽使用情况,而像 nload 这类的工具可以帮助你得到有关整个带宽的信息。

1) nethogs

nethogs 是一个免费的工具,当要查找哪个 PID (注:即 process identifier,进程 ID) 给你的网络流量带来了麻烦时,它是非常方便的。它按每个进程来分组带宽,而不是像大多数的工具那样按照每个协议或每个子网来划分流量。它功能丰富,同时支持 IPv4 和 IPv6,并且我认为,若你想在你的 Linux 主机上确定哪个程序正消耗着你的全部带宽,它是来做这件事的最佳的程序。

一个 Linux 用户可以使用 nethogs 来显示每个进程的 TCP 下载和上传速率,可以使用命令 nethogs eth0 来监控一个指定的设备,上面的 eth0 是那个你想获取信息的设备的名称,你还可以得到有关正在传输的数据的传输速率信息。

对我而言, nethogs 是非常容易使用的,或许是因为我非常喜欢它,以至于我总是在我的 Ubuntu 12.04 LTS 机器中使用它来监控我的网络带宽。

例如要想使用混杂模式来嗅探,可以像下面展示的命令那样使用选项 -p:

nethogs -p wlan0

假如你想更多地了解 nethogs 并深入探索它,那么请毫不犹豫地阅读我们做的关于这个网络带宽监控工具的整个教程。

(LCTT 译注:关于 nethogs 的更多信息可以参考:https://linux.cn/article-2808-1.html

2) nload

nload 是一个控制台应用,可以被用来实时地监控网络流量和带宽使用情况,它还通过提供两个简单易懂的图表来对流量进行可视化。这个绝妙的网络监控工具还可以在监控过程中切换被监控的设备,而这可以通过按左右箭头来完成。

Linux:一大波你可能不知道的 Linux 网络工具
Linux:一大波你可能不知道的 Linux 网络工具

正如你在上面的截图中所看到的那样,由 nload 提供的图表是非常容易理解的。nload 提供了有用的信息,也展示了诸如被传输数据的总量和最小/最大网络速率等信息。

而更酷的是你只需要直接运行 nload 这个工具就行,这个命令是非常的短小且易记的:

nload

我很确信的是:我们关于如何使用 nload 的详细教程将帮助到新的 Linux 用户,甚至可以帮助那些正寻找关于 nload 信息的老手。

(LCTT 译注:关于 nload 的更新信息可以参考:https://linux.cn/article-5114-1.html

3) slurm

slurm 是另一个 Linux 网络负载监控工具,它以一个不错的 ASCII 图来显示结果,它还支持许多按键用以交互,例如 c 用来切换到经典模式, s 切换到分图模式, r 用来重绘屏幕, L 用来启用 TX/RX 灯(注:TX,发送流量;RX,接收流量) ,m 用来在经典分图模式和大图模式之间进行切换, q 退出 slurm。

Linux:一大波你可能不知道的 Linux 网络工具
Linux:一大波你可能不知道的 Linux 网络工具

在网络负载监控工具 slurm 中,还有许多其它的按键可用,你可以很容易地使用下面的命令在 man 手册中学习它们。

man slurm

slurm 在 Ubuntu 和 Debian 的官方软件仓库中可以找到,所以使用这些发行版本的用户可以像下面展示的那样,使用 apt-get 安装命令来轻松地下载它:

sudo apt-get install slurm

我们已经在一个教程中对 slurm 的使用做了介绍,不要忘记和其它使用 Linux 的朋友分享这些知识。

4) iftop

当你想显示连接到网卡上的各个主机的带宽使用情况时,iftop 是一个非常有用的工具。根据 man 手册,iftop 在一个指定的接口或在它可以找到的第一个接口(假如没有任何特殊情况,它应该是一个对外的接口)上监听网络流量,并且展示出一个表格来显示当前的一对主机间的带宽使用情况。

通过在虚拟终端中使用下面的命令,Ubuntu 和 Debian 用户可以在他们的机器中轻易地安装 iftop:

sudo apt-get install iftop

在你的机器上,可以使用下面的命令通过 yum 来安装 iftop:

yum -y install iftop

(LCTT 译注:关于 nload 的更多信息请参考:https://linux.cn/article-1843-1.html

5) collectl

collectl 可以被用来收集描述当前系统状态的数据,并且它支持如下两种模式:

  • 记录模式
  • 回放模式

记录模式 允许从一个正在运行的系统中读取数据,然后将这些数据要么显示在终端中,要么写入一个或多个文件或一个套接字中。

回放模式

根据 man 手册,在这种模式下,数据从一个或多个由记录模式生成的数据文件中读取。

Ubuntu 和 Debian 用户可以在他们的机器上使用他们默认的包管理器来安装 colletcl。下面的命令将为他们做这个工作:

sudo apt-get install collectl

还可以使用下面的命令来安装 collectl, 因为对于这些发行版本(注:这里指的是用 yum 作为包管理器的发行版本),在它们官方的软件仓库中也含有 collectl:

yum install collectl

(LCTT 译注:关于 collectl 的更多信息请参考: https://linux.cn/article-3154-1.html

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

Linux:修复 Ubuntu 14.04 从待机中唤醒后鼠标键盘出现僵死情况

问题:

当Ubuntu14.04或14.10从睡眠和待机状态恢复时,鼠标和键盘出现僵死,不能点击也不能输入。解决这种情况是唯一方法就是按关机键强关系统,这不仅非常不便且令人恼火。因为在Ubuntu的默认情况中合上笔记本等同于切换到睡眠模式。

在这篇短文中,我们将学会如何解决Ubuntu14.04和14.10中出现的鼠标僵死问题。

Linux:修复 Ubuntu 14.04 从待机中唤醒后鼠标键盘出现僵死情况
Linux:修复 Ubuntu 14.04 从待机中唤醒后鼠标键盘出现僵死情况

Ubuntu14.04唤醒后鼠标僵死的解决办法

这个问题的是由内核升级导致的。为何导致这一情况不得而知,但是看起来好像仅需重装输入设备的驱动就能解决了。

sudo apt-get install --reinstall xserver-xorg-input-all

这则贴士源自一个自由开源读者Dev的提问。快试试这篇贴士,看看是否对你也有效。在一个类似的问题中,你可以修复Ubuntu登录后无Unity界面、侧边栏和Dash的问题


via: http://itsfoss.com/keyboard-mouse-freeze-suspend/

作者:Abhishek 译者:martin2011qi 校对:wxy

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

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

Linux:11个让你吃惊的 Linux 终端命令

我已经用了十年的Linux了,通过今天这篇文章我将向大家展示一系列的命令、工具和技巧,我希望一开始就有人告诉我这些,而不是曾在我成长道路上绊住我。

Linux:11个让你吃惊的 Linux 终端命令
Linux:11个让你吃惊的 Linux 终端命令

1. 命令行日常系快捷键

如下的快捷方式非常有用,能够极大的提升你的工作效率:

  • CTRL + U – 剪切光标前的内容
  • CTRL + K – 剪切光标至行末的内容
  • CTRL + Y – 粘贴
  • CTRL + E – 移动光标到行末
  • CTRL + A – 移动光标到行首
  • ALT + F – 跳向下一个空格
  • ALT + B – 跳回上一个空格
  • ALT + Backspace – 删除前一个单词
  • CTRL + W – 剪切光标前一个单词
  • Shift + Insert – 向终端内粘贴文本

那么为了让上述内容更易理解来看下面的这行命令。

sudo apt-get intall programname

如你所见,命令中存在拼写错误,为了正常执行需要把“intall”替换成“install”。

想象现在光标正在行末,我们有很多的方法将她退回单词install并替换它。

我可以按两次ALT+B这样光标就会在如下的位置(这里用指代光标的位置)。

sudo apt-get^intall programname

现在你可以按两下方向键并将“s”插入到install中去了。

如果你想将浏览器中的文本复制到终端,可以使用快捷键”shift + insert”。

2. SUDO !!

如果你还不知道这个命令,我觉得你应该好好感谢我,因为如果你不知道的话,那每次你在输入长串命令后看到“permission denied”后一定会痛苦不堪。

  • sudo !!

如何使用sudo !!?很简单。试想你刚输入了如下命令:

apt-get install ranger

一定会出现“Permission denied”,除非你已经登录了足够高权限的账户。

sudo !! 就会用 sudo 的形式运行上一条命令。所以上一条命令就变成了这样:

sudo apt-get install ranger

如果你不知道什么是sudo,戳这里

警告!主页君强烈反对使用这个命令,因为如果万一上个命令存在一些笔误或者你搞错了哪条是上一条命令,那么有可能带来的后果是灾难性的!所以,千万不要执行这条命令!千万不要执行这条命令!千万不要执行这条命令!重要的事情重复三遍。

3. 暂停并在后台运行命令

我曾经写过一篇如何在终端后台运行命令的指南

  • CTRL + Z – 暂停应用程序
  • fg – 重新将程序唤到前台

如何使用这个技巧呢?

试想你正用nano编辑一个文件:

sudo nano abc.txt

文件编辑到一半你意识到你需要马上在终端输入些命令,但是nano在前台运行让你不能输入。

你可能觉得唯一的方法就是保存文件,退出 nano,运行命令以后在重新打开nano。

其实你只要按CTRL + Z,前台的命令就会暂停,画面就切回到命令行了。然后你就能运行你想要运行命令,等命令运行完后在终端窗口输入“fg”就可以回到先前暂停的任务。

有一个尝试非常有趣就是用nano打开文件,输入一些东西然后暂停会话。再用nano打开另一个文件,输入一些什么后再暂停会话。如果你输入“fg”你将回到第二个用nano打开的文件。只有退出nano再输入“fg”,你才会回到第一个用nano打开的文件。

4. 使用nohup在登出SSH会话后仍运行命令

如果你用ssh登录别的机器时,nohup命令真的非常有用。

那么怎么使用nohup呢?

想象一下你使用ssh远程登录到另一台电脑上,你运行了一条非常耗时的命令然后退出了ssh会话,不过命令仍在执行。而nohup可以将这一场景变成现实。

举个例子,因为测试的需要,我用我的树莓派来下载发行版。我绝对不会给我的树莓派外接显示器、键盘或鼠标。

一般我总是用SSH从笔记本电脑连接到树莓派。如果我在不用nohup的情况下使用树莓派下载大型文件,那我就必须等待到下载完成后,才能登出ssh会话关掉笔记本。可如果是这样,那我为什么要使用树莓派下文件呢?

使用nohup的方法也很简单,只需如下例中在nohup后输入要执行的命令即可:

nohup wget http://mirror.is.co.za/mirrors/linuxmint.com/iso//stable/17.1/linuxmint-17.1-cinnamon-64bit.iso &

5. ‘在(at)’特定的时间运行Linux命令

‘nohup’命令在你用SSH连接到服务器,并在上面保持执行SSH登出前任务的时候十分有用。

想一下如果你需要在特定的时间执行相同的命令,这种情况该怎么办呢?

命令‘at’就能妥善解决这一情况。以下是‘at’使用示例。

at 10:38 PM Fri
at> cowsay 'hello'
at> CTRL + D

上面的命令能在周五下午10时38分运行程序cowsay

使用的语法就是‘at’后追加日期时间。当at>提示符出现后就可以输入你想在那个时间运行的命令了。

CTRL + D 返回终端。

还有许多日期和时间的格式,都需要你好好翻一翻‘at’的man手册来找到更多的使用方式。

6. Man手册

Man手册会为你列出命令和参数的使用大纲,教你如何使用她们。Man手册看起来沉闷呆板。(我思忖她们也不是被设计来娱乐我们的)。

不过这不代表你不能做些什么来使她们变得漂亮些。

export PAGER=most

你需要安装 ‘most’;她会使你的你的man手册的色彩更加绚丽。

你可以用以下命令给man手册设定指定的行长:

export MANWIDTH=80

最后,如果你有一个可用的浏览器,你可以使用-H在默认浏览器中打开任意的man页。

man -H 

注意啦,以上的命令只有在你将默认的浏览器设置到环境变量$BROWSER中了之后才效果哟。

7. 使用htop查看和管理进程

你用哪个命令找出电脑上正在运行的进程的呢?我敢打赌是‘ps’并在其后加不同的参数来得到你所想要的不同输出。

安装‘htop’吧!绝对让你相见恨晚。

htop在终端中将进程以列表的方式呈现,有点类似于Windows中的任务管理器。你可以使用功能键的组合来切换排列的方式和展示出来的项。你也可以在htop中直接杀死进程。

在终端中简单的输入htop即可运行。

htop

8. 使用ranger浏览文件系统

如果说htop是命令行进程控制的好帮手,那么ranger就是命令行浏览文件系统的好帮手。

你在用之前可能需要先安装,不过一旦安装了以后就可以在命令行输入以下命令启动她:

ranger

在命令行窗口中ranger和一些别的文件管理器很像,但是相比上下结构布局,她是左右结构的,这意味着你按左方向键你将前进到上一个文件夹,而右方向键则会切换到下一个。

在使用前ranger的man手册还是值得一读的,这样你就可以用快捷键操作ranger了。

9. 取消关机

无论是在命令行还是图形用户界面关机后,才发现自己不是真的想要关机。

shutdown -c

需要注意的是,如果关机已经开始则有可能来不及停止关机。

以下是另一个可以尝试命令:

10. 杀死挂起进程的简单方法

想象一下,你正在运行的应用程序不明原因的僵死了。

你可以使用‘ps -ef’来找到该进程后杀掉或者使用‘htop’。

有一个更快、更容易的命令叫做xkill

简单的在终端中输入以下命令并在窗口中点击你想杀死的应用程序。

xkill

那如果整个系统挂掉了怎么办呢?

按住键盘上的‘alt’和‘sysrq’不放,然后慢慢输入以下键:

这样不按电源键你的计算机也能重启了。

11. 下载Youtube视频

一般来说我们大多数人都喜欢看Youtube的视频,也会通过钟爱的播放器播放Youtube的流媒体。

如果你需要离线一段时间(比如:从苏格兰南部坐飞机到英格兰南部旅游的这段时间)那么你可能希望下载一些视频到存储设备中,到闲暇时观看。

你所要做的就是从包管理器中安装youtube-dl。

你可以用以下命令使用youtube-dl:

youtube-dl url-to-video

你可以在Youtubu视频页面点击分享链接得到视频的url。只要简单的复制链接在粘帖到命令行就行了(要用shift + insert快捷键哟)。

总结

希望你在这篇文章中得到帮助,并且在这11条中找到至少一条让你惊叹“原来可以这样”的技巧。


via: http://linux.about.com/od/commands/tp/11-Linux-Terminal-Commands-That-Will-Rock-Your-World.htm

作者:Gary Newell 译者:martin2011qi 校对:wxy

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

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

Linux:使用Observium来监控你的网络和服务器

简介

在监控你的服务器、交换机或者设备时遇到过问题吗?Observium 可以满足你的需求。这是一个免费的监控系统,它可以帮助你远程监控你的服务器。它是一个由PHP编写的基于自动发现 SNMP 的网络监控平台,支持非常广泛的网络硬件和操作系统,包括 Cisco、Windows、Linux、HP、NetApp 等等。在此我会给出在 Ubuntu 12.04 上一步步地设置一个 Observium 服务器的介绍。

Linux:使用Observium来监控你的网络和服务器
Linux:使用Observium来监控你的网络和服务器

目前有两种不同的 observium 版本。

  • Observium 社区版本是一个在 QPL 开源许可证下的免费工具,这个版本是对于较小部署的最好解决方案。该版本每6个月进行一次安全性更新。
  • 第2个版本是 Observium 专业版,该版本采用基于 SVN 的发布机制。 会得到每日安全性更新。 该工具适用于服务提供商和企业级部署。

更多信息可以通过其官网获得。

系统需求

要安装 Observium, 需要具有一个最新安装的服务器。Observium 是在 Ubuntu LTS 和 Debian 系统上进行开发的,所以推荐在 Ubuntu 或 Debian 上安装 Observium,因为可能在别的平台上会有一些小问题。

该文章会引导你在 Ubuntu 12.04 上安装 Observium。对于小型的 Observium 安装,建议使用 256MB 内存和双核处理器的配置。

安装需求

在安装 Observuim 之前,你需要确认安装所有的依赖关系包。

首先,使用下面的命令更新你的服务器:

sudo apt-get update

然后你需要安装下列运行 Observuim 所需的全部软件包。

Observium 需要使用下面所列出的软件才能正确的运行:

  • LAMP 服务器
  • fping
  • Net-SNMP 5.4+
  • RRDtool 1.3+
  • Graphviz

对于可选特性的要求:

  • Ipmitool – 仅在当你想要获取服务器上的 IPMI(Intelligent Platform Management Interface 智能平台管理接口)基板控制器时。
  • Libvirt-bin – 仅在当你想要使用 libvirt 进行远程 VM 主机监控时。

    sudo apt-get install libapache2-mod-php5 php5-cli php5-mysql php5-gd php5-mcrypt php5-json php-pear snmp fping mysql-server mysql-client python-mysqldb rrdtool subversion whois mtr-tiny ipmitool graphviz imagemagick libvirt ipmitool

为 Observium 创建 MySQL 数据库及其用户。

现在你需要登录到 MySQL 中并为 Observium 创建数据库:

mysql -u root -p

在用户验证成功之后,你需要按照下面的命令创建该数据库。

CREATE DATABASE observium;

数据库名为 Observium,稍后你会需要这个信息。

现在你需要创建数据库管理员用户。

CREATE USER observiumadmin@localhost IDENTIFIED BY 'observiumpassword';

接下来,你需要给该管理员用户相应的权限来管理创建的数据库。

GRANT ALL PRIVILEGES ON observium.* TO observiumadmin@localhost;

你需要将权限信息写回到磁盘中来激活新的 MySQL 用户:

FLUSH PRIVILEGES;
exit

下载并安装 Observium

现在我们的系统已经准备好了, 可以开始Observium的安装了。

第一步,创建 Observium 将要使用的文件目录:

mkdir -p /opt/observium && cd /opt

按本教程的目的,我们将会使用 Observium 的社区/开源版本。使用下面的命令下载并解压:

wget http://www.observium.org/observium-community-latest.tar.gz
tar zxvf observium-community-latest.tar.gz

现在进入到 Observium 目录。

cd observium

将默认的配置文件 ‘config.php.default‘ 复制到 ‘config.php‘,并将数据库配置选项填充到配置文件中:

cp config.php.default config.php
nano config.php

/ Database config
$config['db_host'] = 'localhost';
$config['db_user'] = 'observiumadmin';
$config['db_pass'] = 'observiumpassword';
$config['db_name'] = 'observium';

现在为 MySQL 数据库设置默认的数据库模式:

php includes/update/update.php

现在你需要创建一个文件目录来存储 rrd 文件,并修改其权限以便让 apache 能将写入到文件中。

mkdir rrd
chown apache:apache rrd

为了在出现问题时排错,你需要创建日志文件。

mkdir -p /var/log/observium
chown apache:apache /var/log/observium

现在你需要为 Observium 创建虚拟主机配置。


  DocumentRoot /opt/observium/html/
  ServerName  observium.domain.com
  CustomLog /var/log/observium/access_log combined
  ErrorLog /var/log/observium/error_log
  
  AllowOverride All
  Options FollowSymLinks MultiViews
  
  

下一步你需要让你的 Apache 服务器的 rewrite (重写)功能生效。

为了让 ‘mod_rewrite’ 生效,输入以下命令:

sudo a2enmod rewrite

该模块在下一次 Apache 服务重启之后就会生效。

sudo service apache2 restart

配置 Observium

在登入 Web 界面之前,你需要为 Observium 创建一个管理员账户(级别10)。

# cd /opt/observium
# ./adduser.php admin adminpassword 10
User admin added successfully.

下一步为发现和探寻任务设置一个 cron 任务,创建一个新的文件 ‘/etc/cron.d/observium’ 并在其中添加以下的内容。

33  */6   * * *   root    /opt/observium/discovery.php -h all >> /dev/null 2>&1
*/5 *      * * *   root    /opt/observium/discovery.php -h new >> /dev/null 2>&1
*/5 *      * * *   root    /opt/observium/poller-wrapper.py 1 >> /dev/null 2>&1

重载 cron 进程来增加新的任务。

# /etc/init.d/cron reload

好啦,你已经完成了 Observium 服务器的安装拉! 使用你的浏览器登录到 http://,然后上路吧。

Linux:使用Observium来监控你的网络和服务器
Linux:使用Observium来监控你的网络和服务器

尽情享受吧!


via: http://www.unixmen.com/monitoring-network-servers-observium/

作者:anismaj 译者:theo-l 校对:wxy

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

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

Linux:Linux有问必答:如何在命令行下压缩JPEG图像

问题: 我有许多数码照相机拍出来的照片。我想在上传到Dropbox之前,优化和压缩下JPEG图片。有没有什么简单的方法压缩JPEG图片并不损耗他们的质量?

如今拍照设备(如智能手机、数码相机)拍出来的图片分辨率越来越大。甚至3630万像素的Nikon D800已经冲入市场,并且这个趋势根本停不下来。如今的拍照设备不断地提高着照片分辨率,使得我们不得不压缩后,再上传到有储存限制、带宽限制的云。

事实上,这里有一个非常简单的方法压缩JPEG图像。一个叫“jpegoptim”命令行工具可以帮助你“无损”美化JPEG图像,让你可以压缩JPEG图片而不至于牺牲他们的质量。万一你的存储空间和带宽预算真的很少,jpegoptim也支持“有损”压缩来调整图像大小。

如果要压缩PNG图像,参考这个指南的例子。

安装jpegoptim

Ubuntu, Debian 或 Linux Mint:

$ sudo apt-get install jpegoptim

Fedora:

$ sudo yum install jpegoptim

CentOS/RHEL安装,先开启EPEL库,然后运行下列命令:

$ sudo yum install jpegoptim

无损压缩jpeg图像

为了无损地压缩一副JPG图片,使用:

$ jpegoptim photo.jpg
photo.jpg 2048x1536 24bit N ICC JFIF  [OK] 882178 --> 821064 bytes (6.93%), optimized.

注意,原始图像会被压缩后图像覆盖。

如果jpegoptim不能无损美化图像,将不会覆盖它:

$ jpegoptim -v photo.jpg
photo.jpg 2048x1536 24bit N ICC JFIF  [OK] 821064 --> 821064 bytes (0.00%), skipped.

如果你想保护原始图片,使用”-d”参数指明保存目录

$ jpegoptim -d ./compressed photo.jpg

这样,压缩的图片将会保存在./compressed目录(以同样的输入文件名)

如果你想要保护文件的创建修改时间,使用”-p”参数。这样压缩后的图片会得到与原始图片相同的日期时间。

$ jpegoptim -d ./compressed -p photo.jpg

如果你只是想看看无损压缩率而不是真的想压缩它们,使用”-n”参数来模拟压缩,然后它会显示出压缩率。

$ jpegoptim -n photo.jpg

有损压缩JPG图像

万一你真的需要要保存在云空间上,你还可以使用有损压缩JPG图片。

这种情况下,使用”-m<质量>“选项,质量数范围0到100。(0是最好质量,100是最差质量)

例如,用50%质量压缩图片:

$ jpegoptim -m50 photo.jpg
photo.jpg 2048x1536 24bit N ICC JFIF  [OK] 882178 --> 301780 bytes (65.79%), optimized.

在牺牲质量的基础上,将会得到一个更小的图片。

Linux:Linux有问必答:如何在命令行下压缩JPEG图像
Linux:Linux有问必答:如何在命令行下压缩JPEG图像

一次压缩多张JPEG图像

最常见的情况是需要压缩一个目录下的多张JPEG图像文件。为了应付这种情况,你可以使用接下来的脚本。

#!/bin/sh
# 压缩当前目录下所有*.jpg文件
# 保存在./compressed目录
# 并拥有与原始文件同样的修改日期
for i in *.jpg; do jpegoptim -d ./compressed -p "$i"; done

via: http://ask.xmodulo.com/compress-jpeg-images-command-line-linux.html

作者:Dan Nanni 译者:VicYu/Vic020 校对:wxy

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

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

Linux:如何在Linux中用命令行工具管理KVM虚拟环境

在我们KVM系列专题的第四部分,我们将会一起讨论下在命令行界面下来管理KVM环境。我们分别用‘virt-install’和virsh命令行工具来创建并配置虚拟机和存储池,用qemu-img命令行工具来创建并管理磁盘映像。

Linux:如何在Linux中用命令行工具管理KVM虚拟环境
Linux:如何在Linux中用命令行工具管理KVM虚拟环境

Linux系统的KVM管理

在这篇文章里没有什么新的概念,我们只是用命令行工具重复之前所做过的事情,也没有什么前提条件,都是相同的过程,之前的文章我们都讨论过。

第一步: 配置存储池

Virsh命令行工具是一款管理virsh客户域的用户界面。virsh程序能在命令行中运行所给的命令以及它的参数。

本节中,我们要用它给我们的KVM环境创建存储池。想知道关于这个工具的更多信息,用以下这条命令。

# man virsh

1. 用virsh带pool-define-as的命令来定义新的存储池,你需要指定名字、类型和类型参数。

本例中,我们将名字取为Spool1,类型为目录。默认情况下你可以提供五个参数给该类型:

  • source-host
  • source-path
  • source-dev
  • source-name
  • target

对于目录类型,我们需要用最后一个参数“target”来指定存储池的路径,其它参数项我们可以用“-”来填充。

# virsh pool-define-as Spool1 dir - - - - "/mnt/personal-data/SPool1/"

Create New Storage Pool

创建新存储池

2. 查看环境中我们所有的存储池,用以下命令。

# virsh pool-list --all

List All Storage Pools

列出所有存储池

3. 现在我们来构造存储池了,用以下命令来构造我们刚才定义的存储池。

# virsh pool-build Spool1

Build Storage Pool

构造存储池

4. 用带pool-start参数的virsh命令来激活并启动我们刚才创建并构造完成的存储池。

# virsh pool-start Spool1

Active Storage Pool

激活存储池

5. 查看环境中存储池的状态,用以下命令。

# virsh pool-list --all

Check Storage Pool Status

查看存储池状态

你会发现Spool1的状态变成了已激活。

6. 对Spool1进行配置,让它每次都能被libvirtd服务自启动。

# virsh pool-autostart Spool1

Configure KVM Storage Pool

配置KVM存储池

7. 最后来看看我们新的存储池的信息吧。

# virsh pool-info Spool1
Linux:如何在Linux中用命令行工具管理KVM虚拟环境
Linux:如何在Linux中用命令行工具管理KVM虚拟环境

查看KVM存储池信息

恭喜你,Spool1已经准备好待命,接下来我们试着创建存储卷来使用它。

第二步: 配置存储卷/磁盘映像

现在轮到磁盘映像了,用qemu-img命令在Spool1中创建一个新磁盘映像。获取更多细节信息,可以查看man手册。

# man qemu-img

8. 我们应该在qemu-img命令之后指定“create, check,…”等等操作、磁盘映像格式、你想要创建的磁盘映像的路径和大小。

# qemu-img create -f raw /mnt/personal-data/SPool1/SVol1.img 10G

Create Storage Volume

创建存储卷

9. 通过使用带info的qemu-img命令,你可以获取到你的新磁盘映像的一些信息。

Check Storage Volume Information

查看存储卷信息

警告: 不要用qemu-img命令来修改被运行中的虚拟机或任何其它进程所正在使用的映像,那样映像会被破坏。

现在是时候来创建虚拟机了。

第三步: 创建虚拟机

10. 现在到最后一个环节了,在最后一步中,我们将用virt-install命令来创建虚拟机。virt-install是一个用来创建新的KVM虚拟机命令行工具,它使用“libvirt”管理程序库。想获取更多细节,同样可以查看man手册。

# man virt-install

要创建新的KVM虚拟机,你需要用到带以下所有信息的命令。

  • Name: 虚拟机的名字。
  • Disk Location: 磁盘映像的位置。
  • Graphics : 怎样连接VM,通常是SPICE。
  • vcpu : 虚拟CPU的数量。
  • ram : 以兆字节计算的已分配内存大小。
  • Location : 指定安装源路径。
  • Network : 指定虚拟网络,通常是virbr0网桥。
virt-install --name=rhel7 --disk path=/mnt/personal-data/SPool1/SVol1.img --graphics spice --vcpu=1 --ram=1024 --location=/run/media/dos/9e6f605a-f502-4e98-826e-e6376caea288/rhel-server-7.0-x86_64-dvd.iso --network bridge=virbr0
Linux:如何在Linux中用命令行工具管理KVM虚拟环境
Linux:如何在Linux中用命令行工具管理KVM虚拟环境

创建新的虚拟机

11. 你会看到弹出一个virt-vierwer窗口,像是在通过它在与虚拟机通信。

Linux:如何在Linux中用命令行工具管理KVM虚拟环境
Linux:如何在Linux中用命令行工具管理KVM虚拟环境

虚拟机启动程式

Linux:如何在Linux中用命令行工具管理KVM虚拟环境
Linux:如何在Linux中用命令行工具管理KVM虚拟环境

虚拟机安装过程

结论

以上就是我们KVM教程的最后一部分了,当然我们还没有完全覆盖到全部,我们只是打了个擦边球,所以现在该轮到你来好好地利用这些丰富的资源来做自己想做的事了。


via: http://www.tecmint.com/kvm-management-tools-to-manage-virtual-machines/

作者:Mohammad Dosoukey 译者:ZTinoZ 校对:wxy

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

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

Linux:建立你自己的 CA 服务:OpenSSL 命令行 CA 操作快速指南

这些是关于使用 OpenSSL 生成证书授权(CA)、中间证书授权和末端证书的速记随笔,内容包括 OCSP、CRL 和 CA 颁发者信息,以及指定颁发和有效期限等。

我们将建立我们自己的根 CA,我们将使用根 CA 来生成一个中间 CA 的例子,我们将使用中间 CA 来签署末端用户证书。

根 CA

创建根 CA 授权目录并切换到该目录:

mkdir ~/SSLCA/root/
cd ~/SSLCA/root/

为我们的根 CA 生成一个8192位长的 SHA-256 RSA 密钥:

openssl genrsa -aes256 -out rootca.key 8192

样例输出:

Generating RSA private key, 8192 bit long modulus
.........++
....................................................................................................................++
e is 65537 (0x10001)

如果你想要用密码保护该密钥,请添加 -aes256选项。

创建自签名根 CA 证书 ca.crt;你需要为你的根 CA 提供一个身份:

openssl req -sha256 -new -x509 -days 1826 -key rootca.key -out rootca.crt

样例输出:

You are about to be asked to enter information that will be incorporated
into your certificate request.
What you are about to enter is what is called a Distinguished Name or a DN.
There are quite a few fields but you can leave some blank
For some fields there will be a default value,
If you enter '.', the field will be left blank.
-----
Country Name (2 letter code) [AU]:NL
State or Province Name (full name) [Some-State]:Zuid Holland
Locality Name (eg, city) []:Rotterdam
Organization Name (eg, company) [Internet Widgits Pty Ltd]:Sparkling Network
Organizational Unit Name (eg, section) []:Sparkling CA
Common Name (e.g. server FQDN or YOUR name) []:Sparkling Root CA
Email Address []:

创建一个存储 CA 序列的文件:

touch certindex
echo 1000 > certserial
echo 1000 > crlnumber

放置 CA 配置文件,该文件持有 CRL 和 OCSP 末端的存根。

# vim ca.conf
[ ca ]
default_ca = myca
[ crl_ext ]
issuerAltName=issuer:copy
authorityKeyIdentifier=keyid:always
 [ myca ]
 dir = ./
 new_certs_dir = $dir
 unique_subject = no
 certificate = $dir/rootca.crt
 database = $dir/certindex
 private_key = $dir/rootca.key
 serial = $dir/certserial
 default_days = 730
 default_md = sha1
 policy = myca_policy
 x509_extensions = myca_extensions
 crlnumber = $dir/crlnumber
 default_crl_days = 730
 [ myca_policy ]
 commonName = supplied
 stateOrProvinceName = supplied
 countryName = optional
 emailAddress = optional
 organizationName = supplied
 organizationalUnitName = optional
 [ myca_extensions ]
 basicConstraints = critical,CA:TRUE
 keyUsage = critical,any
 subjectKeyIdentifier = hash
 authorityKeyIdentifier = keyid:always,issuer
 keyUsage = digitalSignature,keyEncipherment,cRLSign,keyCertSign
 extendedKeyUsage = serverAuth
 crlDistributionPoints = @crl_section
 subjectAltName  = @alt_names
 authorityInfoAccess = @ocsp_section
 [ v3_ca ]
 basicConstraints = critical,CA:TRUE,pathlen:0
 keyUsage = critical,any
 subjectKeyIdentifier = hash
 authorityKeyIdentifier = keyid:always,issuer
 keyUsage = digitalSignature,keyEncipherment,cRLSign,keyCertSign
 extendedKeyUsage = serverAuth
 crlDistributionPoints = @crl_section
 subjectAltName  = @alt_names
 authorityInfoAccess = @ocsp_section
 [alt_names]
 DNS.0 = Sparkling Intermidiate CA 1
 DNS.1 = Sparkling CA Intermidiate 1
 [crl_section]
 URI.0 = http://pki.sparklingca.com/SparklingRoot.crl
 URI.1 = http://pki.backup.com/SparklingRoot.crl
 [ocsp_section]
 caIssuers;URI.0 = http://pki.sparklingca.com/SparklingRoot.crt
 caIssuers;URI.1 = http://pki.backup.com/SparklingRoot.crt
 OCSP;URI.0 = http://pki.sparklingca.com/ocsp/
 OCSP;URI.1 = http://pki.backup.com/ocsp/

如果你需要设置某个特定的证书生效/过期日期,请添加以下内容到[myca]

# format: YYYYMMDDHHMMSS
default_enddate = 20191222035911
default_startdate = 20181222035911

创建中间 CA

生成中间 CA (名为 intermediate1)的私钥:

openssl genrsa -out intermediate1.key 4096

生成中间 CA 的 CSR:

openssl req -new -sha256 -key intermediate1.key -out intermediate1.csr

样例输出:

You are about to be asked to enter information that will be incorporated
into your certificate request.
What you are about to enter is what is called a Distinguished Name or a DN.
There are quite a few fields but you can leave some blank
For some fields there will be a default value,
If you enter '.', the field will be left blank.
-----
Country Name (2 letter code) [AU]:NL
State or Province Name (full name) [Some-State]:Zuid Holland
Locality Name (eg, city) []:Rotterdam
Organization Name (eg, company) [Internet Widgits Pty Ltd]:Sparkling Network
Organizational Unit Name (eg, section) []:Sparkling CA
Common Name (e.g. server FQDN or YOUR name) []:Sparkling Intermediate CA
Email Address []:
Please enter the following 'extra' attributes
to be sent with your certificate request
A challenge password []:
An optional company name []:

确保中间 CA 的主体(CN)和根 CA 不同。

用根 CA 签署中间 CA 的 CSR:

openssl ca -batch -config ca.conf -notext -in intermediate1.csr -out intermediate1.crt

样例输出:

Using configuration from ca.conf
Check that the request matches the signature
Signature ok
The Subject's Distinguished Name is as follows
countryName           :PRINTABLE:'NL'
stateOrProvinceName   :ASN.1 12:'Zuid Holland'
localityName          :ASN.1 12:'Rotterdam'
organizationName      :ASN.1 12:'Sparkling Network'
organizationalUnitName:ASN.1 12:'Sparkling CA'
commonName            :ASN.1 12:'Sparkling Intermediate CA'
Certificate is to be certified until Mar 30 15:07:43 2017 GMT (730 days)
Write out database with 1 new entries
Data Base Updated

生成 CRL(同时采用 PEM 和 DER 格式):

openssl ca -config ca.conf -gencrl -keyfile rootca.key -cert rootca.crt -out rootca.crl.pem
openssl crl -inform PEM -in rootca.crl.pem -outform DER -out rootca.crl

每次使用该 CA 签署证书后,请生成 CRL。

如果你需要撤销该中间证书:

openssl ca -config ca.conf -revoke intermediate1.crt -keyfile rootca.key -cert rootca.crt

配置中间 CA

为该中间 CA 创建一个新文件夹,然后进入该文件夹:

mkdir ~/SSLCA/intermediate1/
cd ~/SSLCA/intermediate1/

从根 CA 拷贝中间证书和密钥:

cp ~/SSLCA/root/intermediate1.key ./
cp ~/SSLCA/root/intermediate1.crt ./

创建索引文件:

touch certindex
echo 1000 > certserial
echo 1000 > crlnumber

创建一个新的 ca.conf文件:

# vim ca.conf
[ ca ]
default_ca = myca
[ crl_ext ]
issuerAltName=issuer:copy
authorityKeyIdentifier=keyid:always
 [ myca ]
 dir = ./
 new_certs_dir = $dir
 unique_subject = no
 certificate = $dir/intermediate1.crt
 database = $dir/certindex
 private_key = $dir/intermediate1.key
 serial = $dir/certserial
 default_days = 365
 default_md = sha1
 policy = myca_policy
 x509_extensions = myca_extensions
 crlnumber = $dir/crlnumber
 default_crl_days = 365
 [ myca_policy ]
 commonName = supplied
 stateOrProvinceName = supplied
 countryName = optional
 emailAddress = optional
 organizationName = supplied
 organizationalUnitName = optional
 [ myca_extensions ]
 basicConstraints = critical,CA:FALSE
 keyUsage = critical,any
 subjectKeyIdentifier = hash
 authorityKeyIdentifier = keyid:always,issuer
 keyUsage = digitalSignature,keyEncipherment
 extendedKeyUsage = serverAuth
 crlDistributionPoints = @crl_section
 subjectAltName  = @alt_names
 authorityInfoAccess = @ocsp_section
 [alt_names]
 DNS.0 = example.com
 DNS.1 = example.org
 [crl_section]
 URI.0 = http://pki.sparklingca.com/SparklingIntermidiate1.crl
 URI.1 = http://pki.backup.com/SparklingIntermidiate1.crl
 [ocsp_section]
 caIssuers;URI.0 = http://pki.sparklingca.com/SparklingIntermediate1.crt
 caIssuers;URI.1 = http://pki.backup.com/SparklingIntermediate1.crt
 OCSP;URI.0 = http://pki.sparklingca.com/ocsp/
 OCSP;URI.1 = http://pki.backup.com/ocsp/

修改 [alt_names]部分,添加你需要的主体备选名。如果你不需要主体备选名,请移除该部分包括subjectAltName = @alt_names的行。

如果你需要设置一个指定的生效/到期日期,请添加以下内容到 [myca]

# format: YYYYMMDDHHMMSS
default_enddate = 20191222035911
default_startdate = 20181222035911

生成一个空白 CRL(同时以 PEM 和 DER 格式):

openssl ca -config ca.conf -gencrl -keyfile rootca.key -cert rootca.crt -out rootca.crl.pem
openssl crl -inform PEM -in rootca.crl.pem -outform DER -out rootca.crl

生成末端用户证书

我们使用这个新的中间 CA 来生成一个末端用户证书,请重复以下操作来使用该 CA 为每个用户签署。

mkdir enduser-certs

生成末端用户的私钥:

openssl genrsa -out enduser-certs/enduser-example.com.key 4096

生成末端用户的 CSR:

openssl req -new -sha256 -key enduser-certs/enduser-example.com.key -out enduser-certs/enduser-example.com.csr

样例输出:

You are about to be asked to enter information that will be incorporated
into your certificate request.
What you are about to enter is what is called a Distinguished Name or a DN.
There are quite a few fields but you can leave some blank
For some fields there will be a default value,
If you enter '.', the field will be left blank.
-----
Country Name (2 letter code) [AU]:NL
State or Province Name (full name) [Some-State]:Noord Holland
Locality Name (eg, city) []:Amsterdam
Organization Name (eg, company) [Internet Widgits Pty Ltd]:Example Inc
Organizational Unit Name (eg, section) []:IT Dept
Common Name (e.g. server FQDN or YOUR name) []:example.com
Email Address []:
Please enter the following 'extra' attributes
to be sent with your certificate request
A challenge password []:
An optional company name []:

使用中间 CA 签署末端用户的 CSR:

openssl ca -batch -config ca.conf -notext -in enduser-certs/enduser-example.com.csr -out enduser-certs/enduser-example.com.crt

样例输出:

Using configuration from ca.conf
Check that the request matches the signature
Signature ok
The Subject's Distinguished Name is as follows
countryName           :PRINTABLE:'NL'
stateOrProvinceName   :ASN.1 12:'Noord Holland'
localityName          :ASN.1 12:'Amsterdam'
organizationName      :ASN.1 12:'Example Inc'
organizationalUnitName:ASN.1 12:'IT Dept'
commonName            :ASN.1 12:'example.com'
Certificate is to be certified until Mar 30 15:18:26 2016 GMT (365 days)
Write out database with 1 new entries
Data Base Updated

生成 CRL(同时以 PEM 和 DER 格式):

openssl ca -config ca.conf -gencrl -keyfile intermediate1.key -cert intermediate1.crt -out intermediate1.crl.pem
openssl crl -inform PEM -in intermediate1.crl.pem -outform DER -out intermediate1.crl

每次你使用该 CA 签署证书后,都需要生成 CRL。

如果你需要撤销该末端用户证书:

openssl ca -config ca.conf -revoke enduser-certs/enduser-example.com.crt -keyfile intermediate1.key -cert intermediate1.crt

样例输出:

Using configuration from ca.conf
Revoking Certificate 1000.
Data Base Updated

通过连接根证书和中间证书来创建证书链文件。

cat ../root/rootca.crt intermediate1.crt > enduser-certs/enduser-example.com.chain

发送以下文件给末端用户:

enduser-example.com.crt
enduser-example.com.key
enduser-example.com.chain

你也可以让末端用户提供他们自己的 CSR,而只发送给他们这个 .crt 文件。不要把它从服务器删除,否则你就不能撤销了。

校验证书

你可以对证书链使用以下命令来验证末端用户证书:

openssl verify -CAfile enduser-certs/enduser-example.com.chain enduser-certs/enduser-example.com.crt
enduser-certs/enduser-example.com.crt: OK

你也可以针对 CRL 来验证。首先,将 PEM 格式的 CRL 和证书链相连接:

cat ../root/rootca.crt intermediate1.crt intermediate1.crl.pem > enduser-certs/enduser-example.com.crl.chain

验证证书:

openssl verify -crl_check -CAfile enduser-certs/enduser-example.com.crl.chain enduser-certs/enduser-example.com.crt

没有撤销时的输出:

enduser-certs/enduser-example.com.crt: OK

撤销后的输出如下:

enduser-certs/enduser-example.com.crt: CN = example.com, ST = Noord Holland, C = NL, O = Example Inc, OU = IT Dept
error 23 at 0 depth lookup:certificate revoked

via: https://raymii.org/s/tutorials/OpenSSL_command_line_Root_and_Intermediate_CA_including_OCSP_CRL%20and_revocation.html

作者:Remy van Elst 译者:GOLinux 校对:wxy

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

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

Linux:Windows Docker第一时间揭秘

【编者的话】这是盆盆谈微软两会(Build/Iginte)系列之一。文章引用孙建波老师关于Linux内核的6大命名空间隔离,看Windows Docker如何实现类似隔离,同时又有哪些不同。文章素材取自Build和Ignite大会视频,但主要展示盆盆自己的分析和研究,还望大家指正为谢。

在咱们微信群里听一位兄弟提到,Docker能将DevOps(意即开发和运维)整合在一起,暗合王阳明先生的“知行合一”之教,这真是一种有趣的说法。

话说从头,盆盆在《Windows Docker深入原理分析》里曾经提到微软Build大会后,会第一时间给大家介绍Windows Docker技术。

还没看过Build在线视频的朋友,您可以泡杯咖啡,带上耳机,静静地欣赏以下由Taylor Brown主讲的Windows Docker讲座,我们的文章就以此为蓝本。

这里需要注意的是:以下的论述,大多是盆盆根据Taylor的demo效果所做的推论,并不是Taylor本人的陈述,所以并不一定正确。由于能力所限,必然谬误不少,还望大家能及时指出哈。

容器即隔离

拿大家熟悉的Linux Docker来看,其涉及到Linux内核所提供的Namespace隔离技术和资源控制的CGroup技术。

这里推荐大家阅读浙大SEL研究生孙建波老师的文章《Docker背后的内核知识——Namespace资源隔离》

孙建波老师提到了一张表格,其中列出了Linux内核所支持的6种隔离:主机名、IPC、进程ID、网络、文件系统、账号。

Linux:Windows Docker第一时间揭秘
Linux:Windows Docker第一时间揭秘
尽管Windows内核实现和Linux不同,但是两者还是有不少可比拟处。所以盆盆根据Build大会上Mark Russinovich这位大神以及Taylor Brown的讲座,来条分缕析。试图按照这几个Namespace隔离的框架来进行阐述。

文件系统隔离

先来看看浙大SEL的另一位大牛孙宏亮老师的文章《Docker源码分析(九):Docker镜像 》。这篇文章清晰地描述了Linux Docker的文件系统隔离,多层的可叠加文件系统。

孙宏亮老师指出,假设我们下拉了Ubuntu:14.04映像,并通过命令docker run –it ubuntu:14.04 /bin/bash将其启动运行。则Docker为其创建的rootfs以及容器可读写的文件系统参见下图。从容器的视角来看,虽然只有一个逻辑的完整文 件系统,但该文件系统由“2层”组成,分别为读写文件系统和只读文件系统(按只读层还可以再逻辑分层,所以极大地节省磁盘空间)。

2.jpg

Windows Docker同样如此,顶层的沙盒层(sandbox layer)是可读写的,只允许该容器自己占用,而其他层则是只读的,可供不同容器共享。在下图中,底层的基础OS层和中间的应用程序框架层都是只读的, 而顶层的沙盒层则可读写,在容器的视角看来,它独占了完整的OS。这有点类似于Hyper-V的差异磁盘链(顶部的子盘才能读写,其上方的所有父盘和 Base盘都是只读的)。

Linux:Windows Docker第一时间揭秘
Linux:Windows Docker第一时间揭秘

为了说明文件系统隔离的魔力,Taylor演示了在Windows容器里用del命令删除C盘根目录下所有文件,然后再用reg命令删除HKLMSoftware下的所有注册表键值,尽管这个容器被毁了,但是并不会影响其他容器,更不会影响主机。

Linux:Windows Docker第一时间揭秘
Linux:Windows Docker第一时间揭秘

盆盆猜测,在Windows容器的视角里,如果只是读取一个文件,在最顶端的沙盒层里只有该文件的重解析点(reparse point);只有在修改该文件时,才会用copy-on-writer的方法从下方的只读层中把文件内容复制到可读写的沙盒层。

创建Windows Container

视频里演示了一个demo。用一段简单的代码,在Docker Client的console里显示“This is a pretty cool app”。

Linux:Windows Docker第一时间揭秘
Linux:Windows Docker第一时间揭秘

这是用来构建Windows Docker映像的Dockerfile。这个文件由以下4行命令组成,基本上每一行命令等于叠加1个Layer:

  • 第1行:表明该映像基于windowsservercore这个Base映像,可以将其理解为rootfs
  • 第2行:表示工作目录是C盘根目录
  • 第3行:将应用目录复制到容器映像里
  • 第4行:启动该应用程序
Linux:Windows Docker第一时间揭秘
Linux:Windows Docker第一时间揭秘

用docker build命令将其构建为容器映像,Tag是1。从命令结果中可以看到Dockerfile里的每个命令都被执行,并叠加新的Image Layer。

Linux:Windows Docker第一时间揭秘
Linux:Windows Docker第一时间揭秘

Docker映像构建完成后,可以运行docker image命令查看新建的映像,运行docker run命令即可快速启动该映像,并成功显示”This is a pretty cool app…”。

Linux:Windows Docker第一时间揭秘
Linux:Windows Docker第一时间揭秘

通过使用docker history命令,我们可以查看容器映像的构建历史,这甚至可以用来逆向生成Dockerfile。例如视频里演示了sysinternals这个映像 的构建历史。从中我们可以看到:首先记录维护人员是谁;然后指定工作目录是C盘根目录;再者是将sysinternals suite这个工具软件目录拷贝到容器映像里;然后设定容器的运行账户(本文后面的账户隔离一节还会再阐述);最后设置启动ipconfig以便显示容器 的IP地址。

Linux:Windows Docker第一时间揭秘
Linux:Windows Docker第一时间揭秘

IPC隔离

和Linux Docker容器一样,Windows容器也采用IPC隔离机制。Windows容器使用Windows自己的session隔离机制。

会话(session)隔离机制,最初是用在Windows终端服务和快速用户切换中,以便这些不同用户的进程不会互相干扰,确保安全。从 Windows Vista开始,也采用这种技术对系统会话进行隔离,Windows系统自己的服务和进程会占用原来的控制台会话(会话0),而后续的用户会依次使用会话 1、会话2等等,这就是我们不能再使用mstsc /console进行控制台登录的原因。

从《Windows Internals》里我们可以学习到:不同会话里的应用,不能够发送窗口消息(Window Message),以防止粉碎攻击。每个会话拥有自己专用的对象命名空间。同样每个Windows容器,也会有自己的独立会话,有自己专用的 BaseNamedObjects等对象命名空间,以便隔离事件、互斥信号和内存段等对象。这样不同容器在同一个Windows主机上访问同一个命名对 象,就不会导致冲突。以下的WinObj对话框是在盆盆自己的Windows 10上截图的,虽然不是取自Windows Docker系统,但是道理是一样的,可以看到不同的会话,拥有自己专用的对象命名空间。

Linux:Windows Docker第一时间揭秘
Linux:Windows Docker第一时间揭秘

有兴趣的朋友可以参考盆盆在9年前发表在ITECN博客上的文章,介绍会话隔离技术。

视频里演示了Docker容器的会话隔离能力。Taylor启动了两个容器,都是从同一个windowsservercore映像里派生出来的。 其中一个容器,可以运行Tasklist命令,看到该容器运行在会话14中。而且还能看到两个系统进程,一个是System进程,代表操作系统本身,另一 个是空闲进程,这两个进程都运行在会话0里。

Linux:Windows Docker第一时间揭秘
Linux:Windows Docker第一时间揭秘

在同一个映像所创建的另一个容器里,我们可以看到该容器运行在会话15中,同样可以看到System进程和空闲进程。

Linux:Windows Docker第一时间揭秘
Linux:Windows Docker第一时间揭秘

Taylor的解释是由于容器是共享Windows Kernel的,所以容易可以看到System进程的PID是一样的,都是4。其实System进程并不是用户模式进程,而是用来代表所有操作系统和驱动 程序的内核模式线程,在所有的Windows主机上,System进程的PID都是4,空闲进程也是同样的道理。

网络隔离+图形化访问

和Linux容器一样,Windows容器也可以有自己的独立网络配置。

Linux:Windows Docker第一时间揭秘
Linux:Windows Docker第一时间揭秘

此外,由于最新的Windows Server 2016具备SDN功能,不但包含先前Windows 2012对于NVGRE的支持,同时也支持Vxlan。理论上来说,Window内置的网络支持能力如果能够和Windows Docker有机的整合,可以更好地支持Windows Docker功能。

由于传统的Windows应用大多是有GUI的,所以这些应用可能需要通过图形化方式进行远程操控。

视频里Taylor举了一个sysinternals容器的例子。有趣的是,这个demo本来是Mark Russsinovich的保留曲目,可惜Build大会Keynote的时间十分宝贵,Mark没有足够的时间去演示,而由Taylor代劳。

Taylor演示直接在docker client上下文里启动Sysinternals Suite里的经典工具Process Explorer,由于该工具带GUI,所以虽然进程已经在容器里启动,但是在Docker Client里无法直接远程显示。

如何才能正常显示呢?Taylor用了一个CC命令,直接连接到该容器的IP地址(192.168.0.23)。从demo里我们可以看出,实际 上这个CC命令连接到容器的RDP服务上,这样就相当于直接通过终端服务连接到容器里的会话里,哈哈,有点类似RemoteApp(或者Citrix XenApp)的效果!

Linux:Windows Docker第一时间揭秘
Linux:Windows Docker第一时间揭秘

盆盆在《Windows Dcoker深入原理分析》里曾经提到,Windows Docker的前身DrawBridge在其沙盒里实现了RDP服务,Windows Docker的原理应该类似。

Linux:Windows Docker第一时间揭秘
Linux:Windows Docker第一时间揭秘

Linux Docker也能访问图形化界面,在这篇文章《在 Docker 中运行 OpenOffice》里介绍,只需在Dockerfiles里添加安装X Server的命令,就能借助VNC客户端连接到OpenOffice图形化界面。

PID隔离

在Linux容器里,容器里的PID有自己的独立命名空间。从演示的情况来看,Windows容器的PID隔离方法看上去略有不同。

在前面IPC隔离一节,我们可以通过tasklist命令确认不同的容器,其CSRSS、Lsass、SVCHOST等重要进程的PID有所不同,用户进程的PID也不一样,可见彼此之间是完全隔离的。

那么从宿主机的角度来看呢?

我们可以用Process Explorer的例子来确认,这需要观看Ignite大会上由Taylor所主讲的视频,由于Process Explorer是在终端会话里打开的,所以我们可以在容器的任务管理器里看到有两个会话:

  • 会话14是Docker客户端访问生成
  • 会话15则是通过RDP访问生成

可以看到Process Explorer的进程有两个版本。显然,会话14是Taylor在Docker客户端里运行的结果(但是我们无法看到图形化界面),而会话15则是RDP访问的结果。

两者的运行账户不一样,RDP登录的运行身份为Administrator(应该和Docker History一致),而会话14则是System账户。

以下是从容器视角所看到的任务管理器。这个任务管理器是从容器的角度来看的,我们可以记下其中的若干SVCHOST进程的PID。

Linux:Windows Docker第一时间揭秘
Linux:Windows Docker第一时间揭秘
接下来我们打开宿主机的任务管理器,从全局的角度来查看。可以发现,从宿主机的角度来看,能看到每个容器里的进程,其PID和容器里面的版本是一样的。

Linux:Windows Docker第一时间揭秘
Linux:Windows Docker第一时间揭秘

用户账户隔离

Linux内核拥有账户隔离能力,可以让容器里的进程以root身份运行,而在宿主机上,该账户实际上是普通用户权限,这样可以极大地改进安全性。

在Taylor的这个演示中,我们也能“察觉”到一些蛛丝马迹。在PID隔离一节的两个任务管理器截图里,从容器的视角来看,可以看到 Process Explorer的运行账户为Administrator,但是从宿主机上查看,对应进程的运行账户为空。所以Windows容器可能也实现了类似的账户 隔离技术(抱歉这只是推测,我们现在还拿不到Windows Docker的测试版本)。

计算机名和域名隔离

Windows容器拥有自己的计算机名和域名隔离能力,这样在网络上,Windows容器看上去类似于一台独立的虚拟机。

不过由于共享内核,所以Windows容器目前应该不支持活动目录,毕竟同一台宿主机上所有容器应该都具有同一个SID,这样就无法加域(无法验证计算机账户)。

盆盆推测,到了Windows容器时代,类似于活动目录这类比较笨重的验证协议可能会逐渐退出历史舞台。毕竟活动目录需要开放那么多端口,需要借助ADFS等手段才能穿透Internet。

不过Windows容器的验证并不会存在问题,Azure AD和证书等都是很合适的办法。

容器的优势

容器非常适合开发的快速迭代、快速回滚。Taylor做了一个简单的演示,对前面所述的代码进行修改,调用私有的msvcr120.dll文件里的_snwprintf函数,以显示”Now it’s really cool”。

Linux:Windows Docker第一时间揭秘
Linux:Windows Docker第一时间揭秘

但是在docker build的时候,Taylor没有修改Dockerfile,没有像Mark之前的demo那样把私有的msvcr120.dll拷贝到容器映像中,以便生成新的Layer。

Linux:Windows Docker第一时间揭秘
Linux:Windows Docker第一时间揭秘

结果由于容器的目标宿主机上没有安装Visual Studio,所以新Build的容器运行失败,提醒缺少msvcr120.dll文件,而无法显示”Now it’s really cool”。

Linux:Windows Docker第一时间揭秘
Linux:Windows Docker第一时间揭秘

解决这个问题很简单,可以根据先前的映像快速生成新的容器,这大概只需要几秒钟时间。这样就可以有充足的时间去调试修改了。

在Build大会的Keynote上,Mark Russinovich演示了用Visual Studio把同一个电商网站的代码签入到Windows容器和Linux容器里,并且可以用Visual Studio来调试Linux容器里的代码。

Linux:Windows Docker第一时间揭秘
Linux:Windows Docker第一时间揭秘

来源:http://dockone.io/article/369

Linux:如何实现 ssh 无密码登录

假设你是hostA上的一个用户”aliceA”,想以用户“aliceB”的身份ssh到hostB上,但又不想输入密码。那么,你可以参考这篇教程实现ssh无密码登录。

Linux:如何实现 ssh 无密码登录
Linux:如何实现 ssh 无密码登录

首先,你需要以用户“aliceA”的身份登录到hostA上。

然后,使用ssh-keygen生成一对rsa公私钥,生成的密钥对会存放在~/.ssh目录下。

$ ssh-keygen -t rsa

接下来,使用下面的命令在目标主机hostB上的aliceB用户目录下创建~/.ssh目录。如果在aliceB@hostB上已经存在.ssh目录,这一步会被略过。

$ ssh aliceB@hostB mkdir -p .ssh

最后,将hostA上用户“aliceA”的公钥拷贝到aliceB@hostB上,来实现无密码ssh。

$ cat .ssh/id_rsa.pub | ssh aliceB@hostB 'cat >> .ssh/authorized_keys'

自此以后,从aliceA@hostA上ssh到aliceB@hostB上再也不需要输入密码。(LCTT 译注:上述的创建目录并复制的操作也可以通过一个 ssh-copy-id 命令一步完成:ssh-copy-id -i ~/.ssh/id_rsa.pub aliceB@hostB

疑难解答

  1. 即使在密钥认证生效后,你可能仍然需要输入SSH密码。如果遇到这种情况,请检查系统日志(如/var/log/secure)以查看是否出现下面的异常。

    Authentication refused: bad ownership or modes for file /home/aliceB/.ssh/authorized_keys

    在这种情况下,密钥认证的失败是由于~/.ssh/authorized_keys文件的权限或拥有者不正确。一般情况,如果这个文件对除了你之外的所有用户都可读,就会出现这个错误。用下面的方式改变文件的权限以修正错误。

    $ chmod 700 ~/.ssh/authorized_keys
    

via: http://xmodulo.com/how-to-enable-ssh-login-without.html

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

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

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

Linux:Linux 有问必答:如何在 Ubuntu 上配置网桥

Question: 我需要在我的Ubuntu主机上建立一个Linux网桥,共享一个网卡给其他一些虚拟主机或在主机上创建的容器。我目前正在Ubuntu上使用网络管理器(Network Manager),所以最好>能使用网络管理器来配置一个网桥。我该怎么做?

网桥是一个硬件装备,用来将两个或多个数据链路层(OSI七层模型中第二层)互联,以使得不同网段上的网络设备可以互相访问。当你想要互联一个主机里的多个虚拟机器或者以太接口时,就需要在Linux主机里有一个类似桥接的概念。这里使用的是一种软网桥。

有很多的方法来配置一个Linux网桥。举个例子,在一个无外接显示/键盘的服务器环境里,你可以使用brct手动地配置一个网桥。而在桌面环境下,在网络管理器里也支持网桥设置。那就让我们测试一下如何用网络管理器配置一个网桥吧。

要求

为了避免任何问题,建议你的网络管理器版本为0.9.9或者更高,它用在 Ubuntu 15.04或者更新的版本。

$ apt-cache show network-manager | grep Version

Version: 0.9.10.0-4ubuntu15.1
Version: 0.9.10.0-4ubuntu15

创建一个网桥

使用网络管理器创建网桥最简单的方式就是通过nm-connection-editor。这款GUI(图形用户界面)的工具允许你傻瓜式地配置一个网桥。

首先,启动nm-connection-editor。

$ nm-connection-editor

该编辑器的窗口会显示给你一个列表,列出目前配置好的网络连接。点击右上角的“添加”按钮,创建一个网桥。

Linux:Linux 有问必答:如何在 Ubuntu 上配置网桥
Linux:Linux 有问必答:如何在 Ubuntu 上配置网桥

接下来,选择“Bridge”(网桥)作为连接类型。

Linux:Linux 有问必答:如何在 Ubuntu 上配置网桥
Linux:Linux 有问必答:如何在 Ubuntu 上配置网桥

现在,开始配置网桥,包括它的名字和所桥接的连接。如果没有创建过其他网桥,那么默认的网桥接口会被命名为bridge0。

回顾一下,创建网桥的目的是为了通过网桥共享你的以太网卡接口,所以你需要添加以太网卡接口到网桥。在图形界面添加一个新的“桥接的连接”可以实现上述目的。点击“Add”按钮。

Linux:Linux 有问必答:如何在 Ubuntu 上配置网桥
Linux:Linux 有问必答:如何在 Ubuntu 上配置网桥

选择“以太网”作为连接类型。

Linux:Linux 有问必答:如何在 Ubuntu 上配置网桥
Linux:Linux 有问必答:如何在 Ubuntu 上配置网桥

在“设备的 MAC 地址”区域,选择你想要从属于网桥的接口。本例中,假设该接口是eth0。

Linux:Linux 有问必答:如何在 Ubuntu 上配置网桥
Linux:Linux 有问必答:如何在 Ubuntu 上配置网桥

点击“常规”标签,并且选中两个复选框,分别是“当其可用时自动连接到该网络”和“所有用户都可以连接到该网络”。

Linux:Linux 有问必答:如何在 Ubuntu 上配置网桥
Linux:Linux 有问必答:如何在 Ubuntu 上配置网桥

切换到“IPv4 设置”标签,为网桥配置DHCP或者是静态IP地址。注意,你应该为从属的以太网卡接口eth0使用相同的IPv4设定。本例中,我们假设eth0是用过DHCP配置的。因此,此处选择“自动(DHCP)”。如果eth0被指定了一个静态IP地址,那么你也应该指定相同的IP地址给网桥。

Linux:Linux 有问必答:如何在 Ubuntu 上配置网桥
Linux:Linux 有问必答:如何在 Ubuntu 上配置网桥

最后,保存网桥的设置。

现在,你会看见一个新增的网桥连接被创建在“网络连接”窗口里。因为已经从属与网桥,以前配置好的有线连接 eth0 就不再需要了,所以去删除原来的有线连接吧。

Linux:Linux 有问必答:如何在 Ubuntu 上配置网桥
Linux:Linux 有问必答:如何在 Ubuntu 上配置网桥

这时候,网桥连接会被自动激活。从指定给eth0的IP地址被网桥接管起,你将会暂时丢失一下连接。当IP地址赋给了网桥,你将会通过网桥连接回你的以太网卡接口。你可以通过“Network”设置确认一下。

Linux:Linux 有问必答:如何在 Ubuntu 上配置网桥
Linux:Linux 有问必答:如何在 Ubuntu 上配置网桥

同时,检查可用的接口。提醒一下,网桥接口必须已经取代了任何你的以太网卡接口拥有的IP地址。

Linux:Linux 有问必答:如何在 Ubuntu 上配置网桥
Linux:Linux 有问必答:如何在 Ubuntu 上配置网桥

就这么多了,现在,网桥已经可以用了。


via: http://ask.xmodulo.com/configure-linux-bridge-network-manager-ubuntu.html

作者:Dan Nanni 译者:wi-cuckoo 校对:wxy

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

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

Linux:一些重要 Docker 命令的简单介绍

大家好,今天我们来学习一些在你使用 Docker 之前需要了解的重要的 Docker 命令。Docker 是一个开源项目,提供了一个可以打包、装载和运行任何应用的轻量级容器的开放平台。它没有语言支持、框架和打包系统的限制,从小型的家用电脑到高端服务器,在何时何地都可以运行。这使它们可以不依赖于特定软件栈和供应商,像一块块积木一样部署和扩展网络应用、数据库和后端服务。

Linux:一些重要 Docker 命令的简单介绍
Linux:一些重要 Docker 命令的简单介绍

Docker 命令简单易学,也很容易实现或实践。这是一些你运行 Docker 并充分利用它需要知道的简单 Docker 命令。

1. 拉取 Docker 镜像

由于容器是由 Docker 镜像构建的,首先我们需要拉取一个 docker 镜像来开始。我们可以从 Docker Registry Hub 获取所需的 docker 镜像。在我们使用 pull 命令拉取任何镜像之前,为了避免 pull 命令的一些恶意风险,我们需要保护我们的系统。为了保护我们的系统不受这个风险影响,我们需要添加 127.0.0.1 index.docker.io 到 /etc/hosts 条目。我们可以通过使用喜欢的文本编辑器完成。

# nano /etc/hosts

现在,增加下面的一行到文件并保存退出。

127.0.0.1 index.docker.io
Linux:一些重要 Docker 命令的简单介绍
Linux:一些重要 Docker 命令的简单介绍

要拉取一个 docker 镜像,我们需要运行下面的命令。

# docker pull registry.hub.docker.com/busybox

Docker pull 命令

我们可以检查本地是否有可用的 Docker 镜像。

# docker images

Docker 镜像

2. 运行 Docker 容器

现在,成功地拉取要求的或所需的 Docker 镜像之后,我们当然想运行这个 Docker 镜像。我们可以用 docker run 命令在镜像上运行一个 docker 容器。在 Docker 镜像上运行一个 docker 容器时我们有很多选项和标记。我们使用 -t 和 -i 选项来运行一个 docker 镜像并进入容器,如下面所示。

# docker run -it busybox

Docker Run Shell 命令

从上面的命令中,我们进入了容器并可以通过交互 shell 访问它的内容。我们可以键入 Ctrl-D 从shell中退出。

现在,在后台运行容器,我们用 -d 标记分离 shell,如下所示。

# docker run -itd busybox

后台运行容器

如果你想进入到一个正在运行的容器,我们可以使用 attach 命令加一个容器 id。可以使用 docker ps 命令获取容器 id。

# docker attach 

进入Docker

3. 检查容器运行

不论容器是否运行,查看日志文件都很简单。我们可以使用下面的命令去检查是否有 docker 容器在实时运行。

# docker ps

现在,查看正在运行的或者之前运行的容器的日志,我们需要运行以下的命令。

# docker ps -a
Linux:一些重要 Docker 命令的简单介绍
Linux:一些重要 Docker 命令的简单介绍

4. 查看容器信息

我们可以使用 inspect 命令查看一个 Docker 容器的各种信息。

# docker inspect 
Linux:一些重要 Docker 命令的简单介绍
Linux:一些重要 Docker 命令的简单介绍

5. 杀死或删除

我们可以使用容器 id 杀死或者停止 docker 容器(进程),如下所示。

# docker stop 

要停止每个正在运行的容器,我们需要运行下面的命令。

# docker kill $(docker ps -q)

现在,如我我们希望移除一个 docker 镜像,运行下面的命令。

# docker rm 

如果我们想一次性移除所有 docker 镜像,我们可以运行以下命令。

# docker rm $(docker ps -aq)

结论

这些都是充分学习和使用 Docker 很基本的 docker 命令。有了这些命令,Docker 变得很简单,可以提供给最终用户一个易用的计算平台。根据上面的教程,任何人学习 Docker 命令都非常简单。如果你有任何问题,建议,反馈,请写到下面的评论框中以便我们改进和更新内容。多谢! 希望你喜欢 🙂


via: http://linoxide.com/linux-how-to/important-docker-commands/

作者:Arun Pyasi 译者:ictlyh 校对:wxy

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

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

Linux:深度Linux使用小记

Deepin是由武汉深度科技有限公司开发的Linux发行版。Deepin 是一个基于 Linux 的操作系统,专注于使用者对日常办公、学习、生活和娱乐的操作体验的极致,适合笔记本、桌面计算机和一体机,它是一个基于Debian的本地化衍生版,系统集成了C、Java、Python编译环境、WPS办公软件、Flash插件、腾讯QQ、各种输入法以及漂亮的字体、还可以灵活使用各种Windows下的工具软件,为你节省了很多配置系统的时间。

总的来说它的宗旨是创造一个全新的简单、易用、美观的 Linux 操作系统。目前最新版:Deepin 2014.3,下载地址:http://www.deepin.org/download.html 

安装

下面对2014.3这一版本的基本应用做一些介绍。以下实验安装均通过Vmware Workstations 10完成。在虚拟机中设置,安装过程非常简单,适合零基础Linux用户。

Linux:深度Linux使用小记
Linux:深度Linux使用小记

从安装开始你会感觉,安装系统比较智能能识别绝大多数硬件,图片美观,字体显示细腻看着非常舒服,也许是吧使用者当成小白的缘故,安装时没有过多的专业问题,整个过程大约经过15~20分钟,操作系统基础安装完毕,下面开始系统设置向导。

Linux:深度Linux使用小记
Linux:深度Linux使用小记

接着,我们首先开始软件更新。

Linux:深度Linux使用小记
Linux:深度Linux使用小记

更改Grub启动菜单背景图片,以前要实现这一目的至少需要4步,可如今只要你用鼠标就可以实现,调时间,文字颜色等细节。

Linux:深度Linux使用小记
Linux:深度Linux使用小记

以下是张背景图片

Linux:深度Linux使用小记
Linux:深度Linux使用小记

灵活的分辨率设置

Linux:深度Linux使用小记
Linux:深度Linux使用小记

查看系统监视器

Linux:深度Linux使用小记
Linux:深度Linux使用小记

 

Linux:深度Linux使用小记
Linux:深度Linux使用小记

Linux:浅谈JS DDoS攻击原理与防御

分布式拒绝服务攻击(DDoS)攻击是一种针对网站发起的最古老最普遍的攻击。Nick Sullivan是网站加速和安全服务提供商CloudFlare的一名系统工程师。近日,他撰文介绍了攻击者如何利用恶意网站、服务器劫持和中间人攻击发起DDoS攻击,并说明了如何使用HTTPS以及即将到来的名为“子资源一致性(Subresource Integrity,简称SRI)”的Web新技术保护网站免受攻击。

现代网站的大部分交互都来自于JavaScript。网站通过直接向HTML中添加JavaScript代码或者通过HTML元素