Docker 概念

Docker是基于容器的應(yīng)用開發(fā)售貌,部署和運(yùn)行平臺(tái)

  • 高性能:相比傳統(tǒng)虛擬機(jī),不需要hepervisor的額外負(fù)載,而是直接在主機(jī)內(nèi)核中運(yùn)行,可以在同一硬件上運(yùn)行更多工作負(fù)載
  • 持續(xù)交付和部署:通過container蜗细,在一個(gè)隔離環(huán)境中打包和運(yùn)行應(yīng)用程序的功能,保證一致的運(yùn)行環(huán)境怒详,非常適合持續(xù)集成和持續(xù)交付(CI Continuous Integration,CD Continuous Delivery )工作流程炉媒,通過利用Docker的方法快速分發(fā),測試和部署代碼昆烁,可以顯著減少編寫代碼和在生產(chǎn)中運(yùn)行代碼之間的延遲
  • 易于擴(kuò)展維護(hù)遷移吊骤,基于容器的特性允許高度可移植的工作負(fù)載,可以進(jìn)行集群的自動(dòng)化編排静尼,容器集群管理方案有:Swarm白粉,Kubernetes,Mesos等

docker_practice:github 上一個(gè)Docker的簡介

架構(gòu)

Docker Engine使用client-server架構(gòu)鼠渺,Docker client(docker鸭巴,是一個(gè)命令行接口,CLI)通過REST API和Docker daemon(dockerd)交互拦盹,服務(wù)端綁定在一個(gè)Unix socket上

  • Docker daemon:監(jiān)聽Docker API請(qǐng)求鹃祖,管理Docker對(duì)象,例如鏡像普舆,容器恬口,網(wǎng)絡(luò)校读,數(shù)據(jù)卷,daemon也可以和其他主機(jī)的daemon通信來管理Docker服務(wù)
  • Docker client:用戶與Docker交互的主要方式祖能,客戶端使用Docker API將命令發(fā)送到dockerd歉秫,后者將其執(zhí)行,Docker client可以與多個(gè)守護(hù)進(jìn)程通信
  • Docker registry:用于存儲(chǔ)Docker鏡像芯杀, Docker Hub和Docker Cloud是公共倉庫端考,Docker默認(rèn)在Docker Hub上查找鏡像,也可以運(yùn)行自己搭建的私有倉庫

容器原理

docker使用go語言編寫揭厚,它基于Linux內(nèi)核的namespace與Cgroups功能

Containers and virtual machines

容器直接運(yùn)行在Linux上却特,并與其他容器共享主機(jī)的內(nèi)核。它運(yùn)行一個(gè)獨(dú)立的進(jìn)程筛圆,不占用其他的內(nèi)存裂明,非常輕量級(jí),是基于操作系統(tǒng)的虛擬化技術(shù)太援,早期的Docker就是基于LXC(Linux Container)項(xiàng)目封裝了一套工具闽晦,后來重新設(shè)計(jì)了自己的虛擬化平臺(tái)并發(fā)布了Libcontainer項(xiàng)目,擺脫了對(duì)LXC的依賴

虛擬機(jī)(VM)運(yùn)行一個(gè)完整的客戶操作系統(tǒng)Cuest OS提岔,通過hypervisor對(duì)主機(jī)資源進(jìn)行虛擬訪問仙蛉,這樣做能夠比較好的實(shí)現(xiàn)虛擬機(jī)與宿主機(jī)操作系統(tǒng)的異構(gòu),例如Linux系統(tǒng)上跑Windows虛擬機(jī)碱蒙,VM需要提供的環(huán)境比大多數(shù)應(yīng)用程序需要的資源更多荠瘪,例如KVM, 全稱是基于內(nèi)核的虛擬機(jī)(Kernel-based Virtual Machine)赛惩,自Linux 2.6.20版本后就整合到內(nèi)核中哀墓,是一個(gè)輕量級(jí)的Hypervisor,依托CPU虛擬化指令集(例如Intel-VT喷兼,Virtualization Technology篮绰、AMD-V)實(shí)現(xiàn)高性能的虛擬化支持

從隔離上來講,虛擬機(jī)是用來對(duì)硬件資源進(jìn)行劃分季惯,屬于硬件虛擬化技術(shù)吠各,通過Hypervisor層來實(shí)現(xiàn)對(duì)資源的徹底隔離,容器是操作系統(tǒng)級(jí)別的虛擬化星瘾,利用內(nèi)核的特性實(shí)現(xiàn)走孽,不需要外部輔助

Namespaces

