Monday, December 15, 2014

一张图比较 Docker 和 Git:镜像管理设计理念

Docker 的镜像管理设计中大量借鉴了 Git 的理念。
下面这张图将对两者的核心概念和操作进行比较,有助于大家快速掌握管理 Docker 镜像的正确方式。



转载请注明:http://yeasy.blogspot.com/2014/12/docker-git.html

Sunday, December 07, 2014

OpenStack 网络项目(Neutron)的历史、现状与未来

转载请注明:
http://yeasy.blogspot.com/2014/12/openstack-neutron.html

历史

OpenStack 作为最热门的云计算开源项目,自 2010 年 10 月发布第一个版本 Austin 以来,到 2014 年 10 月 发布 Juno 版本,已经经历了 10 个主要版本。基本稳定为每年 4 月和 10 月各发布一次大的版本更新。
网络功能实现是自第二个版本,即 Bexar 版本引入,最初作为 Nova 项目的一个功能 Nova-Network,仅支持所有用户共享一个底层网络(即所谓的 Flat 网络),后面自 2012 年 9 月发布的 Folsom 版本开始,将网络功能剥离出来,作为一个新的 Quantum 项目。2013 年 10 月发布的 Havana 版本中,项目改名为 Neutron。最新的 2014 年 10 月发布的 Juno 版本中,更引入了分布式路由(DVR)机制,并停止对于 Nova-Network 的支持。
各个关键版本的更新情况如下:
  • Bexar 版本:
    • 引入 Nova-Network
  • Cactus 版本:
    • IPv6 支持
  • Diablo 版本:
    • FlatDHCP 网络下的 HA
  • Essex 版本:
    • 网络功能数据模型开始从 Nova 中剥离,为独立项目做准备
  • Folsom 版本:
    • 正式从 Nova 中剥离,成为新的独立项目 Quantum
    • 多租户隔离的支持
    • 插件式结构支持多种网络后端技术,包括 Open vSwitch、Cisco、Linux Bridge、Nicira NVP、Ryu、NEC
    • 支持 IP 地址的 Overlapping
    • 支持 provider networks
    • 支持基本的 L3 转发、SNAT、Floating IP
  • Grizzly 版本:
    • 多网络节点支持,提高可靠性
    • 安全组
    • 支持 LBaaS
  • Havana 版本:
    • 项目名称从 Quantum 改名为 Neutron
    • 多种物理网络(Linux Bridge,Hyper-V,OVS)类型同时支持
    • 引入 Fwaas、VPNaas
    • 引入 ML2 支持多种类型二层网络实现
  • IceHouse 版本:
    • 一些新的插件
    • 新的 LBaaS 驱动
  • Juno 版本:
    • 初步支持分布式路由(DVR)机制
    • 完整的 IPv6 支持
    • L3 agent 的 HA 支持
    • 一些新的厂商的功能插件
从上面的过程可以可以看出,网络功能从 Folsom 版本开始引进,经历了 Folsom、Grizzly、Havana、IceHouse 四个版本才形成了比较稳定的集中式网络模型。自最新的 Juno 版本开始,才开始采用分布式路由模型。

现状

