本章內容:docker
一、container是什麼?centos
二、LXC技術介紹安全
三、namespaces-名稱空間,實現資源隔離網絡
四、容器的資源分配--Cgroup,實現資源分配運維
五、LXC與dockerstcp
-------------------------------------------------------------------函數
基於虛擬化基礎知識,咱們這一節開始介紹docker技術的相關內容:docker技術能夠理解爲咱們所學習的虛擬化基礎知識的一個延申;工具
一、container是什麼?性能
二、LXC技術介紹學習
在瞭解LXC以前,咱們先回顧下主機虛擬化技術:主機虛擬化分爲兩類:
type-I、type-II(有VMM管理平臺)
不論是哪一類,咱們都須要經過虛擬技術實現一個系統平臺,目的就是爲了在這個系統平臺上去運行對應的應用進程(例如httpd),來提供服務;
因此,爲了運行一個應用進程,咱們不得不在其下面去跑一個內核系統,來支持這個進程的正常運行,若是咱們能夠跳過這個運行的內核,從而直接去運行一個虛擬機的應用進程,這樣豈不是更加節約資源。因此,這樣,就出現了咱們的容器技術--LXC(LinuX container);
LXC技術的目的:抽調虛擬的內核層;直接去虛擬進程,提供系統硬件設備的資源利用率!
這樣的話,就帶來對應的問題:若是你想運行兩個一樣的服務,這樣,如何在LXC環境下區分這兩個同樣的進程呢?以下圖:
三、namespaces-名稱空間,實現資源隔離
咱們知道,Linux的底層內核依靠的是C語言進行開發的,而C語言中有個函數模塊namespace就是專門用來進行資源隔離--從內核處開始,進行資源隔離;也能夠說是,避免資源衝突;
它是Linux kernel內核默認的功能之一;
隔離的資源以下:
一、獨立的主機名和域名--UTS
二、須要有本身的獨立的掛載數--Mount
三、IPC隔離,實現進行間通信--信號、消息隊列和共享存儲的隔離
四、全部的進程都屬於init進程--每一個獨立空間的init進程要獨立隔離
五、爲每個空間微賺一個root用戶,對於本身空間而言,是root用戶,而對於其餘空間而言是普通用戶;
六、虛擬本身的專用網卡,或者tcp/ip協議棧,網絡隔離;
容器技術須要知足以上隔離條件,才能真正實現;因此,namespaces技術是容器技術的基礎,以下圖:
【內核開始默認支持6種namespaces的最先的內核版本】
此時,咱們就能夠基於內核抽調資源,同時使用namespaces技術進行資源隔離,而這種技術,咱們就叫作容器技術;
容器技術爲了調用這些namespaces資源,namespaces提供了相應的API接口,例如:
clone() 建立新進程。根據系統調用參數來判斷哪一種類型的namespace被建立,並且它們的子進程也會被包含到namespace中
unshare() 將進程移出某個namespace
setns() 將進程加入到namesp中
四、容器的資源分配--Cgroup,實現資源分配
有了資源隔離,咱們就要實現資源分配;內核提供資源分配技術--Control Groups(Cgroups技術)
Cgroups實現資源分配包括:
blkiq:塊設備IO
CPU:CPU
cpuacct:CPU資源使用報告
cpuset:多處理器平臺上的CPU集合
devices:設備訪問
freezer:掛起或恢復任務
memory:內存用量及報告
perf_event:對cgroup中的任務進行統一性能測試
net_cls:CGroup中的任務建立的數據報文的類標識符
Cgroup對應的功能參數:
針對於不一樣的組,咱們使用CGroup技術進行不一樣的資源分配;(不是大鍋飯,而是精細的進行資源分配,知足每一個容器的資源利用)
五、LXC與dockers
最先的容器技術來自於BSD的jail技術,目的就是爲了實現進程隔離,使得一個進程被攻陷後不會影響到其餘進程,這是出於安全的目錄;
而Linux將該技術移植到本身的系統之上,叫作vserver(功能相似於chroot),建立一個本身的更目錄,區分與當前的目錄系統;
咱們知道,爲了使用Linux的內核資源,namespaces提供了相應的API接口(clone(),unshare(),setns(),);這樣就是咱們的容器技術;
真正的容器技術--LXC、docker等,則是爲namespaces、cgroup封裝了一個更好管理的接口;
LXC
這個技術就是最先的容器技術;它方便了容器的管理,例如:
lxc-create 能夠用來建立虛擬的用戶空間; template 能夠用來建立模板【模板能夠選擇應用建立在那些不一樣的髮型版系統上】
而後,咱們須要找到一個目錄空間,將這個目錄制定爲該用戶空間的根目錄,應用則運行在這個所謂的「根目錄」下,這就是所謂的容器技術;
lxc技術對於容器技術的發張功不可沒,可是它有着與生俱來的缺點--沒法實現大規模部署;
因而,出現了docker技術;
docker
爲了解決lxc對於批量化管理容器的缺陷,咱們對lxc進行二次封裝,這樣獲得的管理工具就是咱們的docker了;
docker的工做原理:
docker環境下,咱們將一個系統所須要的全部的文件集中打包,這就是一個鏡像文件,咱們將這個鏡像放在倉庫中,而這個鏡像文件能夠不是系統,並且能夠是具體的服務文件,好比NGINX服務文件;
而後將這個鏡像文件從「倉庫」中下載到本地,運行run命令,這樣就能夠啓動這個倉庫(相似於運行了一個命令);
系統在基於一些列的機制對docker啓動的容器進行資源份分配;這種環境下,咱們運行的docker進程就是一個進程;且多個容器就是多個隔離進程,相互之間不會影響;
如上圖:各類進程的運行,運行在本身的獨立的容器之中,容器之間相互獨立,相互隔離!這樣大大增強了進程之間的安全性,且docker下進程所須要的資源,都由docker環境來提供;
批量建立容器:分層構建、靈活掛載的方式來建立容器;
例如,底層提供一個centos,上層運行進程便可。多個進程能夠共享一個centos底層便可;而後將服務掛在到兩個目錄下,就是兩個容器!且,掛在的文件是隻讀文件;而後再在本地目錄添加一層,去知足該容器須要修改文件的需求;
這樣遷移又會有困難;因此在真正使用的時候,真正數據並不保存於本地,而是存放於後面的共享存儲中;
以下圖:
另一個問題則是,若是關聯進程啓動順序如何肯定?
例如:nmp NGINX MySQL PHP進程運行順序如何來決定啓動?這就涉及到容器的編排問題;常見的解決方案以下:
machine + swarm + compose 來進行系統編排;
mesos + marathon 方案;
kubernetes --> k8s;
以上工具都是用來進行容器進程編排的工具;
容器技術的缺點:
一、無論怎麼說,系統啓動容器,比直接啓動進程是消耗了更多的資源空間;
二、調試工具;自己一個系統下運行多個進程,這些進程使用一套調試工具便可。可是如今進程之間相互隔離,則每一個容器都須要提供一套調試工具;
三、調試進程得進入到容器中進行調試,相對於本來只須要在系統下調試,相對而言更加困難!
總結:
容器給運維帶來了極大的不便,可是給開發帶來了極大的便利,它真正讓代碼實現了一次編寫多環境運行,它極大的節約了軟件開發的成本;
這也是當今社會容器技術如此火的緣由;