Docker使用namespaces技術(shù)來提供容器的隔離工作空間。當(dāng)運(yùn)行容器時(shí)琳状,Docker會(huì)為該容器創(chuàng)建一組名稱空間磕瓷。這些命名空間提供了一層隔離。容器的每個(gè)方面都在一個(gè)單獨(dú)的命名空間中運(yùn)行,其訪問權(quán)限僅限于該命名空間,名稱空間種類如下:

  • The cgroup namespace:CGroup isolation(CGoup: Control Group).讓不同進(jìn)程組看到的CGroup規(guī)則各不相同困食,為不同進(jìn)程組采用各自的配額標(biāo)準(zhǔn)提供便利
  • The pid namespace: Process isolation (PID: Process ID).基于進(jìn)程的隔離能力边翁,容器中的首個(gè)進(jìn)程成為PID為1的進(jìn)程,是所有進(jìn)程的父進(jìn)程硕盹,以及很多特權(quán)
  • The net namespace: Managing network interfaces (NET: Networking).基于網(wǎng)絡(luò)棧的隔離能力符匾,容器中的進(jìn)程和特定的網(wǎng)絡(luò)關(guān)聯(lián)起來
  • The ipc namespace: Managing access to IPC resources (IPC: InterProcess Communication).基于System V進(jìn)程信道的隔離能力
  • The mnt namespace: Managing filesystem mount points (MNT: Mount).基于磁盤掛載點(diǎn)和文件系統(tǒng)的隔離能力
  • The uts namespace: Isolating kernel and version identifiers. (UTS: Unix Timesharing System).基于主機(jī)名的隔離能力
  • The user namespace:基于系統(tǒng)用戶的隔離能力,同一用戶在不同namespace中可以擁有不同的UID和GID
# 查看進(jìn)程的namespace
$ ls -l /proc/$$/ns
總用量 0
lrwxrwxrwx 1 wdy wdy 0 9月  17 15:08 cgroup -> cgroup:[4026531835]
lrwxrwxrwx 1 wdy wdy 0 9月  17 15:08 ipc -> ipc:[4026531839]
lrwxrwxrwx 1 wdy wdy 0 9月  17 15:08 mnt -> mnt:[4026531840]
lrwxrwxrwx 1 wdy wdy 0 9月  17 15:08 net -> net:[4026531957]
lrwxrwxrwx 1 wdy wdy 0 9月  17 15:08 pid -> pid:[4026531836]
lrwxrwxrwx 1 wdy wdy 0 9月  17 15:08 user -> user:[4026531837]
lrwxrwxrwx 1 wdy wdy 0 9月  17 15:08 uts -> uts:[4026531838]

Control groups

Linux上的Docker Engine還依賴于另一種稱為控制組(cgroups)的技術(shù)瘩例。cgroup將應(yīng)用程序限制到特定的一組資源啊胶。控制組允許Docker Engine將可用的硬件資源共享給容器垛贤,也可以強(qiáng)制執(zhí)行限制和約束焰坪。例如限制特定容器的CPU,內(nèi)存聘惦,磁盤IO等

$ cat /proc/$$/cgroup
11:cpuset:/
10:net_cls,net_prio:/
9:devices:/user.slice
8:perf_event:/
7:freezer:/
6:pids:/user.slice/user-1000.slice
5:cpu,cpuacct:/user.slice
4:memory:/user.slice
3:blkio:/user.slice
2:hugetlb:/
1:name=systemd:/user.slice/user-1000.slice/session-c2.scope

本質(zhì)上對(duì)CGroup的所有操作都是對(duì)系統(tǒng)掛載的CGroup目錄進(jìn)行修改某饰,在/sys/fs/cgroup/<controller>目錄下創(chuàng)建新的目錄

Union file systems

聯(lián)合文件系統(tǒng)或UnionFS是通過創(chuàng)建layer來操作的文件系統(tǒng),使它們非常輕量和快速善绎。Docker Engine使用UnionFS為容器提供構(gòu)建塊黔漂。Docker Engine可以使用多種UnionFS,包括AUFS禀酱,btrfs炬守,vfs和DeviceMapper

Container format

Docker Engine將命名空間,控制組和UnionFS組合到一個(gè)稱為容器格式的包裝器中剂跟。默認(rèn)的容器格式是libcontainer劳较。將來,Docker可能支持其他容器格式


Docker基本概念

Images

Docker鏡像依照OCI(Open Container Initiative)規(guī)范浩聋,是一個(gè)只讀模板(內(nèi)容在構(gòu)建之后不會(huì)改變),一個(gè)image由manifest臊恋、image index(可選)衣洁、filesystem layersconfiguration四部分組成

鏡像采用分層的結(jié)構(gòu),可以最大化利用磁盤存儲(chǔ)抖仅,因?yàn)榇蠖鄶?shù)的鏡像都會(huì)基于一些標(biāo)準(zhǔn)的基礎(chǔ)鏡像來構(gòu)建坊夫,分層存儲(chǔ)方便重復(fù)利用

最底層bootfs(boot file system)是一個(gè)引導(dǎo)文件系統(tǒng),Linux在啟動(dòng)后之后撤卢,整個(gè)內(nèi)核都會(huì)被加載進(jìn)內(nèi)环凿,bootfs會(huì)被卸載掉,之上是rootfs放吩,即經(jīng)典的目錄結(jié)構(gòu)智听,對(duì)于base image來說,底層直接用hostkernel,自己只需要提供rootfs就行了到推,對(duì)應(yīng)的所有容器都共用hostkernel

