Docker入門(一)
一、虛擬化技術分類
1.內核級別的虛擬化Xen或者Kvm
[vm.user]
[vm.kern].... //這種虛擬化技術隔離效果最好,但是性能消耗也高
===========
VMM
======
硬件
vm的user進程需要發起system call的時候,需要調用vm.kernel但是真正執行的是host.kernel
使用BT,或者HVM,加速轉換。
內存虛擬化:shadow MMU
CPU虛擬化:tagged TLB
2.容器技術:
lxc:linux container
openvz:
[us1][us2].... //userspace,用戶空間進行隔離,這就是一個容器
===========
kernel
===========
硬件
xen或者kvm隔離效果比較好,
容器技術:隔離的是user space
3.庫虛擬化:
wine
cywin
4.應用級別虛擬化:
jvm
...
二、容器基礎概念:
CGroup + NameSpace + AUFS
1.容器虛擬化依賴到的NS:name space
pstree:
PID 1:用戶和內核交互的進程
假如us1中的進程,需要使用root權限和內核交互,它是否能夠看到id號為1的進程,並且各us又是隔離的?
yum -y install psmisc //安裝該包
內核級別,環境隔離;類似chroot機制
PID NameSpace: kernel 2.6.24虛擬出各種pid,每一個用戶空間都可以虛擬一個pid為1的進程
PID隔離
Network NameSpace: kernel 2.6.29 實現網絡隔離
網路設備,網絡棧,端口號等網絡資源隔離
User NameSpace:用戶隔離,每一個userspace可有同樣的用戶名的用戶
用戶和yoghurt組資源隔離,kernel 3.8 +
IPC NameSpace:進程間通信 kernel 2.6.79
信號量,消息隊列和共享內存等隔離
UTS NameSpace: kernel 2.6.19
主機名和域名的隔離
Mount NameSpace: us1能看到的fs一定是自己能夠看到的fs,us2掛載的專有設備,fs是us1不能看到的
掛載點隔離(FS)隔離;kernel 2.4.19
為了對不同namespace訪問
API:clone(),setns(),unshare();
clone:實現線程的系統調用,來實現新線程的。
setns:設定namespace的屬性,假如某個進程到某個NS
unshare:非共享機制,進程脫離一個NS,關聯到另一個NS
查看:
mount //可以查看掛載情況
lssubsys -m //查看各個名稱空間的掛載情況
2.各容器的資源限制:CGroup
一個NS一個占用整個 userspace 的100%,其他NS就沒資源用了
因此CGroup
CGroup: linux control group:控制組
內核級別:限制,控制與一個進程組群的資源;
可以限制:內存,cpu等
kernel 2.6.24 收入內核
資源:CPU,內存,IO
CGroup的功能:
Resource limitation:資源限制
Prioritization:優先級控制;哪一個NS更優先獲得CPU和資源
Account:統計和審計,主要為了計費
Control:掛起和恢復 進程
/sys/fs/cgroup
進程啟用在哪裏,代表只能使用多少資源
倒置的樹狀結構。
每一資源都是一棵樹,cpu是一個,內存是一個,io也是一個,..也可以內存和cpu一棵樹
還有其他很多的資源等。有的是重合的,有的是獨立的。
術語集:
task(任務):cgroups的術語中,task就表示系統的一個進程。
cgroup(控制組):cgroups 中的資源控制都以cgroup為單位實現。cgroup表示按某種資源控制標準劃分而成的任務組,包含一個或多個子系統。
一個任務可以加入某個cgroup,也可以從某個cgroup遷移到另外一個cgroup。
subsystem(子系統):cgroups中的subsystem就是一個資源調度控制器(Resource Controller)。比如CPU子系統可以控制CPU時間分配,內存子系統可以限制cgroup內存使用量。
hierarchy(層級樹):hierarchy由一系列cgroup以一個樹狀結構排列而成,
每個hierarchy通過綁定對應的subsystem進行資源調度。
hierarchy中的cgroup節點可以包含零或多個子節點,子節點繼承父節點的屬性。
整個系統可以有多個hierarchy。
[C,C,C,C] //CPU
[16G ] //內存
[io....] //io等其他資源
[c] [c] [c,c]
[2G] [2G] [12G] //上級可以使用所屬的所有資源
/ \
[c] [c]
[4G] [8G]
CGroup的子系統(subsystem):
blkio// 塊設備的io資源分配,disk
cpu //設定cpu的限制 ,僅能使用40%
cpuacct //報告cgroup中所使用的cpu資源
cpuset //為cgroup中的任務分配cpu和內存資源,
分配你使用哪一個cpu 和memory,分配可以分配整個
memory //設定內存的使用限制
限制內存使用的空間,例如分配的是1個核心,但是僅運行使用40%
devices //控制cgroup中的任務對設備的訪問;
freezer //掛起和回復cgroup中的任務;
net_cls(classid),使用等級級別標識符來標記網絡數據包,以實現基於tc完成對不同的cgroup中產生的流量的控制;
perf_event:使用後使cgroup中的任務可以進行統一的性能測試
hugetlb;大的tlb,大內存頁,hugetlb讓大內存頁提高命中率,對HugeTLB系統進行限制;
Cgroup的通俗術語:
task:任務,進程或線程
cgroup:一個獨立的資源控制單位,可以包含一個或多個子系統
subsystem:子系統,
hierarchy: 層級,可以再次劃分。
一個子系統可以附加到多個層級//例如一個cpu可以在多個層級上附加
3.AUFS: union FS
Union FS:它支持對文件系統的修改作為一次提交來一層層的疊加,同時可以將不同目錄掛載到同一個虛擬文件系統下
Union 文件系統是 Docker 鏡像的基礎。鏡像可以通過分層來進行繼承,基於基礎鏡像(沒有父鏡像)
另外,不同 Docker 容器就可以共享一些基礎的文件系統層,同時再加上自己獨有的改動層,大大提高了存儲的效率
UnionFS:把不同的物理位置的目錄,合並到同一個目錄中
假如有兩個文件或者目錄名一樣?
疊加:先後順序,最前面的才是可寫的
AUFS:Another UnionFS 、Alternative UFS、Advanced UFS
但是AUFS不是內核的版本,但是ubuntu是沒有的,
Docker 依賴於AUFS,用於提高性能
Docker目前支持的 Union 文件系統種類包括 AUFS, btrfs, vfs 和 DeviceMapper
原因:
之前復制bin,sbin等程序到一個目錄中,chroot後可以執行
ns1和ns2一個需要ls,一個需要cat命令,但是ls和cat命令有重復使用的庫,可以把該庫做成一個聯合庫(只讀)
可以把公共部分做成一個目錄,ns1只放ls獨有的,ns2只放cat獨有的,用ls或者cat獨有的聯合底層公共的庫即可
目的:減少disk占用
centos 不支持AUFS但是支持UNIONFS //UNIONFS沒有AUFS強悍
還有另外一種方案:Device mapper
4.Device Mapper:
多系統機制
md:multi disks
http://www.tldp.org/HOWTO/Multi-Disk-HOWTO-1.html
dm:device mapper
Kernel 2.6 引入的最重要的技術之一,用於在內核中支持邏輯卷管理的通用設備的映射機制;
從邏輯設備到物理設備的映射框架機制,在該機制下,用戶可以很方便的根據自己的需要制定實現存儲資源的管理策略,
當前比較流行的 Linux 下的邏輯卷管理器如
LVM2(Linux Volume Manager 2 version)
EVMS(Enterprise Volume Management System)
dmraid(Device Mapper Raid Tool)等都是基於該機制實現的。
它包含三個重要的對象概念,mapped device、映射表、target device
mapped device:可以理解成為內核向外提供的邏輯設備,它通過映射表描述的映射關系和 target device 建立映射
target device:邏輯設備映射到的一個物理設備
https://www.ibm.com/developerworks/cn/linux/l-devmapper/
為底層塊設備提供抽象設備,
Mapped Device:映射的設備
Mapping table:虛擬設備到物理設備的映射
Target Device:被映射的設備
lVM就依賴於device mapper機制。但是不建議device mapper在docker技術中使用,因為有諸多不穩定性。
三、Docker入門:
程序的發布,需要依賴各種環境
一個docker中應該運行幾個程序?只能運行一個應用程序?
docker容器是為單一目的而實現的,為一個應用程序而實現的
LAMP:基於docker,要啟用是三個容器,http,php,mysql 三者之間進行通信即可
//其實是可以把LAMP坐在一個容器內部的
[]
=====================
[kernel]
[hardware]
運行了三個Nginx容器
第一個cn(conainer) 使用80port,第二個cn也是用80 port,但是內核之有一個80端口
方法:映射,
kernel: 8080 -> cn2.80
kernle: 888 -> cn1.80
...
容器啟動:創建,關閉:刪除 //基於某個cn創建的文件沒有了怎麽辦?讓數據持久化
按需創建,運行在容器雲環境,n個物理節點,
[cn1] //cn1第一次啟動在host1上,第二次可能啟動在host2上
======================== //資源抽象層
host1,host2,........... //物理主機
//容器的路徑映射
\ \ \
=======================
雲存儲//數據持久化
//容器使用的路徑,關聯到容器雲的某個路徑,保存數據。容器關聯到該路徑即可訪問原有的數據
volume 技術:實現數據持久化,可以進行實時遷移
Docker的核心概念:2013,Go,apache 2.0協議
C/S架構
Docker client:發起請求的node
docker server:容器運行的node,
docCloud公司研發
https://www.docker.com/
=========================
dockerfiles [dockerHUB]
\ /
[images]
\
\[backup]
【containers】
=============
linux OS
==============================
啟動docker容器,需要加載images,server從dockerHUB上下載images
把所依賴到的多個images,疊加為一個UnionFS,然後在該容器中運行
可以從公共dockerhub下載,也可以自制
可以共享讓別人訪問。
可以創建私有hub
dockerfile:創建dockerfile 創建docker映像文件。
四、docker層級概念
Linux內核是第0層-->Docker鏡像,是一個只讀的鏡像,位於第1層,它不能被修改或不能保存狀態。
一個Docker鏡像可以構建於另一個Docker鏡像之上,這種層疊關系可以是多層的。
第1層的鏡像層我們稱之為基礎鏡像(Base Image),其他層的鏡像(除了最頂層)我們稱之為父層鏡像(Parent Image)。
這些鏡像繼承了他們的父層鏡像的所有屬性和設置,並在Dockerfile中添加了自己的配置。
Docker鏡像通過鏡像ID進行識別。鏡像ID是一個64字符的十六進制的字符串。
但是當我們運行鏡像時,通常我們不會使用鏡像ID來引用鏡像,而是使用鏡像名來引用。
要列出本地所有有效的鏡像,可以使用命令
可以用同一個鏡像啟動多個Docker容器,這些容器啟動後都是活動的,彼此還是相互隔離的。對其中一個容器所做的變更只會局限於那個容器本身。
附件1:進程間通信常用的方式:
C方法包括管道(PIPE)、消息排隊、旗語、共用內存以及套接字(Socket)
Docker入門(一)