Skip to content Skip to main navigation Skip to footer

Linux

Linux:深入浅出Docker(四):Docker的集成测试部署之道

1. 背景

敏捷开发已经流行了很长时间,如今有越来越多的企业开始践行敏捷开发所提倡的以人为中心、迭代、循序渐进的开发理念。在这样的场景下引入Docker技术,首要目的就是使用Docker提供的虚拟化方式,给开发团队建立一套可以复用的开发环境,让开发环境可以通过Image的形式分享给项目的所有开发成员,以简化开发环境的搭建。但是,在没有Docker技术之前就已经有类如Vagrant的开发环境分发技术,软件开发者一样可以创建类似需求的环境配置流程。所以在开发环境方面,Docker技术的优势并不能很好的发挥出来。笔者认为Docker的优点在于可以简化CI(持续集成)、CD(持续交付)的构建流程,让开发者把更多的精力用在开发上。

每家公司都有自己的开发技术栈,我们需要结合实际情况对其进行持续改进,优化自己的构建流程。当我们准备迈出第一步时,我们首先要确立一张构建蓝图,做到胸有成竹,这样接下来的事情才会很快实现。

Linux:深入浅出Docker(四):Docker的集成测试部署之道
Linux:深入浅出Docker(四):Docker的集成测试部署之道

这张时序图概括了目前敏捷开发流程的所有环节。结合以上时序图给出的蓝图框架,本文的重点是讲解引入Docker技术到每个环节中的实践经验。

2. 创建持续发布的团队

开发团队在引入Docker技术的时候,最大的问题是没有可遵循的业界标准。大家常常以最佳实践为口号,引入多种工具链,导致在使用Docker的过程中没有侧重点。涉及到Docker选型,又在工具学习上花费大量时间,而不是选用合适的工具以组建可持续发布产品的开发团队。基于这样的场景,我们可以把“简单易用”的原则作为评判标准,引入到Docker技术工具选型的参考中。开发团队在引入Docker技术的过程中,首先需要解决的是让团队成员尽快掌握Docker命令行的使用。在熟悉了Docker命令行之后,团队需要解决几个关键问题具体如下:

1)Base Image的选择, 比如phusion-baseimage

2)配置管理Docker镜像的工具的选择,比如AnsibleChefPuppet

3)Host主机系统的选择,比如CoreOSAtomicUbuntu

Base Image包括了操作系统命令行和类库的最小集合,一旦启用,所有应用都需要以它为基础创建应用镜像。Ubuntu作为官方使用的默认版本,是目前最易用的版本,但系统没有经过优化,可以考虑使用第三方有划过的版本,比如如phusion-baseimage。对于选择RHEL、CentOS分支的Base Image,提供安全框架SELinux的使用、块级存储文件系统devicemapper等技术,这些特性是不能和Ubuntu分支通用的。另外需要注意的是,使用的操作系统分支不同,其裁剪系统的方法也完全不同,所以大家在选择操作系统时一定要慎重。

配置管理Docker镜像的工具主要用于基于Dockerfile创建Image的配置管理。我们需要结合开发团队的现状,选择一款团队熟悉的工具作为通用工具。配置工具有很多种选择,其中Ansible作为后起之秀,在配置管理的使用中体验非常简单易用,推荐大家参考使用。

Host主机系统是Docker后台进程的运行环境。从开发角度来看,它就是一台普通的单机OS系统,我们仅部署Docker后台进程以及集群工具,所以希望Host主机系统的开销越小越好。这里推荐给大家的Host主机系统是CoreOS,它是目前开销最小的主机系统。另外,还有红帽的开源Atomic主机系统,有基于FedoraCentOSRHEL多个版本的分支选择,也是不错的候选对象。另外一种情况是选择最小安装操作系统,自己定制Host主机系统。如果你的团队有这个实力,可以考虑自己定制这样的系统。

3. 持续集成的构建系统

当开发团队把代码提交到Git应用仓库的那一刻,我相信所有的开发者都希望有一个系统能帮助他们把这个应用程序部署到应用服务器上,以节省不必要的人工成本。但是,复杂的应用部署场景,让这个想法实现起来并不简单。

首先,我们需要有一个支持Docker的构建系统,这里推荐Jenkins。它的主要特点是项目开源、方便定制、使用简单。Jenkins可以方便的安装各种第三方插件,从而方便快捷的集成第三方的应用。

Linux:深入浅出Docker(四):Docker的集成测试部署之道
Linux:深入浅出Docker(四):Docker的集成测试部署之道

通过Jenkins系统的Job触发机制,我们可以方便的创建各种类型的集成Job用例。但缺乏统一标准的Job用例使用方法,会导致项目Job用例使用的混乱,难于管理维护。这也让开发团队无法充分利用好集成系统的优势,当然这也不是我们期望的结果。所以,敏捷实践方法提出了一个可以持续交付的概念 DeploymentPipeline(管道部署)。通过Docker技术,我们可以很方便的理解并实施这个方法。

Jenkins的管道部署把部署的流程形象化成为一个长长的管道,每间隔一小段会有一个节点,也就是Job,完成这个Job工作后才可以进入下一个环节。形式如下:

Linux:深入浅出Docker(四):Docker的集成测试部署之道
Linux:深入浅出Docker(四):Docker的集成测试部署之道

image source: google image search

大家看到上图中的每一块面板在引入Docker技术之后,就可以使用Docker把任务模块化,然后做成有针对性的Image用来跑需要的任务。每一个任务Image的创建工作又可以在开发者自己的环境中完成,类似的场景可以参考下图:

Linux:深入浅出Docker(四):Docker的集成测试部署之道
Linux:深入浅出Docker(四):Docker的集成测试部署之道

image source: google image search

所以,使用Docker之后,任务的模块化很自然地被定义出来。通过管道图,可以查看每一步的执行时间。开发者也可以针对任务的需要,为每一个任务定义严格的性能标准,已作为之后测试工作的参考基础。

来源:http://www.infoq.com/cn/articles/docker-integrated-test-and-deployment

Linux:Linux有问必答:如何在Debian下安装闭源软件包

提问: 我需要在Debian下安装特定的闭源设备驱动。然而, 我无法在Debian中找到并安装软件包。如何在Debian下安装闭源软件包?

Debian是一个拥有48,000软件包的发行版. 这些软件包被分为三类: main, contrib 和 non-free, 主要是根据许可证要求, 参照Debian开源软件指南 (DFSG)。

Linux:Linux有问必答:如何在Debian下安装闭源软件包
Linux:Linux有问必答:如何在Debian下安装闭源软件包

main软件仓库包括符合DFSG的开源软件。contrib也包括符合DFSG的开源软件,但是依赖闭源软件来编译或者执行。non-free包括不符合DFSG的、可再分发的闭源软件。main仓库被认为是Debian项目的一部分,但是contrib和non-free不是。后两者只是为了用户的方便而维护和提供。

如果你想一直能够在Debian上安装闭源软件包,你需要添加contrib和non-free软件仓库。这样做,用文本编辑器打开 /etc/apt/sources.list 添加”contrib non-free””到每个源。

下面是适用于 Debian Wheezy的 /etc/apt/sources.list 例子。

deb http://ftp.us.debian.org/debian/ wheezy main contrib non-free
deb-src http://ftp.us.debian.org/debian/ wheezy main contrib non-free
deb http://security.debian.org/ wheezy/updates main contrib non-free
deb-src http://security.debian.org/ wheezy/updates main contrib non-free
# wheezy-updates, 之前叫做 'volatile'
deb http://ftp.us.debian.org/debian/ wheezy-updates main contrib non-free
deb-src http://ftp.us.debian.org/debian/ wheezy-updates main contrib non-free
Linux:Linux有问必答:如何在Debian下安装闭源软件包
Linux:Linux有问必答:如何在Debian下安装闭源软件包

修改完源后, 运行下面命令去下载contrib和non-free软件仓库的文件索引。

$ sudo apt-get update

如果你用 aptitude, 运行下面命令。

$ sudo aptitude update

现在你在Debian上搜索和安装任何闭源软件包。

Linux:Linux有问必答:如何在Debian下安装闭源软件包
Linux:Linux有问必答:如何在Debian下安装闭源软件包

via: http://ask.xmodulo.com/install-nonfree-packages-debian.html

译者:mtunique 校对:wxy

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

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

Linux:如何使用Docker构建运行时间较长的脚本

Linux:如何使用Docker构建运行时间较长的脚本
Linux:如何使用Docker构建运行时间较长的脚本

我想我已经找到了一个非常不错的Docker使用案例。你是不是会觉得这是一篇写Docker有多好多好的文章,开始之前我想和你确认,这篇文章会介绍如何把文件系统作为持久性的数据结构。

因此,这篇文章的见解同样适用于其他的 copy-on-write文件系统,如BTRFSZFS

问题

让我们从这个我试图解决的问题开始。我开发了一个会运行很长时间的构建脚本,这个脚本中包含了很多的步骤。

  • 这个脚本会运行1-2个小时。
  • 它会从网络下载比较大的文件(超过300M)。
  • 后面的构建步骤依赖前期构建的库。

但最最烦人的是,运行这个脚本真的需要花很长的时间。

文件系统是固有状态

我们一般是通过一种有状态的方式与文件系统进行交互的。我们可以添加、删除或移动文件。我们可以修改文件的 权限或者它的访问时间。大部分独立的操作都可以撤销,例如将文件移动到其它地方后,你可以将文件恢复到原来的位置。但我们不会通过快照的方式来将它恢复到 原始状态。这篇文章我将会介绍如何在耗时较长的脚本中充分利用快照这一特性。

使用联合文件系统的快照

Docker使用的是联合文件系统叫做AUFS(译者注:简单来说就是支持将不同目录挂载到同一个虚拟文件系统下的文件系统)。联合文件系统实现了Union mount。顾名思义,也就是说不同的文件系统的文件和目录可以分层叠加在单个连贯文件系统之上。这是通过分层的方式完成的。如果一个文件出现在两个文件系统,那最高层级的文件才会显示(该文件其它版本也是存在于层级中的,不会改变,只是看不到的)。

在Docker中,每一个在Union mount转哦给你的文件系统都被称为layers(层)。使用这种技术可以轻松实现快照,每个快照都是所有层的一个Union mount。

生成脚本的快照

使用快照可以帮助构建一个长时运行的脚本。总的想法是,将一个大的脚本分解为许多小的脚本(我喜欢称之为 scriptlets),并单独运行这些小的脚本,脚本运行后为其文件系统打一个快照 (Docker会自动执行此操作)。如果你发现一个scriptlet运行失败,你可以快速回退到上次的快照,然后再试一次。一旦你完成脚本的构建,并且 可以保证脚本能正常工作,那你就可以将它分配给其它主机。

回过头来再对比下,如果你没有使用快照功能了?当你辛辛苦苦等待了一个半小时后,脚本却构建失败了,我想除了少部分有耐心的人外,很多人是不想再来一次了,当然,你也会尽最大努力把系统恢复到失败前的状态,比如可以删除一个目录或运行make clean。

但是,我们可能没有真正地理解我们正在构建的组件。它可能有复杂的Makefile,它会把把文件放到文件系统中我们不知道的地方,唯一真正确定的途径是恢复到快照。

使用快照构建脚本的Docker

在本节中,我将介绍我是如何使用Docker实现GHC7.8.3 ARM交叉编译器的构建脚本。Docker非常适合做这件事,但并非完美。我做了很多看起来没用的或者不雅的事情,但都是必要的,这都是为了保证将开发脚本的总时间降到最低限度。构建脚本可以在这里找到。

用Dockerfile构建

Docker通过读取Dockerfile来构建镜像。Dockerfile会通过一些命令来具体指定应该执行哪些动作。具体使用说明可以参考这篇文章。在我的脚本中主要用到WORKDIR、ADD和RUN。ADD命令非常有用因为它可以让你在运行之前将外部文件添加到当前Docker镜像中然后转换成镜像的文件系统。你可以在这里看到很多scriptlets构成的构建脚本。

设计

1. 在RUN之前ADD scriptlets

如果你很早就将所有的scriptletsADD在Dockerfile,您可能会遇到以下问题:如果你的脚本构建失败,你回去修改scriptlet并再次运行docker build。但是你发现,Docker开始在首次加入scriptlets的地方构建!这样做会浪费了大量的时间并且违背了使用快照的目的。

出现这种情况的原因是由于Docker处理它的中间镜像(快照)的方式。当Docker通过Dockerfile构建镜像时,它会与中间镜像比较当前命令是否一致。然而,在ADD命令的情况下被装进镜像的文件里的内容也会被检查。如果相对于现有的中间镜像,文件已经改变,那么Docker也别无选择,只能从这点开始建立一个新的镜像。因为Docker不知道这些变化会不会影响到构建。

此外,使用RUN命令要注意,每次运行时它都会导致文件系统有不同的更改。在这种情况下,Docker会发现中间镜像并使用它,但是这将是错误的。RUN命令每次运行时会造成文件系统相同的改变。举个例子,我确保在我的scriptlets我总是下载了一个已知版本的文件与一个特定MD5校验。

对Docker 构建缓存更详细的解释可以在这里找到。

2.不要使用ENV命令来设置环境变量,请使用scriptlet。

它似乎看起来很有诱惑力:使用ENV命令来设置所有构建脚本需要的环境变量。但是,它不支持变量替换的方式,例如 ENV BASE=$HOME/base 将设置BASE的值为$HOME/base着很可能不是你想要的。

相反,我用ADD命令添加一个名为set-env.sh文件。此文件会包含在后续的scriptlet中:

THIS_DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )"
source $THIS_DIR/set-env-1.sh

如果你没有在第一时间获取set-env.sh会怎么样呢?它很早就被加入Dockerfile并不意味着修改它将会使随后的快照无效?

是的,这会有问题。在开发脚本时,我发现,我已经错过了在set-env.sh添加一个有用的环境变量。解决方案是创建一个新的文件set-env-1.sh包含:

THIS_DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )"
source $THIS_DIR/set-env.sh
if ! [ -e "$CONFIG_SUB_SRC/config.sub" ] ; then
CONFIG_SUB_SRC=${CONFIG_SUB_SRC:-$NCURSES_SRC}
fi

然后,在所有后续的scriptlets文件中包含了此文件。现在,我已经完成了构建脚本,我可以回去解决这个问题了,但是,在某种意义上,它会破坏最初的目标。我将不得不从头开始运行构建脚本看看这种变化是否能成功。

缺点

一个主要缺点是这种方法是,所构建的镜像尺寸是大于它实际需求的尺寸。在我的情况下尤其如此,因为我在最后删除了大量文件的。然而,这些文件都仍然存在于联合挂载文件系统的底层文件系统内,所以整个镜像是大于它实际需要的大小至少多余的是删除文件的大小。

然而,有一个变通。我没有公布此镜像到Docker Hub Registry。相反,我:

  • 使用docker export导出内容为tar文件。
  • 创建一个新的Dockerfile简单地添加了这个tar文件的内容。

产生尺寸尽可能小的镜像。

结论

这种方法的优点是双重的:

  • 它使开发时间降至最低,不再做那些已经构建成功的子组件。你可以专注于那些失败的组件。
  • 这非常便于维护构建脚本。构建可能会失败,但只要你搞定Dockerfiel,至少你不必再从头开始。

此外,正如我前面提到的Docker不仅使写这些构建脚本更加容易,有了合适的工具同样可以在任何提供快照的文件系统实现。

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

Linux:Attic——删除重复数据的备份程序

Attic是一个Python写的删除重复数据的备份程序,其主要目标是提供一种高效安全的数据备份方式。重复数据消除技术的使用使得Attic适用于日常备份,因为它可以只存储那些修改过的数据。

Linux:Attic——删除重复数据的备份程序
Linux:Attic——删除重复数据的备份程序

Attic特性

空间高效存储

可变块大小重复数据消除技术用于减少检测到的冗余数据存储字节数量。每个文件被分割成若干可变长度组块,只有那些从没见过的组合块会被压缩并添加到仓库中。

可选数据加密

所有数据可以使用256位AES加密进行保护,并使用HMAC-SHA256验证数据完整性和真实性。

离场备份

Attic可以通过SSH将数据存储到安装有Attic的远程主机上。

备份可作为文件系统挂载

备份归档可作为用户空间文件系统挂载,用于便捷地验证和恢复备份。

安装attic到ubuntu 14.10

打开终端并运行以下命令

sudo apt-get install attic

使用Attic

手把手实例教学

在进行备份之前,首先要对仓库进行初始化:

$ attic init /somewhere/my-repository.attic

将~/src和~/Documents目录备份到名为Monday的归档:

$ attic create /somwhere/my-repository.attic::Monday ~/src ~/Documents

第二天创建一个新的名为Tuesday的归档:

$ attic create --stats /somwhere/my-repository.attic::Tuesday ~/src ~/Documents

该备份将更快些,也更小些,因为只有之前从没见过的新数据会被存储。–stats选项会让Attic输出关于新创建的归档的统计数据,比如唯一数据(不和其它归档共享)的数量:

归档名:Tuesday
归档指纹:387a5e3f9b0e792e91ce87134b0f4bfe17677d9248cb5337f3fbf3a8e157942a
开始时间: Tue Mar 25 12:00:10 2014
结束时间: Tue Mar 25 12:00:10 2014
持续时间: 0.08 seconds
文件数量: 358
        最初大小    压缩后大小  重复数据删除后大小
本归档: 57.16 MB    46.78 MB    151.67 kB
所有归档:114.02 MB  93.46 MB    44.81 MB

列出仓库中所有归档:

$ attic list /somewhere/my-repository.attic
Monday Mon Mar 24 11:59:35 2014
Tuesday Tue Mar 25 12:00:10 2014

列出Monday归档的内容:

$ attic list /somewhere/my-repository.attic::Monday
drwxr-xr-x user group 0 Jan 06 15:22 home/user/Documents
-rw-r--r-- user group 7961 Nov 17 2012 home/user/Documents/Important.doc

恢复Monday归档:

$ attic extract /somwhere/my-repository.attic::Monday

通过手动删除Monday归档恢复磁盘空间:

$ attic delete /somwhere/my-backup.attic::Monday

详情请查阅Attic文档


via: http://www.ubuntugeek.com/attic-deduplicating-backup-program.html

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

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

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

Linux:深入浅出Docker(五):基于Fig搭建开发环境

1. 概述

在搭建开发环境时,我们都希望搭建过程能够简单,并且一劳永逸,其他的同事可以复用已经搭建好的开发环境以节省开发时间。而在搭建开发环境时,我们经常会被复杂的配置以及重复的下载安装所困扰。在Docker技术未出现之前,我们可以使用Pupet、Chef、Ansible等配置管理工具把复杂的配置管理起来,这样的管理配置技术仍然是目前比较流行的方式之一。配置管理工具使用的都是自己的DSL语法定义,考虑到环境的复杂性,配置一套通用的开发环境需要针对各个系统定制,对于大部分开发环境这种维护成本仍然是很高的。Docker技术出现之后,系统的依赖问题得到了彻底的解决,我们可以通过镜像的方式简化环境的安装。结合Docker的开发部署工具Fig,我们可以使用fig.yml文件来定义所有的环境,一次定义,多处使用,简单而且高效。

1.1 打包的方式

Docker本省并不能创建一个真实的虚拟机,它只是基于Linux Kernel把额外的系统文件做了封装,并利用Linux Kernel相关的技术如Cgroup、Namespace隔离用户应用。应用Docker技术,团队之间通过共享Image或者Dockefile来复用开发环境。为了简化写Dockerfile的方式 ,Fig提供更加精简的DSL定义文件fig.yml,可以让新成员快速搭建开发环境并将精力投入到开发过程中去,而不是研究如何正确安装并配置诸如PostgreSQL之类的数据库。目前,软件开发需要的环境Image,大部分都可以在Docker Hub中搜索到,需要使用时直接下载就可以使用。

1.2 应用组合的方式

使用Docker之后,我们不再需要在本地机器安装所有的软件包。我们可以根据项目需要在Docker Hub上搜索相关软件的Image,然后使用Fig pull从Docker Hub上直接下载并由Fig调用Docker的Link命令把Image关联起来,这样所有应用都可以直接调用指定端口的服务,比如Mysql的3306端口提供数据库服务。开发者并不需要对Docker有太多的了解,只需要掌握常用的几条Fig命令就可以随时调试自己的环境。