使用Dockerfile創(chuàng)建image考赛,Dockerfile中的每條指令都在鏡像中創(chuàng)建一個(gè)層,每安裝一個(gè)軟件莉测,就在現(xiàn)有鏡像的基礎(chǔ)上增加一層,鏡像的每一層都可以被共享颜骤,例如多個(gè)鏡像都從相同的base鏡像構(gòu)建而來,那么主機(jī)只需在磁盤上保存一份base鏡像捣卤,更改Dockerfile并重建映像時(shí)忍抽,僅重建那些已更改的層,這使鏡像輕量董朝,小巧和快速

當(dāng)容器啟動(dòng)時(shí)鸠项,一個(gè)新的可寫層被加載到鏡像的頂部。這一層通常被稱作容器層 container layer益涧,“容器層”之下的都叫“鏡像層”锈锤,對(duì)容器的改動(dòng) - 無論添加、刪除闲询、還是修改文件都只會(huì)發(fā)生在容器層中久免,只有容器層是可寫的,容器層具有Copy-on-Write特性扭弧,下面的所有鏡像層都是只讀的阎姥,當(dāng)需要修改時(shí)才復(fù)制一份數(shù)據(jù)到容器層進(jìn)行修改「肽恚可見呼巴,容器層保存的是鏡像變化的部分,不會(huì)對(duì)鏡像本身進(jìn)行任何修改

鏡像和層

docker使用UnionFS文件系統(tǒng)御蒲,它能將多個(gè)文件系統(tǒng)的內(nèi)容合并起來衣赶,形成一個(gè)單一的掛載點(diǎn),掛到同一個(gè)目錄下厚满,底層使用copy on write技術(shù)府瞄,對(duì)文件的修改的會(huì)被向上拷貝到文件系統(tǒng)的一個(gè)臨時(shí)分層里,不會(huì)影響文件系統(tǒng)的原始數(shù)據(jù)碘箍,Docker支持眾多的聯(lián)合文件系統(tǒng)遵馆,可以在啟動(dòng)Docker后臺(tái)服務(wù)時(shí)通過--storage-driver參數(shù)制定所使用的容器存儲(chǔ)種類,例如aufx丰榴,overlay2货邓,devicemapper等

Containers

容器是鏡像的可運(yùn)行實(shí)例,可以通過Docker API或CLI創(chuàng)建四濒,啟動(dòng)换况,停止职辨,移動(dòng)或刪除容器「绰。可以將容器連接到一個(gè)或多個(gè)網(wǎng)絡(luò)拨匆,并連接上存儲(chǔ),也可以根據(jù)其當(dāng)前狀態(tài)創(chuàng)建新的鏡像挽拂。

默認(rèn)情況下惭每,容器與其他容器以及宿主機(jī)相對(duì)隔離,但是可以自由控制容器的網(wǎng)絡(luò)亏栈,存儲(chǔ)或其他底層子系統(tǒng)與其他容器或宿主機(jī)的隔離程度台腥。容器由其鏡像以及在創(chuàng)建或啟動(dòng)時(shí)為其提供的配置選項(xiàng)定義,容器內(nèi)的文件是和宿主機(jī)隔離開的绒北,如果不進(jìn)行數(shù)據(jù)卷掛載黎侈,容器關(guān)閉以后數(shù)據(jù)就會(huì)丟失

Services

Service允許在多個(gè)Docker daemons中擴(kuò)展容器,一起作為一個(gè)swarm集群工作闷游,內(nèi)部具有多個(gè)manager和worker節(jié)點(diǎn)峻汉。swarm的每個(gè)成員都是Docker daemon,并且都使用Docker API進(jìn)行通信脐往。 可以再服務(wù)中定義所需的狀態(tài)休吠,例如服務(wù)副本數(shù)。默認(rèn)情況下业簿,服務(wù)在所有工作節(jié)點(diǎn)之間進(jìn)行負(fù)載平衡瘤礁。 對(duì)于訪問者來說,Docker服務(wù)似表現(xiàn)的就像一個(gè)單獨(dú)的應(yīng)用程序梅尤。Docker Engine在Docker 1.12及以上版本中支持swarm模式柜思,進(jìn)行集群服務(wù)管理


部署層次

Containers

Docker通過讀取Dockerfile中的指令自動(dòng)構(gòu)建鏡像,Dockerfile是一個(gè)文本文檔巷燥,定義了容器環(huán)境內(nèi)進(jìn)行的操作赡盘。在容器內(nèi)對(duì)網(wǎng)絡(luò)接口磁盤等資源的訪問是虛擬化的,與系統(tǒng)的其他部分隔離缰揪,因此需要在dockerfile中將端口映射到宿主機(jī)亡脑,具體說明要“復(fù)制”到哪些文件到容器,掛載數(shù)據(jù)卷等邀跃,然后就可以啟動(dòng)一個(gè)運(yùn)行鏡像的容器

Services

在分布式應(yīng)用程序中,應(yīng)用程序的不同部分稱為“services”蛙紫。例如拍屑,如果一個(gè)視頻共享站點(diǎn),它可能包括一個(gè)用于將應(yīng)用程序數(shù)據(jù)存儲(chǔ)在數(shù)據(jù)庫中的服務(wù)坑傅,一個(gè)用戶上傳內(nèi)容后進(jìn)行視頻轉(zhuǎn)碼的服務(wù)僵驰,前端web服務(wù)等

