本章內容:
1、container是什么?
docker使用步驟? 2、LXC技術介紹
3、namespaces-名稱空間,實現資源隔離
4、容器的資源分配--Cgroup,實現資源分配
docker圖形化管理。 5、LXC與dockers
-------------------------------------------------------------------
基于虛擬化基礎知識,我們這一節開始介紹docker技術的相關內容:docker技術可以理解為我們所學習的虛擬化基礎知識的一個延申;
自己構建docker,?
1、container是什么?
2、LXC技術介紹
docker容器的標準使用過程? 在了解LXC之前,我們先回顧下主機虛擬化技術:主機虛擬化分為兩類:
type-I、type-II(有VMM管理平臺)
不管是哪一類,我們都需要通過虛擬技術實現一個系統平臺,目的就是為了在這個系統平臺上去運行對應的應用進程(例如httpd),來提供服務;
docker基礎知識。 所以,為了運行一個應用進程,我們不得不在其下面去跑一個內核系統,來支持這個進程的正常運行,如果我們可以跳過這個運行的內核,從而直接去運行一個虛擬機的應用進程,這樣豈不是更加節約資源。所以,這樣,就出現了我們的容器技術--LXC(LinuX container);
?
LXC技術的目的:抽調虛擬的內核層;直接去虛擬進程,提供系統硬件設備的資源利用率!
這樣的話,就帶來對應的問題:如果你想運行兩個同樣的服務,這樣,如何在LXC環境下區分這兩個一樣的進程呢?如下圖:
3、namespaces-名稱空間,實現資源隔離
我們知道,Linux的底層內核依靠的是C語言進行開發的,而C語言中有個函數模塊namespace就是專門用來進行資源隔離--從內核處開始,進行資源隔離;也可以說是,避免資源沖突;
它是Linux kernel內核默認的功能之一;
隔離的資源如下:
1、獨立的主機名和域名--UTS
2、需要有自己的獨立的掛載數--Mount
3、IPC隔離,實現進行間通訊--信號、消息隊列和共享存儲的隔離
4、所有的進程都屬于init進程--每個獨立空間的init進程要獨立隔離
5、為每一個空間微賺一個root用戶,對于自己空間而言,是root用戶,而對于其他空間而言是普通用戶;
6、虛擬自己的專用網卡,或者tcp/ip協議棧,網絡隔離;
?
容器技術需要滿足以上隔離條件,才能真正實現;所以,namespaces技術是容器技術的基礎,如下圖:
【內核開始默認支持6種namespaces的最早的內核版本】
?
此時,我們就可以基于內核抽調資源,同時使用namespaces技術進行資源隔離,而這種技術,我們就叫做容器技術;
? 容器技術為了調用這些namespaces資源,namespaces提供了相應的API接口,例如:
clone() 創建新進程。根據系統調用參數來判斷哪種類型的namespace被創建,而且它們的子進程也會被包含到namespace中
unshare() 將進程移出某個namespace
setns() 將進程加入到namesp中
?
4、容器的資源分配--Cgroup,實現資源分配
有了資源隔離,我們就要實現資源分配;內核提供資源分配技術--Control Groups(Cgroups技術)
Cgroups實現資源分配包括:
blkiq:塊設備IO
CPU:CPU
cpuacct:CPU資源使用報告
cpuset:多處理器平臺上的CPU集合
devices:設備訪問
freezer:掛起或恢復任務
memory:內存用量及報告
perf_event:對cgroup中的任務進行統一性能測試
net_cls:CGroup中的任務創建的數據報文的類標識符
Cgroup對應的功能參數:
針對于不同的組,我們使用CGroup技術進行不同的資源分配;(不是大鍋飯,而是精細的進行資源分配,滿足每個容器的資源利用)
5、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;
以上工具都是用來進行容器進程編排的工具;
?
容器技術的缺點:
1、不管怎么說,系統啟動容器,比直接啟動進程是消耗了更多的資源空間;
2、調試工具;本身一個系統下運行多個進程,這些進程使用一套調試工具即可。但是現在進程之間相互隔離,則每個容器都需要提供一套調試工具;
3、調試進程得進入到容器中進行調試,相對于原本只需要在系統下調試,相對而言更加困難!
?
總結:
容器給運維帶來了極大的不便,但是給開發帶來了極大的便利,它真正讓代碼實現了一次編寫多環境運行,它極大的節約了軟件開發的成本;
這也是當今社會容器技術如此火的原因;
?