Docker 之NameSpace與Cgroup

1、比較docker容器技術與傳統虛擬化技術
Docker容器技術是一個與傳統的虛擬化技術有些本質上的差異,傳統的虛擬化技術,是站硬件物理資源的基礎上,虛擬出多個OS,而後在OS的基礎上構建相對獨立的程序運行環境,而Docker則是在OS的基礎上進行虛擬,因此,Docker輕量不少,所以其資源佔用、性能消耗相比傳統虛擬化都有很大的優點。docker

docker容器很快,啓動和中止能夠在秒級實現,比傳統的虛擬化技術要快不少,docker核心解決的問題是利用容器來實現相似VM的功能,從而節省更多的硬件資源,docker容器除了運行其中的應用以外,基本不消耗額外的系統資源,從而在保證性能的同時,減少系統開銷,同時,它還能夠達到「一次封裝,處處運行」的目的。centos

Docker和傳統虛擬化的區別以下:安全

特性 Docker容器 傳統虛擬化技術
啓動速度 秒級 分鐘級
隔離性 資源限制 徹底隔離
性能 接近原生 弱於
計算機能力消耗 幾乎無 損耗50%左右
系統支持量(單機) 上千個 幾十個

Docker和傳統虛擬化的架構上的區別比較圖以下:
Docker 之NameSpace與Cgroup
2、NameSpace和Cgroup的概念與做用
Docker中有三個核心概念,分別是鏡像、容器、倉庫。而鏡像的概念主要就是把運行環境和業務代碼進行鏡像打包,每一個鏡像都會存在多個「層」,鏡像層都是隻讀的,不能往裏寫數據,若是想要寫,就須要在其基礎之上啓動成一個容器, 在容器層,咱們是可寫的。markdown

在鏡像的多個「層」中,有一個busybox的概念,我將它理解爲欺騙層。
虛擬化的技術就是來解決宿主機與虛擬機之間的耦合問題(簡稱「解耦」),傳統虛擬化是屬於徹底解耦的,而docker是屬於半解耦的。關於「耦合、解耦」的概念能夠參考文檔:什麼是耦合、解耦?網絡

一、NameSpace
那麼,Docker技術是如何解耦的呢?這就引入了NameSpace的概念,其目的是將某個特定的全局系統資源經過抽象的方法使得NameSpace中的進程看起來擁有他們本身的隔離的全局系統資源實例,Docker技術經過Linux內核實現了六種NameSpace,以下:架構

Namespace 系統調用參數 隔離內容
UTS CLONE_NEWUTS 主機名與域名
IPC CLONE_NEWIPC 信息量、消息隊列和共享內存
PID CLONE_NEWPID 進程編號
Network CLONE_NEWNET 網絡設備、網絡棧、端口等等
Mount CLONE_NEWNS 掛載點(文件系統)
User CLONE_NEWUSER 用戶和用戶組

當Docker建立一個容器時,它會建立新的以上六種NameSpace的實例,而後把容器中的全部進程放到這些NameSpace之中,使得容器這個父進程只對本身的子進程有感知,而對於宿主機其餘進程一無所知,從而產生一種它就是一個獨立的系統的「錯覺」。
三、Cgroup
Cgroup做用:控制程序對資源的佔用。ide

Cgroup的具體做用以下:性能

  • 限制資源的使用:Cgroup能夠對進程組使用的資源總額進行限制;
  • 優先級控制:經過分配CPU時間片數量及磁盤IO帶寬大小,實際上就是至關於控制子進程運行的優先級。
  • 資源統計:Cgroup能夠統計系統資源使用量,好比CPU使用時間,內存使用量等。可用於按量計費。
  • 進程控制:恢復執行進程;

使用Cgroup,咱們能夠更具體地控制對系統資源的分配、優先順序、拒絕、管理和監控。可更好地根據任務和用戶分配硬件資源,提升整體的效率,這樣能夠在docker容器中的服務受到外部干擾時,能夠將其限制在容器之中,而不會影響宿主機或其餘容器的運行,提升了安全性。spa