服務(wù)實(shí)際上只是“工作狀態(tài)的容器”,一個(gè)服務(wù)只運(yùn)行一個(gè)鏡像,但它設(shè)定了鏡像的運(yùn)行方式蒜茴,包括應(yīng)該使用哪些端口星爪,應(yīng)該運(yùn)行多少個(gè)容器副本,以及服務(wù)具有所需的容量粉私,等等顽腾。擴(kuò)展一個(gè)服務(wù)會(huì)改變運(yùn)行該部分程序的容器的數(shù)量,為該服務(wù)分配更多計(jì)算資源诺核,通過YAML文件即可定義抄肖,運(yùn)行和擴(kuò)展服務(wù)

Stacks

stack是一組關(guān)聯(lián)的services,它們共享依賴關(guān)系窖杀,并且可以被一起編排縮放漓摩。堆棧能夠定義和協(xié)調(diào)整個(gè)應(yīng)用程序的功能,對(duì)外體現(xiàn)為多個(gè)容器組合而成的復(fù)雜系統(tǒng)

docker stack deploy -c docker-compose.yml stack_nameXXX

Swarm

Docker Swarm是docker的原生集群入客,用于多個(gè)機(jī)器上創(chuàng)建容器集群服務(wù)管毙,一個(gè)swarm是運(yùn)行Docker并加入一個(gè)群集的一組計(jì)算機(jī),集群中的機(jī)器被稱為node桌硫。該模塊叫做Swarm Mode夭咬,早期版本中叫做Swarm standalone

內(nèi)部使用Etcd中的Raft模塊確定Master節(jié)點(diǎn),raft是分布式一致性協(xié)議鞍泉,用于解決在網(wǎng)絡(luò)集群中進(jìn)行狀態(tài)確認(rèn)的問題

# Manage nodes in a swarm
docker node ls
ID                            HOSTNAME            STATUS              AVAILABILITY        MANAGER STATUS      ENGINE VERSION
4zrcf6u6gfwvpgw7ygcj2rrt5 *   gpu-server5         Ready               Active              Leader              18.06.1-ce
wyndarmh11o1qpt6yqy8717xs     gpu-server7         Ready               Active                                  18.06.1-ce

AVAILABILITY 列表示調(diào)度器是否可以向該節(jié)點(diǎn)分配任務(wù)

Active 正常
Pause不能分配新的任務(wù)皱埠,但是已有task可以繼續(xù)運(yùn)行
Drain 不能分配新的任務(wù),調(diào)度器關(guān)閉已有的Task咖驮,在其他節(jié)點(diǎn)上運(yùn)行边器,通常用于對(duì)節(jié)點(diǎn)進(jìn)行維護(hù)升級(jí)

MANAGER STATUS列顯示節(jié)點(diǎn)在Raft的角色:

  • 沒有值表示不參與群組管理的工作節(jié)點(diǎn)
  • Leader表明節(jié)點(diǎn)是primary manager node,對(duì)集群進(jìn)行管理和編排
  • Reachable該節(jié)點(diǎn)是參與Raft共識(shí)仲裁的manager托修。 如果leader節(jié)點(diǎn)變得不可用忘巧,則該節(jié)點(diǎn)有資格被選為新leader
  • Unavailable意味著該manager節(jié)點(diǎn)無法與其他manage通信

Swarm manager是集群中唯一可以執(zhí)行命令的機(jī)器,或授權(quán)其他機(jī)器作為worker加入群集,worker只執(zhí)行工作睦刃,沒有權(quán)力調(diào)度集群

Docker Machine

Docker Machine是一個(gè)工具砚嘴,用于在虛擬機(jī)上安裝Docker Engine,并使用docker-machine命令管理這些主機(jī)


數(shù)據(jù)管理

在Docker的使用過程中往往需要對(duì)數(shù)據(jù)進(jìn)行持久化涩拙,或者需要在多個(gè)容器之間進(jìn)行數(shù)據(jù)共享际长,所以這就涉及到Docker容器的數(shù)據(jù)操作


  • Volumes方式下:容器內(nèi)的數(shù)據(jù)被存放到宿主機(jī)(linux)一個(gè)特定的目錄下(/var/lib/docker/volumes/)。這個(gè)目錄只有Docker可以管理兴泥,其他進(jìn)程不能修改工育。如果想持久保存容器的應(yīng)用數(shù)據(jù),Volumes是Docker推薦的掛載方式
  • Bind mounts方式下:容器內(nèi)的數(shù)據(jù)被存放到宿主機(jī)文件系統(tǒng)的任意位置搓彻,甚至存放到一些重要的系統(tǒng)目錄或文件中如绸。除了Docker之外的進(jìn)程也可以任意對(duì)他們進(jìn)行修改
  • tmpfs方式下:容器的數(shù)據(jù)只會(huì)存放到宿主機(jī)的內(nèi)存中嘱朽,不會(huì)被寫到宿主機(jī)的文件系統(tǒng)中,因此不能持久保存容器的應(yīng)用數(shù)據(jù)怔接。

Volumes

由Docker創(chuàng)建和管理搪泳,可以通過命令docker volume create來現(xiàn)式創(chuàng)建一個(gè)卷,也可以由Docker在創(chuàng)建容器或服務(wù)的過程中來創(chuàng)建