作为云计算平台的基础之一,网络服务的实现无疑是最能体现技术实力之处。无论是功能全面与否、性能高低、稳定性,每一项想做到满足生产环境的众多要求,都不是那么容易的。这也是现在很多围绕 OpenStack 的创业公司立足之根本。
OpenStack 在宣传上,一直明确表明自身的网络是完全按照软件定义网络(SDN)的理念来设计的。实际上,即使是从网络已经正式成为独立项目的 Folsom 版本开始看,这种说法也是不准确的。这个不明确的设计理念也是目前 OpenStack 在网络项目上收到大量抱怨的重要原因之一。
我们知道,SDN 有几个特点,最基础的一点是以松耦合的方式来处理好控制平面与数据平面的关系。
OpenStack 在设计上的确做到了控制平面与数据平面的分离,所有的数据都存放在数据库,所有的 agent 监听来自 Neutron-Server 的消息,根据这些消息来执行本地的操作。从这个简单的模型上看,Neutron 确实采用了 SDN 的模型。
但是将控制平面与数据平面分离,这仅仅是漫漫长途的第一步。后面的如何设计数据平面,以及如何设计和实现控制平面,才是最为核心的地方。
目前,OpenStack 在这两点上是怎么实现的呢?
2009 年诞生的 OpenvSwitch 项目,提供了足够支持生产环境应用的虚拟交换机实现,可以无缝替换掉 Linux 自身的 bridge,并且还支持一系列额外的功能。看起来,这是个不错的项目。于是,在最初几个版本中,网络就同时支持了 Linux Bridge 和 OpenvSwitch。但是很可惜的是,从一开始,大家在使用 OpenvSwitch 的时候,仅仅是当作一个 Linux Bridge 替代品,在设计新的功能的时候,也局限于 Linux Bridge 所支持的功能。这导致理论上可以充当任意转发组件的 OpenvSwitch,在今天的 Neutron 项目中,大部分时候只是作为一个二层交换机在使用。
那么, 更为重要的控制平面呢?很遗憾,在这点 OpenStack 上的表现差强人意。虽不至于说存在技术漏洞,但至少控制平面缺乏统一的规划,以现代众多控制平面的实现角度去看,只能说是一堆功能放在了一起。为了解决一个部分功能,先用已有技术解决掉,而不管其它功能的实现。这也导致经常出现不同功能模块的冲突。分布式路由机制在 SDN 中是个很自然的事情,但现有的实现先后用了固定的地址映射、ARP 代理、多级的转发表、隧道、L2 Population……并不是说不能用这些技术,但是实现的复杂与紧耦合将给未来的扩展带来更多的困难。并且同时启用路由跟高可靠性、多类型服务链等等功能,现有的设计很难在不提高复杂度的前提下实现。
可能做网络研发出身的人比较难理解为何要这样设计。实际上,换个角度,从 Linux 系统自身管理的来看,这样的设计是有其合理之处的。在没有 SDN 的年代,用 Linux 自身做路由器或防火墙是很常见的事情,通过 IPtables、Linux Bridge 进行各种配置,总能满足局域网内的各种需求。然而,到了云时代,一台物理机动不动就上数十台虚拟机,甚至现在几百成千个的容器,同时是多租户的、有计费需求的、对安全可靠性需求很高的……这里面很多的场景,是之前简单应用 Linux 做服务器或网关时候所难以想象的。即使通过各种技术手段勉强解决了基本的需求,也只能造成今天这样复杂的局面。也可以想象,为何将网络接口接到交换机上这样的操作,在 OpenStack 里面是由 Nova 计算服务来负责的。
在这里也稍微感叹下,如果 OpenStack 当年没有 NASA 项目的代码基础、如果没有选择“生命苦短,我选 Python” 的 Python 语言开发,可能到今天的情况会更加不能让人满意。
当然,使用 OpenStack 除了上面的模式,还有另外一种用法:仅把 Neutron 作为一个框架,让后端的各种插件自己来实现各种网络的服务。这种情况下无疑对于现有代码的依赖最小,也无疑最为广大有自己成熟网络解决方案的厂商所推崇。但是这样的模式,肯定也不是社区能接受的情况。毕竟,仅作为一个壳子转发下各种调用,这失去了作为一个成熟云平台开源项目的意义。

未来

虽然指出了网络项目在设计上的诸多问题,笔者对于 OpenStack 仍然是推崇的。并非出于盲目喜爱开源项目的原因,更多的,自 Linux 项目后,这些年很难见到这么多业界巨头和开源届的紧密合作,一起进行一项解决实际需求的项目。
实际上,思考 Linux 项目之所以能成功的原因,很重要的一点,是 Linus 本人。并非只是因为他在操作系统内核方面的技术境界,不可缺少的一点是 Linus 本人是比较“偏执”的,他认定的事情就轻易不会改变。同时,在很长一段时间里 Linux 系统内核的维护只是由 Linus 说了算。这或许能给今天的 OpenStack 社区一些启发。OpenStack 已经成功了,再宣传赞助基金之巨、参与人数之多其实意义没那么大了。一个真正透彻理解云计算需求和技术的小团队,往往胜过大量自觉或不自觉站在各种立场上的参与者。
从目前的情况推测,在很长一段时间内,网络项目还将沿着现在的路子走下去,一方面是在分布式模型下的新的网络功能实现,以及解决与已有功能的冲突;另一方面仍然是各个厂商以插件的形式支持自己的网络方案。这两种方式发生冲突是迟早的事情,只是希望那个时候 OpenStack 中的网络已经选择了更为高效和可扩展的框架,可以真正地实现“任意替换”的软件定义网络。
附:OpenStack 发布历史(摘自官方 wiki)
Series  Status  Releases    Date
Kilo Under development Due Apr 30, 2015
Juno    Current stable release, security-supported  2014.2   Oct 16, 2014
Icehouse    Security-supported  2014.1   Apr 17, 2014
Havana  EOL 2013.2   Oct 17, 2013
Grizzly EOL 2013.1   Apr 4, 2013
Folsom  EOL 2012.2   Sep 27, 2012
Essex    EOL    2012.1   Apr 5, 2012
Diablo   EOL    2011.3   Sep 22, 2011
Cactus   Deprecated 2011.2   Apr 15, 2011
Bexar    Deprecated 2011.1   Feb 3, 2011
Austin   Deprecated 2010.1   Oct 21, 2010

