Linux 容器的使用
Linux 容器的使用
Linux 容器在 v2.6.29版本之后就加入到内核之中了, 之前虽然也听说过, 但一直没有太留心, 一直使用 KVM 来创建虚拟机.
直至最近 Docker 大出风头, 才开始关注. 想了解一下 Linux 容器究竟是什么? 与现有虚拟机技术(Xen, KVM等)有什么区别?
Linux 容器技术出现的很早, 其实也是一直虚拟化技术, 但似乎一直没有 Xen, KVM 这些来的出名.
同时, 在实现原理上, 和Xen, KVM之类的也是有很大区别的.
下面简单说明下目前4类虚拟技术的区别: (下面说明中, VM:虚拟机, HOST:主机, 即安装虚拟机的机器)
传统的虚拟化技术 (VirtualBox, VMware)
通过在Linux上安装虚拟化软件, 然后通过虚拟化软件来安装虚拟机系统, 大致结构如下:VM1 VM2 VM3 ... ... VirtualBox or VMWare or ... Linux Kernel 硬件 VM是由虚拟化软件(VirtualBox, VMWare…)来管理的, Linux Kernel不能直接管理到各个VM.
Xen (半虚拟化)
Xen是Linux上历史比较长的虚拟化技术, 它的虚拟化结构大致如下:Linux Kernel VM1 VM2 VM3 ... ... Xen 硬件 Xen的虚拟化原理是在 Linux Kernel和硬件之间加入一层 Xen代码, 有Xen来管理Linux Kernel和其它的VM.
KVM (最新的虚拟化技术)
相比其它的虚拟化技术, KVM是比较新的, 它需要CPU的支持. 它的虚拟化结构大致如下:VM1 VM2 VM3 ... ... KVM (由内核管理) Linux Kernel 硬件 这个结构和传统的虚拟化技术很类似, 有一点不同的是, KVM和Linux Kernel是紧密结合的,
所以Linux Kernel能够更好的管理 VMs, VM的性能会比传统的虚拟化技术更好.Linux 容器 (LXC - linux container)
LXC 是非常轻量级的, 它将 VM 的进程也伪装成 HOST 的进程. 大致的结构如下:p1(HOST), p2(VM), p3(VM), p4(HOST)...... Linux Kernel 硬件 那么, 对于某些系统进程, PID是固定的, 比如 init进程的PID=1, VM中的 init进程的PID是如何处理的呢?
原来, VM的 init进程的PID在 HOST的进程表中会显示成其它PID(>1).从上面可以看出, LXC这种虚拟化, VM的进程就像HOST的进程一样运行, 管理, 所以创建和销毁都是非常快速的.
注: 参考 http://veck.logdown.com/posts/200566-compare-of-kvm-and-lxc
Linux 容器相关的2个重要概念
Linux容器功能是基于 cgroups 和 Namespace 来实现的. 所以要了解 Linux 容器必须先了解 cgroup 和 Namespace.
cgroups
cgroups 是将任意进程进行分组化管理的 Linux 内核功能.
通过cgroups可以有效的隔离各类进程, 同时还可以控制进程的资源占用(CPU, 内存等等)情况.
使用示例: (debian v7.6 x86_64)
mount -t tmpfs cgroup_root /sys/fs/cgroup
mkdir /sys/fs/cgroup/test
mount -t cgroup -ocpuset test /sys/fs/cgroup/test
此时, test目录就是一个 cgroup, 这里 -o 指定了 cpuset, cpuset是Linux中既定的一种cgroup, 后面有时间重新写博客详细介绍.
test 目录有cgroup必须的各个文件
cd /sys/fs/cgroup/test
ls -l
total 0
-rw-r--r-- 1 root root 0 Aug 14 14:34 cgroup.clone_children
--w--w--w- 1 root root 0 Aug 14 14:34 cgroup.event_control
-rw-r--r-- 1 root root 0 Aug 14 14:34 cgroup.procs
-rw-r--r-- 1 root root 0 Aug 14 14:34 cpuset.cpu_exclusive
-rw-r--r-- 1 root root 0 Aug 14 14:34 cpuset.cpus
-rw-r--r-- 1 root root 0 Aug 14 14:34 cpuset.mem_exclusive
-rw-r--r-- 1 root root 0 Aug 14 14:34 cpuset.mem_hardwall
-rw-r--r-- 1 root root 0 Aug 14 14:34 cpuset.memory_migrate
-r--r--r-- 1 root root 0 Aug 14 14:34 cpuset.memory_pressure
-rw-r--r-- 1 root root 0 Aug 14 14:34 cpuset.memory_pressure_enabled
-rw-r--r-- 1 root root 0 Aug 14 14:34 cpuset.memory_spread_page
-rw-r--r-- 1 root root 0 Aug 14 14:34 cpuset.memory_spread_slab
-rw-r--r-- 1 root root 0 Aug 14 14:34 cpuset.mems
-rw-r--r-- 1 root root 0 Aug 14 14:34 cpuset.sched_load_balance
-rw-r--r-- 1 root root 0 Aug 14 14:34 cpuset.sched_relax_domain_level
-rw-r--r-- 1 root root 0 Aug 14 14:34 notify_on_release
-rw-r--r-- 1 root root 0 Aug 14 14:34 release_agent
-rw-r--r-- 1 root root 0 Aug 14 14:34 tasks
其中部分文件介绍.
文件名 | R/W | 用途 |
---|---|---|
release_agent | RW | 删除分组时执行的命令. 这个文件只存在于根分组 |
notify_on_release | RW | 设置是否执行 release\_agent. 为1时执行 |
tasks | RW | 属于分组的线程 TID 列表 |
cgroup.procs | R | 属于分组的进程 PID 列表. 仅包括多线程进程的线程leader的TID, 这点与 tasks 不同 |
cgroup.event_control | RW | 监视状态变化的分组删除事件的配置文件 |
在cgroup中还可以建立子cgroup, 建立的方法很简单, 只要创建文件夹即可.
cd /sys/fs/cgroup/test
mkdir test-child
ls -l test-child # 创建了文件夹之后, 自动生成cgroup需要的文件
total 0
-rw-r--r-- 1 root root 0 Aug 14 15:10 cgroup.clone_children
--w--w--w- 1 root root 0 Aug 14 15:10 cgroup.event_control
-rw-r--r-- 1 root root 0 Aug 14 15:10 cgroup.procs
-rw-r--r-- 1 root root 0 Aug 14 15:10 cpuset.cpu_exclusive
-rw-r--r-- 1 root root 0 Aug 14 15:10 cpuset.cpus
-rw-r--r-- 1 root root 0 Aug 14 15:10 cpuset.mem_exclusive
-rw-r--r-- 1 root root 0 Aug 14 15:10 cpuset.mem_hardwall
-rw-r--r-- 1 root root 0 Aug 14 15:10 cpuset.memory_migrate
-r--r--r-- 1 root root 0 Aug 14 15:10 cpuset.memory_pressure
-rw-r--r-- 1 root root 0 Aug 14 15:10 cpuset.memory_spread_page
-rw-r--r-- 1 root root 0 Aug 14 15:10 cpuset.memory_spread_slab
-rw-r--r-- 1 root root 0 Aug 14 15:10 cpuset.mems
-rw-r--r-- 1 root root 0 Aug 14 15:10 cpuset.sched_load_balance
-rw-r--r-- 1 root root 0 Aug 14 15:10 cpuset.sched_relax_domain_level
-rw-r--r-- 1 root root 0 Aug 14 15:10 notify_on_release
-rw-r--r-- 1 root root 0 Aug 14 15:10 tasks
注意, 删除子cgroup的时候, 要用 rmdir 来删除文件夹, 用 rm -rf 的方法无法删除
cd /sys/fs/cgroup/test
rmdir test-child
注: 参考内核文档 Documentation/cgroups/cgroups.txt
Namespace (命名空间)
使用Namespace, 可以让每个进程组有独立的PID, IPC和网络空间.
Namespace的生效主要是通过 clone系统调用来实现的.
clone系统调用的第3个参数flags就是通过设置Namespace来划分资源的.
参数种类如下:
名称 | 说明 |
---|---|
CLONE_NEWIPC | 划分IPC(进程间通信)命名空间, 信号量(semaphore), 共享内存, 消息队列等进程间通信用的资源 |
CLONE_NEWNET | 划分网络命名空间. 分配网络接口 |
CLONE_NEWNS | 划分挂载的命名空间. 与chroot同样分配新的根文件系统 |
CLONE_NEWPID | 划分 PID 命名空间. 分配新的进程ID空间 |
CLONE_NEWUTS | 划分 UTS(Universal Time sharing System)命名空间. 分配新的 UTS 空间 |
Linux 容器的使用方法 (以下命令基于 debian v7.5)
安装 LXC
apt-get install lxc
lxc-checkconfig # 安装完成后, 用这个命令检查系统是否可以使用 lxc
# 我的debian系统上有个 missing
Cgroup namespace: CONFIG_CGROUP_NSmissing
# 对于这个missing, 可能是由于系统中没有挂载cgroup导致的, 挂载一个cgroup即可
mount -t cgroup cgroup /mnt/cgroup
创建容器
从现有模板创建容器, 比较慢, 需要下载# 创建一个 debian 系统
lxc-create -n test -t debian
这样创建的容器默认在 /var/lib/lxc/test 中, 为了将容器创建在我们指定的位置, 可以写个简单的配置文件
lxc.conf, 里面只需要一句lxc.rootfs = /home/lxc/test
然后,
lxc-create -n test -t debian -f /path/to/lxc.conf
这样, 就把容器创建在了 /home/lxc/test 中了, /var/lib/lxc/test 中只有一个 config文件(这个config文件可以作为 lxc-create 命令 -f 参数对应配置文件的参考)
启动容器
启动后就进行入了虚拟机的控制台了. (果然像传说一样, 几秒就启动完成了 _)lxc-start -n test
停止容器
在主机中输入停止的命令.lxc-stop -n test
销毁容器
销毁之前, 可以通过 lxc-ls 来查看有几个容器lxc-ls
test
lxc-destroy -n test
lxc-ls
注: 参考URL - http://obdnmagazine.blogspot.com/2013/07/tested-lxc-080-rc1-debian-wheezyax3a6.html
容器示例 - 配置python uliweb 开发环境
尝试在容器配置一次开发环境, 然后通过复制容器, 形成多个虚拟机.
# 主机中
root@debian-113:~# uliweb # 主机中没有安装uliweb 软件包
-bash: uliweb: command not found
root@debian-113:~# lxc-start -n test
# 虚拟机登录界面, 输入用户名和密码
# 虚拟机中
root@test:~# apt-get install python
root@test:~# apt-get install python-pip
root@test:~# pip install Uliweb
root@test:~# uliweb --version
Uliweb version is 0.3.1
主机中设置网桥, 虚拟机用桥接方式上网, 确保每个虚拟机有独立的IP
# 主机中
root@debian-113:~# lxc-stop -n test
root@debian-113:~# apt-cache search bridge-utils
root@debian-113:~# brctl addbr br0
# 配置主机的网桥
root@debian-113:/var/lib/lxc/test# cat /etc/network/interfaces
# This file describes the network interfaces available on your system
# and how to activate them. For more information, see interfaces(5).
# The loopback network interface
auto lo
#auto eth0
iface lo inet loopback
# 追加的网桥配置
auto br0
iface br0 inet static
address 192.168.1.113
netmask 255.255.255.0
gateway 192.168.1.1
bridge_ports eth0
bridge_stp on
bridge_fd 0
root@debian-113:/var/lib/lxc/test# /etc/init.d/networking restart
配置容器的网络(也是在主机中修改容器的配置文件)
root@debian-113:/var/lib/lxc/test# cat /var/lib/lxc/test/config
... ... (很多默认生成的配置)
# network <-- 这个 network 相关的是要追加的
lxc.network.type = veth
lxc.network.flags = up
lxc.network.link = br0
lxc.network.name = eth0
启动Linux容器, 进入虚拟机
root@debian-113:/var/lib/lxc/test# lxc-start -n test
# 登录进入虚拟机, 确认虚拟机的IP
root@test:~# cat /etc/network/interfaces <-- 默认是自动获取IP
auto lo
iface lo inet loopback
auto eth0
iface eth0 inet dhcp
root@test:~# ifconfig <-- 我的机器自动分配的 192.168.1.167
# 创建一个简单的uliweb工程
root@test:~# cd /home/
root@test:/home# mkdir CM-web
root@test:/home# cd CM-web/
root@test:/home/CM-web# uliweb makeproject test
root@test:/home/CM-web# cd test/
root@test:/home/CM-web/test# uliweb makeapp first_app
root@test:/home/CM-web/test# uliweb runserver -h 0.0.0.0
启动Web服务后, 就可以在主机的浏览器中 通过 http://192.168.1.167:8000/ 来访问虚拟机中的web服务了.
最后, 复制一个新的容器, 也就是再重新生成一个上面的 python uliweb 开发环境
# 在主机中
root@debian-113:~# cd /var/lib/lxc
root@debian-113:/var/lib/lxc# cp -r test test2
# 修改 test2/config 如下
lxc.utsname = test2 <-- 修改名称
xc.rootfs = /home/lxc/test2 <-- 修改 rootfs位置
... ... <-- 其它部分不用修改, 和 test 一样就行
root@debian-113:/var/lib/lxc# cd /home/lxc/
root@debian-113:/home/lxc# cp -r test test2 <-- 重新复制一份 rootfs
root@debian-113:/home/lxc# lxc-start -n test2 <-- 启动 test2 虚拟机, 其中环境和 test一样, IP会不一样, 自动获取的
# 进入 test2 虚拟机中, 可以直接启动之前的 uliweb 测试工程, 也可以从主机中访问其web服务.
Linux 容器的使用的更多相关文章
- Linux 容器技术史话:从 chroot 到未来
Linux 容器是一个在单一 Linux 主机上提供多个隔离的 Linux 环境的操作系统级虚拟技术.不像虚拟机(VM),容器并不需要运行专用的访客(guest)操作系统.容器们共享宿主机的(host ...
- Docker —— 用于统一开发和部署的轻量级 Linux 容器【转】
转自:http://www.oschina.net/translate/docker-lightweight-linux-containers-consistent-development-and-d ...
- 浅谈Linux容器和镜像签名
导读 从根本上说,几乎所有的主要软件,即使是开源软件,都是在基于镜像的容器技术出现之前设计的.这意味着把软件放到容器中相当于是一次平台移植.这也意味着一些程序可以很容易就迁移,而另一些就更困难. 我大 ...
- 通过 Linux 容器进行虚拟化
简单介绍 Linux 容器是一种轻量级"虚拟化"方法,用于在单个控制主机上同一时候执行多个虚拟装置(容器).还有一个可用来描写叙述 Linux 容器所执行的操作的术语是" ...
- Linux 容器 vs 虚拟机 —— 谁更胜一筹
自从Linux上的容器变得流行以来,了解Linux容器和虚拟机之间的区别变得更加棘手.本文将向您提供详细信息,以了解Linux容器和虚拟机之间的差异. Linux容器vs虚拟机 – 应用程序与操作系统 ...
- [Linux容器]当我们谈容器的时候,我们在谈什么
Docker在当下很火,那么,当我们谈Docker,谈容器的时候,我们在谈什么? 或者说,你对Docker,对容器了解吗?容器,到底是怎么一回事儿? 这篇文章着重来讲一下Linux容器,为什么强调Li ...
- 精《Linux内核精髓:精通Linux内核必会的75个绝技》一HACK #7 Cgroup、Namespace、Linux容器
HACK #7 Cgroup.Namespace.Linux容器 本节将介绍Cgroup与Namespace以及通过这两个功能实现的容器功能.CgroupCgroup(control group)是将 ...
- 五分钟搞定Linux容器
[TechTarget中国原创] Linux容器针对特定工作负载提供了全新的灵活性与可能性.存在很多解决方案,但是没有一个解决方案能够像systemd容器那样进行快速部署.给我五分钟,本文将介绍如何使 ...
- Windows上的Linux容器
翻译自:https://docs.microsoft.com/en-us/virtualization/windowscontainers/deploy-containers/linux-contai ...
随机推荐
- openresty(nginx)、lua、drizzle调研
一.概述: 1.研究目标:nginx中使用lua脚本,及nginx直接访问mysql,redis 2.需要安装的内容: openresty,mysql,redis 3.OpenResty (也称为 n ...
- multiprocessing module in python(转)
序.multiprocessing python中的多线程其实并不是真正的多线程,如果想要充分地使用多核CPU的资源,在python中大部分情况需要使用多进程.Python提供了非常好用的多进程包mu ...
- log4j日志优先级导致的不输出日志
在sae部署微信代码的时候,发现它的默认日志很不友好,看起来很费劲,详细看了一下说明发现它可以根据log4j的输出级别而分类输出,就拖了一个log4j的xml文件扔进项目代码,然后部署运行,发现没有日 ...
- Load xlsx in a folder to RDBMS table with Talend
Step 1 . Use tFileList component to get the file list. And set proper property. Step 2. Use tFileInp ...
- [ZZ]Sign Up for the First-Ever Appium Roadshow on August 20th in New York City
http://sauceio.com/index.php/2014/07/appium-roadshow-nyc/?utm_source=feedly&utm_reader=feedly&am ...
- notepad++下的字体设置
设置 - 语言格式设置 中
- JavaWeb学习之Servlet(四)----ServletConfig获取配置信息、ServletContext的应用
[声明] 欢迎转载,但请保留文章原始出处→_→ 文章来源:http://www.cnblogs.com/smyhvae/p/4140877.html [正文] 一.ServletConfig:代表当前 ...
- java10-3 equals方法
public boolean equals(Object obj):指示其他某个对象是否与此对象“相等”. 该方法,默认情况下比较的是地址值.但是,如果只是比较地址值的话,一般来说意义不大,所以要 ...
- MAC在Finder栏显示所浏览文件夹路径的方法
我们在使用MAC时,Finder栏默认只显示当前浏览的文件夹名称,而没有显示访问路径,这个问题该怎么解决呢? 操作步骤: 打开“终端”(应用程序->实用工具),输入以下两条命令: default ...
- jQuery Ajax 操作函数及deferred对象
jQuery Ajax 操作函数 jQuery 库拥有完整的 Ajax 兼容套件.其中的函数和方法允许我们在不刷新浏览器的情况下从服务器加载数据. 函数 描述 jQuery.ajax() 执行异步 H ...