Docker學習筆記 ---儲存與管理
儲存管理
為了適應不同平臺不同場景的儲存需求,Docker提供了各種基於不同檔案系統實現的儲存驅動來管理實際的映象檔案
元資料管理
映象在設計上將元資料和檔案儲存完全隔離。Docker管理元資料採用的也正是從上至下repository、image、layer是3個層次。 所以repository與image兩個元資料並無物理上的映象檔案與之對應,layer則存在物理上的映象檔案與之對應。
-
倉庫元資料
檔案中儲存了所有版本映象的名字和tag以及對應的映象ID(image/aufs) -
映象元資料
檔案中儲存了映象架構、作業系統、預設配置、該映象的容器ID和配置,構建映象的歷史資訊以及rootfs組成(image/aufs/imagedb/content/sha256) -
分層元資料
-
映象層
描述不可改變的映象層(image/aufs/layerdb/sha256) -
容器層
描述可讀寫的容器層(image/aufs/layerdb/mounts/),讀寫層的ID也對應容器的ID
儲存驅動
為支援寫時複製特性,根據不同作業系統底層的支援提供不同的儲存驅動
-
aufs(advanced multi layered unification file system)
是一種支援聯合掛載的檔案系統,支援不同目錄掛載到同一個目錄,掛載對使用者來說是透明的。 -
讀
-
寫
-
刪
-
增
-
從最頂層的讀寫層開始向下尋找,本層沒有則根據層與層之間的關係到下一層找
-
如果檔案不存在則在讀寫層新建一個,否則向上面一樣從頂層開始查詢,找到後複製到讀寫層進行修改
-
如果檔案僅僅在讀寫層則直接刪除;否則需要刪除讀寫層的備份,再在讀寫層中建立whiteout檔案來標誌這個檔案不存在,而不會真正刪除底層檔案(會有.wh.開頭的隱藏檔案)
-
如果這個檔案在讀寫層存在對應的whiteout檔案則先將whiteout檔案刪除再新建
-
檔案操作
-
btrfs
-
zfs
-
devicemapper
-
overlay
overlayFS是一種新型聯合檔案系統,允許一個檔案系統與另外一個檔案系統重疊,在上層檔案系統中記錄更改,而下層的檔案系統保持不變。 -
vfs
儲存目錄
/var/lib/docker /aufs aufs驅動工作的目錄 /diff mount-id容器層,檔案系統所有層的儲存目錄(下載的映象內容就儲存在這裡)和容器層檔案的差異變化會在這裡出現。 /mount-id-init 最後一個只讀層,用於掛載並重新生成dev/etc所列檔案,這些檔案與容器內的環境息息相關,但不適合被打包作為映象的檔案內容, 又不應該直接修改在宿主機檔案上,所以設計了mountID-init層單獨處理這些檔案。這一層只在容器啟動時新增。 /layers mount-id儲存上述所有aufs層之間的關係等元資料,記錄該層所依賴的所有其它層 /mnt aufs檔案系統的掛載點,graphdriver會將diff中屬於容器映象的所有層目錄以只讀方式掛到mnt /container 容器配置檔案目錄 /image /aufs 儲存映象與映象層元資料資訊,真正的映象層內容儲存在aufs/diff /imagedb/content 儲存所有映象的元資料 /layerdb 儲存所有映象層和容器層的元資料 /mounts 儲存容器層元資料 /init-id init層id,這個layer存放的位置 /mount-id mount層id,這個layer存放的位置 /parent 父layer的chain-id /share256 儲存映象層元資料 /cache-id 該層資料存放的位置,在對應驅動目錄下 /diff 標識每一個layer /parent 標識父layer的chain-id /size 存放layer的資料大小 /tar-split.json.gz 存放layer層的json資訊 /repositories.json 記錄映象倉庫中所有映象的repository和tag名 /volumes volumes的工作目錄,存放所有volume資料和元資料 讀寫層、volumes、init-layer、只讀層這幾部分結構共同組成了一個容器所需的檔案系統。 diff-id:通過docker pull下載映象時,映象的json檔案中每一個layer都有一個唯一的diff-idchain-id:chain-id是根據parent的chain-id和自身的diff-id生成的,假如沒有parent,則chain-id等於diff-id,假如有parent,則chain-id等於sha256sum( “parent-chain-id diff-id”) cache-id:隨機生成的64個16進位制數。cache-id標識了這個layer的資料具體存放位置
資料卷
volume是存在於一個或多個容器中的特定檔案或資料夾,這個目錄以獨立聯合檔案系統的形式存在於宿主機中
-
特點
-
容器建立時就會初始化,在容器執行時就可以使用其中的檔案
-
能在不同的容器中共享和重用
-
對volume中的資料操作不會影響到映象本身
-
生命週期獨立,即使刪除容器volume依然存在
Namespace
同一個namespace下的程序可以感知彼此的變化,而對外界程序一無所知
-
UTS 隔離主機名與域名
-
IPC 隔離訊號量、訊息佇列和共享記憶體
-
PID 隔離程序編號
-
不同的PID namespaces會形成一個層級體系
-
每個pid namespace的第一個程序 pid 1會像傳統linux的init程序號一樣擁有特權
-
Net 隔離網路裝置、網路棧、埠
-
Mount 隔離掛載點(檔案系統)
-
User 隔離使用者和使用者組
例子
mkdir newroot cd newroot cp -r /bin/ binchroot newrootexit
Cgroup
根據需求把一系列的系統任務和子任務整合到按資源劃分等級的不同組內,從而為系統資源管理提供一個統計的框架
主要作用
-
資源限制
-
優先順序分配
-
資源統計
-
任務控制
主要特點
-
cgroup的api是以一個為檔案系統的方式實現,使用者態的程式可以通過檔案操作實現cgroup的組織管理
-
組織管理操作單元可以細粒度到執行緒級別,可以建立和銷燬cgroup從而實現資源再分配和管理
-
所有資源管理的功能都以子系統的方式實現,介面統一
-
子任務建立之初與父任務處於同一個cgroups控制組
相關術語
task
表示系統的一個程序或執行緒
cgroup
按某種資源控制標準劃分而成的任務組,包含一個或多個子系統
-
實現形式表現為一個檔案系統mount -t cgroup
-
docker實現
-
會在單獨掛載了每一個子系統的控制組目錄下建立一個名為docker的控制組
-
在docker控制組裡面再為每個容器建立一個容器id為名稱的容器控制組
-
容器裡的所有程序號都會寫到該控制組tasks中,並在控制組檔案cpu.cfs_quota_us中寫入預設的限制引數值
-
工作原理
-
本質上來說,cgroups是核心附加在程式上的一系列鉤子,通過程式執行時對資源的排程觸發相應的鉤子以達到資源追蹤和限制的目的
-
程序所需記憶體超過它所屬cgroup最大限制以後,如果設定了oom control,程序會收到oom訊號並結束,否則程序會掛起,進入睡眠狀態,直到cgroup中的其他程序釋放了足夠的記憶體資源為止
subsystem
資源排程器,cpu子系統可以控制cpu分配時間(/sys/fs/cgroup/cpu/docker/)
-
blkio 可以為塊裝置設定輸入、輸出限制,比如物理驅動裝置(磁碟、固態硬碟、USB)
-
cpu 使用排程程式控制任務對CPU的使用
-
cpuacct 自動生成cgroup中任務對cpu資源使用情況的報告
-
cpuset 為cgroup中的任務分配獨立的cpu和記憶體
-
devices 可以開啟或關閉cgroup中任務對裝置的訪問
-
freezer 可以掛起或恢復cgroup中的任務
-
memory 可以設定cgroup中任務對記憶體使用量的限定
-
perf_event 使用後使cgroup中的任務可以進行統一的效能測試
-
net_cls 通過使用等級識別符標記網路資料包,從而允許linux流量控制程式(traffic controller)識別從具體cgroup中生成的資料包
hierachy
層級是由一系列cgroup以一個樹狀結構排列而成,每個層級通過繫結對應的子系統進行資源控制
依賴其他的核心能力
-
seccomp(secure computing mode)
安全計算模式,這個模式可以設定容器在對系統進行呼叫時進行一些篩選,也就是所謂的白名單。 是一種簡潔的sandboxing機制。能使一個程序進入到一種“安全”執行模式,該模式下的程序只能呼叫4種系統呼叫(system calls),即read(), write(), exit()和sigreturn(),否則程序便會被終止。 -
SELinux
安全增強式Linux(SELinux, Security-Enhanced Linux)是一種強制訪問控制(mandatory access control)的實現 -
Netlink
用來讓不同的容器之間進行通訊,可用於程序間通訊,Linux核心與使用者空間的程序間、使用者程序間的通訊 -
Netfilter
Linux核心中的一個軟體框架,用於管理網路資料包。
不僅具有網路地址轉換(NAT)的功能,也具備資料包內容修改、以及資料包過濾等防火牆功能。 -
AppArmor
類似於selinux,主要的作用是設定某個可執行程式的訪問控制權限,可以限制程式 讀/寫某個目錄/檔案,開啟/讀/寫網路埠等等 -
capability
Linux把原來和超級使用者相關的高階許可權劃分成為不同的單元,稱為Capability,可以單獨啟用或者關閉, 它打破了UNIX/LINUX作業系統中超級使用者/普通使用者的概念,由普通使用者也可以做只有超級使用者可以完成的工作
網路原理
一些概念
-
net namespace
隔離網路棧,有自己的介面、路由、防火牆規則 -
bridge
相當於交換機,為連線在其上的裝置轉發資料幀 -
veth
相當於交換機上的埠,是一對虛擬網絡卡,用於不同網路空間進行通訊的方式,從一張veth網絡卡發出的資料包可以直接到達它的peer veth -
gateway
就是一個網路連線到另一個網路的“關口”,與本地網路連線的機器會把向外的流量傳遞到此地址中從而使那個地址成為本地子網以外的IP地址的"閘道器". -
iptables
linux核心的包過濾系統。在3、4層提供規則鏈對包進行標記、偽裝、轉發等
兩個例子
通過虛擬網絡卡實現2個namespace通訊
1、建立虛擬網路環境 ip netns add net0 ip netns add net12、在虛擬的net0環境中執行 ip netns exec net0 ifconfig -aip netns exec net0 ping localhost ip netns exec net0 ip link set lo up ip netns exec net0 ping localhost3、建立一對虛擬網絡卡 ip link add type veth4、把veth0移動到net0環境裡面,把veth1移動到net1環境裡面 ip link set veth0 netns net0 ip link set veth1 netns net14、配置虛擬網絡卡 ip netns exec net0 ip link set veth0 up ip netns exec net0 ip address add 10.0.1.1/24 dev veth0 ip netns exec net1 ip link set veth1 up ip netns exec net1 ip address add 10.0.1.2/24 dev veth15、測試 ip netns exec net0 ping -c 3 10.0.1.2ip netns exec net0 ping -c 3 10.0.1.1ip netns exec net1 ping -c 3 10.0.1.1
通過網橋實現多個namespace通訊及外網訪問原理
1、建立虛擬網路環境並連線網線 ip netns add net0 ip netns add net1 ip netns add bridge ip link add type veth ip link set dev veth0 name net0-bridge netns net0 ip link set dev veth1 name bridge-net0 netns bridge ip link add type veth ip link set dev veth0 name net1-bridge netns net1 ip link set dev veth1 name bridge-net1 netns bridge2、在bridge中建立虛擬網橋 ip netns exec bridge brctl addbr br ip netns exec bridge ip link set dev br up ip netns exec bridge ip link set dev bridge-net0 up ip netns exec bridge ip link set dev bridge-net1 up ip netns exec bridge brctl addif br bridge-net0 ip netns exec bridge brctl addif br bridge-net1 ip netns exec bridge brctl show3、配置虛擬環境網絡卡 ip netns exec net0 ip link set dev net0-bridge up ip netns exec net0 ip address add 10.0.1.1/24 dev net0-bridge ip netns exec net1 ip link set dev net1-bridge up ip netns exec net1 ip address add 10.0.1.2/24 dev net1-bridge4、測試 ip netns exec net0 ping -c 3 10.0.1.2ip netns exec net1 ping -c 3 10.0.1.1ip netns exec bridge ping -c 3 10.0.1.25、需要給當前網路環境配置一個網絡卡ip不然沒有網路路由網路不可達 ip netns exec bridge ip address add 10.0.1.3/24 dev br6、想要ping宿主機網路怎麼辦? ip netns exec bridge ping 192.168.99.100ip link add A type veth peer name B ip link set B netns bridge ip netns exec bridge ip link set dev B up ip link set A up6、給AB網絡卡配置ip ip netns exec bridge ip address add 172.22.0.11/24 dev B ip address add 172.22.0.10/24 dev A7、設定bridge預設閘道器 ip netns exec bridge route add default gw 172.22.0.10ip netns exec bridge ping 192.168.99.1008、設定net0預設閘道器 ip netns exec net0 ping 192.168.99.100ip netns exec net0 route add default gw 10.0.1.3ip netns exec net0 ping 192.168.99.100 不通9、地址偽裝 ip netns exec bridge iptables -t nat -A POSTROUTING -o B -j MASQUERADE ip netns exec net0 ping 192.168.99.10010、讓虛擬網絡卡訪問外網 ip netns exec net0 ping 8.8.8.8iptables -t filter -I FORWARD -o A -j ACCEPT iptables -t filter -I FORWARD -i A -j ACCEPT iptables -t nat -A POSTROUTING -o eth0 -s 172.22.0.0/24 -j MASQUERADE11、vbox訪問mac地址 ip netns exec bridge ping 192.168.99.1iptables -t nat -A POSTROUTING -o eth1 -j MASQUERADE ip netns exec bridge ping 192.168.99.1
影響網路連通的幾個要素
-
核心是否開啟IP轉發支援
cat /proc/sys/net/ipv4/ip_forward
sysctl -w net.ipv4.ip_forward=1 -
防火牆轉發規則是否開啟
-
是否開啟IP地址偽裝
-
是否正確設定閘道器
CNM網路模型
-
沙盒,一個沙盒包含了一個容器網路棧資訊。沙盒可以對容器的介面、路由和DNS設定等進行管理。一個沙盒可以有多個端點和多個網路。
-
端點,一個端點可以加入一個沙盒和一個網路。端點的實現可以使veth pair、open vSwitch內部埠。
-
網路,一個網路是一組可以互相聯通的端點。網路的實現可以是linux bridge、VLAN等。
內建驅動
-
bridge
預設設定,libnetwork將創建出來的容器連線到docker網橋。其與外界使用NAT.操作例子
docker network create br3 docker run -itd --name busybox-bridge --net=br3 busybox docker run -itd --name busybox-bridge-none busybox docker network connect br3 busybox-bridge-none 檢視容器網路和宿主機網橋及其上埠
-
host
libnetwork不為docker容器建立網路協議棧及獨立的network namespace。 -
容器使用宿主機的網絡卡、IP、埠、路由、iptable規則
-
host驅動很好的解決了容器與外界通訊的地址轉換問題,但也降低了容器與容器建、容器與宿主機之間的網路隔離性,引起網路資源競爭的衝突。
例子
docker run -itd --name busybox-host --net=host busybox
-
container
-
指定新建立的容器和已存在的容器共享一個網路空間
-
兩個容器的程序可以通過lo網絡卡裝置通訊
例子
docker run -itd --name busybox busyboxdocker run -itd --name busybox-container --net=container:busybox-bridge busybox
-
none
容器擁有自己的network namespace,但不進行任何網路配置。例子
docker run -itd --name busybox-none --net=none busybox
-
overlay
-
使用標準的VXLAN
-
使用過程中需要一個額外的配置儲存服務如consul、etcd、Zookeeper
-
需要在daemon啟動的時候額外新增引數來指定配置儲存服務地址
-
remote
實現外掛化,呼叫使用者自行實現的網路驅動外掛
DNAT來實現外部訪問容器
docker run -itd -p 9901:991 --name busybox-dnat busybox
容器雲平臺
雲平臺廠家
-
時速雲
-
靈雀雲
-
有容雲
-
阿里雲容器服務
-
騰訊雲容器服務