Wednesday, December 03, 2014

查看 Docker 容器的名字空间

熟悉 Linux 技术的人都知道,容器只是利用名字空间进行隔离的进程而已,Docker 在容器实现上也是利用了 Linux 自身的技术。
有时候,我们需要在宿主机上对容器内进行一些操作,当然,这种绕过 Docker 的操作方式并不推荐。
如果你使用的是比较新的 Docker 版本,会尴尬的发现,直接使用系统命令,会无法访问到容器名字空间。
这里,首先介绍下 ip netns 系列命令。这些命令负责操作系统中的网络名字空间。
首先,我们使用 add 命令创建一个临时的网络名字空间
$ip netns add test
然后,使用 show 命令来查看系统中的网络名字空间,会看到刚创建的 test 名字空间。
$ip netns show
test
另外,一个很有用的命令是 exec,会在对应名字空间内执行命令。例如
$ ip netns exec test ifconfig
使用 del 命令删除刚创建的 test 名字空间。
$ip netns del test
接下来运行一个 Docker 容器,例如
$ docker run -it ubuntu
再次执行 ip netns show命令。很遗憾,这里什么输出都没有。
原因在于,Docker 启动容器后仍然会以进程号创建新的名字空间,但在较新的版本里面,默认删除了系统中的名字空间信息文件。
网络名字空间文件位于 /var/run/netns 下面,比如我们之前创建的 test 名字空间,则在这个目录下有一个 test 文件。诸如 netns 类似的系统命令依靠这些文件才能获得名字空间的信息。
在容器启动后,查看这个目录,会发现什么都没有。
OK,那让我们手动重建它。
首先,使用下面的命令查看容器进程信息,比如这里的1234。
$ docker inspect --format='{{. State.Pid}} ' $container_id
1234
接下来,在 /proc 目录(保存进程的所有相关信息)下,把对应的网络名字空间文件链接到 /var/run/netns 下面
$ ln -s proc/1234/ns/net /var/run/netns/
然后,就可以通过正常的系统命令来查看或访问容器的名字空间了。例如
$ip netns show
1234
$ ip netns exec 1234 ifconfig eth0 172.16.0.10/16

Tuesday, November 25, 2014

支持 Markdown 的网页 slides 工具总结

支持 Markdown 的网页 slides 工具总结

在注重效率的今天,很多人都不喜欢制作 PPT,特别是技术人员。流行的 PPT 制作工具往往需要用户关注太多内容无关的细节。而像 TeX 这样强大的系统又似乎太过于重量级了。
现在越来越流行制作网页格式的 slides,并通过浏览器来播放和发布。 这样做有很多优点:包括跨平台(特别在移动端)、无需特殊软件支持、分享方便、轻量级等。
可惜并不是所有人都精通网页编程技术,即便是最常见的 html 和 css,也常常造成 slides 编写人员的困扰。
一款最理想的 slides 制作工具,应该做到让用户只需要关心内容,其它的包括布局、风格等都交由软件来完成。
随着 HTML5 的流行,现在已经出现了不少这方面的工具,允许用户用 Markdown 等文本标记语言来编写好内容。它们能自动转化为网页形式,添加合适的主题,获得不亚于 PPT 软件的播放效果,甚至更为强大。
在这里介绍几种支持 Markdown 来编写内容的网页 slides 生成工具。
对于 Markdown 不熟悉的读者,推荐先花个五分钟,简单看下 Markdown 的简单语法:http://daringfireball.net/projects/Markdown。顺便说下,本文就是使用 Markdown 编写的。

