一、命名空間
命名空間(namespace)是Linux內核一強大特性,為容器虛擬化的實作帶來極大便利,利用這一特性,每個容器都可以擁有自己獨立的命名空間,保證了容器之間彼此互不影響,
在作業系統中,包括內核、檔案系統、網路、PID、UID、IPC、記憶體、CPU、硬碟等資源,所有資源都是應用行程直接共享的,要想實作虛擬化,除了要實作對記憶體、CPU、網路IO、硬碟IO、存盤空間等限制外,還要實作對檔案系統、網路、PID、UID、IPC等的相互隔離,前者相對容易實作一些,后者則需要宿主機系統的深入支持,
1、行程命名空間
Linux通過命名空間管理行程號,對于同一行程(即同一個task_struct),在不同的命名空間中,看到的行程號不相同,每個行程命名空間都有一套自己的行程號管理方法,行程命名空間是一個父子關系結構,子空間中的行程對于父空間是可見的,新fork出的行程在父命名空間和子命名空間將分別有一個行程號來對應,
2、網路命名空間
如果有了PID命名空間,那么每個命名空間中的行程就可以相互隔離,但是網路埠還是共享本地系統的埠,
通過網路命名空間,可以實作網路隔離,網路命名空間為行程提供了一個完全獨立的網路協議堆疊的視圖,包括網路設備介面、IPv4和IPv6協議堆疊、IP路由表、防火墻規則、socket等,這樣每個容器的網路就能隔離出來,Docker采用虛擬網路設備的方式,將不同網路命名空間的網路設備連接到一起,默認情況下,容器中的虛擬網卡將同本地主機上的Docker0 網橋連接在一起,可以通過brctl show查看docker0 網橋上的虛擬網口,
3、IPC命名空間
容器中行程互動采用了Linux常見的行程間互動方法,包括信號量、訊息佇列和共享記憶體等,PID Namespace和IPC Namespace可以組合起來一起使用,同一個IPC命名空間內的行程可以彼此可見,允許進行互動;不同空間的行程則無法互動,
4、掛載命名空間
類似于chroot,將一個行程放到一個特定的目錄執行,掛載命名空間允許不同命名空間的行程看到的檔案結構不同,這樣每個命名空間中的行程所看到的檔案目錄彼此被隔離,
5、UTS命名空間
UTS命名空間允許每個容器擁有獨立的主機名和域名,從而可以虛擬出一個獨立主機名和網路空間的環境,就跟網路上一臺獨立的主機一樣,默認情況下,Docker容器的主機名就是回傳容器的ID,
6、用戶命名空間
每個容器可以擁有不同的用戶和組ID,也就是說可以在容器內使用特定的內部用戶執行程式,而非本地系統上存在的用戶,每個容器內部都可以由root賬號,但跟宿主機不在一個命名空間,通過使用隔離的用戶命名空間可以提高安全性,避免容器內行程獲取到額外的權限,
二、控制組
控制組(CGroup)是Linux內核的一個特性,主要用來對共享資源進行隔離、限制、審計等,只有能控制分配到容器的資源,才能避免多個容器同時運行時對宿主機系統的資源競爭,控制組可以提供對容器的記憶體、CPU、磁盤IO等資源進行限制和計費管理,具體看來,控制組提供:
- 資源限制: 可以將組設定為不超過設定的記憶體限制,比如:記憶體子系統可以為行程組設定一個記憶體使用上限,一旦行程組使用的記憶體達到限額在申請記憶體,就會發出OOM警告,
- 優先級:通過優先級讓一組優先得到更多的CPU等資源,
- 資源審計:通過統計系統實際上把多少資源用到合適的墓地上,可以使用cpuacct子系統記錄某個行程組使用的CPU時間,
- 隔離:為組隔離命名空間,這樣一個組不會看到另一個組的行程、網路連接和檔案系統,
- 控制:掛起、恢復和重啟動等操作,
安裝Docker后,用戶可以在/sys/fs/cgroup/memory/docker/目錄下看到對Docker組應用的各種限制項,用戶可以修改這些檔案值來控制組限制Docker應用資源,可以在創建或啟動容器時為每個容器指定資源限制,例如使用 -c|--cpu-shares[=0]引數來調整容器使用CPU的權重;使用-m|--memory[=MEMORY]引數來調整容器使用的記憶體大小,
三、聯合檔案系統
聯合檔案系統(UnionFS)是一種輕量級的高性能分層檔案系統,它支持將檔案系統中的修改資訊作為一次提交,并層層疊加,同時可以將不同目錄掛載到同一個虛擬檔案系統下,應用看到的是掛載的最終結果,Docker鏡像自身就是由多個檔案層組成,每一層有唯一的編號(層ID),可以通過docker history查看一個鏡像由哪些層組成,
對于Docker鏡像來說,這些層的內容都是不可修改的,只讀的,而當Docker利用鏡像啟動一個容器時,將在鏡像檔案系統的最頂端在掛載一個新的可讀寫的層給容器,容器中的內容更新將會發生在可讀寫層,當所操作物件位于較深的某層時,需要先復制到最上層的可讀寫層,當資料物件較大時,往往意味著IO性能較差,因此,一般推薦將容器修改的資料通過volume方式掛載,而不是直接修改鏡像內資料,
Docker所有的存盤都在Docker目錄下,Ubuntu為例,默認路徑是/var/lib/docker,在這個目錄下最重要的就是aufs目錄,這是aufs檔案系統所在,保存了Docker鏡像相關資料和資訊,該目錄下包含layers、diff和mnt三個子目錄,
- layers子目錄包含層屬性檔案,用來保存各個鏡像層的元資料
- diff子目錄包含層內容子目錄,用來保存所有鏡像層的內容資料
- mnt子目錄是各個容器最終的掛載點,所有相關AUFS層在這里掛載到一起,一個運行容器的根檔案系統就掛載在這個下面的子目錄上
轉載請註明出處,本文鏈接:https://www.uj5u.com/qita/502854.html
標籤:其他
