Docker之Namespace與Cgroup

博文大綱:
一、Docker概述
二、Namespace概念
三、Cgroup基本概念與示例

一、Docker概述

1.Docker簡介

Docker作爲開源社區最火爆的項目,它是在Linux容器裏運行應用的開源工具,是一種輕量級的“虛擬機”,docker的全部源代碼都在https://github.com/docker 進行相關維護,其官網是:https://www.docker.com

Docker的Logo設計爲藍色鯨魚,拖着許多集裝箱。如圖:

Docker之Namespace與Cgroup
如圖所示:鯨魚可以看作宿主機,而集裝箱可以理解爲相互隔離的容器,每個集裝箱中都包含自己的應用程序。正如 Docker的設計宗旨一樣:Buid、 Ship and Run Any App、 Anywhere,即通過對應用組件的封裝、發佈、部署、運行等生命週期的管理,達到應用組件級別的“一次封裝,到處運行”的目的。這裏的組件,既可以是一個應用,也可以是一套服務,甚至是一個完整的操作系統。

2.Docker和虛擬機的區別

作爲一種輕量級的虛擬化方式,Docker與傳統虛擬機相比具有顯著的優勢。如圖:
Docker之Namespace與Cgroup

Docker之所以擁有衆多優勢,與操作系統虛擬化自身的特點是分不開的。傳統虛擬機需要有額外的虛擬機管理程序和虛擬操作系統層,而Docker容器是直接在操作系統層面之上實現的虛擬化,如圖:
Docker之Namespace與Cgroup

3.Docker的使用場景

現在需要能方便地創建運行在雲平臺上的應用,必須要脫離底層的硬件,同時還需要任何時間、地點可獲取這些資源,這正是Docker所能提供的。

Docker的容器技術可以在一條主句上輕鬆爲任何應用創建一個輕量級的、可移植的、自給自足的容器。通過這種容器打包應用程序,意味着簡化了重新部署、調試這些瑣碎的重複工作,極大地提高了工作效率。

比如:服務器從騰訊雲遷移到阿里雲,如果採用了Docker容器技術,遷移只需要在新的服務器上啓動需要的容器即可。

4.Docker的優勢:

  • 靈活性:在複雜的應用都可以被容器化;
  • 輕量級:容器利用共享的是主機的內核;
  • 即時性:可以隨時部署更新和升級;
  • 通用性:一次封裝,到處運行;
  • 伸縮性:控制容器副本數量來任意伸縮;

二、Namespace概念

虛擬化的技術就是用來解決宿主機與虛擬機之間的耦合問題(簡稱“解耦”),傳統虛擬化技術是屬於完全解耦的,而docker這種虛擬化技術是屬於半解耦的。

耦合:就是指兩個或兩個以上的體系或兩種運動形式間通過相互作用而彼此影響以至聯合起來的現象;
解耦:接觸耦合、衝突現象;

Docker是如何解耦的呢?這就需要使用到——Namespace(命名空間)

Namespace(命名空間):是Linux爲我們提供的用於分離進程樹、網絡接口、掛載點以及進程間通信等資源的方法。

Namespace(命名空間)在docker中主要實現了六項隔離,如圖:
Docker之Namespace與Cgroup

Docker通過使用Namespace(命名空間)這項技術實現了容器與容器之間、容器與docker host之間的隔離。

當Docker創建一個容器時,它會創建新的以上六種NameSpace的實例,然後把容器中的所有進程放到這些NameSpace之中,使得容器這個父進程只對自己的子進程有感知,而對於宿主機其他進程一無所知,從而產生一種它就是一個獨立的系統的“錯覺”。

如果docker 宿主機是centos系統,運行docker容器時,容器也是centos 系統,所必需的目錄、文件就是通過docker宿主機進行軟連接提供的,包括宿主機的內核;但如果運行的docker容器是Ubuntu系統,其中目錄、文件與centos 系統始終是會有一些區別的,那麼這就需要使用到——Busybox(欺騙層)

如果需要使用虛擬機來部署一些服務時,這些服務對內核版本有要求,那麼就不太適合使用docker這種虛擬化技術,建議使用KVM等虛擬化技術。

docker這種服務本身並不佔用端口,只是保持後臺運行。

三、Cgroup基本概念與示例

Cgroup(控制組):是Linux內核提供的一種限制Docker容器使用Docker宿主機資源的一種機制。

Cgroup四大功能:

  • 1)資源限制;Cgroup可以對進程組使用的資源總額進行限制;
  • 2)優先級分配;通過分配的CPU時間片數量以及硬盤IO帶寬大小,實際相當於控制了進程運行的優先級別;
  • 3)資源統計;Cgroup可以統計系統資源使用量,比如CPU使用時間,內存使用量等,用於按量計費。同時還支持掛起功能,也就是說通過cgroup吧所有資源限制起來,對資源都不能使用,注意這並不意味說我們的程序不能使用了,只是不能使用資源,處於等待狀態;
  • 4)進程控制;可以對進程組執行掛起、恢復等操作;