slidedown

比较早期的一个利用 Markdown 生成网页 slides 的工具。
它功能比较单一,特色是支持语法高亮。后面出现的不少工具都参考了它,功能要更加丰富。
  • 官方网站:https://github.com/nakajima/slidedown
  • 推荐指数:3.5

Remarkjs

remarkjs 是一个简单的基于 Markdown 的网页 slides 生成工具。
remarkjs 生成的网页 slides 支持语法高亮、响应式设计。

Reveal.js

Reveal.js 是基于 Node.js 实现的一个网页 slides 编写框架。
它支持自定义快捷键、嵌套 slides、在网页中直接嵌入 Markdown 语法、导出 pdf、备注和 JavaScript 等强大功能。
它需要用户对 HTML 和 CSS 相关技术比较熟悉一些。支持的很多参数可以直接在模板中进行配置,比如自动翻页、快捷键等。

slidify

slidify 支持 RMarkdown 语言,可以利用 RMarkdown 文件生成效果惊艳的 HTML5 页面,并且支持发布到 GitHub、RPub、DropBox 等,当然这就需要用户熟悉 Markdown,R、LaTex 等多种语言的语法。
R Markdown 语言是 RStudio 支持的一种专门为编写 HTML 5 的 slides 而提出的混合型语言,它可以很好的混合利用 Markdown,R、LaTex 等多种语言来生成十分复杂的页面。

KeyDown

KeyDown 与 Showoff, Slidedown, HTML5 Rocks 等类似,也是专注生成单页的网页 slides。 它基于 Ruby 语言编写,利用 deck.js 转化 Markdown 为网页 slides。支持语法高亮、背景图片、快捷键等。用户要自定义一些风格可以修改 css 文件。
其使用过程十分简单,需要 Ruby、Rubygems 环境。
$ gem install keydown
$ keydown generate my_presentation
然后编写 Markdown 文件,并可以调整 css,之后进行转换。
$ keydown slides

Showoff