那麼,docker是如何來定義容器使用的資源呢?
(1)Cgroup的應用舉例
一、基於centos鏡像運行一個容器,要求CPU使用權重爲512。
先來看看其不進行CPU限制時,它是什麼樣子的?
1)宿主機的CPU限制.net

[root@docker ~]# cat /sys/fs/cgroup/cpu/cpu.shares         # 查看宿主機CPU的權重
1024

2)容器的CPU限制

[root@docker ~]# docker run -it centos
[root@40033df95ce4 /]# cat /sys/fs/cgroup/cpu/cpu.shares 
1024                        # 能夠看到和宿主機是同樣的

若是不進行修改CPU的權重,那麼容器與宿主機對CPU的權重都是默認的1024,這樣是很危險的,由於宿主機與容器對CPU的權重同樣,於是致使,它們在對CPU資源出現搶佔的狀況下,其可以使用的CPU資源是1:1,那麼,若是在運行這個容器時,對其進行限制呢?若限制容器爲512,宿主機仍是1024,那麼其CPU使用權重的比例就變成了2:1,下面對容器進行限制:

[root@docker ~]# docker run -it --name test1 -c 512 centos
[root@1694de884b3a /]# cat /sys/fs/cgroup/cpu/cpu.shares 
512              # 能夠看到已經變成了512

二、基於centos鏡像運行一個容器,要求MEM爲200M,MEM-SWAP爲400M
1)如下是宿主機內存、交換空間的限制

[root@docker ~]# cat /sys/fs/cgroup/memory/memory.limit_in_bytes         # 查看內存的限制
9223372036854771712
[root@docker ~]# cat /sys/fs/cgroup/memory/memory.memsw.limit_in_bytes        # 查看交換空間的限制
9223372036854771712

2)如下是容器中對內存、交換空間的限制

[root@docker ~]# docker run -it centos
[root@692e78a5fedf /]# cat /sys/fs/cgroup/memory/memory.limit_in_bytes            # 內存限制
9223372036854771712
[root@692e78a5fedf /]# cat /sys/fs/cgroup/memory/memory.memsw.limit_in_bytes           # 交換空間限制
9223372036854771712              #單位是「bytes」

能夠看到容器對內存和交換空間可使用的量和宿主機是同樣的,說明並無進行限制,那麼如何進行限制呢?

[root@docker ~]# docker run -it --name test2 -m 200M --memory-swap 400M centos
# 啓動一個容器限制內存爲300M,交換空間爲400M
[root@bfc999f40acf /]# cat /sys/fs/cgroup/memory/memory.limit_in_bytes 
209715200                 # 查看確認,單位爲bytes
[root@bfc999f40acf /]# cat  /sys/fs/cgroup/memory/memory.memsw.limit_in_bytes 
419430400                # 查看確認,單位爲bytes

三、基於centos鏡像運行一個容器,要求寫入速度爲40M。
默認運行一個容器,不進行限制:

[root@bfc999f40acf /]# time dd if=/dev/zero of=a.txt bs=1M count=200 oflag=direct
200+0 records in
200+0 records out
209715200 bytes (210 MB, 200 MiB) copied, 0.203469 s, 1.0 GB/s                             # 結果爲每秒寫入468MB。

real    0m0.206s
user    0m0.001s
sys 0m0.167s

能夠看到,若是不對其進行限制,那麼會使用宿主機最大的寫速度,那麼怎麼限制呢?

[root@docker ~]# docker run -it --name test3 --device-write-bps /dev/sda:40MB centos
[root@a3cd9813e2e6 /]# time dd if=/dev/zero of=a.txt bs=1M count=200 oflag=direct
200+0 records in
200+0 records out
209715200 bytes (210 MB, 200 MiB) copied, 4.91592 s, 42.7 MB/s                   # 寫入速度被限制在了40MB左右

real    0m4.918s
user    0m0.000s
sys 0m0.155s
相關文章
相關標籤/搜索