Linux Namespace (實例隔離)
The purpose of each namespace is to wrap a particular global system resource in an abstraction that makes it appear to the processes within the namespace that they have their own isolated instance of the global resource.
每個用戶實例之間相互隔離绳匀,互不影響。一般的硬件虛擬化方法給出的方法是VM呻疹,而LXC給出的方法是 container几于,更細一點講就是 kernel namespace蕊苗。其中pid、net沿彭、ipc朽砰、mnt、uts喉刘、user等 namespace 將 container 的進程瞧柔、網(wǎng)絡、消息睦裳、文件系統(tǒng)造锅、UTS(“UNIX Time-sharing System”)和用戶空間隔離開。
-
pid namespace
不同用戶的進程就是通過 pid namespace 隔離開的廉邑,且不同 namespace 中可以有相同 pid哥蔚。所有的 LXC 進程在 docker 中的父進程為 docker 進程倒谷,每個lxc進程具有不同的 namespace。同時由于允許嵌套糙箍,因此可以很方便的實現(xiàn) Docker in Docker恨锚。
-
net namespace
有了 pid namespace, 每個 namespace 中的 pid 能夠相互隔離,但是網(wǎng)絡端口還是共享 host 的端口倍靡。網(wǎng)絡隔離是通過 net namespace 實現(xiàn)的猴伶, 每個 net namespace 有獨立的 network devices, IP addresses, IP routing tables, /proc/net 目錄。這樣每個 container 的網(wǎng)絡就能隔離開來塌西。LXC 在此基礎上有5種網(wǎng)絡類型他挎,docker 默認采用 veth 的方式將 container 中的虛擬網(wǎng)卡同 host上的一個 docker bridge—docker0 連接在一起。
-
mnt namespace
類似chroot捡需,將一個進程放到一個特定的目錄執(zhí)行办桨。mnt namespace允許不同namespace的進程看到的文件結構不同,這樣每個 namespace 中的進程所看到的文件目錄就被隔離開了站辉。同chroot不同呢撞,每個namespace中的container在/proc/mounts`的信息只包含所在namespace的mount point。
-
uts namespace
UTS("UNIX Time-sharing System") namespace 允許每個 container 擁有獨立的 hostname 和 domain name, 使其在網(wǎng)絡上可以被視作一個獨立的節(jié)點而非Host上的一個進程饰剥。
-
user namespace
每個 container 可以有不同的 user 和 group id, 也就是說可以以 container 內(nèi)部的用戶在 container 內(nèi)部執(zhí)行程序而非 Host 上的用戶殊霞。
有了以上6種 namespace 從進程、網(wǎng)絡汰蓉、IPC绷蹲、文件系統(tǒng)、UTS和用戶角度的隔離顾孽,一個 container 就可以對外展現(xiàn)出一個獨立計算機的能力祝钢,并且不同container從OS層面實現(xiàn)了隔離。 然而不同 namespace 之間資源還是相互競爭的若厚,仍然需要類似 ulimit 來管理每個 container 所能使用的資源——LXC 采用的是 cgroup拦英。
cgroup(資源配額)
cgroups 實現(xiàn)了對資源的配額和度量。cgroups 的使用非常簡單测秸,提供類似文件的接口疤估,在 /cgroup目錄下新建一個文件夾即可新建一個 group,在此文件夾中新建task文件乞封,并將pid寫入該文件做裙,即可實現(xiàn)對該進程的資源控制。具體的資源配置選項可以在該文件夾中新建子subsystem肃晚,{子系統(tǒng)前綴}.{資源項} 是典型的配置方法锚贱, 如memory.usage_in_bytes就定義了該group 在 subsystem memory 中的一個內(nèi)存限制選項。
我們主要關心 cgroups 可以限制哪些資源关串,即有哪些 subsystem 是我們關心的拧廊。
-
cpu
在cgroup中监徘,并不能像硬件虛擬化方案一樣能夠定義CPU能力,但是能夠定義CPU輪轉的優(yōu)先級吧碾,因此具有較高CPU優(yōu)先級的進程會更可能得到CPU運算凰盔。 通過將參數(shù)寫入cpu.shares,即可定義改cgroup的CPU優(yōu)先級 - 這里是一個相對權重,而非絕對值倦春。當然在cpu這個subsystem中還有其他可配置項户敬,手冊中有詳細說明。
-
cpuacct
產(chǎn)生cgroup任務的cpu資源報告
-
cpuset
cpusets 定義了有幾個CPU可以被這個group使用睁本,或者哪幾個CPU可以供這個group使用尿庐。在某些場景下,單CPU綁定可以防止多核間緩存切換呢堰,從而提高效率
-
memory
設置每個cgroup的內(nèi)存限制以及產(chǎn)生內(nèi)存資源報告
-
blkio
block IO相關的統(tǒng)計和限制抄瑟,byte/operation統(tǒng)計和限制(IOPS等),讀寫速度限制等枉疼,但是這里主要統(tǒng)計的都是同步IO
-
net_cls
標記每個網(wǎng)絡包以供cgroup方便使用
-
devices
允許或拒絕cgroup任務對設備的訪問
-
freezer
暫停和恢復cgroup任務
LXC(LinuX Container)
LXC (LinuX Container) is an operating system-level virtualization method for running multiple isolated Linux systems (containers) on a single control host. This is accomplished through kernel level isolation.
借助于namespace的隔離機制和 cgroup 限額功能皮假,LXC 提供了一套統(tǒng)一的 API 和工具來建立和管理 container,LXC 利用了如下 kernel 的特性:
- Kernel namespaces (ipc, uts, mount, pid, network and user)
- Apparmor and SELinux profiles (security)
- Seccomp policies
- Chroots (using pivot_root)
- Kernel capabilities
- Control groups (cgroups)
LXC 旨在提供一個共享 kernel 的 OS 級虛擬化方法骂维,在執(zhí)行時不用重復加載Kernel惹资,且 container 的 kernel 與 host共享,因此可以大大加快 container 的 啟動過程席舍,并顯著減少內(nèi)存消耗布轿。
這篇ctackoverflow上的問題和答案很好地詮釋了 Docker 和 LXC 的區(qū)別哮笆,能夠讓你更好的了解什么是 Docker来颤, 簡單翻譯下就是以下幾點:
Portable deployment across machines
Docker提供了一種可移植的配置標準化機制,允許你一致性地在不同的機器上運行同一個Container稠肘;而LXC本身可能因為不同機器的不同配置而無法方便地移植運行福铅;
Application-centric
Docker以App為中心,為應用的部署做了很多優(yōu)化项阴,而LXC的幫助腳本主要是聚焦于如何機器啟動地更快和耗更少的內(nèi)存滑黔;
Automatic build
Docker為App提供了一種自動化構建機制(Dockerfile),包括打包环揽,基礎設施依賴管理和安裝等等略荡;
Versioning
Docker提供了一種類似git的Container版本化的機制,允許你對你創(chuàng)建過的容器進行版本管理歉胶,依靠這種機制汛兜,你還可以下載別人創(chuàng)建的Container,甚至像git那樣進行合并通今;
Component reuse
Docker Container是可重用的粥谬,依賴于版本化機制肛根,你很容易重用別人的Container(叫Image),作為基礎版本進行擴展漏策;
Sharing
Docker Container是可共享的派哲,有點類似github一樣,Docker有自己的INDEX掺喻,你可以創(chuàng)建自己的Docker用戶并上傳和下載Docker Image芭届;
Tool ecosystem
Docker提供了很多的工具鏈,形成了一個生態(tài)系統(tǒng)感耙;這些工具的目標是自動化喉脖、個性化和集成化,包括對PAAS平臺的支持等抑月。
注:stackoverflow(http://stackoverflow.com/questions/17989306/what-does-docker-add-to-lxc-tools-the-userspace-lxc-tools)
AUFS
Docker 對container 的使用基本是建立在 LXC 基礎之上的树叽,然而 LXC 存在的問題是難以移動——難以通過標準化的模板制作、重建谦絮、復制和移動 container题诵。在以VM為基礎的虛擬化手段中,有 image 和 snapshot 可以用于VM的復制层皱、重建以及移動的功能性锭。想要通過 container 來實現(xiàn)快速的大規(guī)模部署和更新, 這些功能不可或缺。Docker 正是利用AUFS來實現(xiàn)對container 的快速更新——在 docker0.7中引入了 storage driver, 支持 AUFS, VFS, device mapper, 也為 BTRFS 以及 ZFS 引入提供了可能叫胖。
AUFS (Another Union FS) 是一種 Union FS草冈,簡單來說就是支持將不同目錄掛載到同一個虛擬文件系統(tǒng)下(unite several directories into a single virtual filesystem)的文件系統(tǒng), 更進一步的理解, AUFS 支持為每一個成員目錄(類似Git Branch)設定readonly、readwrite 和 whiteout-able 權限, 同時 AUFS 里有一個類似分層的概念, 對 readonly 權限的 branch 可以邏輯上進行修改(增量地, 不影響 readonly 部分的)瓮增。通常 Union FS 有兩個用途, 一方面可以實現(xiàn)不借助 LVM怎棱、RAID 將多個disk掛到同一個目錄下, 另一個更常用的就是將一個 readonly 的 branch 和一個 writeable 的 branch 聯(lián)合在一起,Live CD正是基于此方法可以允許在 OS image 不變的基礎上允許用戶在其上進行一些寫操作绷跑。Docker 在 AUFS 上構建的 container image 也正是如此拳恋,接下來我們從啟動 container 中的 linux 為例來介紹 docker 對AUFS特性的運用。
典型的啟動Linux運行需要兩個FS: bootfs + rootfs:
bootfs(boot file system)主要包含 bootloader 和 kernel, bootloader主要是引導加載kernel, 當boot 成功后 kernel 被加載到內(nèi)存中后 bootfs就被umount了砸捏。rootfs (root file system) 包含的就是典型 Linux 系統(tǒng)中的 /dev, /proc, /bin, /etc等標準目錄和文件谬运。
由此可見對于不同的linux發(fā)行版, bootfs基本是一致的, rootfs會有差別, 因此不同的發(fā)行版可以公用bootfs 如下圖:
典型的Linux在啟動后,首先將 rootfs 置為 readonly垦藏,進行一系列檢查梆暖,然后將其切換為 “readwrite” 供用戶使用。在 docker 中掂骏,起初也是將 rootfs 以readonly方式加載并檢查轰驳,然而接下來利用 union mount 的將一個 readwrite 文件系統(tǒng)掛載在 readonly 的rootfs之上,并且允許再次將下層的 file system設定為 readonly 并且向上疊加,這樣一組readonly和一個writeable的結構構成一個 container 的運行目錄滑废,每一個被稱作一個Layer蝗肪。如下圖:
得益于AUFS的特性,每一個對 readonly 層文件/目錄的修改都只會存在于上層的 writeable 層中蠕趁。這樣由于不存在競爭薛闪,多個 container 可以共享 readonly 的layer。所以docker 將 readonly 的層稱作 “image”——對于container而言整個 rootfs 都是 read-write 的俺陋,但事實上所有的修改都寫入最上層的writeable層中豁延,image不保存用戶狀態(tài),可以用于模板腊状、重建和復制诱咏。
上層的image依賴下層的image,因此docker中把下層的image稱作父image缴挖,沒有父image的image稱作 base image袋狞。
因此想要從一個image啟動一個container,docker會先加載其父image直到base image映屋,用戶的進程運行在writeable的layer中苟鸯。所有parent image中的數(shù)據(jù)信息以及 ID、網(wǎng)絡和lxc管理的資源限制等具體container的配置棚点,構成一個docker概念上的container早处。如下圖:
由此可見,采用AUFS作為docker的container的文件系統(tǒng)瘫析,能夠提供如下好處:
節(jié)省存儲空間:多個 container 可以共享 base image存儲
快速部署:如果要部署多個 container砌梆,base image可以避免多次拷貝
內(nèi)存更省:因為多個container共享base image, 以及OS的disk緩存機制贬循,多個container中的進程命中緩存內(nèi)容的幾率大大增加
升級更方便:相比于 copy-on-write 類型的FS咸包,base-image也是可以掛載為可writeable的,可以通過更新base image而一次性更新其之上的container
允許在不更改base-image的同時修改其目錄中的文件:所有寫操作都發(fā)生在最上層的writeable層中甘有,這樣可以大大增加base image能共享的文件內(nèi)容诉儒。
以上5條 ,1-3 條可以通過 copy-on-write 的FS實現(xiàn)亏掀,4可以利用其他的union mount方式實現(xiàn), 5只有AUFS實現(xiàn)的很好,這也是為什么Docker一開始就建立在AUFS之上泛释。
由于AUFS并不會進入 linux 主干 (According to Christoph Hellwig, linux rejects all union-type filesystems but UnionMount.), 同時要求 kernel版本3.0以上(docker推薦3.8及以上)滤愕,因此在 RedHat工程師的幫助下在 docker0.7版本中實現(xiàn)了 driver機制, AUFS只是其中的一個driver, 在RHEL中采用的則是Device Mapper的方式實現(xiàn)的 container文件系統(tǒng)。
全文參考
http://tiewei.github.io/cloud/Docker-Getting-Start/
https://docker.cn/a/1
http://blog.dotcloud.com/category/under-the-hood
http://www.slideshare.net/BodenRussell/realizing-linux-containerslxc
轉載
作者:seanlook
來源:http://seanlook.com/2014/12/18/docker-core-technology-preview/
運維自動化班 6 期火熱報名中
課程概述:
理論結合實戰(zhàn)怜校,使學員既可掌握快速從零構建一套實用间影、完整、可擴展的運維自動化平臺茄茁。
1
深度結合使用流行的 Zabbix魂贬、Ansible巩割、Git、Docker付燥、Rancher宣谈、ELK 等開源框架與工具, 以為應用最廣泛的 Django 框架為基礎键科,構建一站式運維自動化平臺闻丑。
2
通過深度剖析與二次開發(fā)定制,結合 REST API勋颖、運維流程化嗦嗡、運維可視化、運維平臺化 思想來構造企業(yè)級的運維自動化解決方案饭玲。
3
在老師帶領下大戰(zhàn) Zabbix侥祭、CMDB、集群自動化部署上線茄厘、ELK 日志大數(shù)據(jù)分析卑硫、Docker 容器管理平臺等多個最新實戰(zhàn),天天實戰(zhàn)蚕断,招招實用气筋。
上課模式:
網(wǎng)絡直播班 線下面授班
咨詢報名:
QQ:979950755 小月
WeChat : 1902433859 小月
開課時間:
12月24日(周日)