Showoff 是一个成熟的网页 slides 生成工具,基于 Ruby 语言编写。它借鉴了 S5 (http://meyerweb.com/eric/tools/s5/)。设计了基于 Markdown 的 DSL,因此,用户只需要懂 Markdown 语法即可。
举一个例子。
!SLIDE

# My Presentation #!

SLIDE bullets incremental transition=fade

# Bullet Points #

* first point
* second point
* third point
所生成的网页 slides 功能十分全面,可以说,能想到的功能都实现了,包括语法高亮、菜单、JavaScript、效果、备注等等。
安装和使用。
$ gem install showoff
$ git clone (showoff-repo)
$ cd (showoff-repo)
$ showoff serve
showoff 唯一的问题可能是它已经有数年没有更新了,不然完全可以打 5 分。

cleaver

cleaver 可以将 Markdown 文档转化为网页格式,基于 Ruby 语言编写,同样支持基于 Markdown 的 DSL。它的整体设计风格也是十分简约,作者还有其它几个很 cute 的小工具。
下面给出一个 clever 支持的文件的例子。
title: Basic Example
author:
  name: Jordan Scales
  twitter: jdan
  url: http://jordanscales.com
output: basic.html
controls: true

--

# Cleaver 101
## A first look at quick HTML presentations

--

### A textual example

Content can be written in **Markdown!** New lines no longer need two angle brackets.

This will be in a separate paragraph

--

### A list of things

* Item 1
* Item B
* Item gamma

No need for multiple templates!
安装和使用:
npm install -g cleaver
cleaver path/to/something.md
它支持多种主题和语法高亮等功能,
  • 官方网站:http://jdan.github.io/cleaver/
  • 项目维护:https://github.com/jdan/cleaver
  • 推荐指数:4.5

Landslide

Landslide 可以利用 markdown、ReST 或 textile 格式文件生成 HTML5 的网页 slides,参考了 Google 的 html5slides。
Landslide 基于 Python 开发,最大的优点就是简洁,从安装到编写,到生成的 slides 风格都十分简洁。整个过程,用户只需要懂 Markdown 语法就可以。
此外,它的配置文件(.cfg)使用了类似 ini 文件的语法,也很容易理解。
安装:
pip install landslide
运行
landslide slides.md
默认会生成 html 格式的 slides。
是不是很简单?
此外,它还支持生成 pdf、快捷键、备注、自定义主题、CSS、JavaScript、注册新的语法宏等高级功能。

其它

HTML5 Rocks 是一个基于 HTML5 的强大的网页 slides 展示系统。它生成的网页可以支持多种风格,但需要用户掌握一定的网页编程技术。
另外,可能有人会推荐 Prezi(http://prezi.com),我也为 Prezi 的动态效果所惊讶。但对于关注内容的人员(特别是工程师)来说,并不十分推荐 Prezi,Prezi 往往更适合于设计或市场营销人员。

Monday, October 27, 2014

云计算时代应用设计十二要素

云计算时代应用设计十二要素

  • 什么样的软件才是可用性和可维护性好的软件?
  • 什么样的代码才能避免后续开发的上手障碍?
  • 什么样的实行才能稳定的运行在分布式的环境中?
Heroku (一家 PaaS 服务提供者,2010 年被 Salesforce 收购)平台创始人 Adam Winggins 提出了推荐的应用十二风格,对我们设计和实现云时代(特别是 PaaS 和 SaaS 上)高效的应用都有很好的参考意义。

代码

每个子系统都用一个代码库管理,使用版本管理,实现独立的部署。

依赖

显式声明依赖,通过环境来严格隔离不同依赖。

配置

在环境变量中保存配置信息,而避免放在源码或配置文件中。

后端服务

后端服务作为可挂载资源来使用,这样系统跟外部依赖尽量松耦合。

生命周期

区分不同声明周期的运行环境,包括创建、发布、部署,各个步骤要相互隔离。

进程

以一个或多个无状态的进程来运行应用,即尽量实现无状态,不要在进程中保存数据。

端口

通过端口绑定来对外提供服务。

并发

通过进程控制来扩展,即以多进程模型进行扩展。

可丢弃性

快速启动,优雅关闭,并尽量鲁棒(随时 kill,随时 crash)。

开发与生产环境的差异性

尽量保持从开发到生产部署环境的相似性。

日志

将日志当作事件流来进行统一的管理和维护(使用 Logstash 等工具)。

管理

将管理作为一次性的系统服务来使用。

Friday, October 17, 2014

Docker 1.3 发布


Docker 1.3 已经正式发布,新的特性包括镜像签名、进程注入、新的创建和运行容器命令、安全选项和 Mac OS 上进行目录共享。特别是针对安全方面的改进,成为本地发布的亮点。
镜像签名
支持对镜像的发布者和镜像文件进行验证。
进程注入
除了通过 nsinit 和 nsenter 的方式查看容器内应用之外,可以使用更方便的 docker exec 命令。这将给容器 debug 带来便利。
例如 
$ docker exec ubuntu_bash -it bash 
会在 ubuntu_bash 容器中运行 bash 命令。
新的创建和运行容器命令 create 和 start
传统的 docker run 会创建容器并运行它,现在可以通过 create 和 start 进行细粒度的控制。 
例如,先创建一个容器(并不处于运行态): 
$ docker create -t -i fedora bash 6d8af538ec541dd581ebc2a24153a28329acb5268abe5ef868c1f1a261221752 
然后,让它运行: 
$ docker start -a -i 6d8af538ec5 
bash-4.2#

安全选项
在运行容器的时候通过 --security-opt 选项来指定系统的安全选项,包括 SELinux 和 AppArmor 的标签等。 例如 
$ docker run --security-opt label:type:svirt_apache -i -t centos \ bash 
这个功能将大量减少使用 --privileged,从而提高使用容器的安全性。
Mac OS X 上的共享目录 
基于 boot2docker,支持在本地 Mac 系统和容器之间直接共享目录 例如, 
$ docker run -v /Users/bob/myapp/src:/src [...] 
将直接挂在本地的/Users/bob/myapp/src 目录到容器内。
更多改进,参考 https://github.com/docker/docker/issues?q=milestone%3A1.3.0。