當(dāng)創(chuàng)建一個(gè)volume時(shí)扼脐,它將會(huì)被存儲(chǔ)到宿主機(jī)的一個(gè)目錄下/lib/docker/volumes/<volumn-name>岸军,當(dāng)掛載這個(gè)volume到一個(gè)容器中時(shí),就是掛載這個(gè)目錄到容器中谎势。這和bind mount的工作機(jī)制很相似凛膏,但是volume是被Docker所管理并與宿主機(jī)其他核心功能隔離

一個(gè)volume可以被同時(shí)掛載到多個(gè)容器中。當(dāng)沒有任何容器在使用這個(gè)volume的時(shí)候脏榆,這個(gè)volume也仍然可以被Docker獲取猖毫,并不會(huì)被自動(dòng)被刪除⌒胛梗可以使用命令刪除不使用的volume:docker volume prune

當(dāng)掛載一個(gè)volume時(shí)吁断,可以選擇為他命名(named),也可以匿名(anonymous). 匿名volume首次被掛載到一個(gè)容器中時(shí)坞生,Docker會(huì)給它一個(gè)隨機(jī)的名字仔役,保證在宿主機(jī)操作系統(tǒng)中這個(gè)volume的名字是唯一的。除了名字之外是己,命名和匿名的volume沒有區(qū)別又兵。

Volume也支持使用volume drivers,用來將數(shù)據(jù)保存到遠(yuǎn)程主機(jī)或云上

Bind mounts

在docker的早期版本中就存在該功能卒废,與volumes相比沛厨,他的功能比較局限。當(dāng)使用bind mounts時(shí)摔认,宿主機(jī)的目錄或文件被掛載到容器中。容器將按照掛載目錄或文件的絕對(duì)路徑來使用或修改宿主機(jī)的中的數(shù)據(jù)参袱。宿主機(jī)中的目錄或文件不需要預(yù)先存在电谣,在需要的時(shí)候會(huì)自動(dòng)創(chuàng)建。使用Bind mounts在性能上是非常好的抹蚀,但這依賴于宿主機(jī)有一個(gè)目錄結(jié)構(gòu)妥善的文件系統(tǒng)剿牺。如果你要?jiǎng)?chuàng)建一個(gè)新的Docker應(yīng)用,推薦使用named volume的方式环壤,因?yàn)槟銦o法通過Docker CLI來管理bind mounts

bind mounts是一把雙刃劍晒来,因?yàn)榭梢栽谕ㄟ^容器內(nèi)部的進(jìn)程對(duì)主機(jī)文件系統(tǒng)進(jìn)行修改,包括創(chuàng)建镐捧,修改和刪除重要的系統(tǒng)文件和目錄潜索,這個(gè)功能雖然很強(qiáng)大,但顯然也會(huì)造成安全方面的影響懂酱,包括影響到宿主機(jī)上Docker以外的進(jìn)程

tmpfs mounts

僅Linux系統(tǒng)支持竹习,容器內(nèi)的應(yīng)用數(shù)據(jù)將不會(huì)被持久的保存到硬盤上,其中的數(shù)據(jù)只能在某個(gè)容器的生存周期內(nèi)被使用列牺,用于保存一些不需要持久存儲(chǔ)整陌,或一些敏感的數(shù)據(jù)信息。比如瞎领,在docker內(nèi)部泌辫,swarm服務(wù)使用tmpfs方式來將secrets掛載到服務(wù)容器中

Bind mounts和volumes都可以通過使用標(biāo)志v--volume來掛載到容器中,只是格式有些許不同九默。tmpfs可以使用標(biāo)志-tmpfs進(jìn)行掛載震放。在Docker17.06及其以上版本中,推薦使用--mount來對(duì)容器或服務(wù)進(jìn)行這三種方式的掛載驼修,因?yàn)檫@種格式更加清晰


網(wǎng)絡(luò)

Docker網(wǎng)絡(luò)模塊主要依賴libnetwork殿遂,依照Container Network Model (CNM) 實(shí)現(xiàn)

網(wǎng)絡(luò)模型

CNM:Container Network Model,容器的標(biāo)準(zhǔn)網(wǎng)絡(luò)模型乙各,只要符合這個(gè)模型的網(wǎng)絡(luò)接口就能被用于容器之間的通信墨礁,通信的細(xì)節(jié)和過程完全由網(wǎng)絡(luò)接口實(shí)現(xiàn),涉及三個(gè)術(shù)語:

  • Sandbox:對(duì)應(yīng)一個(gè)網(wǎng)絡(luò)環(huán)境耳峦,包括網(wǎng)卡配置恩静、路由表、DNS配置等
  • Endpoint:容器中的虛擬網(wǎng)卡蹲坷,顯示為eth0驶乾、eth1
  • Network:能夠相互通信的容器網(wǎng)絡(luò),加入了同一個(gè)網(wǎng)絡(luò)的容器可以直接通過對(duì)方的名字相互連接冠句,實(shí)體是主機(jī)上的虛擬網(wǎng)卡或網(wǎng)橋

