- 容器與虛擬機的差異
1)虛擬機的原理:通過額外的虛擬化層,將虛擬機中運行的操作系統指令翻譯成宿主機系統能夠執行的系統調用然后操作具體的硬件。
優點:實現虛擬機和宿主機操作系統的異構,如在Linux系統上運行Windows的虛擬機
缺點:依賴於硬件的支持,特別是CPU虛擬化的支持
2)容器技術的原理:完全建立在操作系統內核特性之上,是一種與運行硬件無關的虛擬化技術。
優點:由於沒有轉換異構指令的虛擬化層,因此運行效率高於虛擬機。
缺點:只能實現與宿主機操作系統相同系統的虛擬化。
3)在實際使用中,常常將兩者相結合,以實現“跨不同操作系統”運行容器的目的。
- Namespace & CGroup
Linux系統中的容器技術主要是利用內核的Namespace特性和CGroup特性實現了服務進程組的資源隔離和配額。
Namespace:
實現內核級虛擬化(容器)服務,讓同一個Namespace下的進程可以感知彼此的變化,同時又能確保對外界的進程一無所知,以達到獨立和隔離的目的。
CGroup:
Linux內核提供的一種可以限制、記錄、隔離進程組所使用的物理資源(包括CPU、內存、磁盤I/O速度等)的機制,也是容器管理虛擬化系統資源的手段。
- Namespace
通過查看 /proc 目錄下以進程ID作為名稱的子目錄中的信息,能了解該進程的一組Namespace ID
root@Ubuntu14:/proc# ls -l /proc/1009/ns total 0 lrwxrwxrwx 1 root root 0 Jun 20 14:00 cgroup -> cgroup:[4026531835] lrwxrwxrwx 1 root root 0 Jun 20 14:00 ipc -> ipc:[4026531839] lrwxrwxrwx 1 root root 0 Jun 20 14:00 mnt -> mnt:[4026531840] lrwxrwxrwx 1 root root 0 Jun 20 14:00 net -> net:[4026531957] lrwxrwxrwx 1 root root 0 Jun 20 14:00 pid -> pid:[4026531836] lrwxrwxrwx 1 root root 0 Jun 20 14:00 user -> user:[4026531837] lrwxrwxrwx 1 root root 0 Jun 20 14:00 uts -> uts:[4026531838] root@Ubuntu14:/proc#
每個進程都具有這樣的7個屬性。
CGroup Namespace:(cgroup)
提供基於CGroup的隔離能力。
使不同進程組看到的CGroup規則各不相同。
IPC Namespace:(ipc)
提供基於System V進程信道的隔離能力。
IPC(Inter-Process Communication)是Linux中的一種標准的進程間通信方式,包括共享內存、信號量、消息隊列等具體方法。
IPC隔離使得只有在同一命名空間下的進程才能相互通信。
Mount Namespace:(mnt)
提供基於磁盤掛載點和文件系統的隔離能力。
為隔離空間創建獨立的mount節點樹。
在文件系統隔離的作用下,容器中的進程將無法訪問到容器以外的任何文件。必要時,可通過掛載額外目錄的方式和主機共享文件系統。
Network Namespace:(net)
提供基於網絡棧的隔離能力。
讓每個容器通過命名空間來隔離和管理自己的網卡配置。
虛擬網卡最終可以通過某些方式(NAT、VxLan、SDN等)連接到實際的物理網卡上,從而實現像普通主機一樣的網絡通信。
PID Namespace:(pid)
提供基於進程的隔離能力。
進程隔離使得在容器內的首個進程成為所在命名空間中PID值為1的進程。
PID為1的進程很特殊,它作為所有進程的根父進程,有很多特權,如屏蔽信號、接管孤兒進程等。
User Namespace:(user)
提供基於用戶的隔離能力。
同一系統用戶在不同的命名空間可擁有不同的UID和GID,它們之間存在一定的映射關系。
因此,在特定命名空間中,UID為0的用戶並不一定是root系統管理員。
該特性限制了容器的用戶權限,有利於保護主機系統的安全。
UTS Namespace:(uts)
提供基於主機名的隔離能力。
每個獨立容器空間中的程序可以有不同的主機名稱信息。
該主機名不唯一,允許重復。因此,它雖然可以在網絡中用於通信會定位服務,但並不是可靠的方法。
- CGroup
查看任意進程在 /proc 目錄下的內容,可以看到下面這樣一個名為cgroup的文件
root@Ubuntu14:/proc# cat /proc/1009/cgroup 13:pids:/ 12:hugetlb:/ 11:net_prio:/ 10:perf_event:/ 9:net_cls:/ 8:freezer:/ 7:devices:/ 6:memory:/ 5:blkio:/ 4:cpuacct:/ 3:cpu:/ 2:cpuset:/ 1:name=systemd:/ root@Ubuntu14:/proc#
這當中的每個掛載點都是一個CGroup子系統的根目錄,例如上圖中進程所屬的cpuset子系統路徑為 "/",實際上就是指 "/sys/fs/cgroup/cpuset" 這個目錄,其余子系統的位置可以此類推。
在Linux 4.7.1內核中,已經支持了10類不同的子系統,分別如下所示:
1)hugetlb: 限制進程對大頁內存(Hugepage)的使用
2)memory: 限制進程對內存和Swap的使用,並生成每個進程使用的內存資源報告
3)pids: 限制每個CGroup中能夠創建的進程總數
4)cpuset: 在多核系統中為進程分配獨立CPU和內存
5)devices: 允許或拒絕進程訪問特定設備
6)net_cls 和 net_prio: 標記每個網絡包,並控制網卡優先級
7)cpu 和 cpuacct: 限制進程對CPU的用量,並生成每個進程所使用的CPU報告
8)freezer: 掛起或恢復特定的進程
9)blkio: 為進程對塊設備(如磁盤、USB等)限制輸入/輸出
10)perf_event: 監測屬於特定的CGroup的所有線程以及運行在特定CPU上的線程