理解warden-基本概念及如何做资源隔离限制

长平狐 发布于 2013/11/25 18:34
阅读 1K+
收藏 0

在阅读本文之前,作者假设您先对warden的安装过程有所了解,最好已经在自己的机器上安装好了可以使用的warden。因此,建议先阅读http://kelby.writings.io/articles/21

一,3个概念rootfs container warden  

warden安装后,会生成1个目录 /tmp/warden,在这下面又有3个子目录:cgroup  containers  rootfs

下面先来介绍第1个概念rootfs,也就是对应的/tmp/warden/rootfs

首先,从前文中我们知道 rootfs 的来源:

1.        unshare - run program with some namespaces unshared from parent。有点类似clone(),fork()等

sudo -E unshare -m root/linux/rootfs/setup.sh "/tmp/warden/rootfs"

2.        debootstrap - Bootstrap a basic Debian system

debootstrap –verbose –include "openssh-server,rsync" "lucid" "/tmp/warden/rootfs"  "http://archive.ubuntu.com/ubuntu/"

3.        chroot - run command or interactive shell with special root directory。根目录的切换工作

 chroot "/tmp/warden/rootfs" env -i PATH="/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games"  /bin/bash

4.            chroot 后 apt-get install xxx # 安装软件

用我的话说呐,就是:

  • unshare 脱离父子(组织)关系
  • debootstrap 白手起家,另起炉灶
  • chroot 和 apt-get install 培养自己的势力
debootstrap
源代码: https://github.com/ccoss/debootstrap
基本用法:debootstrap  发行版代号  安装点  镜像
显示安装了哪些软件:
debootstrap --print-debs "lucid" . "http://archive.ubuntu.com/ubuntu/"

至此,我们得到一个与外界隔离(严格意义上来讲,没有绝对隔离)的操作系统。为方便理解,暂切把我们安装warden的本地操作系统称之为“宿主机”,而这个新生的操作系统称之为“基本文件系统”

rootfs大小:304M

bin  boot  dev etc  home  lib lib64  media  mnt  opt proc  root  sbin  selinux  srv sys  tmp  usr  var

从它的产生过程,我们就大概知道它能起到一定的资源隔离的作用,在一定程度上还起到了安全作用。

但从以上所述,我们也不得不承认rootfs是需要占用大量时间和系统资源的。在我们的PaaS环境中,显然是不合理的。由此,我们引入另一个重要概念container

这就意味着……。

container的创建、删除所需要的时间,以及里面所包含的软件是很少的!

container大小:3.2M

换句话,我们可以很容易的创建、删除一个container,而且基本上用不了多少时间。

那么,container包含了什么?

container = src + skeleton + mini rootfs

  • src 指的是warden源代码里的src部分。src编译后会得到几个可执行文件,其中的 iomux-link, iomux-spawn, wsh, wshd则成为container的一部分。
  • skeleton 指的是warden源代码里的root/linux/skeleton部分。在我们‘create container’时,会原封不动的复制过来,成为container的又一部分。
  • mini rootfs 这是我自己提出的概念,为了是与上文提到的rootfs区分开来,并且说明它们之间又有一定联系。

在每个container目录下,都会有一个mnt目录。它从上面我们提到的rootfs而来,根据我们使用的操作系统版本,执行:

  lucid|natty|oneiric
    mount -n -t aufs -o br:tmp/rootfs=rw:$rootfs_path=ro+wh none mnt
    
  precise
    mount -n -t overlayfs -o rw,upperdir=tmp/rootfs,lowerdir=$rootfs_path none mnt

而mini rootfs则是根据操作系统及其版本将读写部分(不包含只读)copy或者mount这个mnt中的 dev, etc, home, sbin, tmp ,成为container的另一部分。用大白话说就是container中的一部分软件从rootfs而来的。

mini rootfs大小:1.1M

dev  etc  home sbin  var

48K ./var/log

52K ./var

960K ./sbin

52K ./etc

16K ./home/vcap

20K ./home

4.0K ./dev/pts

8.0K ./dev

接下来,我们来说说warden

先来看看,我们执行 bin/warden 进入与warden交互部分,有哪些可用命令:

warden> help


copy_in       Copy files/directories into the container.

copy_out      Copy files/directories out of the container.

create        Create a container, optionally pass options.

destroy       Shutdown a container.

echo          Echo a message.

info          Show metadata for a container.

limit_disk    set or get the disk limit for the container.

limit_memory  Set or get the memory limit for the container.

link          Do blocking read on results from a job.

list          List containers.

net_in        Forward port on external interface to container.

net_out       Allow traffic from the container to address.

ping          Ping warden.

run           Short hand for spawn(stream(cmd)) i.e. spawns a command, streams the result.

spawn         Spawns a command inside a container and returns the job id.

stop          Stop all processes inside a container.

stream        Do blocking stream on results from a job.

help          Show help.