1.3 环境共享的方式

Fig直接定义好了Image,我们不需要过多的关心容器或者镜像。在分享环境时,只需要把对应的Dockerfile和fig.yml文件分享给同事,他们就可以在自己的机器上运行并搭建出需要的环境,且不用再担心环境依赖带来的意外调试烦恼。团队成员在git clone项目代码后,就可以如下图一样使用一条命令启动自己的开发环境:

Linux:深入浅出Docker(五):基于Fig搭建开发环境
Linux:深入浅出Docker(五):基于Fig搭建开发环境

2. Fig安装指南

首先,我们需要安装Docker Engine,官方针对主流的系统提供了对应的安装手册。这里,我的开发机系统是一台MacBook Pro,所以我需要安装boot2docker来支持Docker。

接下来,我们就可以安装对应系统版本的Fig运行文件。比如在Mac OS或者在64位的Linux上安装Fig:

$ curl -L https://github.com/docker/fig/releases/download/1.0.0/fig-`uname
-s`-`uname -m` > /usr/local/bin/fig; chmod +x /usr/local/bin/fig

当以上的安装方式不能成功的话,我们可以选择使用Python Package的安装方式:

$ sudo pip install -U fig

最后,不管使用什么Linux系统,安装完Fig之后通过运行以下命令来确保环境的一致性。

$ fig --version

如果一切顺利的话,恭喜你,Fig安装成功了。下面请随我一起学习如何使用Fig配置开发环境。

来源:http://www.infoq.com/cn/articles/docker-build-development-environment-based-on-fig

Linux:在Google被封的那些日子里,我们这样科学上网

Linux:在Google被封的那些日子里,我们这样科学上网
Linux:在Google被封的那些日子里,我们这样科学上网

这个标题的前半部分,其实水的很,因为随着防火墙的升级,被封的名单只会越来越多,看不到尽头。

回到正题,如果某天你喜欢的网站被封了,你工作用的邮箱无法访问了,该如何用正确姿势实现科学上网呢?雷锋网为大家整理了数个小技巧。

1、Freegate类傻瓜工具

很多人第一次用翻墙,应该是从Freegate、WuJie、fqrouter、Shadowsocks(请大家自行脑补中文名称)这些软件开始。前两个是纵横多年、经久不衰的老牌Windows健将,后两个是智能机时代新流行起来的Android新星。(Freegate、WuJie也有推出移动版本,但大家似乎很少讨论,不知为何)

之所以把这类软件列在第一,是因为它们用起来实在是太简单了,真正的一键上网,无需任何操作。唯一不太方便的是,找到它们你得花费很多功夫,因为提供下载的网站许多都无法访问。

(提一句,Freegate的主要技术叫在线代理,它还有非常多的衍生形式,诸如PAC、goagent等,这里不再累述)

2、hosts文件

hosts是小白用户的进阶技巧。在Google被封的不是那么厉害的时间里,它是大家首选的科学上网方式。

曾经,smarthosts+hosts自动更新软件,是大家的首选方式,因为这个很方便,不需要折腾各类软件,只需要修改设备上的一个文件即可,而且跨平台Windows、Mac、Android、iOS通用。

不过smarthost在去年停止更新,后来木有稳定更新的hosts源,这一方式逐渐没落,只有在12306抢票时还能看到。

3、VPN

无需多言,VPN用户,是目前最大的科学上网群体。

无论是购买第三方VPN服务、自己搭建VPN服务器还是使用公用的VPN服务,都非常的盛行。一般来说,购买群体大多不太愿意折腾,自建服务器多是是技术人士,公用VPN就是真正的折腾界玩家了。

购买用户还有一个非常大的群体,是微软、IBM、杜邦等跨国公司,一般防火墙管理员手贱贱的时候,这群人就会向商务部投诉,然后商务部再去找防火墙主管,嗯,又能正常上网了。

每个VPN服务商都有详尽的使用教程,这里不多说。

4、OpenVPN

OpenVPN是更安全的VPN。

它开源、开放,跟VPN一样每个平台都能用,并提供了多种加密组合。

和VPN一样,OpenVPN也有不少基于其构建的第三方服务。如果你愿意折腾,可以自己去搭一套这样的服务;图省事?那么购买第三方服务或许是个不错的选择。

OpenVPN并不是为科学上网而准备的,很多中国大学都使用OpenVPN作为一种基础的网络连接方式,只是有国人发现OpenVPN.net(最大的一家OpenVPN服务商)的服务居然可以翻墙,而且还是免费的,因此在国内逐渐流行起来。

据传闻说,现在防火墙可以识别并阻挡OpenVPN.net的流量,NSA可以识别并窃听OpenVPN流量中的内容。

5、Tor

Tor是一个匿名的代理网络。

如果你是从Freegate、WuJie等服务过来、并略折腾的用户,应该知道它们都是使用代理服务器做中转的。Tor也一样,但它的代理服务器是所有的志愿者们,大家在自己电脑上运行Tor软件,就可以作为代理网络的一个节点。

Tor是黑客、敏感者常用的上网方式。在国内Tor节点不多,因此速度较慢。

6、Lantern

Lantern(灯笼)是Tor的可信版本。

Tor太杂,不对节点做任何审核,因此许多审查者也能进来。

Lantern的核心是信任,你邀请你的朋友进来,并把他们的节点设置为可信,这种上网方式比Tor的陌生节点更能赢得信任。

顺带说下,Lantern由Google提供资助。

最后

强调一下,以上只是科学上网方式,并非匿名工具。

在国内,没有匿名网络。

来源:http://www.leiphone.com/news/201412/nG8sH9AHZpmDNkEo.html

Linux:360 for Linux 与 setuid

前言

今日,国内著名安全类软件 360 正式进军 Linux 平台,目前已提供 Debian/Ubuntu/Deepin 以及中标麒麟的预编译二进制。而包括我在内的吃螃蟹者都不同程度地注意到了 360 for Linux 的二进制在正常状况下被设置了 setuid 位。即 4755 权限。如 http://www.v2ex.com/t/158380#reply27 以及 http://tieba.baidu.com/p/3499343332 

Linux:360 for Linux 与 setuid
Linux:360 for Linux 与 setuid

图: 360 for Linux 的权限位

如图所示,这是我在 VirtualBox OSE 中安装的 Lubuntu 14.10 中的 360 for Linux 安装后的权限位, ls 已经将其标红并且显示权限位为 -rwsr-xr-x (4755) 。下面就 setuid 以及其作用展开一些推论。

什么是 setuid 以及相关的安全隐患

setuid 以及 setgid 是 UNIX 环境下的特殊权限位。当作用于可执行文件时,该权限位将导致无论以何用户启动,该可执行文件将拥有其所有者的权限。如 /usr/bin/sudo 的拥有者为 root 且权限为 4755, 那么即使一个非 root 用户执行了 sudo, 其依然会拥有 root 的权限,如读取 /etc/shadow 文件 (-r————, root:root) 的权限。对于用户而言,其最直接的意义在于合法的无密码提权。这使得一般使用该特性的程序都被小心设计以免不测。因为如果设计不当,攻击者可能可以在不需要任何密码的情况下轻松夺取对目标系统的最高权限。基于同样的原因,包括 Linux 在内的部分操作系统会忽略设置在脚本文件上的 setuid/setgid 位。对于普通用户而言,一个被 setuid/setgid 了的恶意可执行文件将能够在不盗取密码的情况下破坏整个系统(尤其是当类似 TOMOYO Linux 的强制访问控制系统没有正确设置时)。因而一般情况下开发者以及系统管理员都会谨慎处理这一特殊权限。如在 Debian 中,可以通过对 man 程序设置 setuid 位来加快 man-db 索引但是由于可能带来的安全隐患该选项必须在安装过程中由用户启用。

360 for Linux 对 setuid 应用的利弊分析

setuid 位最直接的用处是允许 360 for Linux 在不被用户注意的情况下以 root 权限允许。一方面,这将免除用户每次开机都要输入密码的麻烦;另一方面,由于用户无法察觉,该程序可能在有意无意之中对系统造成无法修复的破坏或者成为其他恶意软件入侵系统的跳板(比如 Windows 上的 Sony BMG CD 反拷贝程序由于设计不良就成为了其他恶意软件的跳板)。同时,如果该程序留有(可能存在)的后门,用户也无法从 UNIX 权限系统得到应有的保护。

Linux:360 for Linux 与 setuid
Linux:360 for Linux 与 setuid

图:部分使用了 setuid 的程序。这些程序并非全部都需要该权限位,部分程序可以改用 PolicyKit 来实现提权。

PolicyKit 与无密码提权一些想法

Linux:360 for Linux 与 setuid
Linux:360 for Linux 与 setuid

图: GNOME PackageKit 使用 PolicyKit 进行有密码提权以删除软件包

Linux:360 for Linux 与 setuid
Linux:360 for Linux 与 setuid

图: Windows UAC 对需要 Administrator 权限的 Acronis True Image 进行提权前提示用户输入凭据

我们必须承认,无密码提权在一定程度上方便了用户,但与此同时这种行为也埋下了安全隐患。比如在 AOSC OS2 时代, AnthonOS 默认 sudo 可以进行无密码提权但是这一设定以及因为潜在的安全风险被禁止了。

在很多时候,密码是给用户知情权与选择权。用户知道一个程序要提权并且用户也有选择去拒绝他所不信任的提权请求。同时,如果用户如果对某个先前的决定反悔或发现其为误操作,此时也可以阻止该行为的继续以避免损失。

360 这种行为则涉嫌向用户隐瞒自身的提权行为。这也许只是为了方便用户,也有可能有其他企图。

而如果只是为了避免在 Windows Vista 时代的尴尬,也就是每次开机都出现授权弹窗,也不一定需要使用 setuid 这一有严重安全隐患的方法。 PolicyKit 提供了一套将程序分离为以特权权限运行和以非特权权限运行的两部分并且进行互相沟通的机制。比如 GNOME PackageKit 本身以非特权运行,其通过 PolicyKit 发起需要特权的请求并由 PolicyKit 决定是否需要用户参与提权。而在 Windows 平台上,Avira 旗下的安全产品的主界面并不需要以特权启动,而仅在更改设定或关闭/开启监控时通过 UAC 进行提权,避免了开机时弹出交互式授权对话框的尴尬。

结语

综上所述, 360 for Linux 使用 setuid 可能有其原因。但是鉴于 setuid 本身巨大的隐患,建议用户现阶段慎重使用该软件。我本人也呼吁现在与或即将与奇虎有合作的厂商对 360 for Linux 本身进行全面的安全审计以防被居心叵测者利用或者可能存在后门。与此同时,我本人也建议 360 for Linux 使用标准的 PolicyKit 架构,实现特权部分与非特权部分的分离,并且给用户适当的提示以满足其知情权和选择权。

来源:http://blog.tombu.biz/post/106768706750/360-for-linux-setuid

Linux:“Github”里的“hub”改用Go语言开发

刚刚过去的2014年是Go语言重要的一年,不仅版本升级到了1.4,而且Go语言的集成开发环境LiteIDE也发布了x26,还在云计算方便吸引力不是的注意力。虽然有很多程序员不喜欢Go语言,但每种语言都有直接的缺点和优点,这是很正常的事情。最重要的是取之长、补己短。最近github宣布使用Go1.4重新开发了hub命令,就是要利用Go语言的长处。

Linux:“Github”里的“hub”改用Go语言开发
Linux:“Github”里的“hub”改用Go语言开发

Github是世界上最大的代码托管服务,它是在于最近几年迅速超过了SoruceForge,很大程度上得益于Linux创始人Linus的影响力,和Git中去中心化的思想。相信很多人都使用过git和github,但估计很少人知道这个等式:git + hub = github,hub是一个用来封装git的工具,为其扩展更多的功能和特性,是GitHub运行起来更加快捷方便。

$ hub clone rtomayko/tilt
# expands to:
$ git clone git://github.com/rtomayko/tilt.git

hub命令的最佳使用方法是当作git的别名,这样,当你输入$ git  时,你不仅能获得git的所有功能,而且能增添很多附加特性。设置别名的方法是在你的.bash_profile文件放置下一行代码:

eval "$(hub alias -s)"

从2.2.0版本开始,hub开始改用Go语言开发,主要原因是Go语言的高效。要想从源代码安装hub 2.x版本,你需要有一个Go语言开发环境,版本要在1.4以上:

$ git clone https://github.com/github/hub.git
$ cd hub
$ ./script/build
$ cp hub 你的BIN目录

hub2.x版本将对1.x版本保持最大的兼容。下面我里看一下hub命令提供了哪些额外的强大功能。

(下面这些代码中假设你已经做了git别名设置)

git clone

$ git clone schacon/ticgit
> git clone git://github.com/schacon/ticgit.git
$ git clone -p schacon/ticgit
> git clone git@github.com:schacon/ticgit.git
$ git clone resque
> git clone git@github.com/YOUR_USER/resque.git

git remote add

$ git remote add rtomayko
> git remote add rtomayko git://github.com/rtomayko/CURRENT_REPO.git
$ git remote add -p rtomayko
> git remote add rtomayko git@github.com:rtomayko/CURRENT_REPO.git
$ git remote add origin
> git remote add origin git://github.com/YOUR_USER/CURRENT_REPO.git

git fetch

$ git fetch mislav
> git remote add mislav git://github.com/mislav/REPO.git
> git fetch mislav
$ git fetch mislav,xoebus
> git remote add mislav ...
> git remote add xoebus ...
> git fetch --multiple mislav xoebus

git cherry-pick

$ git cherry-pick http://github.com/mislav/REPO/commit/SHA
> git remote add -f mislav git://github.com/mislav/REPO.git
> git cherry-pick SHA
$ git cherry-pick mislav@SHA
> git remote add -f mislav git://github.com/mislav/CURRENT_REPO.git
> git cherry-pick SHA
$ git cherry-pick mislav@SHA
> git fetch mislav
> git cherry-pick SHA

git am, git apply

$ git am https://github.com/defunkt/hub/pull/55
[ downloads patch via API ]
> git am /tmp/55.patch
$ git am --ignore-whitespace https://github.com/davidbalbert/hub/commit/fdb9921
[ downloads patch via API ]
> git am --ignore-whitespace /tmp/fdb9921.patch
$ git apply https://gist.github.com/8da7fb575debd88c54cf
[ downloads patch via API ]
> git apply /tmp/gist-8da7fb575debd88c54cf.txt

git fork

$ git fork
[ repo forked on GitHub ]
> git remote add -f YOUR_USER git@github.com:YOUR_USER/CURRENT_REPO.git

git pull-request

# while on a topic branch called "feature":
$ git pull-request
[ opens text editor to edit title & body for the request ]
[ opened pull request on GitHub for "YOUR_USER:feature" ]
# explicit title, pull base & head:
$ git pull-request -m "Implemented feature X" -b defunkt:master -h mislav:feature

git checkout

$ git checkout https://github.com/defunkt/hub/pull/73
> git remote add -f -t feature mislav git://github.com/mislav/hub.git
> git checkout --track -B mislav-feature mislav/feature
$ git checkout https://github.com/defunkt/hub/pull/73 custom-branch-name

git merge

$ git merge https://github.com/defunkt/hub/pull/73
> git fetch git://github.com/mislav/hub.git +refs/heads/feature:refs/remotes/mislav/feature
> git merge mislav/feature --no-ff -m 'Merge pull request #73 from mislav/feature...'

git create

$ git create
[ repo created on GitHub ]
> git remote add origin git@github.com:YOUR_USER/CURRENT_REPO.git
# with description:
$ git create -d 'It shall be mine, all mine!'
$ git create recipes
[ repo created on GitHub ]
> git remote add origin git@github.com:YOUR_USER/recipes.git
$ git create sinatra/recipes
[ repo created in GitHub organization ]
> git remote add origin git@github.com:sinatra/recipes.git

git init

$ git init -g
> git init
> git remote add origin git@github.com:YOUR_USER/REPO.git

git push

$ git push origin,staging,qa bert_timeout
> git push origin bert_timeout
> git push staging bert_timeout
> git push qa bert_timeout

git browse

$ git browse
> open https://github.com/YOUR_USER/CURRENT_REPO
$ git browse -- commit/SHA
> open https://github.com/YOUR_USER/CURRENT_REPO/commit/SHA
$ git browse -- issues
> open https://github.com/YOUR_USER/CURRENT_REPO/issues
$ git browse -- issues/10
> open https://github.com/YOUR_USER/CURRENT_REPO/issues/10
$ git browse schacon/ticgit
> open https://github.com/schacon/ticgit
$ git browse schacon/ticgit commit/SHA
> open https://github.com/schacon/ticgit/commit/SHA
$ git browse resque
> open https://github.com/YOUR_USER/resque
$ git browse resque network
> open https://github.com/YOUR_USER/resque/network

git compare

$ git compare refactor
> open https://github.com/CURRENT_REPO/compare/refactor
$ git compare 1.0..1.1
> open https://github.com/CURRENT_REPO/compare/1.0...1.1
$ git compare -u fix
> (https://github.com/CURRENT_REPO/compare/fix)
$ git compare other-user patch
> open https://github.com/other-user/REPO/compare/patch

git submodule

$ git submodule add wycats/bundler vendor/bundler
> git submodule add git://github.com/wycats/bundler.git vendor/bundler
$ git submodule add -p wycats/bundler vendor/bundler
> git submodule add git@github.com:wycats/bundler.git vendor/bundler
$ git submodule add -b ryppl --name pip ryppl/pip vendor/pip
> git submodule add -b ryppl --name pip git://github.com/ryppl/pip.git vendor/pip

git ci-status

$ git ci-status [commit]
> (prints CI state of commit and exits with appropriate code)
> One of: success (0), error (1), failure (1), pending (2), no status (3)

git help

$ git help
> (improved git help)
$ git help hub
> (hub man page)

来源:http://www.techug.com/hub-is-powered-by-go

Linux:基于 Docker 的 PHP 开发环境

【编者的话】本文作者是Geoffrey,他是一个PHP的Web开发者,喜欢DevOps和Docker。本文主要介绍了如何使用Docker构建 PHP的开发环境,文中作者也探讨了构建基于Docker的开发环境应该使用单容器还是多容器,各有什么利弊。推荐PHP开发者阅读。

Linux:基于 Docker 的 PHP 开发环境
Linux:基于 Docker 的 PHP 开发环境

现在很多开发者都使用Vagrant来管理他们的虚拟机开发环境,Vagrant确实很酷, 不过也有不少缺点(最主要的是它占用太多的资源)。在容器技术、Docker和更多类Docker技术出现后,解决这个问题就变得简单了。

免责声明

由于boot2docker的工作方式,本文所述的方法在你的环境中可能无法正常运行。如果需要在非Linux环境下共享文件夹到Docker容器,还需要注意更多额外的细节。后续我会写篇文章专门来介绍实际遇到的问题。

怎样才算是好的开发环境

首先,我们得知道什么才是好的开发环境, 对于我而言,一个好的开发环境需要具备以下几个特点:

  1. 可随意使用。我必须可以随意删除和创建新的环境。
  2. 快速启动。我想要用它工作时候,它立马就能用。
  3. 易于更新。在我们行业中,事物发展变化非常快,必须能让我很容易将我的开发环境更新到新的软件版本。

而Docker都支持以上这些特点,甚至更多。你几乎可以即时销毁和重建容器,而更新环境只需要重建你当前使用的镜像即可。

什么是PHP开发环境

目前Web应用错综复杂,PHP开发环境需要很多的东西,为了保证环境的简单性,需要做各种各样的限制。 我们这次使用Nginx、PHP5-FPM、MySQL来运行Synmfony项目。由于在容器中运行命令行会更复杂,所以这方面的内容我会放到下一篇博客中再说。

Pet 与 Cattle

另一个我们要讨论的重点是:我们要把开发环境部署在多容器还是单容器中。 两种方式各有优点:

  • 单容器易于分发、维护。因为它们是独立的,所有的东西都运行在同一个容器中,这点就像是一个虚拟机。但这也意味着,当你要升级其中的某样东西(比如PHP新版本)的时候, 需要重新构建整个容器。
  • 多容器可以在添加组件时提供更好的模块化。因为每个容器包含了堆栈的一部分:Web、PHP、MySQL等,这样可以单独扩展每个服务或者添加服务,并且不需要重建所有的东西。

因为我比较懒,加上我需要在我的笔记本上放点别的内容,所以,这里我们只介绍单个容器的方法。

初始化工程

首先要做的是初始化一个新的Symfony工程. 推荐的方法是用composer的create-project命令。本来可以在工作站上安装composer,但是那样太简单了。这次我们通过Docker来使用它。 我之前发过一篇关于Docker命令的文章:make docker commands(好吧,我说谎了,我本来把它写在这篇文章中了,然后觉得把它独立出来会比较好)。

不管怎么样,你可以读一下。接下来如果还没有composer命令的话,你可以创建一个属于自己的composer 别名。

$ alias composer="docker run -i -t -v $PWD:/srv ubermuda/composer"

现在你可以初始化Symfony工程了:

$ composer create-project symfony/framwork-standard-edition SomeProject

帅呆了!下面来点实在的工作。(省略了博主自娱自乐的一堆balabla….原文:Awesome. Give yourself a high-five, get a cup of coffee or whatever is your liquid drug of choice, and get ready for the real work.)

容器

构建一个运行标准Symfony项目且自给自足的容器相当容易,只需要安装好常用的Nginx、PHP5-FPM和MySQL-Server即可,然后把预先准备好的Nginx的虚拟主机配置文件扔进去,再复制一些配置文件进去就完事了。

本容器的源代码在GitHub上的 ubermuda/docker-symfony仓库中可以找到。 Dockerfile 是Docker构建镜像要用到的配置文件,我们来看一下:

FROM debian:wheezy
ENV DEBIAN_FRONTEND noninteractive
RUN apt-get update -y
RUN apt-get install -y nginx php5-fpm php5-mysqlnd php5-cli mysql-server supervisor
RUN sed -e 's/;daemonize = yes/daemonize = no/' -i /etc/php5/fpm/php-fpm.conf
RUN sed -e 's/;listen.owner/listen.owner/' -i /etc/php5/fpm/pool.d/www.conf
RUN sed -e 's/;listen.group/listen.group/' -i /etc/php5/fpm/pool.d/www.conf
RUN echo "ndaemon off;" >> /etc/nginx/nginx.conf
ADD vhost.conf /etc/nginx/sites-available/default
ADD supervisor.conf /etc/supervisor/conf.d/supervisor.conf
ADD init.sh /init.sh
EXPOSE 80 3306
VOLUME ["/srv"]
WORKDIR /srv
CMD ["/usr/bin/supervisord"]

我们通过扩展 debian:wheezy 这个基础镜像开始,然后通过一系列的sed命令来配置Nginx和PHP5-FPM。

RUN sed -e 's/;daemonize = yes/daemonize = no/' -i /etc/php5/fpm/php-fpm.conf
RUN sed -e 's/;listen.owner/listen.owner/' -i /etc/php5/fpm/pool.d/www.conf
RUN sed -e 's/;listen.group/listen.group/' -i /etc/php5/fpm/pool.d/www.conf
RUN echo "ndaemon off;" >> /etc/nginx/nginx.conf

这里我们要做两件事。 首先配置PHP5-FPM和Nginx让他们在前台运行以便supervisord可以追踪到他们。 然后,配置PHP5-FPM以指定的用户运行Web-Server,并处理好文件权限。

接下来需要安装一组配置文件,首先是Nginx的虚拟主机配置文件vhost.conf:

server {
    listen 80;
    server_name _;
    access_log /var/log/nginx/access.log;
    error_log /var/log/nginx/error.log;
    root /srv/web;
    index app_dev.php;
    location / {
        try_files $uri $uri/ /app_dev.php?$query_string;
    }
    location ~ [^/].php(/|$) {
        fastcgi_pass unix:/var/run/php5-fpm.sock;
        include fastcgi_params;
    }
}

因为我们不需要域名,所以把server_name设成了_(有点像perl的$_占位符变量), 并配置根目录(document root)为/svr/web, 我们会把应用程序部署在/srv下,剩下的就是标准的Mginx + PHP5-FPM配置.

因为一个容器每次只能运行一个程序, 我们需要supervisord(或者任何别的进程管理器,不过我比较中意supervisord)。幸运的是, 这个进程管理器会产生我们需要的所有进程!下面是一小段supervisord的配置:

[supervisord]
nodaemon=true
[program:nginx]
command=/usr/sbin/nginx
[program:php5-fpm]
command=/usr/sbin/php5-fpm
[program:mysql]
command=/usr/bin/mysqld_safe
[program:init]
command=/init.sh
autorestart=false
redirect_stderr=true
redirect_stdout=/srv/app/logs/init.log

这里我们需要做的是定义所有的服务, 加上一个特殊的program:init进程,它不是一个实际的服务,而是一个独创的运行启动脚本的方式。

这个启动脚本的问题在于,它通常需要先启动某些服务。比如,你可能要初始化一些数据库表,但前提是你得先把MySQL跑起来,一个可能的解决办法 是,在启动脚本中启动MySQL,然后初始化表,然后为了防止影响到supervisord的进程管理,需要停掉MySQL,最后再启动 supervisord。

这样的脚本看起来类似下面这样:

/etc/init.d/mysql start
app/console doctrine:schema:update --force
/etc/init.d/mysql stop
exec /usr/bin/supervisord

看起来丑爆了有木有,咱换种方式,让supervisor来运行它并且永不重启。 实际的init.sh脚本如下:

#!/bin/bash
RET=1
while [[ RET -ne 0 ]]; do
    sleep 1;
    mysql -e 'exit' > /dev/null 2>&1; RET=$?
done
DB_NAME=${DB_NAME:-symfony}
mysqladmin -u root create $DB_NAME
if [ -n "$INIT" ]; then
    /srv/$INIT
fi

脚本先等待MySQL启动,然后根据环境变量DB_NAME创建DB,默认为symfony, 然后在INIT环境变量中查找要运行的脚本,并尝试运行它。本文的结尾有说明如何使用这些环境变量。

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

Linux:跨越15年的相逢,用 3.16 内核跑 RedHat 6.2古董 Linux

Linux:跨越15年的相逢,用 3.16 内核跑 RedHat 6.2古董 Linux
Linux:跨越15年的相逢,用 3.16 内核跑 RedHat 6.2古董 Linux

最近我在看《KVM 虚拟化技术–实战与原理解析》这本书,学到了不少虚拟机的玩法。 不由得感叹自己以前对虚拟机的功能认识还停留在非常简单的程度。有时间我会在另一篇文章里介绍一下我认为比较有意思的虚拟机折腾玩法。这里专门记录我为了能让15年前红帽出品的6.2发行版能跑在 QEMU 上所折腾的事情。

为啥要跑 Red Hat 6.2

某个夜深人静的夜晚,没有约妹子,我在网上乱逛,在 tldp 站点上看到一篇介绍如何构造最小 Linux 系统的HOWTO文章(http://users.cecs.anu.edu.au/~okeefe/p2b/buildMin/buildMin.html)。文章很老了,2000年的,而且里面所用的系统是Red Hat Linux 6.1版本的。我一直觉得 LFS 还是太复杂了,而这篇文章所涉及的组件最少,于是我就想找个6.1版的系统安装到qemu虚拟机上再照着做一个最小系统出来。在这个kernel archive可以找到很多古董发行版。我只找到了6.2版的iso镜像而文章里所用的6.1版没有提供镜像。所以我下载了redhat-6.2-i386.iso安装盘。

安装系统

我的host用的是 Ubuntu 14.10。系统安装有 QEMU 最新版本,启用kvm模块。

1. 创建一个硬盘镜像

qemu-img create -f qcow2 redhat.img 2G

这样创建了一个2G大小的镜像

2. 启动虚拟机&安装系统

qemu-system-x86_64 redhat.img -cdrom redhat-6.2-i386.iso -net nic,model=rtl8139 -m 128M

安装系统提供了字符菜单,至于中文就别指望了。不过安装过程倒很简单。

遇到的问题

1. 启动失败和对策

安装好系统以后,重启虚拟机,机器会提示如此错误:

Linux:跨越15年的相逢,用 3.16 内核跑 RedHat 6.2古董 Linux
Linux:跨越15年的相逢,用 3.16 内核跑 RedHat 6.2古董 Linux

这里找到了线索。做法是在 LILO 提示符出来时按 Tab 键 ,出现两个启动选项,输入 linux-up 回车即可。此时系统就能无误启动成功了。

2. 网卡问题

从启动 QEMU 的命令行可以看出,QEMU 模拟了 rtl8139 这款较老的网卡。在6.2系统中内核已经认出了这个设备。但是用 ifconfig 可以看出网卡接收不到任何数据:

Linux:跨越15年的相逢,用 3.16 内核跑 RedHat 6.2古董 Linux
Linux:跨越15年的相逢,用 3.16 内核跑 RedHat 6.2古董 Linux

我怀疑可能是宿主机的桥接网络设置有问题,于是用相同的配置启动了ezgo 的虚拟机,发现网卡工作正常。那么可以确定是6.2自己的内核网卡驱动和 QEMU 的网卡配合起来出问题了。

试试看,用宿主机的内核来启动

QEMU 提供-kernel 和-initrd 选项用来指定启动虚拟机 Linux 的内核。我们来试试看用3.16的内核替代6.2红帽的2.4.7内核看看!

步骤一:

将geust的fstab文件中所有hdaX改为sdaX。在老内核中ide设备的命名形式是hda1,hdb2等等,sda是专门命名scsi设备的。现在的内核硬盘都使用了scsi设备驱动,统一都以scsi设备的形式命名。

步骤二:

新建/sys目录,下次启动就可以挂载sysfs文件系统,这个是2.4内核没有的功能。

步骤三:

qemu-system-x86_64 redhat.img -net nic,model=rtl8139 -sdl -net tap -enable-kvm -kernel /boot/vmlinuz-3.16.0-25-generic -append 'root=/dev/sda5' -initrd /boot/initrd.img-3.16.0-25-generic

注意在上面的选项中,用-append制定了向内核指定的参数,我们指定了root设备参数。当然推荐再加个vga参数,让一屏显示更多字符。

开机

哇塞!新内核可以顺利启动了!真是有点惊喜,经测试,网卡也终于允许正常了,甚至还能获取到 ipv6 地址。

Linux:跨越15年的相逢,用 3.16 内核跑 RedHat 6.2古董 Linux
Linux:跨越15年的相逢,用 3.16 内核跑 RedHat 6.2古董 Linux

简单测试一下,GCC 什么的工具都能运行,但是和内核打交道的工具肯定会有问题。例如ps会 core dump。guest中的ps期望读到的/proc目录里面的文件格式是2.4内核生成的文件格式。我们这个3.16内核生成的文件肯定不一样了。

更改了X配置文件中鼠标设备路径,从/dev/mouse 改成/dev/input/mouse0,X也可以启动了!不过分辨率还是有问题。应该深入一下可以解决的。

来源:http://www.linuxstory.org/meet-after-15-years-red-hat-linux-6-1-zoot-run-on-kernel-3-16/

Linux:Docker 编排工具 Fig 介绍

【编者的话】Fig是一个基于Docker的用于快速搭建开发环境的工具,目前Fig团队已经加入Docker公司。Fig通过一个配置文件来管理多个 Docker容器,非常适合组合使用多个容器进行开发的场景。Fig可以和Docker一起来构建基于Docker的复杂应用。本文详细介绍了Fig的安装以及使用。

什么是编排?

Linux:Docker 编排工具 Fig 介绍
Linux:Docker 编排工具 Fig 介绍

编排(译者注:Orchestration,翻译为编排)是指同时管理多个容器的行为。当你刚开始玩Docker 的时候,你只需要操作一个容器。紧接着你学习了网络并得知把所有进程都放入同一个容器中并不合适,然后不知不觉你就发现自己已经建立了多容器的基础架构。 你第一次尝试可能不会感到复杂,但是当使用两个或者三个容器的时候,你就会觉得很麻烦。手动连接容器、管理卷,很快你就乱了,应该有更好更实用的工具来做 这件事。

Fig简介

这个更实用的工具称为Fig。Fig是Orchard的一个产品并很快成为自动化Docker容器编排一个事实标准,目前Fig已经被Docker公司收购并成为官方支持的解决方案。

安装Fig

Fig是一个Python Package,你可以使用以下命令来安装:

$ sudo pip install -U fig

就这么简单。如果不能工作,可以从Fig的官方文档中了解更多信息。

使用Fig

使用Fig来编排一个基础设施,你首先需要在YAML配置文件中描述它。描述语法很简单,和Docker有点类似。 下面是Pagekit CMS的Fig配置示例:

web:
image: ubermuda/pagekit
ports:
    - 80
links:
    - db:pagekit_db_1
volumes_from:
    - data
db:
image: orchardup/mysql
environment:
    MYSQL_ROOT_PASSWORD: changethis
    MYSQL_DATABASE: pagekit
data:
image: busybox
command: /bin/true
volumes:
    - /pagekit/storage
    - /pagekit/app/cache

这个配置文件定义了三个不同的容器。

web容器是面向web方面的容器,它基于ubermuda/pagekit镜像构建,你可以从GitHub上获取ubermuda/pagekit的源码,web容器会暴露80端口(通过ports参数),使用别名pagekit_db_1(links)连接到db容器,并且data容器的卷(volumes)也会被挂载到web容器。

从db容器中我们能看到在容器中定义环境变量是多么简单:只要使用environment配置即可。在示例中,我们在配置文件中定义了所有的值,但你也可以省略这些值,这样容器会从它的宿主机中获取。

db:
environment:
    MYSQL_ROOT_PASSWORD

所述的MYSQL_ROOT_PASSWORD环境变量被来自主机的同名环境变量填充。

最后,data容器通过volumes参数定义了即将使用的所有目录作为共享卷目录。

配置文件写完后,你只需要一个fig up命令即可启动你的基础设施。

$ fig up
Creating dockerpagekit_db_1...
...
Creating dockerpagekit_data_1...
Creating dockerpagekit_web_1...
...
Attaching to dockerpagekit_db_1, dockerpagekit_web_1
...
db_1  | 141110  4:14:02 [Note] /usr/sbin/mysqld: ready for connections.
db_1  | Version: '5.5.38-0ubuntu0.12.04.1-log'  socket: '/var/run/mysqld/mysqld.sock'  port: 3306  (Ubuntu)
...
web_1 | 2014-11-10 04:15:20,750 INFO success: nginx entered RUNNING state, process has stayed up for > than 1 seconds (startsecs)
web_1 | 2014-11-10 04:15:20,750 INFO success: php5-fpm entered RUNNING state, process has stayed up for > than 1 seconds (startsecs)

完整的启动日志有点太长了,所以我只截取了一部分。正如你所看到的,Fig创建了三个容器,dockerpagekit_db_1可以连接到dockerpagekit_web_1,正是我们想要的。

你可能还注意到有一个数据容器没有日志线,那是因为 /bin/true 命令无法正常输出。

现在你可以在另一个终端中运行docker ps命令来检查一切是否运行正常,同时,可是使用浏览器来确认web容器是否正常启动。(你首先需要确认映射端口,可以使用docker ps或docker port)。

说明

截至本文写作之时,Fig不支持远程编排,这意味着你只能在单台主机上编排一个基础设施。

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

Linux:趣图:21 副 GIF 动图让你了解各种数学概念

Linux:趣图:21 副 GIF 动图让你了解各种数学概念
Linux:趣图:21 副 GIF 动图让你了解各种数学概念

“让我们面对它;总的来说数学是不容易的,但当你征服了问题,并达到新的理解高度,这就是它给你的回报。”

——Danica McKellar

数学是很难的科学,但因为它是科学家用数学来解释宇宙的语言,我们无可避免的要学习它。看看下面的这些GIF动图,它们提供了视觉的方式来帮助你理解各种数学技巧。你看懂了几个呢?

1、椭圆的画法

Linux:趣图:21 副 GIF 动图让你了解各种数学概念
Linux:趣图:21 副 GIF 动图让你了解各种数学概念

2、杨辉三角问题(Pascal triangles)解法

Linux:趣图:21 副 GIF 动图让你了解各种数学概念
Linux:趣图:21 副 GIF 动图让你了解各种数学概念

3、使用“FOIL”轻松的解决二项式乘法

Linux:趣图:21 副 GIF 动图让你了解各种数学概念
Linux:趣图:21 副 GIF 动图让你了解各种数学概念

4、对数解法技巧

Linux:趣图:21 副 GIF 动图让你了解各种数学概念
Linux:趣图:21 副 GIF 动图让你了解各种数学概念

5、矩阵转置的技巧

Linux:趣图:21 副 GIF 动图让你了解各种数学概念
Linux:趣图:21 副 GIF 动图让你了解各种数学概念

6、勾股定理

Linux:趣图:21 副 GIF 动图让你了解各种数学概念
Linux:趣图:21 副 GIF 动图让你了解各种数学概念

7、多边形的外角之和总是等于360度

Linux:趣图:21 副 GIF 动图让你了解各种数学概念
Linux:趣图:21 副 GIF 动图让你了解各种数学概念

来源:http://www.vaikan.com/math-gifs/

Linux:如何在 Linux 上配置点对点 VPN

一个传统的 VPN(如 OpenVPN、PPTP)由一个 VPN 服务器和一个或多个连接到这台服务器的客户端组成。当任意两个 VPN 客户端彼此通信时,VPN 服务器需要中继它们之间的 VPN 数据流量。这样一个中心辐射型的 VPN 拓扑结构存在的问题是,当连接的客户端增多以后,VPN 服务器很容易成为一个性能上的瓶颈。从某种意义上来说,中心化的 VPN 服务器也同样成为一个单点故障的来源,也就是当 VPN 服务器出现故障的时候,整个 VPN 都将无法被任何 VPN 客户端访问。

Linux:如何在 Linux 上配置点对点 VPN
Linux:如何在 Linux 上配置点对点 VPN

点对点 VPN(又称 P2P VPN)是另一个 VPN 模型,它能解决传统的基于服务器-客户端模型的 VPN 存在的这些问题。一个 P2P VPN 中不再有一个中心的 VPN 服务器,任何拥有一个公开 IP 地址的节点都能引导其他节点进入 VPN。当连接到一个 VPN 之后,每一个节点都能与 VPN 中的任何其他节点直接通信,而不需要经过一个中间的服务器节点。当然任何节点出现故障时,VPN 中的剩余节点不会受到影响。节点中的延迟、带宽以及 VPN 扩展性在这样的设定中都有自然的提升,当你想要使用 VPN 进行多人游戏或者与许多朋友分享文件时,这都是十分理想的。

开源的 P2P VPN 实现已经有几个了,比如 Tinc、peerVPN,以及 n2n。在本教程中,我将会展示如何在 Linux 上用 n2n 配置点对点 VPN

n2n 是一个开源(GPLv3)软件,它允许你在用户间构建一个加密的 2/3 层点对点 VPN。由 n2n 构建的 VPN 是“对 NAT 友好”的,也就是说,不同 NAT 路由器后方的两个用户可以通过 VPN 直接与对方通信。n2n 支持对称的 NAT 类型,这是 NAT 中限制最多的一种。因此,n2n 的 VPN 数据流量是用 UDP 封装的。

一个 n2n VPN 由两类节点组成:边缘(edge)节点和超级(super)节点。一个边缘节点是一台连接到 VPN 的电脑,它可能在一个 NAT 路由器后方。一个超级节点则是拥有一个可以公共访问的 IP 地址的电脑,它将会帮助 NAT 后方的边缘节点进行初始通信。想要在用户中创建一个 P2P VPN 的话,我们需要至少一个超级节点。

Linux:如何在 Linux 上配置点对点 VPN
Linux:如何在 Linux 上配置点对点 VPN

准备工作

在这篇教程中,我将会创建一个拥有 3 个节点的 P2P VPN:一个超级节点和两个边缘节点。唯一的要求是,边缘节点需要能够 ping 通超级节点的 IP 地址,而它们是否在 NAT 路由器之后则没有什么关系。

在 Linux 上安装 n2n

若想用 n2n 构建一个 P2P VPN,你需要在每个节点上安装 n2n,包括超级节点。

由于它非常精简的依赖需求,在大多数 Linux 平台上 n2n 都能被轻松编译。

在基于 Debian 的系统上安装 n2n:

$ 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

在基于 Red Hat 的系统上安装 n2n:

$ sudo yum install subversion gcc-c++ openssl-devel
$ svn co https://svn.ntop.org/svn/ntop/trunk/n2n
$ cd n2n/n2n_v2
$ make
$ sudo make install

用 n2n 配置一个 P2P VPN

如前文所述,我们需要至少一个超级节点,它将会作为一个初始化引导服务器。我们假设这个超级节点的 IP 地址是 1.1.1.1。

超级节点:

在一个作为超级节点的电脑上运行下面的命令。其中“-l <端口>”指定超级节点的监听端口。运行 supernode 并不需要 root 权限。

$ supernode -l 5000

边缘节点:

在每个边缘节点上,使用下面的命令来连接到一个 P2P VPN。edge 守护程序将会在后台运行。

边缘节点 #1:

 $ sudo edge -d edge0 -a 10.0.0.10 -c mynetwork -u 1000 -g 1000 -k password -l 1.1.1.1:5000 -m ae:e0:4f:e7:47:5b

边缘节点 #2:

 $ sudo edge -d edge0 -a 10.0.0.11 -c mynetwork -u 1000 -g 1000 -k password -l 1.1.1.1:5000 -m ae:e0:4f:e7:47:5c

下面是对命令行的一些解释:

  • “-d <接口名>”选项指定了由 edge 命令创建的 TAP 接口的名字。
  • “-a ”选项(静态地)指定了分配给 TAP 接口的 VPN 的 IP 地址。如果你想要使用 DHCP,你需要在其中一台边缘节点上配置一台 DHCP 服务器,然后使用“-a dhcp:0.0.0.0”选项来代替。
  • “-c <组名>”选项指定了 VPN 组的名字(最大长度为 16 个字节)。这个选项可以被用来在同样一组节点中创建多个 VPN。
  • “-u”和“-g”选项被用来在创建一个 TAP 接口后降权放弃 root 权限。edge 守护进程将会作为指定的用户/组 ID 运行。
  • “-k <密钥>”选项指定了一个由 twofish 加密的密钥来使用。如果你想要将密钥从命令行中隐藏,你可以使用 N2N_KEY 环境变量。
  • “-l ”选项指定了超级节点的监听 IP 地址和端口号。为了冗余,你可以指定最多两个不同的超级节点(比如 -l <超级节点 A> -l <超级节点 B>)。
  • “-m ”给 TAP 接口分配了一个静态的 MAC 地址。不使用这个参数的话,edge 命令将会随机生成一个 MAC 地址。事实上,为一个 VPN 接口强制指定一个静态的 MAC 地址是被强烈推荐的做法。否则,比如当你在一个节点上重启了 edge 守护程序的时候,其它节点的 ARP 缓存将会由于新生成的 MAC 地址而遭到污染,它们将不能向这个节点发送数据,直到被污染的 ARP 记录被消除。
Linux:如何在 Linux 上配置点对点 VPN
Linux:如何在 Linux 上配置点对点 VPN

至此,你应该能够从一个边缘节点用 VPN IP 地址 ping 通另一个边缘节点了。

故障排除

  1. 在调用 edge 守护程序的时候得到了如下错误。

    n2n[4405]: ERROR: ioctl() [Operation not permitted][-1]

注意 edge 守护进程需要超级用户权限来创建一个 TAP 接口。因此需要确定用 root 权限来执行,或者对 edge 命令设置 SUID。之后你总是可以使用“-u”和“-g”选项来降权放弃 root 权限。

总结

n2n 可以成为对你来说非常实用的免费 VPN 解决方案。你可以轻松地配置一个超级节点,无论是用你自己家里的网络,还是从云主机提供商购买一个可以公共访问的 VPS 实例。你不再需要把敏感的凭据和密钥放在第三方 VPN 提供商的手里,使用 n2n,你可以在你的朋友中配置你自己的低延迟、高带宽、可扩展的 P2P VPN。

你对 n2n 有什么想法吗?请在评论中分享你的观点。


via: http://xmodulo.com/configure-peer-to-peer-vpn-linux.html

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

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

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

Linux:想玩 BGP 路由器么?用 CentOS 做一个

之前的教程中,我对如何简单地使用Quagga把CentOS系统变成一个不折不扣地OSPF路由器做了一些介绍。Quagga是一个开源路由软件套件。在这个教程中,我将会重点讲讲如何把一个Linux系统变成一个BGP路由器,还是使用Quagga,演示如何建立BGP与其它BGP路由器对等。

在我们进入细节之前,一些BGP的背景知识还是必要的。边界网关协议(即BGP)是互联网的域间路由协议的实际标准。在BGP术语中,全球互联网是由成千上万相关联的自治系统(AS)组成,其中每一个AS代表每一个特定运营商提供的一个网络管理域(据说,美国前总统乔治.布什都有自己的 AS 编号)。

Linux:想玩 BGP 路由器么?用 CentOS 做一个
Linux:想玩 BGP 路由器么?用 CentOS 做一个

为了使其网络在全球范围内路由可达,每一个AS需要知道如何在英特网中到达其它的AS。这时候就需要BGP出来扮演这个角色了。BGP是一个AS去与相邻的AS交换路由信息的语言。这些路由信息通常被称为BGP线路或者BGP前缀。包括AS号(ASN;全球唯一号码)以及相关的IP地址块。一旦所有的BGP线路被当地的BGP路由表学习和记录,每一个AS将会知道如何到达互联网的任何公网IP。

在不同域(AS)之间路由的能力是BGP被称为外部网关协议(EGP)或者域间协议的主要原因。就如一些路由协议,例如OSPF、IS-IS、RIP和EIGRP都是内部网关协议(IGPs)或者域内路由协议,用于处理一个域内的路由.

测试方案

在这个教程中,让我们来使用以下拓扑。

我们假设运营商A想要建立一个BGP来与运营商B对等交换路由。它们的AS号和IP地址空间的细节如下所示:

  • 运营商 A: ASN (100), IP地址空间 (100.100.0.0/22), 分配给BGP路由器eth1网卡的IP地址(100.100.1.1)

  • 运营商 B: ASN (200), IP地址空间 (200.200.0.0/22), 分配给BGP路由器eth1网卡的IP地址(200.200.1.1)

路由器A和路由器B使用100.100.0.0/30子网来连接到对方。从理论上来说,任何子网从运营商那里都是可达的、可互连的。在真实场景中,建议使用掩码为30位的公网IP地址空间来实现运营商A和运营商B之间的连通。

在 CentOS中安装Quagga

如果Quagga还没安装好,我们可以使用yum来安装Quagga。

# yum install quagga

如果你正在使用的是CentOS7系统,你需要应用一下策略来设置SELinux。否则,SElinux将会阻止Zebra守护进程写入它的配置目录。如果你正在使用的是CentOS6,你可以跳过这一步。

# setsebool -P zebra_write_config 1

Quagga软件套件包含几个守护进程,这些进程可以协同工作。关于BGP路由,我们将把重点放在建立以下2个守护进程。

  • Zebra:一个核心守护进程用于内核接口和静态路由.
  • BGPd:一个BGP守护进程.

配置日志记录

在Quagga被安装后,下一步就是配置Zebra来管理BGP路由器的网络接口。我们通过创建一个Zebra配置文件和启用日志记录来开始第一步。

# cp /usr/share/doc/quagga-XXXXX/zebra.conf.sample /etc/quagga/zebra.conf

在CentOS6系统中:

# service zebra start
# chkconfig zebra on

在CentOS7系统中:

# systemctl start zebra
# systemctl enable zebra

Quagga提供了一个叫做vtysh特有的命令行工具,你可以输入与路由器厂商(例如Cisco和Juniper)兼容和支持的命令。我们将使用vtysh shell来配置BGP路由在教程的其余部分。

启动vtysh shell 命令,输入:

# vtysh

提示将被改成该主机名,这表明你是在vtysh shell中。

Router-A#

现在我们将使用以下命令来为Zebra配置日志文件:

Router-A# configure terminal
Router-A(config)# log file /var/log/quagga/quagga.log
Router-A(config)# exit

永久保存Zebra配置:

Router-A# write

在路由器B操作同样的步骤。

配置对等的IP地址

下一步,我们将在可用的接口上配置对等的IP地址。

Router-A# show interface   #显示接口信息

Interface eth0 is up, line protocol detection is disabled
. . . . .
Interface eth1 is up, line protocol detection is disabled
. . . . .

配置eth0接口的参数:

site-A-RTR# configure terminal
site-A-RTR(config)# interface eth0
site-A-RTR(config-if)# ip address 100.100.0.1/30
site-A-RTR(config-if)# description "to Router-B"
site-A-RTR(config-if)# no shutdown
site-A-RTR(config-if)# exit

继续配置eth1接口的参数:

site-A-RTR(config)# interface eth1
site-A-RTR(config-if)# ip address 100.100.1.1/24
site-A-RTR(config-if)# description "test ip from provider A network"
site-A-RTR(config-if)# no shutdown
site-A-RTR(config-if)# exit

现在确认配置:

Router-A# show interface

Interface eth0 is up, line protocol detection is disabled
  Description: "to Router-B"
  inet 100.100.0.1/30 broadcast 100.100.0.3
Interface eth1 is up, line protocol detection is disabled
  Description: "test ip from provider A network"
  inet 100.100.1.1/24 broadcast 100.100.1.255

Router-A# show interface description   #显示接口描述

Interface       Status  Protocol  Description
eth0            up      unknown   "to Router-B"
eth1            up      unknown   "test ip from provider A network"

如果一切看起来正常,别忘记保存配置。

Router-A# write

同样地,在路由器B重复一次配置。

在我们继续下一步之前,确认下彼此的IP是可以ping通的。

Router-A# ping 100.100.0.2

PING 100.100.0.2 (100.100.0.2) 56(84) bytes of data.
64 bytes from 100.100.0.2: icmp_seq=1 ttl=64 time=0.616 ms

下一步,我们将继续配置BGP对等和前缀设置。

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

Linux:八个Docker的真实应用场景

【编者的话】Flux 7介绍了常用的8个Docker的真实使用场景,分别是简化配置、代码流水线管理、提高开发效率、隔离应用、整合服务器、调试能力、多租户环境、快速部署。我们一直在谈Docker,Docker怎么使用,在怎么样的场合下使用?也许本文可以帮到你。有需要交流的地方,可以通过评论与我们交流。

Linux:八个Docker的真实应用场景
Linux:八个Docker的真实应用场景

几周前我们参加了DockerCon ,Dockercon是首个以Docker为中心的技术大会。它面向开发者以及对在Docker开放平台上构建、交付、运行分布式应用感兴趣的从业者,不论这些开放平台是运行于自用笔记本上或者是数据中心的虚拟机上。我们参加了这次大会,Flux7是Docker基础的系统集成合作伙伴,同时也是演讲嘉宾。

我们的CEO Aater Suleman和我们的一位客户一同进行了演讲。虽然DockerCon大会十分有趣,但我觉得大会太关注Docker的具体细节,而忽略了Docker的使用场景。所以,在这篇文章中,我想介绍并分享一些Docker的实际应用案例。

在我们讨论Docker的使用场景之前,先来看看Docker这个工具有什么特别的地方吧。

Docker提供了轻量级的虚拟化,它几乎没有任何额外开销,这个特性非常酷。

首先你在享有Docker带来的虚拟化能力的时候无需担心它带来的额外开销。其次,相比于虚拟机,你可以在同一台机器上创建更多数量的容器。

Docker的另外一个优点是容器的启动与停止都能在几秒中内完成。Docker公司的创始人 Solomon Hykes曾经介绍过Docker在单纯的LXC之上做了哪些事情,你可以去看看。

下面是我总结的一些Docker的使用场景,它为你展示了如何借助Docker的优势,在低开销的情况下,打造一个一致性的环境。

1. 简化配置

这是Docker公司宣传的Docker的主要使用场景。虚拟机的最大好处是能在你的硬件设施上运行各种配置不一样的平台(软件、系统),Docker在降低额外开销的情况下提供了同样的功能。它能让你将运行环境和配置放在代码中然后部署,同一个Docker的配置可以在不同的环境中使用,这样就降低了硬件要求和应用环境之间耦合度。

2. 代码流水线(Code Pipeline)管理

前一个场景对于管理代码的流水线起到了很大的帮助。代码从开发者的机器到最终在生产环境上的部署,需要经过很多的中间环境。而每一个中间环境都有自己微小的差别,Docker给应用提供了一个从开发到上线均一致的环境,让代码的流水线变得简单不少。

3. 提高开发效率

这就带来了一些额外的好处:Docker能提升开发者的开发效率。如果你想看一个详细一点的例子,可以参考Aater在DevOpsDays Austin 2014 大会或者是DockerCon上的演讲。

不同的开发环境中,我们都想把两件事做好。一是我们想让开发环境尽量贴近生产环境,二是我们想快速搭建开发环境。

理想状态中,要达到第一个目标,我们需要将每一个服务都跑在独立的虚拟机中以便监控生产环境中服务的运行状态。然而,我们却不想每次都需要网络连接,每次重新编译的时候远程连接上去特别麻烦。这就是Docker做的特别好的地方,开发环境的机器通常内存比较小,之前使用虚拟的时候,我们经常需要为开发环境的机器加内存,而现在Docker可以轻易的让几十个服务在Docker中跑起来。

4. 隔离应用

有很多种原因会让你选择在一个机器上运行不同的应用,比如之前提到的提高开发效率的场景等。

我们经常需要考虑两点,一是因为要降低成本而进行服务器整合,二是将一个整体式的应用拆分成松耦合的单个服务(译者注:微服务架构)。如果你想了解为什么松耦合的应用这么重要,请参考Steve Yege的这篇论文,文中将Google和亚马逊做了比较。

5. 整合服务器

正如通过虚拟机来整合多个应用,Docker隔离应用的能力使得Docker可以整合多个服务器以降低成本。由于没有多个操作系统的内存占用,以及能在多个实例之间共享没有使用的内存,Docker可以比虚拟机提供更好的服务器整合解决方案。

6. 调试能力

Docker提供了很多的工具,这些工具不一定只是针对容器,但是却适用于容器。它们提供了很多的功能,包括可以为容器设置检查点、设置版本和查看两个容器之间的差别,这些特性可以帮助调试Bug。你可以在《Docker拯救世界》的文章中找到这一点的例证。

7. 多租户环境

另外一个Docker有意思的使用场景是在多租户的应用中,它可以避免关键应用的重写。我们一个特别的关于这个场景的例子是为IoT(译者注:物联网)的应用开发一个快速、易用的多租户环境。这种多租户的基本代码非常复杂,很难处理,重新规划这样一个应用不但消耗时间,也浪费金钱。

使用Docker,可以为每一个租户的应用层的多个实例创建隔离的环境,这不仅简单而且成本低廉,当然这一切得益于Docker环境的启动速度和其高效的diff命令。

你可以在这里了解关于此场景的更多信息。

8. 快速部署

在虚拟机之前,引入新的硬件资源需要消耗几天的时间。Docker的虚拟化技术将这个时间降到了几分钟,Docker只是创建一个容器进程而无需启动操作系统,这个过程只需要秒级的时间。这正是Google和Facebook都看重的特性。

你可以在数据中心创建销毁资源而无需担心重新启动带来的开销。通常数据中心的资源利用率只有30%,通过使用Docker并进行有效的资源分配可以提高资源的利用率。

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

Linux:安装 Fedora 21 工作站后要做的10件事情

Fedora 21已经在2014年12月正式发布。对于Fedora新手和初学者来说,初始化设置可能存在一点困难,我们翻译了一篇Fedora系统配置文章,为新手提供参考。下面一起看看Fedora 21安装后到底要做哪些事情?

当然,系统安装完毕后,首先要确保已经从Fedora 21仓库获得最新更新:sudo yum update 。

Linux:安装 Fedora 21 工作站后要做的10件事情
Linux:安装 Fedora 21 工作站后要做的10件事情

1. 配置GNOME Shell界面

Fedora 21工作站系统版本默认桌面环境为GNOME Shell,我们可以通过“Gnome Tweak Tool”工具来对GNOME Shell进行更多的个性化设置。可使用下面命令安装Gnome Tweak Tool:

$ sudo yum install gnome-tweak-tool

打开“Gnome Tweak Tool”,可以轻松设置工作区、字体、键盘、桌面、电源等选项:

Linux:安装 Fedora 21 工作站后要做的10件事情
Linux:安装 Fedora 21 工作站后要做的10件事情

2. 安装GNOME Shell扩展

GNOME Shell扩展可极大帮助我们对GNOME Shell进行定制,GNOME Shell扩展站点:https://extensions.gnome.org/,大家可在此选取适合自己的扩展。

3. 安装YUM Extender

YUM Extender或“yumex”是YUM包管理系统的图形化工具,便于我们对软件包的管理:

$ sudo yum install yumex

4. 启用RPM Fusion仓库

RPM Fusion是一个流行的仓库,它主要是系列依赖于非自由软件包的闭源软件集合,它也包括了尚未收录进入Fedora官方仓库的软件。

启用RPM Fusion仓库:

$ sudo yum localinstall --nogpgcheck http://download1.rpmfusion.org/free/fedora/rpmfusion-free-release-21.noarch.rpm
$ sudo yum localinstall --nogpgcheck http://download1.rpmfusion.org/nonfree/fedora/rpmfusion-nonfree-release-21.noarch.rpm

然后升级系统:

$ sudo yum update

5. 安装Yum升级最快镜像选择工具

Yum Fastest Mirror Plugin,可以帮助你选择最适合你下载系统更新的镜像站点,以便得到更快速度,它是YUM软件包管理的一个插件:

Linux:安装 Fedora 21 工作站后要做的10件事情
Linux:安装 Fedora 21 工作站后要做的10件事情
$ sudo yum install yum-plugin-fastestmirror

6. 安装Flash播放器

目前常见的视频站点都在使用Flash技术,所以我们也需要安装Flash播放器来播放网络视频:

32位系统:

$ sudo rpm -ivh http://linuxdownload.adobe.com/adobe-release/adobe-release-i386-1.0-1.noarch.rpm
$ sudo rpm --import /etc/pki/rpm-gpg/RPM-GPG-KEY-adobe-linux
$ sudo yum install flash-plugin

64位系统:

$ sudo rpm -ivh http://linuxdownload.adobe.com/adobe-release/adobe-release-x86_64-1.0-1.noarch.rpm
$ sudo rpm --import /etc/pki/rpm-gpg/RPM-GPG-KEY-adobe-linux
$ sudo yum install flash-plugin

7. 安装其它桌面环境

 Fedora 21默认将GNOME Shell作为桌面环境,如果你不喜欢GNOME Shell,你也可以尝试安装其他桌面环境,如KDE、Mate等。具体安装方法如下:

  • Mate桌面环境:$ sudo yum install @mate-desktop
  • KDE桌面环境:$ sudo yum install @kde-desktop
  • XFCE桌面环境:$ sudo yum install @xfce-desktop
  • LXDE桌面环境:$ sudo yum install @lxde-desktop
  • Cinnamon桌面环境:$ sudo yum install @cinnamon-desktop

8. 安装.zip & .rar 文件插件

如果要处理.zip & .rar文件,你需要安装部分插件才行,可以运行下面命令安装所需软件包:

$ sudo yum install unrar unzip

9. 安装Java

如果你需要运行Java程序或浏览使用Java的站点,需要安装Java才行,可以按照下面步骤安装。

  • 下载Java:前往 下载页面下载Java最新版本;
  • 双击下载的文件,安装;
  • 安装完毕后,执行下面命令:
$ sudo alternatives --install /usr/bin/java java /usr/java/latest/jre/bin/java 200000

如果你想在火狐浏览器中启用Java插件,可分别在32位和64位系统上分别执行:

32位系统:

$ sudo alternatives --install /usr/lib/mozilla/plugins/libjavaplugin.so libjavaplugin.so /usr/java/jdk1.8.0_11/lib/i386/libnpjp2.so 200000

64位系统: 

$ sudo alternatives --install /usr/lib64/mozilla/plugins/libjavaplugin.so libjavaplugin.so.x86_64 /usr/java/jdk1.8.0_11/lib/amd64/libnpjp2.so 200000

10. 安装必备软件

(1)Google Chrome浏览器:基于开源的Chromium浏览器开发。

32位系统:

$ sudo yum localinstall --nogpgcheck https://dl.google.com/linux/direct/google-chrome-stable_current_i386.rpm

64位系统:

$ sudo yum localinstall --nogpgcheck https://dl.google.com/linux/direct/google-chrome-stable_current_x86_64.rpm

(2)VLC媒体播放器。VLC具有“万能播放器”之称,是目前世界上最流行的开源媒体播放器,可以说它几乎可以支持任何格式的多媒体文件。VLC 2.2没有进入到Fedora官方仓库,需要在完成第四步骤后,才能执行下面的安装命令:

$ sudo yum install vlc

(3)VirtualBox虚拟机。可以在虚拟机里面运行其他操作系统:

$ sudo yum install VirtualBox

(4)GNOME音乐。GNOME音乐应用是一款简洁的音乐播放器: 

$ sudo yum install gnome-music

(5)BT下载工具qBittorrent:

$ sudo yum install qbittorrent

(6)游戏客户端Steam:

$ sudo yum install steam(需完成第四步操作)

来源:http://code.csdn.net/news/2823459

Linux:Linux有问必答:如何在Linux上安装内核头文件

提问:我在安装一个设备驱动前先要安装内核头文件。怎样安装合适的内核头文件?

当你在编译一个设备驱动模块时,你需要在系统中安装内核头文件。内核头文件同样在你编译与内核直接链接的用户空间程序时需要。当你在这些情况下安装内核头文件时,你必须确保内核头文件精确地与你当前内核版本匹配(比如:3.13.0-24-generic)。

Linux:Linux有问必答:如何在Linux上安装内核头文件
Linux:Linux有问必答:如何在Linux上安装内核头文件

如果你的内核是发行版自带的内核版本,或者使用默认的包管理器的基础仓库升级的(比如:apt-ger、aptitude或者yum),你也可以使用包管理器来安装内核头文件。另一方面,如果下载的是kernel源码并且手动编译的,你可以使用make命令来安装匹配的内核头文件。

现在我们假设你的内核是发行版自带的,让我们看下该如何安装匹配的头文件。

在 Debian、Ubuntu 或者 Linux Mint 上安装内核头文件

假设你没有手动编译内核,你可以使用apt-get命令来安装匹配的内核头文件。

首先,使用dpkg-query命令检查是否有可用的内核头文件。

$ dpkg-query -s linux-headers-$(uname -r)

dpkg-query: package 'linux-headers-3.11.0-26-generic' is not installed and no information is available

接着使用下面的命令安装匹配的内核头文件。

$ sudo apt-get install linux-headers-$(uname -r)
Linux:Linux有问必答:如何在Linux上安装内核头文件
Linux:Linux有问必答:如何在Linux上安装内核头文件

验证头文件是否成功安装。

$ dpkg-query -s linux-headers-$(uname -r)

Package: linux-headers-3.11.0-26-generic
Status: install ok installed

Debian、Ubuntu、Linux Mint默认头文件在/usr/src下。

在 Fedora、CentOS 或者 RHEL 上安装内核头文件

假设你没有手动编译内核,你可以使用yum命令来安装匹配的内核头文件。

首先,用下面的命令检查系统是否已经安装了头文件。如果下面的命令没有任何输出,这就意味着还没有头文件。

$ rpm -qa | grep kernel-headers-$(uname -r)

接着用yum命令安装头文件。这个命令会自动找出合适的头文件并安装。

$ sudo yum install kernel-headers
Linux:Linux有问必答:如何在Linux上安装内核头文件
Linux:Linux有问必答:如何在Linux上安装内核头文件

验证包安装的状态。

$ rpm -qa | grep kernel-headers-$(uname -r)

kernel-headers-3.10.0-123.9.3.el7.x86_64

Fedora、CentOS 或者 RHEL上默认内核头文件的位置是/usr/include/linux


via: http://ask.xmodulo.com/install-kernel-headers-linux.html

译者:geekpi 校对:wxy

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

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

Linux:2014年5个最流行前端框架对比

当今时代众多CSS的前端框架纷涌而至,但真正的优秀的却屈指可数。

在这篇文章中我们将对我认为最好的五个框架进行比较,每个框架都有自己优缺点和特定的应用领域,这允许你根据特定项目的需求选择合适的框架。比如, 如果你的项目比较简单,你就不需要复杂的框架,此外,许多选项是模块化的,这允许你仅使用你需要的组件,或者混合使用不同框架的组件。

我们要讨论的框架都是基于其在github上的人气展示的,首先说最流行的,当然是:Bootstrap。

(注意:下面的一些信息在未来的几周和几月后就过时了,如:GitHub 上的评分(Stars)和版本数,因此如果你是在这篇文章发布很久以后阅读的话,你需要留意这一点。此外,还要注意框架大小是否将必要的CSS和JS文件最小化。)

1. Bootstrap

Bootstrap 在当今流行的各种框架中是无可争议的老大。鉴于其每天仍在增长的巨大人气,可以肯定,这个美妙的工具绝对不会让你失望,它也不会在你成功建立网站前就离你而去。

Linux:2014年5个最流行前端框架对比
Linux:2014年5个最流行前端框架对比
  • 创建者: Mark Otto and Jacob Thornton.
  • 发布: 2011
  • 当前版本: 3.3.1
  • 人气: 在Github上有75,000+ stars
  • 描述: “Bootstrap是最流行的的 HTML, CSS和 JavaScript 响应式开发框架 ,web上开发的第一个移动项目.”
  • 核心概念/原则: RWD 和移动优先
  • 框架大小: 145 KB
  • 预处理器: Less 和 Sass
  • 响应式: Yes
  • 模块化: Yes
  • 开始模板/布局: Yes
  • 图标设置: Glyphicons Halflings set
  • 附加/插件: 没有捆绑插件,但许多第三方插件可用.
  • 独特的组件: Jumbotron
  • 文档: 良好
  • 定制: 基本的GUI定制器。不幸的是,你需要手动输入的颜色值,因为没有可用的颜色选择器。
  • 浏览器支持: Firefox, Chrome, Safari, IE8+ (你需要 Respond.js for IE8)
  • 许可证: MIT

Bootstrap说明

  •  Bootstrap 的主要优点是它非常流行。从技术上讲,它并不一定比这次列出来的其他框架好,但它提供的资源(文章和教程、第三方插件和扩展、主题开发者等等)比其他四个框架的总和还要多。简而言之,Bootstrap无处不在。这是人们继续选择它的主要原因。
  • (注意:“独特的组件”的意思是,相比这里提到的其他框架是独一无二的。)

2. Foundation by ZURB

Foundation是这几个框架中第二大的,在像ZURB一样实力雄厚的公司支持下,这个框架确实很强大,是的,就是foundation。毕 竟, Foundation已经在很多大型网站上投入使用,包括 Facebook, Mozilla, Ebay, Yahoo!和国家地理等等。

Linux:2014年5个最流行前端框架对比
Linux:2014年5个最流行前端框架对比
  • 创建者: ZURB
  • 发布: 2011
  • 当前版本:5.4.7
  • 人气: 在Github上有18,000+ stars
  • 描述: “世界上最优秀的响应式前端框架”
  • 核心概念/原则: RWD 、手机优先、语义的
  • 框架大小: 326KB
  • 预处理器: Sass
  • 响应式: Yes
  • 模块化: Yes
  • 开始模板/布局: Yes
  • 图标设置: Foundation Icon Fonts
  • 附加/插件: yes
  • 独特的组件: Icon Bar, Clearing Lightbox, Flex Video, Keystrokes, Joyride, Pricing Tables
  • 文档: 良好,还有许多额外的资源是可用的。
  • 定制: 没有GUI编辑器,只能手工定制。
  • 浏览器支持: Chrome, Firefox, Safari, IE9+; iOS, Android, Windows Phone 7+
  • 许可证: MIT

Foundation说明

Foundation 是一个提供业务支持、培训和咨询真正专业的框架。它还提供了很多资源帮助你更快和更容易学习和使用框架。

3. Semantic UI

Semantic UI 经过多年的努力,致力于能够以更语义化的方式构建网站。它使用自然语言的原则,使代码更可读,更容易理解。

Linux:2014年5个最流行前端框架对比
Linux:2014年5个最流行前端框架对比
  • 创建者: Jack Lukic
  • 发布:2013
  • 当前版本:1.2.0
  • 人气: 在Github上有12,900+ stars
  • 描述: “基于自然语言有效原则的UI组件框架”
  • 核心概念/原则: 语义,标签的矛盾性、响应式
  • 框架大小: 552KB
  • 预处理器: Less
  • 响应式: Yes
  • 模块化: Yes
  • 开始模板/布局: No
  • 图标设置: Font Awesome
  • 附加/插件: yes
  • 独特的组件: Divider, Flag, Rail, Reveal, Step, Advertisement, Card, Feed, Item, Statistic, Dimmer, Rating, Shape.
  • 文档: 非常好。Semantic提供了一个很好的组织文档,还有一个提供入门指南,定制和创建主题单独的网站,。
  • 定制: 没有GUI定制器,只能手工定制。
  • 浏览器支持:Firefox, Chrome, Safari, IE10+ (IE9 with browser prefix only), Android 4, Blackberry 10
  • 许可证: MIT

Semantic UI说明

Semantic 是这里讨论的最创新和功能最全面的框架。在框架的总体结构和命名约定方面,也以清晰的逻辑和语义类超过了别的框架。

来源:http://web.jobbole.com/81876/

Linux:在 CentOS 7 / RHEL 7 上怎样安装 Eclipse Luna IDE

Eclipse是一个集成开发环境(IDE),包含一个基工作区和定制环境的可扩展插件系统。大部分使用于 Java 编写,Eclipse 可以用来开发应用程序。

通过各种插件,Eclipse 也可以用于其他编程语言开发应用程序:Ada、ABAP、C、C++、COBOL、 Fortran、Haskell、 JavaScript、Lasso、Natural、Perl、 PHP、 Prolog、 Python、Ruby、Scala、Clojure、 Groovy、Scheme 和 Erlang。它也可以用来开发Mathematica软件包。

开发环境包括 Eclipse Java 开发工具(JDT)支持 Java与Scala,Eclipse CDT C / C + +和Eclipse PDT PHP,等等。

Installation

1 – 首先安装 JAVA

yum install java

2 – 检查 java 是否已经安装

java -version
java version "1.7.0_51"
OpenJDK Runtime Environment (rhel-2.4.5.5.el7-x86_64 u51-b31)
OpenJDK 64-Bit Server VM (build 24.51-b03, mixed mode)

3 – 下载 Eclipse LUNA 最终版

解压到 /opt 目录下;

tar -zxvf eclipse-java-luna-SR1-linux-gtk-x86_64.tar.gz -C /opt

4 – 使符号链接目录

ln -s /opt/eclipse/eclipse /usr/bin/eclipse

5 – 创建一个  Gnome 启动

vi /usr/share/applications/eclipse.desktop

添加如下代码:

[Desktop Entry]
Encoding=UTF-8
Name=Eclipse 4.4.1
Comment=Eclipse Luna
Exec=/usr/bin/eclipse
Icon=/opt/eclipse/icon.xpm
Categories=Application;Development;Java;IDE
Version=1.0
Type=Application
Terminal=0

6 – 检查 app 是否已经被添加 

Linux:在 CentOS 7 / RHEL 7 上怎样安装 Eclipse Luna IDE
Linux:在 CentOS 7 / RHEL 7 上怎样安装 Eclipse Luna IDE

7 – 运行 Eclipse 

Linux:在 CentOS 7 / RHEL 7 上怎样安装 Eclipse Luna IDE
Linux:在 CentOS 7 / RHEL 7 上怎样安装 Eclipse Luna IDE
Linux:在 CentOS 7 / RHEL 7 上怎样安装 Eclipse Luna IDE
Linux:在 CentOS 7 / RHEL 7 上怎样安装 Eclipse Luna IDE

从市场下载插件和扩展的帮助>

Linux:在 CentOS 7 / RHEL 7 上怎样安装 Eclipse Luna IDE
Linux:在 CentOS 7 / RHEL 7 上怎样安装 Eclipse Luna IDE

 

来源:http://imcn.me/html/y2015/23020.html

Linux:Docker 终极指南

Docker是一个相对较新且发展非常快速的项目,可用来创建非常轻量的“虚拟机”。注意这里的引号非常重要,Docker创建的并非真正的虚拟机,而更像是打了激素的chroot,嗯,是大量的激素。

在我们继续之前,我先说下,截至目前(2015年1月4日)为止,Docker只能在Linux上工作,暂不支持Windows或OSX(译者注:不直接支持)。我稍后会讲到Docker的架构,你会明白其中的原因。所以,如果想在非Linux平台上使用Docker,你需要在虚拟机里运行Linux。

Linux:Docker 终极指南
Linux:Docker 终极指南

本教程有三个目标:说明Docker解决的问题、说明它如何解决这个问题、以及说明它使用了哪些技术来解决这个问题。这不是一篇教你怎么运行安装Docker的教程,Docker此类教程已经很多,包括Docker作者的在线互动教程。本文最后有一个步骤说明,目的是用一个明确的现实世界的例子来串联文章中所有的理论,但不会太过详细。

Docker能做什么?

Docker可以解决虚拟机能够解决的问题,同时也能够解决虚拟机由于资源要求过高而无法解决的问题。Docker能处理的事情包括:

  • 隔离应用依赖
  • 创建应用镜像并进行复制
  • 创建容易分发的即启即用的应用
  • 允许实例简单、快速地扩展
  • 测试应用并随后销毁它们

Docker背后的想法是创建软件程序可移植的轻量级容器,让其可以在任何安装了Docker的机器上运行,而不用关心底层操作系统,类似船舶使用的集装箱,野心勃勃的他们成功了!

Docker究竟做了什么?

这一节我不会说明Docker使用了哪些技术来完成它的工作,或有什么具体的命令可用,这些放在了最后一节,这里我将说明的是Docker提供的资源和抽象。

Docker两个最重要的概念是镜像和容器。除此之外,链接和数据卷也很重要。我们先从镜像入手。

镜像

Docker的镜像类似虚拟机的快照,但更轻量,非常非常轻量(下节细说)。

创建Docker镜像有几种方式,多数是在一个现有镜像基础上创建新镜像,因为几乎你需要的任何东西都有了公共镜像,包括所有主流Linux发行版,你应该不会找不到你需要的镜像。不过,就算你想从头构建一个镜像也有好几种方法

要创建一个镜像,你可以拿一个已有的镜像,对它进行修改来创建它的子镜像。实现的方式有两种:在一个文件中指定一个基础镜像及需要完成的修改;或通过“运行”一个镜像,对其进行修改并提交。不同方式各有优点,不过一般会使用第一种的文件方式来指定所做的变化。

镜像拥有唯一ID,以及一个供人阅读的名字和标签对。镜像可以命名为类似ubuntu:latest、ubuntu:precise、django:1.6、django:1.7等等。

容器

现在说容器了。你可以从镜像中创建容器,这等同于从快照中创建虚拟机,不过更轻量。应用是由容器运行的。

举个例子,你可以下载一个Ubuntu的镜像(有个叫docker registry的镜像公共仓库),做一些修改:安装Gunicorn和你的Django应用及其依赖;然后从该镜像中创建一个容器,在它启动后运行你的应用。

1.png

容器与虚拟机一样,是隔离的(有一点要注意,我稍后会讨论到)。它们也拥有一个唯一ID和唯一的供人阅读的名字。容器有必要对外暴露服务,因此Docker允许暴露容器的特定端口。

Linux:Docker 终极指南
Linux:Docker 终极指南

容器与虚拟机相比有两个主要差异。第一个是:它们被设计成运行单进程,无法很好地模拟一个完整的环境(如果那是你需要的,请看看LXC)。你可能会尝试运行runit或supervisord实例来启动多个进程,但(以我的愚见)这真的没有必要

单进程与多进程之争非常精彩。你应该知道的是,Docker设计者极力推崇“一个容器一个进程的方式”,如果你要选择在一个容器中运行多个进程,那唯一情况是:出于调试目的,运行类似ssh的东西来访问运行中的容器,不过docker exec命令解决了这个问题。

容器和虚拟机的第二个巨大差异是:当你停止一个虚拟机时,可能除了一些临时文件,没有文件会被删除;当你停止一个Docker容器,对初始状态(创建容器所用的镜像的状态)做的所有变化都会丢失。这是使用Docker时必须做出的最大思维变化之一:容器是短暂和一次性的

数据卷

如果你的电子商务网站刚收到客户支付的3万元,内核崩溃了,所有数据库变化都丢失了……对你或Docker来说都不是一件好事,不过不要担心。Docker允许你定义数据卷——用于保存持久数据的空间。Docker强制你定义应用部分和数据部分,并要求你将它们分开。

卷是针对容器的,你可以使用同一个镜像创建多个容器并定义不同的卷。卷保存在运行Docker的宿主文件系统上,你可以指定卷存放的目录,或让Docker保存在默认位置。保存在其他类型文件系统上的都不是一个卷,稍后再具体说。

Linux:Docker 终极指南
Linux:Docker 终极指南

链接

链接是Docker的另一个重要部分。

容器启动时,将被分配一个随机的私有IP,其它容器可以使用这个IP地址与其进行通讯。这点非常重要,原因有二:一是它提供了容器间相互通信的渠道,二是容器们将共享一个本地网络。我曾经碰到一个问题,在同一台机器上为两个客户启动两个elasticsearch容器,但保留集群名称为默认设置,结果这两台elasticsearch服务器立马变成了一个自主集群。

要开启容器间通讯,Docker允许你在创建一个新容器时引用其它现存容器,在你刚创建的容器里被引用的容器将获得一个(你指定的)别名。我们就说,这两个容器链接在了一起。

因此,如果DB容器已经在运行,我可以创建web服务器容器,并在创建时引用这个DB容器,给它一个别名,比如dbapp。在这个新建的web服务器容器里,我可以在任何时候使用主机名dbapp与DB容器进行通讯。

Docker更进一步,要求你声明容器在被链接时要开放哪些端口给其他容器,否则将没有端口可用。

Linux:Docker 终极指南
Linux:Docker 终极指南

Docker镜像的可移植性

在创建镜像时有一点要注意。Docker允许你在一个镜像中指定卷和端口。从这个镜像创建的容器继承了这些设置。但是,Docker不允许你在镜像上指定任何不可移植的内容。

例如,你可以在镜像里定义卷,只要它们被保存在Docker使用的默认位置。这是因为如果你在宿主文件系统里指定了一个特定目录来保存卷,其他使用这个镜像的宿主无法保证这个目录是存在的。

你可以定义要暴露的端口,但仅限那些在创建链接时暴露给其他容器的端口,你不能指定暴露给宿主的端口,因为你无从知晓使用那个镜像的宿主有哪些端口可用。

你也不能在镜像上定义链接。使用链接要求通过名字引用其他容器,但你无法预知每个使用那个镜像的宿主如何命名容器。

镜像必须完全可移植,Docker不允许例外。

以上就是主要的部分,创建镜像、用它们创建容器,在需要时暴露端口和创造卷、通过链接将几个容器连接在一起。不过,这一切如何能在不引起额外开销条件下达成?

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

Linux:7款绚丽的jQuery/HTML5动画及源码

jQuery是一款非常流行的JavaScript框架,利用jQuery,我们可以制作简单的动画效果,但是结合HTML5,这样的动画效果就会变得更加出彩。本文分享了7款jQuery结合HTML5的动画以及源码下载。

1、HTML5/SVG实现布谷鸟时钟动画

这是一款非常有意思的HTML5动画,它是一个老式的时钟,有布谷鸟报时,情侣的浪漫舞蹈。

Linux:7款绚丽的jQuery/HTML5动画及源码
Linux:7款绚丽的jQuery/HTML5动画及源码

2、HTML5/CSS3实现图片倒影3D效果

这款应用主要利用了CSS3的transform属性实现了图片的倾斜和倒影,动画效果也非常不错。

Linux:7款绚丽的jQuery/HTML5动画及源码
Linux:7款绚丽的jQuery/HTML5动画及源码

3、jQuery图片放大预览插件

这款基于jQuery的图片放大预览插件,只需要将鼠标滑过缩略图,即可将当前区域的图片放大预览,这个功能一般在商品图片展示的时候非常有用。

Linux:7款绚丽的jQuery/HTML5动画及源码
Linux:7款绚丽的jQuery/HTML5动画及源码

4、jQuery内容层叠滚动切换动画插件

这是一款很有创意的jQuery内容滑动动画,我们可以设置任意数量的文字层,让其层叠在一起,然后点击按钮让其出现层叠滚动切换的效果。

Linux:7款绚丽的jQuery/HTML5动画及源码
Linux:7款绚丽的jQuery/HTML5动画及源码

5、jQuery文件夹管理插件

这款jQuery插件模拟了操作系统的文件管理系统,可以新建、删除和重命名文件夹。

Linux:7款绚丽的jQuery/HTML5动画及源码
Linux:7款绚丽的jQuery/HTML5动画及源码

6、jQuery全屏广告图片焦点图

这款jQuery全屏广告图片焦点图插件也非常不错,图片切换时有淡出淡出的动画效果,并且也相当流畅。

jquery-full-ad-slider

7、jQuery带格式验证的注册表单

这款jQuery表单的特点是带有严格的表单字段格式验证功能,比如电子邮箱的格式、用户名格式以及密码复杂度和长度等。

Linux:7款绚丽的jQuery/HTML5动画及源码
Linux:7款绚丽的jQuery/HTML5动画及源码

以上的jQuery动画也有源代码下载,大家可以自行研究,欢迎分享。

来源:http://www.codeceo.com/article/7-cool-jquery-html5-animation.html

Linux:网页响应式设计的现状与趋势

Linux:网页响应式设计的现状与趋势
Linux:网页响应式设计的现状与趋势

从2012年开始到2014年,各大家对Web设计的趋势预测中,都提到响应式设计;2015年网页设计趋势预测中,响应式仍在继续。这个经历了几年依然大热的响应式,在过去的几年里,快速巩固了自己的地位,并掀起了一股网页设计新标准的浪潮。这里本人基于一些资料文献及自己的陋见,谈谈响应式设计的一些现状和趋势。

源起

2010年5月,伊桑.马科特(Ethan Marcotte)在“A List Apart”写了一篇开创性的文章(题为“Responsive Web Design” ),他利用三种已有的工具:流动布局(fluid grids)、媒介查询(media queries)和弹性图片(scalable images)创建了一个在不同分辨率屏幕下都能漂亮地显示的网站。 Ethan Marcotte力劝设计师们要去利用那些Web独有的特性去进行设计: “我们可以将不同联网设备上众多的体验,当作是同一网站体验的不同侧面来对待,而不要为每种设备进行单独剪裁而使得设计彼此断开,这才是我们前进的方向。虽然我们已经能够设计出最佳的视觉体验,但还要把基于标准的技术也嵌入到我们的设计中去,这样才能使得我们的设计不仅灵活,而且还能适应渲染它们的各种媒介。” Ethan Marcotte证明了一种在多种设备上都能提供卓越体验的方法的存在,而且这一方法不会忽视不同设备的差异,也不会强调设计师的控制权,而是选择了顺其自然并拥抱Web的灵活性。

这里简单介绍下上面的提到的三个概念:流动布局(fluid grids)、媒介查询(media queries)和弹性图片(scalable images)原本都是指现有的一些技术手段,但在做响应式设计研究的过程中,这些概念还是有更广泛的意义,设计师也应该有所了解:

  1. 流动布局:原特指以百分比为度量单位的布局技术实现方式。这里就不对如流动布局、弹性布局、流体栅格等各种概念做一一说明。笔者就此统为一个大的概念:在响应式设计的布局中,不再以像素(px)作为唯一单位,而是采用百分比或者混合百分比、像素为单位,设计出更具灵活性的布局方式。
  2. 媒介查询:媒介查询可以让你根据在特定环境下查询到的各种属性值——比如设备类型、分辨率、屏幕物理尺寸及色彩等——来决定应用什么样的样式。通过使用媒介查询,可以获取到设备及设备的特性,并给出求同存异的方案,从而解决之前在单纯的布局设计中遗留的问题。
  3. 弹性图片:伴随布局的弹性,图片作为信息重要的形式之一也必须有更灵活的方式去适应布局的变化。个人认为弹性图片是Ethan Marcotte提出设计产品时提出的概念,我们在后续的研究中可以以图片为典型,扩大研究范围:除了图片,还应该包括图标、图表、视频等信息内容的响应方式研究。

盛行

响应式设计的概念从提出至今,一直不断蔓延扩散,并得到各方认可的主要原因:

  1. 外部环境:快速增长且日趋加剧的可联网设备的多样化,让现今已不再有标准的屏幕尺寸;
  2. 自身特色:严格定义的响应式一般是指响应式Web设计,而Web凭借其特有的灵活性和可塑性,可以适应各种尺寸和配置的设备,可以无处不在。
  3. 内部需求:响应式设计概念一提出,各大网站及平台都希望能够采用这秉一应万的模式,可以更灵活地去适配更多设备,尤其是现在移动设备大爆棚的时代。
Linux:网页响应式设计的现状与趋势
Linux:网页响应式设计的现状与趋势

当然也并不是所有的情况都理所应带应该采用响应式设计,那么什么情况下更适合采用响应式呢?

  1. 你想节约成本地去适应更多场景:> 资源都是有限的,但总是希望能利用有限的资源去获得更大的价值。虽然比起开发设计一个普通的网站来说,要打造一个响应式站点,所需要的人力和时间资源都会有所增加,但比起为不同设备分别打造多个版本的成本还是要低很多;从维护的角度来说,也会轻松很多。
  2. 你并不清楚要设计开发的全新产品更适合哪个场景:> 与其通过预测挑选核心设备再进行分别设计,倒不如先花些心思将网站打造得更具弹性,使其在各种设备中都拥有尽可能优秀体验。因为在各方面都未知都情况下,做预测会加剧过程风险,使得结果存在巨大的挑战性。
  3. 你希望网站可以兼容未来的新设备:> 新的设备层出不穷,与其被动地进行更新维护,不如主动应万变,成为响应式。 当然这里只是说更适合,其实个人认为只要项目资源和时间允许,基本上大部分网站都可以去尝试实现响应式;而对于初次尝试响应式设计的,也可以从“简单浏览型页面”开始。

模式

目前大多网站中选择成为响应式的设计模式主要有两种:

  1. 基于设备:通过主流设备的类型及尺寸来确定布局断点(break point),设计多套样式,再分别投射到响应的设备。
    Linux:网页响应式设计的现状与趋势
    Linux:网页响应式设计的现状与趋势
  2. 内容优先:根据内容的可读性、易读性作为确定断点(break point)的标准,即在对内容进行布局设计的时候,可以无视设备,有内容决定何时需要采用不同的呈现方式。
    Linux:网页响应式设计的现状与趋势
    Linux:网页响应式设计的现状与趋势

个人还是倾向内容优先的方式,这是真正符合响应式设计核心策略的模式,也是对未来友好的方式。 从过去基本上是基于pc的几个尺寸,选择最佳的标准尺寸去设计页面;到现在移动设备已经玲琅满目,同时电视、穿戴设备也慢慢开始起来,已经不再有固定的尺寸;未来,将是更加无法预知的设备环境;那么什么才是王道呢?——就是内容本身! 变化总是来得快且狠,我们要做的就是抓住那根可以贯通全局的线!

Linux:网页响应式设计的现状与趋势
Linux:网页响应式设计的现状与趋势

在内容优先的策略中,有三点思维模式可以贯穿整个响应式设计的过程:

  1. 忘记设备:因为我们不知道用户会用什么样的设备来访问网站,因此,我们必须尽可能地把所有情况都囊括进来;所有的东西(布局、组件等)都能与不同类型的设备和平台相兼容。
  2. 优雅降级:虽然这个概念一开始是技术实现上对新的特性在老的浏览器上无法很好实现时的折中做法,但在此仅想表达在对布局做弹性设计时,内容从宽到窄的变化呈现,必须经过重重筛选,留存最核心的内容块。这种模式非常适合对已存在的pc页面产品进行响应式设计改造。
  3. 渐进增强:此概念是在Steven在2003年的SXSW活动上提出的。在本质上来说,就是把优雅降级倒过来:先创建一个基本体验,侧重让内容以一种简介的方式来展现;之后,在保证基本体验的前提下,开始着手做有关显示的布局和交互。而在此,也借用来说明下对于响应式设计的内容策略中,内容从窄到宽的变化呈现中,可以让内容的丰富度也相应地有所增加。这种模式与移动优先策略是相匹配的。

当然,目前响应式也是有存在各种争论的,也许你有一个很好的理由不用响应式网页设计?但我想没人会说,“让我们摆脱响应式设计吧”,而实际上,越来越多的网站选择成为响应式。2014年如此,2015年也还是会继续,因为这已经不是种趋势,而怡然是种常态了。

未来的路

虽然响应式设计的优势和趋势已被普遍认可,但目前响应式设计的模式的普及还是有很多难题需要突破:

  1. 响应式图片:目前弹性图片的做法主要是:缩放、剪裁、分条件加载等实现方法本质上都只是一个技巧,只是治标不治本地掩盖了问题,并未真正完美地实现图片的弹性。
  2. 跨端的交互:在响应式设计中,我们不仅要需要考虑桌面用户的使用习惯,还必须兼顾不同尺寸的手持设备。比如在桌面端无尽优雅的Hover,在移动端却是无比糟糕的体验,如何“求同存异”,让各端体验均能最佳,还是需要继续深入探究的。
  3. 性能:性能估计是在响应式开发中最大的痛,按条件加载、隐藏或显示什么内容,都会比单一条件判断的代码结构来的繁琐,并影响体验及维护。尤其是移动性能上,更多样的设备具有更加复杂的使用环境,如何识别设备,并让设备在不同环境均能良好体验,也是一根硬骨头。
  4. 合作流程:响应式设计远远不止是一种简单的设计策略,它为Web项目带来的是一整套全新的、完整的方法,还应该包括一种新的、可以更好地利用这一模式的工作流程。

最后,我想说下响应式体现的是一种高度适应性的设计思维模式。在响应式设计探究的道路上,响应式本身不是唯一目的,基于任意设备对页面内容进行完美规划的设计策略及工作流程应该是我们更大的课题~

来源:http://www.aliued.cn/2015/01/04/%E5%93%8D%E5%BA%94%E5%BC%8F%E8%AE%BE%E8%AE%A1%E7%9A%84%E7%8E%B0%E7%8A%B6%E4%B8%8E%E8%B6%8B%E5%8A%BF.html

Linux:如何在源码包编译安装的 LEMP 环境下开启 OpenSSL 功能

Linux:如何在源码包编译安装的 LEMP 环境下开启 OpenSSL 功能
Linux:如何在源码包编译安装的 LEMP 环境下开启 OpenSSL 功能

Hello,大家好!我是——邪恶君子!

今天,给大家分享一下解决源码包编译安装 LEMP 环境下开启 OpenSSL 功能问题的过程。前几天,在访问页面时,突然报错,要求开启 openssl 功能。那怎么办呢,首先想到的是 yum 安装,但是,安装后还是没解决,因为 LEMP 的环境是源码包编译安装的,所以,还需要编译安装 openssl。

经过邪恶不懈的努力,终于找到了解决办法,而且真的成功了,下面就给大家分享一下!

首先,要确保 LEMP 环境是源码包编译安装的,并且要清楚 PHP 的安装目录在哪里。

其次,可以通过 yum 源的方式或者源码包编译安装 OpenSSL、OpenSSL-devel 两个包。

然后,进入到 PHP 解压出来的目录里面,我这里的目录是 PHP-5.4.24。在 PHP 目录下,会有一个 ext 的扩展目录,进入里面,找到并进入 openssl 的目录。这时,我们所在的目录是:/root/php-5.4.24/ext/openssl

这个目录下会有如下文件,看图:

 

然后,执行 /usr/local/php5/bin/phpize 命令(在执行前要确保已安装 m4 和 autoconf 两个工具,否则会报错)。

注意:这里是我的phpize路径,根据自己的安装路径执行;如果找不到,使用 whereis phpize 查找。如果执行时报错无法找到 config.m4 文件,那么就把目录下面的 config0.m4 重命名 config.m4,因为 config0.m4就是config.m4 的模版。

如果命令成功执行完毕,那么目录下面就会自动多出个 configure 文件,这时,只需要编译安装就行了。过程如下:

# ./configure --with-openssl --with-php-config=/usr/local/php5/bin/php-config
# make && make install

耐心等候,安装完成后,会在当前的modules目录下面多出一个openssl.so文件;然后在php.ini配置文件最后面加上如下一行内容:

extension=openssl.so

然后,重启nginx服务和php-fpm,就可以了!

至此,在源码编译安装LNMP环境下开启openssl功能成功解决!


如果有在操作中遇到啥问题,可以留言交流一下,共同学习,共同进步!

Personal Home Page:http://linux.cn/space/16475

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

Linux:不重启不当机!Linux内核热补丁的四种技术

Linux:不重启不当机!Linux内核热补丁的四种技术
Linux:不重启不当机!Linux内核热补丁的四种技术

供图: Shutterstock

有多种技术在竞争成为实现Linux内核热补丁的最优方案。

没人喜欢重启机器,尤其是涉及到一个内核问题的最新补丁程序。

为达到不重启的目的,目前有3个项目在朝这方面努力,将为大家提供内核升级时打热补丁的机制,这样就可以做到完全不重启机器。

Ksplice项目

首先要介绍的项目是Ksplice,它是热补丁技术的创始者,并于2008年建立了与项目同名的公司。Ksplice在替换新内核时,不需要预先修改;只需要一个diff文件,列出内核即将接受的修改即可。Ksplice公司免费提供软件,但技术支持是需要收费的,目前能够支持大部分常用的Linux发行版本。

但在2011年Oracle收购了这家公司后,情况发生了变化。 这项功能被合入到Oracle自己的Linux发行版本中,只对Oralcle自己提供技术更新。 这就导致,其他内核hacker们开始寻找替代Ksplice的方法,以避免缴纳Oracle税。

Kgraft项目

2014年2月,Suse提供了一个很好的解决方案:Kgraft,该内核更新技术以GPLv2/GPLv3混合许可证发布,且Suse不会将其作为一个专有发明封闭起来。Kgraft被提交到Linux内核主线,很有可能被内核主线采用。目前Suse已经把此技术集成到Suse Linux Enterprise Server 12

Kgraft和Ksplice在工作原理上很相似,都是使用一组diff文件来计算内核中需要修改的部分。但与Ksplice不同的是,Kgraft在做替换时,不需要完全停止内核。 在打补丁时,正在运行的函数可以先使用老版本或新内核中对应的部分,当补丁打完后就可以完全切换新的版本。

Kpatch项目

Red Hat也提出了他们的内核热补丁技术。同样是在2014年初 — 与Suse在这方面的工作差不多 — Kpatch的工作原理也和Kgraft相似。

主要的区别点在于,正如Red Hat的Josh Poimboeuf总结的那样,Kpatch并不将内核调用重定向到老版本。相反,它会等待所有函数调用都停止时,再切换到新内核。Red Hat的工程师认为这种方法更为安全,且更容易维护,缺点就是在打补丁的过程中会带来更大的延迟。

和Kgraft一样,Kpatch不仅仅可以在Red Hat的发行版本上使用,同时也被提交到了内核主线,作为一个可能的候选。 坏消息是Red Hat还未将此技术集成到产品中。 它只是被合入到了Red Hat Enterprise Linux 7的技术预览版中。

…也许 Kgraft + Kpatch更合适?

Red Hat的工程师Seth Jennings在2014年11月初,提出了第四种解决方案。将Kgraft和Kpatch结合起来, 补丁包用这两种方式都可以。在新的方法中,Jennings提出,“热补丁核心为其他内核模块提供了一个热补丁的注册接口”, 通过这种方法,打补丁的过程 — 更准确的说,如何处理运行时内核调用 –可以被更加有序的组织起来。

这项新建议也意味着两个方案都还需要更长的时间,才能被linux内核正式采纳。尽管Suse步子迈得更快,并把Kgraft应用到了最新的enterprise版本中。让我们也关注一下Red Hat和Canonical近期是否会跟进。


via: http://www.infoworld.com/article/2851028/linux/four-ways-linux-is-headed-for-no-downtime-kernel-patching.html

作者:Serdar Yegulalp 译者:coloka 校对:tinyeyeser

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

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

Linux:Linux有问必答:如何禁止Ubuntu的Apport内部错误报告程序

问题:在桌面版Ubuntu中,我经常遇到一些弹窗窗口,警告我Ubuntu发生了内部错误,问我要不要发送错误报告。每次软件崩溃都要烦扰我,我如何才能关掉这个错误报告功能呢?

Linux:Linux有问必答:如何禁止Ubuntu的Apport内部错误报告程序
Linux:Linux有问必答:如何禁止Ubuntu的Apport内部错误报告程序

Ubuntu桌面版预装了Apport,它是一个错误收集系统,会收集软件崩溃、未处理异常和其他,包括程序bug,并为调试目的生成崩溃报告。当一个应用程序崩溃或者出现Bug时候,Apport就会通过弹窗警告用户并且询问用户是否提交崩溃报告。你也许也看到过下面的消息。

  • “Sorry, the application XXXX has closed unexpectedly.”
  • “对不起,应用程序XXXX意外关闭了。”
  • “Sorry, Ubuntu XX.XX has experienced an internal error.”
  • “对不起,Ubuntu XX.XX 发生了一个内部错误。”
  • “System program problem detected.”
  • “检测到系统程序问题。”
Linux:Linux有问必答:如何禁止Ubuntu的Apport内部错误报告程序
Linux:Linux有问必答:如何禁止Ubuntu的Apport内部错误报告程序

也许因为应用一直崩溃,频繁的错误报告会使人心烦。也许你担心Apport会收集和上传你的Ubuntu系统的敏感信息。无论什么原因,你想关掉Apport的错误报告功能。

临时关闭Apport错误报告

如果你想要临时关闭Apport,使用下列命令

$ sudo service apport stop

注意重启Ubuntu系统Apport会继续开启

永久关闭Apport错误报告

为了永久关闭Apport,编辑/etc/default/apport,修改下列参数

enabled=0

重启你的Ubuntu系统,Apport将会自动关闭

如果你再也不会用Apport,有一种简单的方法完全移除它

$ sudo apt-get purge apport

via: http://ask.xmodulo.com/disable-apport-internal-error-reporting-ubuntu.html

译者:VicYu/Vic020 校对:wxy

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

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

Linux:Web API设计方法论

 

设计Web API不止是URL、HTTP状态码、头信息和有效负载。设计的过程–基本上是为了你的API“观察和感受” — 这非常重要,并且值得你付出努力。本文简要概括了一种同时发挥HTTP和Web两者优势的API设计方法论。并且它不仅对HTTP有效。如果有时你还需要 通过WebSockets、XMPP、MQTT等实现同样的服务,大部分API设计的结果同样可用。可以让未来支持多种协议更容易实现和维护。

优秀的设计超越了URL、状态码、头信息和有效负载

一般来说, Web API设计指南的重点是通用的功能特性,比如URL设计,正确使用状态码、方法、头信息之类的HTTP功能特性,以及持有序列化的对象或对象图的有效负载 设计。这些都是重要的实现细节,但不太算得上API设计。并且正是API的设计–服务的基本功能特性的表达和描述方式–为Web API的成功和可用性做出了重要贡献。

一个优秀的设计过程或方法论定义了一组一致的、可重复的步骤集,可以在将一个服务器端服务组件输出为一个可访问的、有用的Web API时使用。那就是说,一个清晰的方法论可以由开发人员、设计师和软件架构师共享,以便在整个实现周期内帮助大家协同活动。一个成熟的方法论还可以随着 时间的发展,随着每个团队不断发现改善和精简过程的方式而得到精炼,却不会对实现细节产生不利的影响。实际上,当实现细节设计过程两者都有清晰的定义并相互分离时,实现细节的改变(比如采用哪个平台、OS、框架和UI样式)可以独立于设计过程。

API设计七步法

接下来我们要对Richardson和Amundsen合著的《REST风格的Web API》一书中所介绍的设计方法论做简要地概述。因为篇幅所限,我们不能深入探讨这一过程中的每一步骤,但这篇文章可以让你有个大概的认识。另外,读者可以用这篇概述作为指南,根据自己组织的技能和目标开发一个独有的Web API设计过程。

说明:是的,7步看起来有点儿多。实际上清单中有5个步骤属于设计,额外还有两个条目是实现和发布。最后这两个设计过程之外的步骤是为了提供一个从头到尾的体验。

你应该计划好根据需要重新迭代这些步骤。通过步骤2(绘制状态图)意识到在步骤1(列出所有组成部分)有更多工作要做。当你接近于写代码(步骤6) 时,可能会发现第5步(创建语义档案)中漏了一些东西。关键是用这个过程暴露尽可能多的细节,并愿意回退一步或者两步,把前面漏掉的补上。迭代是构建更加 完整的服务画面以及澄清如何将它暴露给客户端程序的关键。

步骤1 : 列出所有组成部分

第一步是列出客户端程序可能要从我们的服务中获取的,或要放到我们的服务中的所有数据片段。我们将这些称为语义描述符。语义是指它们处理数据在应用 程序中的含义,描述符是指它们描述了在应用程序自身中发生了什么。注意,这里的视点是客户端,不是服务器端。将API设计成客户端使用的东西很重要。

比如说,在一个简单的待办事项列表应用中,你可能会找到下面这些语义描述符:

  • id : 系统中每条记录的唯一标识符
  • title : 每个待办事项的标题
  • dateDue : 待办事项应该完成的日期
  • complete : 一个是/否标记,表明待办事项是否已经完成了。

在一个功能完备的应用程序中,可能还会有很多语义描述符,涉及待办事项的分类(工作、家庭、园艺等),用户信息(用于多用户的实现)等等。不过为了突出过程本身,我们会保持它的简单性。

步骤2 : 绘制状态图

下一步是根据建议的API绘制出状态图。图中的每个框都表示一种可能的表示–一个包含在步骤1中确定的一或多个语义描述符的文档。你可以用箭头表示从一个框到下一个的转变–从一个状态到下一个状态。这些转变是由协议请求触发的。

在每次变化中还不用急着指明用哪个协议方法。只要标明变化是安全的(比如HTTP GET),还是不安全/非幂等的(比如HTTP POST),或者不安全/幂等的(PUT)。

说明:幂等动作是指重复执行时不会有无法预料的副作用。比如HTTP PUT,因为规范说服务器应该用客户端传来的状态值替换目标资源的已有值,所以说它是幂等的。而 HTTP POST是非幂等的,因为规范指出提交的值应该是追加到已有资源集合上的,而不是替换。

在这个案例中,我们这个简单的待办事项服务的客户端应用程序可能需要访问可用条目的清单,能过滤这个清单,能查看单个条目,并且能将条目标记为已完 成。这些动作中很多都用状态值在客户端和服务器之间传递数据。比如add-item 动作允许客户端传递状态值title和dueDate。下面是一个说明那些动作的状态图。

Linux:Web API设计方法论
Linux:Web API设计方法论

这个状态图中展示的这些动作(也在下面列出来了)也是语义描述符– 它们描述了这个服务的语义动作

  • read-list
  • filter-list
  • read-item
  • create-item
  • mark-complete

在你做这个状态图的过程中,你可能会发现自己漏掉了客户端真正想要或需要的动作或数据项。这是退回到步骤1的机会,添加一些新的描述符,并/或者在步骤2中改进状态图。

在你重新迭代过这两步之后,你应该对客户端跟服务交互所需的所有数据点和动作有了好的认识和想法。

步骤 3 : 调和魔法字符串

下一步是调和服务接口中的所有“魔法字符串”。“魔法字符串” 全是描述符的名称–它们没有内在的含义,只是表示客户端跟你的服务通讯时将要访问的动作或数据元素。调和这些描述符名称的意思是指采用源自下面这些地方的,知名度更高的公共名称:

这些全是明确定义的、共享的名称库。当你服务接口使用来自这些源头的名称时,开发人员很可能之前见过并知道它们是什么意思。这可以提高API的可用性。

说明:尽管在服务接口上使用共享名称是个好主意,但在内部实现里可以不用(比如数据库里的数据域名称)。服务自身可以毫不困难地将公共接口名称映射为内部存储名称。

以待办事项服务为例,除了一个语义描述符- create-item,我能找到所有可接受的已有名称。为此我根据Web Linking RFC5988中的规则创建了一个具有唯一性的URI。在给接口描述符选择知名的名称时需要折中。它们极少能跟你的内部数据存储元素完美匹配,不过那没关系。

这里是我的结果:

经过名称调和,我的状态图变成了下面这样:

Linux:Web API设计方法论
Linux:Web API设计方法论

步骤 4 : 选一个媒体类型

API设计过程的下一步是选一个媒体类型,用来在客户端和服务器端之间传递消息。Web的特点之一是数据是通过统一的接口作为标准化文档传输的。选 择同时支持数据描述符(比如”identifier”、”status”等)和动作描述符(比如”search”、”edit”等)的媒体类型很重要。有相当多可用的格式。

在我写这篇文章时,一些顶尖的超媒体格式是 (排名不分先后):

  • 超文本标记语言 (HTML)
  • 超文本应用程序语言(HAL)
  • Collection+JSON (Cj)
  • Siren
  • JSON-API
  • 交换表达式的统一基础 (UBER)

让所选择的媒体类型适用于你的目标协议也很重要。大多数开发人员喜欢用HTTP 协议做服务接口。然而WebSocketsXMPPMQTTCoAP 也会用–特别是对于高速、短消息、端到端的实现。

在这个例子中,我会以HTML为消息格式,并采用HTTP协议。HTML有所有数据描述符所需的支持(

    用于列表,

  • 用于条目, 用于数据元素)。它也有足够的动作描述符支持 (用于安全链接,
    用于安全转变,

    用于非安全转变)。

    注意:在这个状态图中, 编辑动作是幂等的(比如HTTP PUT),并且HTML仍然没有对PUT的原生支持。在这个例子中,我会添加一个域来将HTMLPOST做成幂等的。

    好了,现在我可以基于那个状态图创建一些样例表示来“试试”这个接口了。对我们的例子而言,只有两个表示要渲染:“待办事项列表”和“待办事项条目”表示:

    1 :用HTML表示待办事项列表集合

    Linux:Web API设计方法论
    Linux:Web API设计方法论
    Linux:Web API设计方法论
    Linux:Web API设计方法论

    图2:用HTML表示待办事项条目

    Linux:Web API设计方法论
    Linux:Web API设计方法论

    记住,在你做状态图的表示样例时,可能会发现之前的步骤中有所遗漏(比如漏掉描述符,动作描述符中有幂等之类的变化等)。那也没关系。现在就是解决所有这些问题的时机– 在你把这个设计变成代码之前。

    等你对表示完全满意之后,在开始写代码之前还有一个步骤–创建语义档案。

    步骤 5 : 创建语义档案

    语义档案是一个文档,其中列出了设计中的所有描述符,包括对开发人员构建客户端和服务器端实现有帮助的所有细节。这个档案是一个实现指南,不是实现描述。这个差别很重要。

    服务描述符的格式

    服务描述文档格式已经出现了相当长一段时间了,并且当你想给已有的服务实现生产代码或文档时很方便。确实有很多种格式。

    在我写这篇文章时,顶级竞争者有:

    档案的格式

    现在只有几种档案格式。我们推荐下面两种:

    这两个都比较新。JSON-LD规范在2014年早期达成了W3C推荐状态。Hydra仍是一个非官方草案(本文写成时还是),有一个活跃的开发者社区。ALPS仍处于IETF的早期草案阶段。

    因为档案文档的理念是要描述一个问题空间的现实生活方面(不只是那一空间中的单一实现),所以其格式跟典型的描述格式十分不同:

    3 : ALPS格式的待办事项列表语义档案

    Linux:Web API设计方法论
    Linux:Web API设计方法论

    你会注意到,这个文档就像一个基本的词汇表,包含了待办事项服务接口中所有可能的数据值和动作–就是这个理念。同意遵循这个档案的服务可以自行决定它们的协议、消息格式甚至URL。同意接受这个档案的客户端将会构建为可以识别,如果合适的话,启用这个文档中的描述符。

    这种格式也很适合生成人类可读的文档,分析相似的档案,追踪哪个档案用得最广泛,甚至生成状态图。但那是另外一篇文章的课题了。

    现在你有完整的已调和名称的描述符清单,已标记的状态图,以及一个语义档案文档,可以开始准备编码实现样例服务器和客户端了。

    步骤 6 : 写代码

    到了这一步,你应该可以将设计文档(状态图和语义档案)交给服务器和客户端程序的开发人员了,让他们开始做具体的实现。

    HTTP服务器应该实现在第2步中创建的状态图,并且来自客户端的请求应该触发正确的状态转变。服务发送的每个表示都应该用第3步中选好的格式,并 且应该包含一个第4步中创建的指向一个档案的链接。响应中应该包含相应的超媒体控件,实现了在状态图中显示、并在档案文档中描述的动作。客户端和服务器端 开发人员在这时可以创建相对独立的实现,并用测试验证其是否遵守了状态图和档案。

    有了稳定的可运行代码,还有一步要做:发布。

    步骤 7 : 发布你的API

    Web API应该至少发布一个总能给客户端响应的URL — 即便是在遥远的将来。我将其称为“看板URL” –每个人都知道的。发布档案文档也是个好主意,服务的新实现可以在响应中链接它。你还可以发布人类可读的文档、教程等,以帮助开发人员理解和使用你的服 务。

    做好这个之后,你应该有了一个设计良好的、稳定的、可访问的服务运行起来了,随时可以用。

    总结

    本文讨论了为Web设计API的一组步骤。重点是让数据和动作描述正确,并以机器可读的方式记录它们,以便让人类开发人员即便不直接接触也能轻松为这个设计实现客户端和服务器端。

    这些步骤是:

    1. 列出所有组成部分 收集客户端跟服务交互所需的所有数据元素。
    2. 绘制状态图 记录服务提供的所有动作(状态变化)
    3. 调和魔法字符串 整理你的公开接口以符合(尽可能)知名的名称
    4. 选择媒体类型 评审消息格式,找到跟目标协议的服务转变最贴近的那个。
    5. 创建语义档案 编写一个档案文档,定义服务中用的所有描述符。
    6. 写代码 跟客户端和服务器端开发人员分享档案文档,并开始写代码测试跟档案/状态图的一致性,并在有必要时进行调整。
    7. 发布你的API 发布你的”看板URL”和档案文档,以便其他人可以用他们创建新的服务以及/或者客户端程序。

    在你的设计过程中,你可能会发现有遗漏的元素,需要重做某些步骤,以及要做一些折中的决定。这在设计过程中出现得越早越好。将来开发人员要求用新的格式和协议实现时,你还有可能用这个API设计。

    最后,这个方法论只是为Web API设计过程创建一种可靠、可重复、一致的设计过程的一种可能方式。在你做这个例子时,可能会发现插入一些额外的步骤,或者缩减一些会更好用,并且– 当然 — 消息格式和协议决策在不同案例中可能也会发生变化。

    希望这篇文章能给你一些启发,让你知道如何给自己的组织以及/或者团队创建一个最佳的API设计方法论。

    关于作者

    Web API设计方法论 Mike Amundsen 是Layer 7科技的首席API架构师,帮助人们为Web创建优秀的API。国际知名作者和讲师,Mike 在欧美四处旅行,就分布式网络架构、Web应用程序开发、云计算和其他题目提供咨询和演讲。他的名下有十多本书。

    来源:http://www.infoq.com/cn/articles/web-api-design-methodology

Linux:网络时间的那些事及 ntpq 详解

Gentoo(也许其他发行版也是?)中 “ntpq -p” 的 man page 只有简短的描述:“打印出该服务器已知的节点列表和它们的状态概要信息。

我还没见到关于这个命令的说明文档,因此这里对此作一个总结,可以补充进 “man ntpq” man page 中。更多的细节见这里 “ntpq – 标准 NTP 请求程序”(原作者),和 其他关于 man ntpq 的例子.

NTP 是一个设计用于通过 udp 网络 (WAN 或者 LAN) 来同步计算机时钟的协议。引用 Wikipedia – NTP

网络时间协议(英语:Network Time Protocol,NTP)一种协议和软件实现,用于通过使用有网络延迟的报文交换网络同步计算机系统间的时钟。最初由美国特拉华大学的 David L. Mills 设计,现在仍然由他和志愿者小组维护,它于 1985 年之前开始使用,是因特网中最老的协议之一。

想了解更多有关时间和 NTP 协议的知识,可以参考 “The NTP FAQ, Time, what Time?”和 RFCs for NTP。早期的“Network Time Protocol (Version 3) RFC” (txt, or pdf, Appendix E, The NTP Timescale and its Chronometry, p70) 包含了对过去 5000 年我们的计时系统的变化和关系的有趣解释。维基百科的文章 TimeCalendar 提供了更宏观的视角。

Linux:网络时间的那些事及 ntpq 详解
Linux:网络时间的那些事及 ntpq 详解

命令 “ntpq -q” 输出下面这样的一个表:

     remote           refid      st t when poll reach   delay   offset  jitter
==============================================================================
 LOCAL(0)        .LOCL.          10 l  96h   64    0    0.000    0.000   0.000
*ns2.example.com 10.193.2.20      2 u  936 1024  377   31.234    3.353   3.096

更多细节

表头

  • remote – 用于同步的远程节点或服务器。“LOCAL”表示本机 (当没有远程服务器可用时会出现)
  • refid – 远程的服务器进行同步的更高一级服务器
  • st – 远程节点或服务器的 Stratum(级别,NTP 时间同步是分层的)
  • t – 类型 (u: unicast(单播)manycast(选播) 客户端, b: broadcast(广播)multicast(多播) 客户端, l: 本地时钟, s: 对称节点(用于备份), A: 选播服务器, B: 广播服务器, M: 多播服务器, 参见“Automatic Server Discovery“)
  • when – 最后一次同步到现在的时间 (默认单位为秒, “h”表示小时,“d”表示天)
  • poll – 同步的频率:rfc5905建议在 NTPv4 中这个值的范围在 4 (16秒) 至 17 (36小时) 之间(即2的指数次秒),然而观察发现这个值的实际大小在一个小的多的范围内 :64 (26 )秒 至 1024 (210 )秒
  • reach – 一个8位的左移移位寄存器值,用来测试能否和服务器连接,每成功连接一次它的值就会增加,以 8 进制显示
  • delay – 从本地到远程节点或服务器通信的往返时间(毫秒)
  • offset – 主机与远程节点或服务器时间源的时间偏移量,offset 越接近于0,主机和 NTP 服务器的时间越接近(以方均根表示,单位为毫秒)
  • jitter – 与远程节点同步的时间源的平均偏差(多个时间样本中的 offset 的偏差,单位是毫秒),这个数值的绝对值越小,主机的时间就越精确

字段的统计代码

表中第一个字符(统计代码)是状态标识(参见 Peer Status Word),包含 ” “,”x”,”-“,”#”,”+”,”*”,”o”:

  • ” ” – 无状态,表示:
    • 没有远程通信的主机
    • “LOCAL” 即本机
    • (未被使用的)高层级服务器
    • 远程主机使用的这台机器作为同步服务器
  • x” – 已不再使用
  • ” – 已不再使用
  • #” – 良好的远程节点或服务器但是未被使用 (不在按同步距离排序的前六个节点中,作为备用节点使用)
  • +” – 良好的且优先使用的远程节点或服务器(包含在组合算法中)
  • “*” – 当前作为优先主同步对象的远程节点或服务器
  • o” – PPS 节点 (当优先节点是有效时)。实际的系统同步是源于秒脉冲信号(pulse-per-second,PPS),可能通过PPS 时钟驱动或者通过内核接口。

参考 Clock Select Algorithm.

refid

refid 有下面这些状态值

  • 一个IP地址 – 远程节点或服务器的 IP 地址
  • .LOCL. – 本机 (当没有远程节点或服务器可用时)
  • .PPS. – 时间标准中的“Pulse Per Second”(秒脉冲)
  • .IRIG.Inter-Range Instrumentation Group 时间码
  • .ACTS. – 美国 NIST 标准时间 电话调制器
  • .NIST. –美国 NIST 标准时间电话调制器
  • .PTB. – 德国 PTB 时间标准电话调制器
  • .USNO. – 美国 USNO 标准时间 电话调制器
  • .CHU.CHU (HF, Ottawa, ON, Canada) 标准时间无线电接收器
  • .DCFa.DCF77 (LF, Mainflingen, Germany) 标准时间无线电接收器
  • .HBG.HBG (LF Prangins, Switzerland) 标准时间无线电接收器
  • .JJY.JJY (LF Fukushima, Japan) 标准时间无线电接收器
  • .LORC.LORAN-C station (MF) 标准时间无线电接收器,注: 不再可用 (被 eLORAN 废弃)
  • .MSF.MSF (LF, Anthorn, Great Britain) 标准时间无线电接收器
  • .TDF.TDF (MF, Allouis, France)标准时间无线电接收器
  • .WWV.WWV (HF, Ft. Collins, CO, America) 标准时间无线电接收器
  • .WWVB.WWVB (LF, Ft. Collins, CO, America) 标准时间无线电接收器
  • .WWVH.WWVH (HF, Kauai, HI, America) 标准时间无线电接收器
  • .GOES. – 美国静止环境观测卫星;
  • .GPS. – 美国 GPS;
  • .GAL.伽利略定位系统欧洲 GNSS;
  • .ACST. – 选播服务器
  • .AUTH. – 认证错误
  • .AUTO. – Autokey (NTP 的一种认证机制)顺序错误
  • .BCST. – 广播服务器
  • .CRYPT. – Autokey 协议错误
  • .DENY. – 服务器拒绝访问;
  • .INIT. – 关联初始化
  • .MCST. – 多播服务器
  • .RATE. – (轮询) 速率超出限定
  • .TIME. – 关联超时
  • .STEP. – 间隔时长改变,偏移量比危险阈值小(1000ms) 比间隔时间 (125ms)大

操作要点

一个时间服务器只会报告时间信息而不会从客户端更新时间(单向更新),而一个节点可以更新其他同级节点的时间,结合出一个彼此同意的时间(双向更新)。

初次启动时:

除非使用 iburst 选项,客户端通常需要花几分钟来和服务器同步。如果客户端在启动时时间与 NTP 服务器的时间差大于 1000 秒,守护进程会退出并在系统日志中记录,让操作者手动设置时间差小于 1000 秒后再重新启动。如果时间差小于 1000 秒,但是大于 128 秒,会自动矫正间隔,并自动重启守护进程。

当第一次启动时,时间频率文件(通常是 ntp.drift 文件,记录时间偏移)不存在,守护进程进入一个特殊模式来矫正频率。当时钟不符合规范时这会需要 900 秒。当校正完成后,守护进程创建时间频率文件进入普通模式,并分步校正剩余的偏差。

NTP 0 层(Stratum 0 )的设备如原子钟(铯,铷),GPS 时钟或者其他标准时间的无线电时钟为 1 层(Stratum 1)的时间服务器提供时间信号。NTP 只报告UTC 时间(统一协调时,Coordinated Universal Time)。客户端程序使用时区从 UTC 导出本地时间。

NTP 协议是高精度的,使用的精度小于纳秒(2的 -32 次方)。主机的时间精度和其他参数(受硬件和操作系统限制)使用命令 “ntpq -c rl” 查看(参见 rfc1305 通用变量和 rfc5905)。

“ntpq -c rl”输出参数

  • precision 为四舍五入值,且为 2 的幂数。因此精度为 2precision (秒)
  • rootdelay – 与同步网络中主同步服务器的总往返延时。注意这个值可以是正数或者负数,取决于时钟的精度。
  • rootdisp – 相对于同步网络中主同步服务器的偏差(秒)
  • tc – NTP 算法 PLL (phase locked loop,锁相环路) 或 FLL (frequency locked loop,锁频回路) 时间常量
  • mintc – NTP 算法 PLL/FLL 最小时间常亮或“最快响应
  • offset – 由结合算法得出的系统时钟偏移量(毫秒)
  • frequency – 系统时钟频率
  • sys_jitter – 由结合算法得出的系统时钟平均偏差(毫秒)
  • clk_jitter – 硬件时钟平均偏差(毫秒)
  • clk_wander – 硬件时钟偏移(PPM – 百分之一)

Jitter (也叫 timing jitter) 表示短期变化大于10HZ 的频率, wander 表示长期变化大于10HZ 的频率 (Stability 表示系统的频率随时间的变化,和 aging, drift, trends 等是同义词)

操作要点(续)

NTP 软件维护一系列连续更新的频率变化的校正值。对于设置正确的稳定系统,在非拥塞的网络中,现代硬件的 NTP 时钟同步通常与 UTC 标准时间相差在毫秒内。(在千兆 LAN 网络中可以达到何种精度?)

对于 UTC 时间,闰秒 leap second 可以每两年插入一次用于同步地球自传的变化。注意本地时间为夏令时时时间会有一小时的变化。在重同步之前客户端设备会使用独立的 UTC 时间,除非客户端使用了偏移校准。

闰秒发生时会怎样

闰秒发生时,会对当天时间增加或减少一秒。闰秒的调整在 UTC 时间当天的最后一秒。如果增加一秒,UTC 时间会出现 23:59:60。即 23:59:59 到 0:00:00 之间实际上需要 2 秒钟。如果减少一秒,时间会从 23:59:58 跳至 0:00:00 。另见 The Kernel Discipline.

那么… 间隔阈值(step threshold)的真实值是多少: 125ms 还是 128ms? PLL/FLL tc 的单位是什么 (log2 s? ms?)?在非拥塞的千兆 LAN 中时间节点间的精度能达到多少?

感谢 Camilo M 和 Chris B的评论。 欢迎校正错误和更多细节的探讨。

谢谢 Martin

附录

另见

其他

SNTP (Simple Network Time Protocol, RFC 4330,简单网络协议)基本上也是NTP,但是少了一些基于 RFC 1305 实现的 NTP 的一些不再需要的内部算法。

Win32 时间 Windows Time Service 是 SNTP 的非标准实现,没有精度的保证,并假设精度几乎有 1-2 秒的范围。(因为没有系统时间变化校正)

还有一个PTP (IEEE 1588) Precision Time Protocol(精准时间协议)。见维基百科:Precision Time Protocol。软件程序为 PTPd。虫咬的功能是这是一个 LAN 高精度主从同步系统,精度在毫秒级,使用 International Atomic Time (TAI, monotonic,无闰秒)。数据报时间戳需要在网卡中启用。支持 PTP 的网络会对数据报记录时间戳以减少交换机路由器的影响。也可以在不记录时间戳的网络中使用 PTP 但可能应为时间偏差太大而无法同步。因此使用这个需要对网络进行设置。

更老的时间同步协议


via: http://nlug.ml1.co.uk/2012/01/ntpq-p-output/831

作者:Martin L 译者:Liao 校对:wxy

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

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

Linux:Windows和Ubuntu双系统,修复UEFI引导的两种办法

读者在读过我的安装Ubuntu和Windows 8双系统教程以后,碰到的主要的问题是电脑直接启动到Windows 8而没有出现启动Ubuntu的选项。

这里有两种修复EFI启动引导的方法,使Ubuntu可以正常启动

将GRUB2设置为启动引导

1. 启用GRUB引导

在安装时,有些地方可能会出问题。

理论上来说,如果你首先安装Ubuntu,那么你需要关闭快速启动

希望你按照这个指南创建一个UEFI Ubuntu 启动优盘安装正确的UEFI引导程序。

如果你在安装时已经完成了这些事情,那么可能出错的地方就是将GRUB2设置为启动管理器。

可以按照以下几个步骤将GRUB2设置为默认的引导程序:

  1. 登录Windows 8
  2. 转到桌面
  3. 右击开始按钮,选择管理员命令行
  4. 输入 mountvol g: /s (这将你的EFI目录结构映射到G盘)
  5. 输入 cd g:EFI
  6. 当你输入 dir 列出文件夹内容时,你可以看到一个Ubuntu的文件夹
  7. 这里的参数可以是grubx64.efi或者shimx64.efi
  8. 运行下列命令将grub64.efi设置为启动引导程序: bcdedit /set {bootmgr} path EFIubuntugrubx64.efi
  9. 重启你的电脑
  10. 你将会看到一个包含Ubuntu和Windows选项的GRUB菜单
  11. 如果你的电脑仍然直接启动到Windows,重复步骤1到7,但是这次输入: bcdedit /set {bootmgr} path EFIubuntushimx64.efi
  12. 重启你的电脑

这里你做的事情就是登录Windows管理员命令行,将EFI引导区映射到磁盘上,来查看Ubuntu的引导程序是否安装成功,然后选择grubx64.efi或者shimx64.efi作为引导程序。

那么grubx64.efi和shimx64.efi有什么区别呢?在安全启动(serureboot)关闭的情况下,你可以使用grubx64.efi。如果安全启动打开则需要选择shimx64.efi。

在我上面的步骤里面,我建议先试一个,然后再试试另外一个。另外一种方法是选择一个,然后根据你选择的引导程序在BIOS中启用或者禁用安全启动。

2.使用rEFInd引导Ubuntu和Windows双系统

rEFInd引导程序会以图标的方式列出你所有的操作系统。因此,你可以通过点击相应的图标来启动Windows、Ubuntu或者优盘中的操作系统。

点击这里下载rEFInd for Windows 8。

下载和解压以后,按照以下的步骤安装rEFInd。

  1. 返回桌面
  2. 右击开始按钮,选择管理员命令行
  3. 输入 mountvol g: /s (这将你的EFI目录结构映射到G盘)
  4. 进入解压的rEFInd目录。例如: cd c:usersgarydownloadsrefind-bin-0.8.4refind-bin-0.8.4 。 当你输入 dir 命令,你可以看到一个refind目录
  5. 输入如下命令将refind拷贝到EFI引导区 xcopy /E refind g:EFIrefind
  6. 输入如下命令进入refind文件夹 cd g:EFIrefind
  7. 重命名示例配置文件 rename refind.conf-sample refind.conf
  8. 运行如下命令将rEFind设置为引导程序 bcdedit /set {bootmgr} path EFIrefindrefind_x64.efi
  9. 重启你的电脑
  10. 你将会看到一个包含Ubuntu和Windows的图形菜单

这个过程和选择GRUB引导程序十分相似。

简单的说,主要是下载rEFind,解压文件。拷贝文件到EFI引导区,重命名配置文件,然后将rEFind设置为引导程序。

概要

希望这篇文章可以解决有些人在安装Ubuntu和Windows 8.1双系统时出现的问题。如果你仍然有问题,可以通过上面的电邮和我进行交流。


via: http://linux.about.com/od/LinuxNewbieDesktopGuide/tp/3-Ways-To-Fix-The-UEFI-Bootloader-When-Dual-Booting-Windows-And-Ubuntu.htm

作者:Gary Newell 译者:zhouj-sh 校对:wxy

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

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

Linux:使用火焰图分析CPU性能回退问题

你能快速定位CPU性能回退的问题么? 如果你的工作环境非常复杂且变化快速,那么使用现有的工具是来定位这类问题是很具有挑战性的。当你花掉数周时间把根因找到时,代码已经又变更了好几轮,新的性能问题又冒了出来。

幸亏有了CPU火焰图(flame graphs),CPU使用率的问题一般都比较好定位。但要处理性能回退问题,就要在修改前后的火焰图之间,不断切换对比,来找出问题所在,这感觉就是像在太阳系中搜寻冥王星。虽然,这种方法可以解决问题,但我觉得应该会有更好的办法。

所以,下面就隆重介绍红/蓝差分火焰图(red/blue differential flame graphs)

上面是一副交互式SVG格式图片(链接)。图中使用了两种颜色来表示状态,红色表示增长蓝色表示衰减

这张火焰图中各火焰的形状和大小都是和第二次抓取的profile文件对应的CPU火焰图是相同的。(其中,y轴表示栈的深度,x轴表示样本的总数,栈帧的宽度表示了profile文件中该函数出现的比例,最顶层表示正在运行的函数,再往下就是调用它的栈)

在下面这个案例展示了,在系统升级后,一个工作载荷的CPU使用率上升了。 下面是对应的CPU火焰图(SVG格式

通常,在标准的火焰图中栈帧和栈塔的颜色是随机选择的。 而在红/蓝差分火焰图中,使用不同的颜色来表示两个profile文件中的差异部分。

在第二个profile中deflate_slow()函数以及它后续调用的函数运行的次数要比前一次更多,所以在上图中这个栈帧被标为了红色。可以看出问题的原因是ZFS的压缩功能被启用了,而在系统升级前这项功能是关闭的。

这个例子过于简单,我甚至可以不用差分火焰图也能分析出来。但想象一下,如果是在分析一个微小的性能下降,比如说小于5%,而且代码也更加复杂的时候,问题就为那么好处理了。

红/蓝差分火焰图

这个事情我已经讨论了好几年了,最终我自己编写了一个我个人认为有价值的实现。它的工作原理是这样的:

  1. 抓取修改前的堆栈profile1文件
  2. 抓取修改后的堆栈profile2文件
  3. 使用profile2来生成火焰图。(这样栈帧的宽度就是以profile2文件为基准的)
  4. 使用“2 – 1”的差异来对火焰图重新上色。上色的原则是,如果栈帧在profile2中出现出现的次数更多,则标为红色,否则标为蓝色。色彩是根据修改前后的差异来填充的。

这样做的目的是,同时使用了修改前后的profile文件进行对比,在进行功能验证测试或者评估代码修改对性能的影响时,会非常有用。新的火焰图是基于修改后的profile文件生成(所以栈帧的宽度仍然显示了当前的CPU消耗),通过颜色的对比,就可以了解到系统性能差异的原因。

只有对性能产生直接影响的函数才会标注颜色(比如说,正在运行的函数),它所调用的子函数不会重复标注。

生成红/蓝差分火焰图

我已经把一个简单的代码实现推送到github上(见火焰图),其中新增了一个程序脚本,difffolded.pl。为了展示工具是如何工作的,用Linux perf_events 来演示一下操作步骤。(你也可以使用其他profiler)

抓取修改前的profile 1文件:

# perf record -F 99 -a -g -- sleep 30
# perf script > out.stacks1

一段时间后 (或者程序代码修改后), 抓取profile 2文件:

# perf record -F 99 -a -g -- sleep 30
# perf script > out.stacks2

现在将 profile 文件进行折叠(fold), 再生成差分火焰图:

$ git clone --depth 1 http://github.com/brendangregg/FlameGraph
$ cd FlameGraph
$ ./stackcollapse-perf.pl ../out.stacks1 > out.folded1
$ ./stackcollapse-perf.pl ../out.stacks2 > out.folded2
$ ./difffolded.pl out.folded1 out.folded2 | ./flamegraph.pl > diff2.svg

difffolded.p只能对“折叠”过的堆栈profile文件进行操作,折叠操作是由前面的stackcollapse系列脚本完成的。(见链接火焰图)。 脚本共输出3列数据,其中一列代表折叠的调用栈,另两列为修改前后profile文件的统计数据。

func_a;func_b;func_c 31 33
[...]

在上面的例子中”funca()->funcb()->func_c()” 代表调用栈,这个调用栈在profile1文件中共出现了31次,在profile2文件中共出现了33次。然后,使用flamegraph.pl脚本处理这3列数据,会自动生成一张红/蓝差分火焰图。

其他选项

再介绍一些有用的选项:

difffolded.pl -n:这个选项会把两个profile文件中的数据规范化,使其能相互匹配上。如果你不这样做,抓取到所有栈的统计值肯定会不相同,因为抓取的时间和CPU负载都不同。这样的话,看上去要么就是一片红(负载增加),要么就是一片蓝(负载下降)。-n选项对第一个profile文件进行了平衡,这样你就可以得到完整红/蓝图谱。

difffolded.pl -x: 这个选项会把16进制的地址删掉。 profiler时常会无法将地址转换为符号,这样的话栈里就会有16进制地址。如果这个地址在两个profile文件中不同,这两个栈就会认为是不同的栈,而实际上它们是相同的。遇到这样的问题就用-x选项搞定。

flamegraph.pl –negate: 用于颠倒红/蓝配色。 在下面的章节中,会用到这个功能。

不足之处

虽然我的红/蓝差分火焰图很有用,但实际上还是有一个问题:如果一个代码执行路径完全消失了,那么在火焰图中就找不到地方来标注蓝色。你只能看到当前的CPU使用情况,而不知道为什么会变成这样。

一个办法是,将对比顺序颠倒,画一个相反的差分火焰图。例如:

上面的火焰图是以修改前的profile文件为基准,颜色表达了将要发生的情况。右边使用蓝色高亮显示的部分,从中可以看出修改后CPU Idle消耗的CPU时间会变少。(其实,我通常会把cpuidle给过滤掉,使用命令行grep -v cpuidle)

图中把消失的代码也突显了出来(或者应该是说,没有突显),因为修改前并没有使能压缩功能,所以它没有出现在修改前的profile文件了,也就没有了被表为红色的部分。

下面是对应的命令行:

$ ./difffolded.pl out.folded2 out.folded1 | ./flamegraph.pl --negate > diff1.svg

这样,把前面生成diff2.svg一并使用,我们就能得到:

  • diff1.svg: 宽度是以修改前profile文件为基准,颜色表明将要发生的情况
  • diff2.svg: 宽度是以修改后profile文件为基准,颜色表明已经发生的情况

如果是在做功能验证测试,我会同时生成这两张图。

CPI 火焰图

这些脚本开始是被使用在CPI火焰图的分析上。与比较修改前后的profile文件不同,在分析CPI火焰图时,可以分析CPU工作周期与停顿周期的差异变化,这样可以凸显出CPU的工作状态来。

其他的差分火焰图

也有其他人做过类似的工作。Robert Mustacchi在不久前也做了一些尝试,他使用的方法类似于代码检视时的标色风格:只显示了差异的部分,红色表示新增(上升)的代码路径,蓝色表示删除(下降)的代码路径。一个关键的差别是栈帧的宽度只体现了差异的样本数。右边是一个例子。这个是个很好的主意,但在实际使用中会感觉有点奇怪,因为缺失了完整profile文件的上下文作为背景,这张图显得有些难以理解。

Cor-Paul Bezemer也制作了一种差分显示方法flamegraphdiff,他同时将3张火焰图放在同一张图中,修改前后的标准火焰图各一张,下面再补充了一张差分火焰图,但栈帧宽度也是差异的样本数。 上图是一个例子。在差分图中将鼠标移到栈帧上,3张图中同一栈帧都会被高亮显示。这种方法中补充了两张标准的火焰图,因此解决了上下文的问题。

我们3人的差分火焰图,都各有所长。三者可以结合起来使用:Cor-Paul方法中上方的两张图,可以用我的diff1.svg 和 diff2.svg。下方的火焰图可以用Robert的方式。为保持一致性,下方的火焰图可以用我的着色方式:蓝->白->红。

火焰图正在广泛传播中,现在很多公司都在使用它。如果大家知道有其他的实现差分火焰图的方式,我也不会感到惊讶。(请在评论中告诉我)

结论

如果你遇到了性能回退问题,红/蓝差分火焰图是找到根因的最快方式。这种方式抓取了两张普通的火焰图,然后进行对比,并对差异部分进行标色:红色表示上升,蓝色表示下降。 差分火焰图是以当前(“修改后”)的profile文件作为基准,形状和大小都保持不变。因此你通过色彩的差异就能够很直观的找到差异部分,且可以看出为什么会有这样的差异。

差分火焰图可以应用到项目的每日构建中,这样性能回退的问题就可以及时地被发现和修正。


via: http://www.brendangregg.com/blog/2014-11-09/differential-flame-graphs.html

作者:Brendan Gregg 译者:coloka 校对:wxy

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

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

Linux:一些不起眼但非常有用的 Vim 命令

如果我的关于这个话题的最新帖子没有提醒到你的话,那我明确地说,我是一个 Vim 的粉丝。所以在你们中的某些人向我扔石头之前,我先向你们展示一系列“鲜为人知的 Vim 命令”。我的意思是,一些你可能以前没有碰到过的命令,但可能对你来说很有用。作为第二免责声明,我不知道哪些命令是你可能知道的,以及哪些是对你来说有用的。因此这些命令实际上是一些相对少见,但很可能很有用的 Vim 命令。

保存文件并退出

说起来有些惭愧,我也是最近才学到这个命令

:x

和下面的命令是等价的:

:wq

都是保存当前文件并退出。

(译者注:这两个命令实际上并不完全等价,当文件被修改时两个命令时相同的。但如果未被修改,使用 😡 不会更改文件的修改时间,而使用 :wq 会改变文件的修改时间。)

基本计算器

在插入模式下,你可以使用 Ctrl+r 键然后输入 =,再输入一个简单的算式。按 Enter 键,计算结果就会插入到文件中。例如,尝试输入:

Ctrl+r '=2+2' ENTER

然后计算结果“4 ”会被插入到文件中。

查找重复的连续的单词

当你很快地打字时,很有可能会连续输入同一个单词两次,就像 this this。这种错误可能骗过任何一个人,即使是你自己重新阅读一遍也不可避免。幸运的是,有一个简单的正则表达式可以用来预防这个错误。使用搜索命令(默认时 /)然后输入:

\(\<\w\+\>\)\_s*\1

这会显示所有重复的单词。要达到最好的效果,不要忘记把下面的命令:

set hlsearch

放到你的 .vimrc 文件中高亮所有的匹配。

缩写

一个很可能是最令人印象深刻的窍门是你可以在 Vim 中定义缩写,它可以实时地把你输入的东西替换为另外的东西。语法格式如下:

:ab [缩写] [要替换的文字]

一个通用的例子是:

:ab asap as soon as possible

会把你输入的 “asap” 替换为 “as soon as possible”。

在你忘记用 root 方式打开文件时的文件保存

这可能是一个在论坛中一直受欢迎的命令。每当你打开一个你没有写入权限的文件(比如系统配置文件)并做了一些修改,Vim 无法通过普通的 “:w” 命令来保存。

你不需要重新以 root 方式打开文件再进行修改,只需要运行:

:w !sudo tee %

这会直接以 root 方式保存。

实时加密文本

如果你不想让别人看懂你的屏幕上的内容,你可以使用一个内置的选项,通过下面的命令使用 ROT13 来对文本进行编码:

ggVGg?

gg 把光标移动到 Vim 缓冲区的第一行,V 进入可视模式,G 把光标移动到缓冲区的最后一行。因此,ggVG 使可视模式覆盖这个当前缓冲区。最后 g? 使用 ROT13 对整个区域进行编码。

注意它可以被映射到一个最常使用的键。它对字母符号也可以很好地工作。要对它进行撤销,最好的方法就是使用撤销命令:u。

自动补全

这是另外一个令我感到惭愧的功能,但我发现周围很多人并不知道。Vim 默认有自动补全的功能。的确这个功能是很基本的,并且可以通过插件来增强,但它也很有帮助。方法很简单。Vim 尝试通过已经输入的单词来预测单词的结尾。比如当你在同一个文件中第二次输入 “compiler” 时,仅仅输入 “com” 然后保持在插入模式,按 Ctrl+n 键就可以看到 Vim 为你补全了单词。很简单,但也很有用。

比较两个文件的不同

你们中的大多数很可能都知道 vimdiff 命令,它可以使用分离模式打开 Vim 并比较两个文件的不同。语法如下:

$ vimdiff [文件1] [文件2]

但同样的结果也可以通过下面的 Vim 命令来获得:

:diffthis

首先在 Vim 中打开原始文件。然后使用分离模式带来第二个文件:

:vsp [文件2]

最后在第一个缓冲区里输入:

:diffthis

通过 Ctrl+w 来切换缓冲区并再次输入:

:diffthis

这样两个文件中不同的部分就会被高亮。

(译者注:可以直接在一个缓冲区里使用命令 :windo diffthis,而不用输入 :diffthis 两次)

要停止比较,使用:

:diffoff

按时间回退文件

Vim 会记录文件的更改,你很容易可以回退到之前某个时间。该命令是相当直观的。比如:

:earlier 1m

会把文件回退到 1 分钟以前的状态。

注意,你可以使用下面的命令进行相反的转换:

:later

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