CNI標(biāo)準(zhǔn):Container Networking Interface 另一個(gè)輕量級(jí)的應(yīng)用容器網(wǎng)絡(luò)的開放插件化標(biāo)準(zhǔn)轻掩,多數(shù)容器集群架構(gòu)都使用該標(biāo)準(zhǔn),例如Kubernetes懦底、Mesos

  • Container:擁有獨(dú)立Network Namespace的運(yùn)行單元唇牧,與CNM的Sandbox概念基本一致
  • Network:可以互相連接的一組實(shí)體,實(shí)體擁有各自獨(dú)立的唯一IP地址聚唐,例如容器丐重,物理機(jī)或網(wǎng)關(guān)、路由器等網(wǎng)絡(luò)設(shè)備杆查,相當(dāng)于CNM的Network加Endpoint概念

容器網(wǎng)絡(luò)涉及的其他技術(shù):

  • Virtual Bridge:虛擬的網(wǎng)絡(luò)交換單元扮惦,功能相當(dāng)于交換機(jī),為連在其中的設(shè)備轉(zhuǎn)發(fā)數(shù)據(jù)幀亲桦,例如Docker默認(rèn)創(chuàng)建的docker0網(wǎng)橋
  • iptable:內(nèi)置在內(nèi)核中的基于規(guī)則的網(wǎng)絡(luò)防火墻和包轉(zhuǎn)發(fā)服務(wù)崖蜜,為容器提供于NAT和網(wǎng)絡(luò)安全相關(guān)的特性
  • Veth(Virtual Ethernet Device) Pair浊仆,由兩個(gè)虛擬網(wǎng)卡組成的數(shù)據(jù)通道,用于不同network namespace間進(jìn)行通信豫领,例如veth pair 一端連接到容器中作為eth0網(wǎng)卡抡柿,另一端連接到docker0網(wǎng)橋,將容器的數(shù)據(jù)發(fā)往另一個(gè) network namespace

Docker的網(wǎng)絡(luò)實(shí)現(xiàn)

Docker網(wǎng)絡(luò)共有四種模式


  1. none
    容器內(nèi)只有回環(huán)網(wǎng)絡(luò)等恐,容器擁有自己獨(dú)立的network namespace洲劣,但不進(jìn)行配置,通常在容器不需要網(wǎng)絡(luò)或者自定義網(wǎng)絡(luò)時(shí)使用
  2. host
    直接使用host的網(wǎng)絡(luò)课蔬,容器共享宿主機(jī)的network namespace囱稽,使用的是宿主機(jī)的IP、端口等資源
  3. bridge
    docker的默認(rèn)網(wǎng)絡(luò)模式二跋,docker在安裝時(shí)會(huì)創(chuàng)建一個(gè)名為docker0的Linux bridge战惊,默認(rèn)網(wǎng)段是172.17.0.0/16,在不指定network的情況下同欠,新建的容器都會(huì)通過veth pair默認(rèn)掛到docker0上样傍,并在該網(wǎng)段內(nèi)獲取一個(gè)IP,在同一個(gè)網(wǎng)橋內(nèi)的容器可以通過IP地址通信铺遂,外部以及不同網(wǎng)絡(luò)之間的通信需要通過映射到主機(jī)的端口衫哥,底層依靠iptables實(shí)現(xiàn)端口轉(zhuǎn)發(fā)功能

容器與宿主機(jī)通信:在橋接模式下,Docker Daemon 將 veth0 附加到 docker0 網(wǎng)橋上襟锐,保證宿主機(jī)的報(bào)文有能力發(fā)往 veth0撤逢。再將 veth1 添加到 Docker 容器所屬的網(wǎng)絡(luò)命名空間,保證宿主機(jī)的網(wǎng)絡(luò)報(bào)文若發(fā)往 veth0 可以立即被 veth1 收到

容器與外界通信:容器如果需要聯(lián)網(wǎng)粮坞,則需要采用 NAT方式蚊荣。準(zhǔn)確的說,是 NATP (網(wǎng)絡(luò)地址端口轉(zhuǎn)換) 方式莫杈。NATP 包含兩種轉(zhuǎn)換方式:SNAT 和 DNAT

  • 目的 NAT (Destination Network Address Translation互例,DNAT): 修改數(shù)據(jù)包的目的地址。


  • 源 NAT (Source Network Address Translation筝闹,SNAT): 修改數(shù)據(jù)包的源地址


  1. overlap
    overlap網(wǎng)絡(luò)驅(qū)動(dòng)程序在多個(gè)Docker daemon主機(jī)之間創(chuàng)建分布式的網(wǎng)絡(luò)媳叨。該網(wǎng)絡(luò)(overlap)位于主機(jī)網(wǎng)絡(luò)之上,允許連接到它的容器進(jìn)行通信关顷。它基于VxLAN實(shí)現(xiàn)糊秆,原理就是進(jìn)行額外的裝包、拆包议双,因?yàn)楝F(xiàn)有網(wǎng)絡(luò)只認(rèn)識(shí)節(jié)點(diǎn)到節(jié)點(diǎn)的路由痘番,容器間通信時(shí)將數(shù)據(jù)包加上額外的傳輸協(xié)議包頭(ISO網(wǎng)絡(luò)模型二層或以上協(xié)議),先將數(shù)據(jù)傳輸?shù)侥康墓?jié)點(diǎn),解包后傳輸?shù)侥康娜萜?/li>

