容器周边开源工具新秀:Sysdig和Calico
伴随着容器技术的普及和落地,许多围绕在容器与 微服务生态圈周边的开源工具也逐渐获得社区的关注和投入。其中有许多工具的名字已经广为人知,比如服务发现 工具Etcd和Consul,日志收集工具组合Elasticsearch、Logstash和Kiba n a,任 务编排工具 Fleet、Kubernetes和Mesos等。这些工具之所以出名, 一方面是由于它们解决了实际生产中遇到的问题,另一方面则是由于项目主导者和参与者的大力宣传。与此相对的,在社区中同样存在着许多十分优秀但出镜率并不高的开源项目。
在今年CoreOS Fest 大会接近尾声的时候,会场上出现了两个值 得关注的话题,演讲者分别展示了 S y sdig和Calico在CoreOS系统中的运用,这两个产品都是与容 器密切相关的开源工具,它们分别补充了现有容器技术在特定功能领域方面的不足。即使 是在CoreOS Fest 已经过去几个月的现在看来,在Sysdig和Calico各自所处 的领域内,它们都依然是无可替代的选择。本文将从安装和使用两个方面分别介绍这两个工具的使用场景。
容器监控器 Sysdig
S ysdig 【1】是S ysdig Cloud 公 司开发的一款开源的系统运行信息和网络流监控软件,早先在网络上的一些文章也对它有所介绍,但几乎都只关注于它对主机的监控和管理功能。而 Sysdig之所以能够出现在CoreOS Fest上,一个重要的原 因,就是它在近期的版本中 【2】将容器的监控纳入了其首位支持的特性。
通 过 Sysdig工 具,用户能够很方便地查看到主机上所有应用程序的 CPU、文 件 I/O、网络访 问状况,这个工具最初的产生就是为了取代传统服务器上的一系列系统检测工具如 strace、tcpdump、htop、iftop、lsof等。它的Logo被设计为一个铲 子的轮廓,寓意着 Sysdig对 系统信息的强大挖掘能力。
新版本的Sysdig在设计上充分运用了容器技术的成果,这主要体现在两个方面。一方面 是 Sysdig提供了 可以快速运行的 Docker容器 镜像,这使得用户能够很方便地在任何安装了 Docker的Linux环 境中快速使用它进行系统数据的收集和分析。另一方面是 S y sd i g专 门提供了容器级别的信息采集命令,支持查看指定容器之间的网络流量、查看特定容器的 CPU使用量等。
对于 大多数的 Linux发行版,都 可以通过下面这个命令直接安装 Sysdig工具。
$ curl -s https://s3.amazonaws.com/download.draios.com/stable/install-sysdig | sudo bash或者通过以下命令 ,用 Docker快速启动一个包含有Sysdig命令的控制台【3】。
$ docker run -i -t --name sysdig --privileged -v /var/run/docker.sock:/host/var/run/docker.sock -v /dev:/host/dev -v /proc:/host/proc:ro -v /boot:/host/boot:ro -v /lib/modules:/host/lib/modules:ro -v /usr:/host/usr:ro sysdig/sysdig
安装完Sysdig后 ,下面介绍一下它的使用。 Sysdig令的默认作用域是 整个主机 ,用户需要通过 “ container.name”参数将作用域限定为指定容器,我 们将重点讨论这种情况的应用场景。
首先运行一交互 模式的 Ubuntu容器 ,命名为 ubuntu01,它将作为被监控的容器
$ docker run -it --rm --name ubuntu01 ubuntu /bin/bash
在接下来 的所有命令中,都会使用“ cont ainer.name=ubuntu01 ”参数,这样就将监控的作用域限定 在这个容器相关的系统资源上。
不加其他参数 的 sysdig命令的作用相 当于 tcpdump, 它将打印出指定容器中所有的网络数据到控制台上,可以使用 -w将捕获的数据写入指定的文件中。保存的 抓包文件除了通过专用软件如 wireshark进行分析,也 可以直接用 sysdig的-r参数读取出来再打印到控制台。
$ sysdig container.name=ubuntu01默认情况下,这个命令的 输出显示的是容器中运行的进程在主机上的实际 PID号。使用-p参数可以改变输 出内容的格式,给命令加上 -pcontainer参数(可简写 为 -pc),就 会额外打印出进程所处的容器名称,以及在容器中的 PID信息。
此外,使用-c参数可以指定监控的操作类型,Sysdig提 供了几十种客供查看和监控的系统数据。包括 CPU使 用率、文件 I/O、网络流量、系统错误、系统日志、性 能瓶颈甚至监控指定用户的行为。例如,在 Sysdig的Shell输入:
$ sysdig -pc -c topprocs_cpu container.name=ubuntu01Sysdig将显示属于ubuntu01容器中的所有进程的CPU使用情况,并以CPU使用率排序。显示内容举例如下:
CPU% Process Host_pid Container_pid container.name
--------------------------------------------------------------------------------
0.00% bash 3997 1 ubuntu01
此时如果在ubuntu01容器中开始“apt-getupdate”的操作,同时在Sysdig的Shell输入:
$ sysdig -pc -c topprocs_net container.name=ubuntu01
就能够 看到容器中所有进程的网络使用情况了。显示内容举例如下:
Bytes Process Host_pid Container_pid container.name
--------------------------------------------------------------------------------
62.58KB http 4491 22 ubuntu01
S y sdi g 还支持一些复杂的数据过 滤操作,例如下面这个命令能够监控 ubuntu01容器中所 有由 c a t进程 发起的“ open”系统调用。
$ sysdig -pc proc.name=cat and evt.type=open and container.name=ubuntu01在Sysdig提供的 命令中,有个十分有趣的“ spy_ users ”功能,可以实时监控指定容器的用户输入内 容。例如,在 Sysdig的Shell输入以下命令:
$ sysdig -pc -c spy_users container.name=ubuntu01
回到ubuntu01容器中,执行一个“ ls —color=auto” 命令,然后就会看到刚刚输入命令实时的回显在了 Sysdig的Shell里面。显示内容举例如下:
3997 11:30:19 root@ubuntu01) ls --color=auto
这些 示例仅仅是展示了 Sysdig能 力的冰山一角,在目前的其他系统监控类工具中,笔者还没有看到像 Sysdig这 样功能如此强大、而又对容器支持这样好的。所以,对于经常使用容器作为产品运行方式的用户,这是一款值得深入了解的“故障排查神器”。
容器级防火墙 Calico
在传 统的服务应用架构设计中,通常会将各种服务模块按照功能类型进行分层,例如 Web应 用服务、核心业务服务、数据库服务等,在层与层之间通过防火墙限定上层服务对下层服务的访问规则。如图 1所示。
图1 传统应用架构通用的分层设计
而对 于容器化的服务场景,许多用户往往倾向于构建 由大量可横向扩展的、独立的小单元组成的微服务式 架构。在这样的架构中,主机节点的个数和 IP地址都 是快速变化的,且在业务服务单元之间存在很多相互调用的情况,也需要进行访问的安全控制,这使得分层防火墙的思路不再可行。
Calic o 【4】是Metaswitch Ne tworks公司提供的 一种容器级路由和防火墙工具,它能够在容器级别上为每个容器实例或 Kubernetes的Pod实例指定访问规则,达到服 务间可控的访问。从原理上说, Calico是通过修 改每个主机节点上的 iptables和路由表规 则实现容器间数据路由和访问控制,并通过 Etcd协调节点配置信 息的。因此 Calico服 务本身和许多分布式服务一样,需要运行在集群的每一个节点上。
Calico的Logo被设计 成一只玩毛线球的斑点猫,仿佛说明它能够将乱如毛线团的容器网络通信整理得规规整整。由于不同的容器调度框架对网络结构和容器调度单元的实现上并不一致, Calico针对许多主流 的应用场景分别进行了定制,例如直接用于 Doc k e r 、直接用于Rkt、作为lib n etwo r k插件、作为Kubernetes插件、作为Mesos插件等场景。与Kubernetes结合使用时,它还 能够替代其他网络规划工具,例如 F l ann e l,直接接管 集群不同节点间的网络通信路由功能。
下面重点介绍Calico直接用于Docker的场景 ,它是 Calico最基本、也最具代表性的一种使用方法。
Calico的安装 可以通过它的控制客户端工具完成,这个命令行工具可以从 Calico的Github仓 库直接下载。下面的命令将其放到系统的 /opt/b i n/目录中,以方便 使用:
$ wget -O /opt/bin/calicoctl https://github.com/projectcalico/calico-docker/releases/download/v0.6.0/calicoctl $ chmod +x /opt/bin/calicoctl
为了演示Calico提供的跨节点路由功能,下面将在 两个主机节点上分别启动 Calico服务。启动的命令 为“ calicoctl node ”,这个命令会在当前节点通过Docker启动 一个部署有 Calico服务的容器,并在 后台保持运行。
$ hostname core-01 $ sudo calicoctl node No IP provided. Using detected IP: 10.0.2.15 Calico node is running with id: … $ docker ps CONTAINER ID IMAGE COMMAND … NAMES d0388bcdca86 calico/node:v0.6.0 "/sbin/my_init" … calico-node
在另一个节点也将Calico服务启动起来。
$ hostname core-02 $ sudo calicoctl node No IP provided. Using detected IP: 10.0.2.16 Calico node is running with id: …
在每个节点上分别运行 两个 Docker容器,并 将网络模 式设置为none,然后通过“calicoctl container add”命 令将容器添加到 C a lico服务的 管理之下,首先是节点 core-01:
$ hostname core-01 $ docker run --net=none --name docker-01-A -tid ubuntu:15.10 $ docker run --net=none --name docker-01-B -tid ubuntu:15.10 $ sudo calicoctl container add docker-01-A 192.168.0.1 $ sudo calicoctl container add docker-01-B 192.168.0.2
然后在节点core-02做 相同操作,注意容器的命名差异。
$ hostname core-02 $ docker run --net=none --name docker-02-A -tid ubuntu:15.10 $ docker run --net=none --name docker-02-B -tid ubuntu:15.10 $ sudo calicoctl container add docker-02-A 192.168.0.3 $ sudo calicoctl container add docker-02-B 192.168.0.4
由 于目前还未在 Calico中添加任何规则,这四个容器 之间是无法 ping通的。接下来 ,先创建两个访问组“ GROUP_A”和“GROUP_01”,这个操作 可以在任意的一个节点上完成。
$ calicoctl profile add GROUP_A Created profile GROUP_A $ calicoctl profile add GROUP_01 Created profile GROUP_01
最后将容器docker-01-A和docker-02 -A 添加到访问组GRO UP_A 中,将容 器 doc ker-01-A 和doc ker-01-B 添加到访问中GROUP_01中。注意“calicoctl container ”命令必须在 运行有指定容器的主机上运行,首先是主机 core-01。
$ hostname core-01 $ calicoctl container docker-01-A profile append GROUP_A Profiles GROUP_A appended $ calicoctl container docker-01-A profile append GROUP_01 Profiles GROUP_01 appended $ calicoctl container docker-01-B profile append GROUP_01 Profiles GROUP_01 appended
然后是主机core-02。
$ hostname core-02 $ calicoctl container docker-02-A profile append GROUP_A Profiles GROUP_A appended
图2 示例配置形成的网络结构
以上配置形成的网络结构如图2所示。若使用ping命令验 证容器两两之间的可访问性,可以 发 现只要同属一个访问组的两个容器之间,不论它们是否处在相同物理节点,相互访问都是成功,反之则无法连接。
- 容器docker-01-A能够同 时和 docker-02 -A 和docker-01-B通信
- 容器docker-01-B和docker-02-A都只能与docker-01-A通信
- 容器docker-02-B与其他任何容器之间都不能通信
上面这个案例很好的解释了“容器级防火墙”的含 义。实际上,对于比较大型的服务集群,手工修改每一个容器的 IP地址 和访问规则是不现实的, Calico内 置了对常见的容器扩展库(例如 libnetwork)和调度 框架(例如 K u bernetes和Mesos)的插件方式支持,
其底层工作原理与上面演示的直接用于Docker的情况基本一致,同时利用这些扩展和框架的功能简化 了访问规则的配置方法。比如将 C a lico与Kubernetes进行集成时,仅需要安装Kubernetes的Calico插件,并 在启动 Kub e rnetes Node 节点 的 kub e let进 程时,添加 network_plugin参数指定Calico作为其网络层的 地址分配工具即可。 Calico将允许用户在创建Pod和Serv i ce描 述文件时,使用 Kubernetes内置的标签功能和特 殊的“ projectcalico.org/policy”属性【5】设 置基于标签过滤数据的防火墙访问规则。这样就很容易将防火墙规则通过 Pod和Ser vice 描述文件的方式固化 起来,从而免去每次手工配置,达到基础实施即代码( Infrastructureas Code )的作用。
小结
任何一 项趋于成熟的技术领域,总是伴随着生态圈周边众多工具的支持。目前,容器技术领域已经形成了围绕集群编排、服务部署、监控管理等方面的一整套体系。组成这个体系的设施,除了 Docker、R k t、Intel Clear这些核心容器组件,还有包括许多的辅 助工具。它们有些作为独当一面的系统工具形式存在,例如 Sysdig,有些则主要以其他核心组件的插件形式存在, 例如 Calico。
这篇文章中介绍的两种容器辅助工具虽然仅仅是这一 庞大生态圈中的 冰山一角,然而它们很好地扩扩展了容器技术在监控和安全方面的能力,在实际生产中的作用不容小觑。
参考资料
【2】准确地说是2015年3月2日发布的0.1.98版本
【3】在比较 特殊的 CoreOS系统中,由于系统目录是只 读的,必须使用这种方法运行 Sysdig
【4】 http://www.projectcalico.org/
【5】https://github.com/projectcalico/calico-docker/blob/master/docs/kubernetes/KubernetesPolicy.md
作者简介
林帆, 生在80后尾巴的IT攻城狮,ThoughtWorks成都办公室CloudOps小 组成员,平时喜欢在业余时间研究 DevOps相关的应用,目前在备考AWS认证和推广Docker相关技术。
(责编/周建丁 zhoujd at csdn dot net)