从上面加粗的部分,我们基本可以知道:warden就是这些container的管理控制器。通过它,我们可以增、删、查、改container的一些基本信息,还有复制文件进出、网络进出、限制container内存硬盘大小等。

题外话:这些交互命令中,一部分用于warden管理container,另一部分用于container本身的自管理。对于刚接触warden组件的人来说,很容易误导他们混淆warden,container之间的概念。

二,container-资源隔离与限制

首先,来说说container是如何创建的。这是一个复杂的过程,说得不好,大家不要见怪。

我们在交互的命令提示行里输入:

warden> create
handle : 17527e1o5nv

1. 复制skeleton目录(包含了编译后的src。上文提到过container的构成)

/tmp/warden/containers/17527e1o5nv$ ls

bin  destroy.sh  etc  jobs  lib  mnt  net_rate.sh  net.sh  run	setup.sh  snapshot.json  start.sh  stop.sh  tmp

2. 执行自管理命令setup.sh

包含了:

  • container及warden相关网络的设置
$ ifconfig
w-17527e1o5nv-0 Link encap:Ethernet  HWaddr 4a:69:e5:90:4d:7c  
          inet addr:10.254.0.157  Bcast:10.254.0.159  Mask:255.255.255.252
          inet6 addr: fe80::4869:e5ff:fe90:4d7c/64 Scope:Link
          UP BROADCAST RUNNING MULTICAST  MTU:1500  Metric:1
          RX packets:4 errors:0 dropped:0 overruns:0 frame:0
          TX packets:3 errors:0 dropped:0 overruns:0 carrier:0
          collisions:0 txqueuelen:1000 
          RX bytes:328 (328.0 B)  TX bytes:238 (238.0 B)
  • mini rootfs的生成(上文提到过container的构成)
/tmp/warden/containers/17527e1o5nv$ ls tmp/rootfs/

dev  etc  home	sbin  var
  • 一些零散的文件权限设置
  • 默认vcap用户的创建
useradd -mU -u 10000 -s /bin/bash vcap

上面提到container有一个mini rootfs,那么我们可以通过chroot切换进mini rootfs,并且执行一些操作包括创建用户。默认的container会创建一个vcap用户供我们使用,我们执行 bin/warden 进入与warden交互部分,在里面执行的:run, spawn, stream等命令都是以vcap用户的身份来运行的

3. 以hook(钩子)的形式完成其它一些操作

包括但不限于:

  • wshd文件的创建(前文提到过,判断container的死活它起到很大的作用。除此之外,它还有很大作用,详情请看源代码……。)
  • cgroup相关部分的创建

warden有用到cgroup来做资源限制,但出乎我们意料的是:使用得很少!

创建container时默认使用:

# Add new group for every subsystem
for system_path in /tmp/warden/cgroup/*
do
  instance_path=$system_path/instance-$id

  mkdir -p $instance_path

  if [ $(basename $system_path) == "cpuset" ]
  then
    cat $system_path/cpuset.cpus > $instance_path/cpuset.cpus
    cat $system_path/cpuset.mems > $instance_path/cpuset.mems
  fi

  if [ $(basename $system_path) == "devices" ]
  then
    # disallow everything, allow explicitly
    echo a > $instance_path/devices.deny
    # /dev/null
    echo "c 1:3 rw" > $instance_path/devices.allow
    # /dev/zero
    echo "c 1:5 rw" > $instance_path/devices.allow
    # /dev/random
    echo "c 1:8 rw" > $instance_path/devices.allow
    # /dev/urandom
    echo "c 1:9 rw" > $instance_path/devices.allow
    # /dev/tty
    echo "c 5:0 rw" > $instance_path/devices.allow
    # /dev/ptmx
    echo "c 5:2 rw" > $instance_path/devices.allow
    # /dev/pts/*
    echo "c 136:* rw" > $instance_path/devices.allow
  fi

  echo $PID > $instance_path/tasks
done

也就是大小默认都是从cgroup目录树的根继承而来的。在后面我们可以通过limit_memory等命令来管理,但可管理项也很少。

三, 小结

PaaS中资源的限制与隔离是一个很大的话题,容器技术由于对资源的利用率高,创建、删除方便快速,管理容易等特点,在PaaS中起到很大的作用。

还是用warden来做例子吧。

通过前面提到的unshare, debootstrap, chroot等命令我们得到了一个相对隔离的环境,起到了一定的安全作用。

然后又在此基础上使用:setquota, iptables, tc, cgroup等限制硬盘、网络、流量、cpu、内存等资源。

…………

……。

预告:

warden里执行copy_in、copy_out,net_in、net_out,run等命令,大概是什么意思?

warden的整体架构,及源代码阅读建议。

下一篇文章讲解。


本文采用知识共享“署名 3.0 中国大陆”许可协议授权。

联系作者:微博@李真宽


原文链接:http://blog.csdn.net/restkuan/article/details/13630351
加载中
返回顶部
顶部