通過Cgroup,我們就可以具體地控制對系統資源的分配、優先順序、拒絕、管理和監控。這樣就可以避免在docker容器中服務受到外部干擾時,可以將其限制在容器之中,而不會影響宿主機或其他容器的運行的,提高了安全性。

Docker是通過以下幾個方面對容器使用的資源進行限制:

  • 對CPU進行限制;
  • 對內存、SWAP進行限制;
  • 對block IO進行限制;

示例如下:

1.對CPU進行限制

[root@localhost ~]# cat /sys/fs/cgroup/cpu/cpu.shares 
1024
//查看宿主機默認的CPU權重爲1024
[root@localhost ~]# docker run -it --name test centos:7         //隨便創建一個容器進行測試
[root@6afc120f16e1 /]# cat /sys/fs/cgroup/cpu/cpu.shares
1024
//可以看到默認情況下,docker容器默認的CPU權重也是1024

如果不對容器進行限制的話,是非常危險的,因爲Docker宿主機與Docker容器對CPU的權重值是一樣的,這樣,它們在對CPU資源進行搶佔時,比例爲1:1。顯然在生產環境中需要對其做一些限制,方法如下:

[root@localhost ~]# docker run -it --name test1 -c 512 centos:7
//基於centos鏡像運行一個名爲test1的容易,其CPU使用的權重爲512
//設置方法相對來說,十分簡單,就是添加了一個“-t”的選項而已!
[root@fc842b8af840 /]# cat /sys/fs/cgroup/cpu/cpu.shares
512
//驗證是否設置是否成功

2.對物理內存、Swap進行限制

容器內存主要包括兩部分:物理內存與Swap(交換分區)
可以通過以下參數控制容器對內存的使用情況:

  • -m或--memory:設置內存的使用限額;
  • --memory-swap:設置內存+swap的使用限制;
    [root@localhost ~]# cat /sys/fs/cgroup/memory/memory.limit_in_bytes 
    9223372036854771712
    //查看宿主機對內存的使用情況,單位是字節,這麼大的數字表示沒有限制
    [root@localhost ~]# docker run -it --name test2 centos:7
    [root@d65dd3da663c /]# cat /sys/fs/cgroup/memory/memory.limit_in_bytes 
    9223372036854771712
    //創建容器,查看容器對宿主機內存的使用情況,單位是字節,這麼大的數字表示沒有限制

    通過以下可以看出這樣是不安全的,所以需要使用以下方法對其進行限制,方法如下:

    [root@localhost ~]# docker run -it --name test4 -m 200M --memory-swap 300M centos:7 
    //創建一個容器,並限制容器最多使用200M內存和100M的交換分區
    //--memory-swap:這個值是物理內存加Swap的值
    [root@3de51b7474c5 /]# cat /sys/fs/cgroup/memory/memory.limit_in_bytes 
    209715200
    //查看物理內存是否生效,單位是字節,可以自行進行換算驗證
    [root@3de51b7474c5 /]# cat /sys/fs/cgroup/memory/memory.memsw.limit_in_bytes 
    314572800
    //查看物理內存和交換分區內存是否生效,單位是字節,這個值是物理內存加Swap分區的值

3.對block IO進行限制

block IO:磁盤的讀寫性能。

docker中可以通過設置權重,限制bps和iops的方式控制容器讀寫磁盤的IO。

  • bps:每秒讀寫的數據量
  • iops:每秒IO的次數
    默認情況下,所有容器都能平等的讀寫磁盤,也可以通過“--blkio-weight"參數改變容器的block IO的優先級。

常用的選項有:

  • --device-read-bps:顯示讀取某個設備的bps;
  • --device-write-bps:顯示寫入某個設備的bps;
  • --device-read-iops:顯示讀取某個設備的iops;
  • --device-write-iops:顯示寫入某個設備的iops;

默認運行一個容器,不對其進行限制:

[root@3de51b7474c5 /]# time dd if=/dev/zero of=test.out bs=1M count=800 oflag=direct
//oflag=direct用來指定directIO方式寫入文件,這樣纔會使--device-write-bps生效,主要測試讀寫性能 
800+0 records in
800+0 records out
838860800 bytes (839 MB) copied, 1.6379 s, 512 MB/s             //不進行限制,結果爲每秒寫入512MB

real    0m2.022s
user    0m0.001s
sys 0m1.146s
[root@localhost ~]# docker run -it --name test5 --device-write-bps /dev/sda:30M centos:7
//創建一個容器對其限制爲每秒爲30M
[root@f5bd3f122881 /]# time dd if=/dev/zero of=test.out bs=1M count=800 oflag=direct
800+0 records in
800+0 records out
838860800 bytes (839 MB) copied, 26.6317 s, 31.5 MB/s               //雖然有點超出限制,但是並沒有限制強太多

real    0m26.633s
user    0m0.004s
sys 0m2.097s

———————— 本文至此結束,感謝閱讀 ————————

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章