初始化swarm或?qū)ocker主機(jī)加入現(xiàn)有swarm時(shí)汞舱,會(huì)在該Docker主機(jī)上創(chuàng)建兩個(gè)新網(wǎng)絡(luò):

  • 一個(gè)名為ingressoverlay網(wǎng)絡(luò)伍纫,用于處理與swarm service相關(guān)的控制和數(shù)據(jù)流量。創(chuàng)建swarm service時(shí)昂芜,如果不將其連接到用戶定義的overlay網(wǎng)絡(luò)翻斟,則默認(rèn)下會(huì)連接到ingress網(wǎng)絡(luò)
  • 一個(gè)名為docker_gwbridge的bridge網(wǎng)絡(luò),所有加入swarm的主機(jī)上都有該網(wǎng)橋说铃,且網(wǎng)段是相同的

端口相關(guān):

  • TCP 端口 2377 用來進(jìn)行集群管理通信
  • TCP UDP 端口 7946 用來節(jié)點(diǎn)之間通信
  • UDP 端口 4789 用來進(jìn)行覆蓋網(wǎng)絡(luò)的通信

容器網(wǎng)絡(luò)還有另外一種經(jīng)典模式,Container模式:該模式下啟動(dòng)的容器將和指定的其他容器共享network namespace嘹履,該模式也是Kubernetes使用的網(wǎng)絡(luò)模式

跨結(jié)點(diǎn)網(wǎng)絡(luò)

基本條件

  • 對(duì)IP分配進(jìn)行規(guī)劃腻扇,使得每個(gè)容器對(duì)應(yīng)不同的IP地址
  • 記錄容器IP和宿主機(jī)IP的映射關(guān)系

解決方案:
集群IP統(tǒng)一分配,通常會(huì)給每個(gè)主機(jī)分配一個(gè)IP段砾嫉,每個(gè)主機(jī)會(huì)知道當(dāng)前節(jié)點(diǎn)所有容器的路由規(guī)則幼苛,以及集群所有IP段到對(duì)應(yīng)主機(jī)的路由規(guī)則,路由過程中首先是源容器將數(shù)據(jù)發(fā)送到目標(biāo)容器所在的主機(jī)節(jié)點(diǎn)焕刮,然后由目標(biāo)主機(jī)的本地路由規(guī)則將數(shù)據(jù)包送到真正的目標(biāo)容器
此外該中心地址分配器需要保證穩(wěn)定性舶沿,例如Flannal和Calico通過Etcd服務(wù)存儲(chǔ)網(wǎng)絡(luò)分配信息,內(nèi)部使用一致性協(xié)議Raft保證消息的可靠性

  • 覆蓋網(wǎng)絡(luò):主要是基于VxLAN實(shí)現(xiàn)夸節(jié)點(diǎn)網(wǎng)絡(luò)
    • Docker內(nèi)置的overlap網(wǎng)絡(luò)
    • Flannel的UDP和VxLAN模式
  • 擴(kuò)展路由:讓容器的IP和主機(jī)的IP地址一樣配并,直接進(jìn)行通信括荡,不需要額外的封裝,具體有macvlan溉旋,節(jié)點(diǎn)網(wǎng)關(guān)路由畸冲,節(jié)點(diǎn)BGP路由三種
    • Docker的macvlan網(wǎng)絡(luò)模式
    • Caliao基于節(jié)點(diǎn)BGP協(xié)議的路由方案,可以直接利用數(shù)據(jù)中心的網(wǎng)絡(luò)結(jié)構(gòu)观腊,不需要額外的NAT邑闲、隧道或者Overlay Network,沒有額外的封包解包梧油,提升網(wǎng)絡(luò)效率
    • Flannel的HostGW模式:基于內(nèi)核路由表和Iptable規(guī)則的路由方案

macvlan技術(shù)在主機(jī)網(wǎng)卡上添加多個(gè)MAC地址(需要硬件設(shè)備的支持)苫耸,對(duì)應(yīng)上多個(gè)IP,每個(gè)網(wǎng)卡分配給容器的不同Network Namespace儡陨,就相當(dāng)于把所有容器的網(wǎng)絡(luò)都直接相連到了主機(jī)網(wǎng)卡

節(jié)點(diǎn)網(wǎng)關(guān)路由:每個(gè)節(jié)點(diǎn)上運(yùn)行一個(gè)Agent服務(wù)褪子,監(jiān)聽容器IP段的分配,一旦由變化就將新的路由規(guī)則刷新到內(nèi)核路由表迄委,每個(gè)節(jié)點(diǎn)上的Agent就是一個(gè)控制網(wǎng)絡(luò)聯(lián)通規(guī)則的網(wǎng)關(guān)程序褐筛,這種方法稱為主機(jī)網(wǎng)關(guān)

節(jié)點(diǎn)BGP路由:如果節(jié)點(diǎn)直接隔著一個(gè)路由器,節(jié)點(diǎn)網(wǎng)關(guān)路由就會(huì)失效叙身,路由器沒有相應(yīng)的路由規(guī)則渔扎,此時(shí)需要Agent把自己作為容器所在IP子網(wǎng)段的邊界路由器,利用BGP協(xié)議讓網(wǎng)絡(luò)中的其他三層設(shè)備學(xué)習(xí)到容器網(wǎng)段的路由信息

Flannel容器網(wǎng)絡(luò)方案

Flannel實(shí)現(xiàn)原理

  • 每個(gè)主機(jī)上的Docker容器分配互相不沖突的IP地址
  • 在這些IP地址之間建立一個(gè)覆蓋網(wǎng)絡(luò)

Flannel會(huì)啟動(dòng)flanneld進(jìn)程信轿,連接etcd晃痴,管理IP地址段的分配残吩,初始時(shí)獲取一個(gè)未分配的地址段糜俗,然后在Docker的啟動(dòng)參數(shù)中指定docker0網(wǎng)橋的地址蛤虐,flannel之間的底層通信協(xié)議有很多,例如UDP味抖,VxLAN等紧唱,通過在應(yīng)用層進(jìn)行封裝活尊、解包進(jìn)行通信

 --bip=172.24.77.1/24
# ifconfig 中的部分?jǐn)?shù)據(jù)
docker0: flags=4099<UP,BROADCAST,MULTICAST>  mtu 1500
        inet 172.24.77.1  netmask 255.255.255.0  broadcast 172.24.77.255

flannel.1: flags=4163<UP,BROADCAST,RUNNING,MULTICAST>  mtu 1450
        inet 172.24.77.0  netmask 255.255.255.255  broadcast 0.0.0.0
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市漏益,隨后出現(xiàn)的幾起案子蛹锰,更是在濱河造成了極大的恐慌,老刑警劉巖绰疤,帶你破解...
    沈念sama閱讀 206,482評(píng)論 6 481
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件铜犬,死亡現(xiàn)場離奇詭異,居然都是意外死亡轻庆,警方通過查閱死者的電腦和手機(jī)癣猾,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 88,377評(píng)論 2 382
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來余爆,“玉大人纷宇,你說我怎么就攤上這事《攴剑” “怎么了呐粘?”我有些...
    開封第一講書人閱讀 152,762評(píng)論 0 342
  • 文/不壞的土叔 我叫張陵,是天一觀的道長转捕。 經(jīng)常有香客問我作岖,道長,這世上最難降的妖魔是什么五芝? 我笑而不...
    開封第一講書人閱讀 55,273評(píng)論 1 279
  • 正文 為了忘掉前任痘儡,我火速辦了婚禮,結(jié)果婚禮上枢步,老公的妹妹穿的比我還像新娘沉删。我一直安慰自己,他們只是感情好醉途,可當(dāng)我...
    茶點(diǎn)故事閱讀 64,289評(píng)論 5 373
  • 文/花漫 我一把揭開白布矾瑰。 她就那樣靜靜地躺著,像睡著了一般隘擎。 火紅的嫁衣襯著肌膚如雪殴穴。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 49,046評(píng)論 1 285
  • 那天,我揣著相機(jī)與錄音采幌,去河邊找鬼劲够。 笑死,一個(gè)胖子當(dāng)著我的面吹牛休傍,可吹牛的內(nèi)容都是我干的征绎。 我是一名探鬼主播,決...
    沈念sama閱讀 38,351評(píng)論 3 400
  • 文/蒼蘭香墨 我猛地睜開眼磨取,長吁一口氣:“原來是場噩夢啊……” “哼人柿!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起忙厌,我...
    開封第一講書人閱讀 36,988評(píng)論 0 259
  • 序言:老撾萬榮一對(duì)情侶失蹤顷扩,失蹤者是張志新(化名)和其女友劉穎,沒想到半個(gè)月后慰毅,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 43,476評(píng)論 1 300
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡扎阶,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 35,948評(píng)論 2 324
  • 正文 我和宋清朗相戀三年汹胃,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片东臀。...
    茶點(diǎn)故事閱讀 38,064評(píng)論 1 333
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡着饥,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出惰赋,到底是詐尸還是另有隱情宰掉,我是刑警寧澤,帶...
    沈念sama閱讀 33,712評(píng)論 4 323
  • 正文 年R本政府宣布赁濒,位于F島的核電站轨奄,受9級(jí)特大地震影響,放射性物質(zhì)發(fā)生泄漏拒炎。R本人自食惡果不足惜挪拟,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,261評(píng)論 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望击你。 院中可真熱鬧玉组,春花似錦、人聲如沸丁侄。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,264評(píng)論 0 19
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽鸿摇。三九已至石景,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背鸵钝。 一陣腳步聲響...
    開封第一講書人閱讀 31,486評(píng)論 1 262
  • 我被黑心中介騙來泰國打工糙臼, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人恩商。 一個(gè)月前我還...
    沈念sama閱讀 45,511評(píng)論 2 354
  • 正文 我出身青樓变逃,卻偏偏與公主長得像,于是被迫代替她去往敵國和親怠堪。 傳聞我的和親對(duì)象是個(gè)殘疾皇子揽乱,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 42,802評(píng)論 2 345

推薦閱讀更多精彩內(nèi)容