目錄
文章目錄
- 目錄
- 容器網路的發展趨勢
- CNI
- Flannel
- Callico
- Weave
- Macvlan
- ServiceMesh + CNI
- Docker 容器網路
- bridge 模式
- host 模式
- macvlan 模式
- Container 模式
- none 模式
- Overlay 模式
- 容器埠映射
容器網路的發展趨勢

CNI
CNI(Container Network Interface,容器網路介面)是 Google 和 CoreOS 主導制定的容器網路標準,它是在 RKT 網路提議的基礎上發展起來的,綜合考慮了靈活性、擴展性、IP 分配、多網卡等因素,
CNI 旨在為容器平臺提供網路的標準化,不同的容器平臺(e.g. Kubernetes、Mesos 和 RKT)能夠通過相同的介面呼叫不同的網路組件,這個協議連接了兩個組件:
- 容器管理系統
- 網路插件
具體的事情都是插件來實作的,包括:創建容器網路空間(network namespace)、把網路介面(interface)放到對應的網路空間、給網路介面分配 IP 等,
目前采用 CNI 提供的方案一般分為兩種
- 隧道方案
- 路由方案
具體為:Flannel,Callico,Weave 和 macvlan 網路方案,從難易度上來講,Callico 最簡單,其次 Flannel,Weave 最復雜,從網路技術來看,Weave 和 Flannel 都是網路封裝隧道技術,區別在于封裝的位置在網路設備上還是主機上,

Flannel

Flannel 是 CoreOS 提出用于解決容器集群跨主機通訊的網路解決方案,Flannel 實質上是一種 Overlay 網路,也就是將 TCP 資料包裝在另一種網路包里面進行路由轉發和通信,目前已支持 UDP、VXLAN、AWS VPC、GCE 路由等資料轉發方式,其中以 VXLAN 技術最為流行,很多資料中心在考慮引入容器時,也考慮將網路切換到 Flannel 的 VXLAN 網路中來,
Flannel 為每個主機分配一個 Subnet,容器從此 Subnet 中分配 IP,這些 IP 可在主機間路由,容器間無需 NAT 和埠映射就可以跨主機通訊,Flannel 讓集群中不同節點主機創建容器時都具有全集群唯一虛擬 IP 地址,并連通主機節點網路,Flannel 可為集群中所有節點重新規劃 IP 地址使用規則,從而使得不同節點上的容器能夠獲得 “同屬一個內網” 且 “不重復的” 的 IP 地址,讓不同節點上的容器能夠直接通過內網 IP 通信,網路封裝部分對容器是不可見的,源主機服務將原本資料內容 UDP 封裝后根據自己的路由表投遞給目的節點,資料到達以后被解包,然后直接進入目的節點虛擬網卡,然后直接達到目的主機容器虛擬網卡,實作網路通信目的,
Flannel 雖然對網路要求較高,要引入封裝技術,轉發效率也受到影響,但是卻可以平滑過渡到 SDN 網路,VXLAN 技術可以和 SDN 很好地結合起來,值得整個網路實作自動化部署,智能化運維和管理,較適合于新建資料中心網路部署,
Callico

Callico 容器網路和其他虛擬網路最大的不同是:它沒有采用 Overlay 網路做報文轉發,提供了純三層網路模型,三層通信模型表示每個容器都通過 IP 直接通信,要想路由作業能夠正常,每個容器所在的主機節點必須有某種方法知道整個集群的路由資訊,Callico 采用 BGP 路由協議,使得全網所有的 Node 和網路設備都記錄到全網路由,
然而這種方式會產生很多的無效路由,對網路設備路由規格要求較大,整網不能有路由規格低的設備,另外,Callico 實作了從源容器經過源宿主機,經過資料中心路由,然后到達目的宿主機,最后分配到目的容器,整個程序中始終都是根據 BGP 協議進行路由轉發,并沒有進行封包,解包程序,這樣轉發效率就會快得多,這是 Callico 容器網路的技術優勢,
Weave

Weave 實質上也是 Overlay 網路,Weave 可以把不同主機上容器互相連接的網路虛擬成一個類似于本地網路的網路,不同主機之間都使用自己的私有 IP 地址,當容器分布在多個不同的主機上時,通過 Weave 可以簡化這些容器之間的通信,
Weave 網路中的容器使用標準的埠提供服務(e.g. MySQL 默認使用 3306),管理微服務是十分直接簡單的,每個容器都可以通過域名來與另外的容器通信,也可以直接通信而無需使用 NAT,也不需要使用埠映射或者復雜的聯接,
部署 Weave 容器網路最大的好處是無需修改你的應用代碼,Weave 通過在容器集群的每個主機上啟動虛擬路由器,將主機作為路由器,形成互聯互通的網路拓撲,在此基礎上,實作容器的跨主機通信,
要部署 Weave 需要確保主機 Linux 內核版本在 3.8 以上,Docker1.10 以上,主機間訪問如果有防火墻,則防火墻必須彼此放行 TCP 6783 和 UDP 6783/6784 這些埠號,這些是 Weave 控制和資料埠,主機名不能相同,Weave 要通過主機名識別子網,
Weave 網路類似于主機 Overlay 技術,直接在主機上進行報文流量的封裝,從而實作主機到主機的跨 Underlay 三層網路的互訪,這是和 Flannel 網路的最大區別,Flannel 是一種網路 Overlay 方案,
Macvlan
Macvlan 是 Linux Kernel 比較新的特性,允許在主機的一個網路介面上配置多個虛擬的網路介面,這些網絡 interface 有自己獨立的 MAC 地址,也可以配置上 IP 地址進行通信,macvlan 下的虛擬機或者容器網路和主機在同一個網段中,共享同一個廣播域,macvlan 和 bridge 比較相似,但因為它省去了 bridge 的存在,所以配置和除錯起來比較簡單,而且效率也相對高,除此之外,macvlan 自身也完美支持 VLAN,
ServiceMesh + CNI

ServiceMesh 和 CNI 是組合的關系,ServiceMesh 并不會替代 CNI,他們作業在不同的 SDN 層次,CNI 更多作業在 L2-4 層,ServiceMesh 在 L5-7 層 Application SDN,ServiceMesh 不能獨立于 CNI 部署,與 CNI 一起提供層次化微服務應用所需要的網路服務,根據 Gartner 報告指出,在 2020 年,幾乎 100% 容器云都將內置 ServiceMesh 技術,而目前開源的Istio 僅提供單一 Kubernetes 集群內部微服務治理,缺失異構容器云,跨云能力,
CNI 需要交付給容器云 L2-4 層細化至微服務內部的每個 POD 容器,應用終端交付所需要的 L2 網路連接,L3 路由,L2-4 層安全隔離,容器云整體安全,負載均衡等,
ServiceMesh 更多的致力于微服務應用層面的服務治理,致力于 L5-7 層網路服務,服務網格在每一個應用容器前部署一個 Sidecar Envoy 應用代理,提供微服務間的智能路由,分布式負載均衡,流量管理,藍綠,金絲雀發布,微服務彈性,限流熔斷,超時重試,微服務間的可視化,安全等等,
·
Docker 容器網路
Docker 提供幾種型別的網路,它決定容器之間、容器與外界之前的通信方式,
-
基礎網路型別

-
查看所有容器網路型別:
$ docker network ls
NETWORK ID NAME DRIVER SCOPE
c79756cf9cde bridge bridge local
204025a5abbc host host local
9b9024f5ac40 macvlan macvlan local
6478888548d8 none null local
p2e02u1zhn8x overlay overlay swarm
bridge 模式
bridge 模式的 Docker 網路基于 Linux 的虛擬網路技術來實作,Docker Container 的網路介面默認都是虛擬介面,可以充分發揮資料在不同 Container 之間或跨主機的 Container 之間的轉發效率,這是因為 Linux 虛擬網路技術通過在內核中的資料復制來實作虛擬介面之間的資料轉發,即:發送介面的發送快取中的資料包將被直接復制到接收介面的接收快取中,而無需通過外部物理網路設備進行交換,
當 Docker Daemon 啟動后,會在宿主機上創建一個名為 docker0 的 Linux Bridge,在此宿主機上啟動的 Docker Container 都會連接到這個虛擬網橋上,Docker Daemon 會從 docker0(一個虛擬的 L2 網路)子網中分配一個 IP 給 Container 使用,并設定 docker0 的 IP 地址為 Container 的默認網關,同時,在宿主機上創建一對 veth pair 虛擬網線設備,Docker Daemon 將 veth pair 設備的一端插入新建的 Container 中,并命名為eth0(容器的網卡),另一端插入 docker0 Linux Bridge 中,以 vethxxx 格式命名,
在這個網路的容器之間可以相互通信,外界想要訪問到這個網路中的 Containers 也同樣需要接入 bridge 網路并通過 iptables 做了 DNAT 規則,實作內外部地址轉換,

$ ip a
3: docker0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP group default
link/ether 02:42:46:c3:00:eb brd ff:ff:ff:ff:ff:ff
inet 172.17.0.1/16 scope global docker0
valid_lft forever preferred_lft forever
inet6 fe80::42:46ff:fec3:eb/64 scope link
valid_lft forever preferred_lft forever
$ docker run -itd --name box1 busybox
$ docker exec -it box1 sh
/ # ip a
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue qlen 1000
link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
inet 127.0.0.1/8 scope host lo
valid_lft forever preferred_lft forever
inet6 ::1/128 scope host
valid_lft forever preferred_lft forever
6: eth0@if7: <BROADCAST,MULTICAST,UP,LOWER_UP,M-DOWN> mtu 1500 qdisc noqueue
link/ether 02:42:ac:11:00:02 brd ff:ff:ff:ff:ff:ff
inet 172.17.0.2/16 scope global eth0
valid_lft forever preferred_lft forever
inet6 fe80::42:acff:fe11:2/64 scope link
valid_lft forever preferred_lft forever
/ # ip r
default via 172.17.0.1 dev eth0
172.17.0.0/16 dev eth0 scope link src 172.17.0.2
$ brctl show
bridge name bridge id STP enabled interfaces
docker0 8000.024246c300eb no vethd4ae072
host 模式
如果啟動 Container 的時候使用 host 模式,那么這個容器將不會獲得一個獨立的 Network Namespace,而是和宿主機共用一個 Network Namespace,也就是說 Container 不會虛擬出自己的網卡,配置自己的 IP 等,而是直接使用宿主機的 IP 和埠,
當然,Container 的其他方面,如:檔案系統、行程串列等還是和宿主機隔離的,只用這種網路的容器會使用主機的網路,這種網路對外界是完全開放的,能夠訪問到主機,就能訪問到容器,
$ docker run -itd --network host --name box2 busybox
$ docker exec -it box2 sh
/ # ip a
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue qlen 1000
link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
inet 127.0.0.1/8 scope host lo
valid_lft forever preferred_lft forever
inet6 ::1/128 scope host
valid_lft forever preferred_lft forever
2: eth0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast qlen 1000
link/ether fa:16:3e:94:84:10 brd ff:ff:ff:ff:ff:ff
inet 172.18.22.204/24 brd 172.18.22.255 scope global dynamic eth0
valid_lft 48054sec preferred_lft 48054sec
inet6 fe80::f816:3eff:fe94:8410/64 scope link
valid_lft forever preferred_lft forever
3: docker0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue
link/ether 02:42:46:c3:00:eb brd ff:ff:ff:ff:ff:ff
inet 172.17.0.1/16 scope global docker0
valid_lft forever preferred_lft forever
inet6 fe80::42:46ff:fec3:eb/64 scope link
valid_lft forever preferred_lft forever
7: vethd4ae072@if6: <BROADCAST,MULTICAST,UP,LOWER_UP,M-DOWN> mtu 1500 qdisc noqueue master docker0
link/ether ce:95:19:64:d0:d4 brd ff:ff:ff:ff:ff:ff
inet6 fe80::cc95:19ff:fe64:d0d4/64 scope link
valid_lft forever preferred_lft forever
macvlan 模式
對于某些應用程式,比如需要監視網路流量,期望直接連接到物理網路,這種情況下,可以使用 macvlan 的網路模式,macvlan 驅動程式不僅將 IP 地址分配給容器,而且還將物理 MAC 地址分配給容器,通過 macvlan 還可以實作跨主機容器之前的通信,
- 創建一個 macvlan 網路:
docker network create -d macvlan --subnet=172.16.86.0/24 --gateway=172.16.86.1 -o parent=eth0 macvlan1
- 設定網卡為混雜模式:
ip link set eth0 promisc on
- 創建使用 macvlan 網路的容器:
docker run -it --network macvlan1 --ip=172.16.86.2 busybox /bash
Container 模式
Container 模式,又稱為 Docker links,是一種 Docker Container 之間的通信機制,如果一個新容器鏈接到一個已有容器,新容器將會通過環境變數獲得已有容器的鏈接資訊,通過提供給信任容器有關已有容器的鏈接資訊,實作容器間的通信,
Container 模式和 host 模式很類似,只是 Container 模式創建容器共享的是其他容器的 IP 和 Port 而不是物理機的,此模式容器自身是不會配置網路和埠,創建此模式的容器進去后會發現里邊的 IP 是你所指定的那個容器 IP 并且 Port 也是共享的,當然,其它還是互相隔離的,如行程等,
docker run -it --network container:<container ID>

none 模式
使用 none 模式 Container 會擁有自己的 Network Namespace,但是,并不為 Container 進行任何網路配置,也就是說,這個 Container 不會具有網卡、IP、路由等資訊,需要手動的為 Container 添加網卡、配置 IP 等,使用此種網路的容器會完全隔離,
使用的 none 模式后,這個容器就是封閉的,不會去參與網路通信,這樣就能夠保證容器的安全性,
$ docker run -itd --network none --name box3 busybox
$ docker exec -it box3 sh
/ # ip a
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue qlen 1000
link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
inet 127.0.0.1/8 scope host lo
valid_lft forever preferred_lft forever
inet6 ::1/128 scope host
valid_lft forever preferred_lft forever
Overlay 模式
Overlay 模式使用在 Swarm 集群中,用于連接跨主機 Docker Container,允許不同宿主機上的容器相互通信,Overlay 模式在 Docker 集群節點間加入了一層虛擬網路,它有獨立的虛擬網段,因此 Container 發送的內容,會先發送到虛擬子網,再由虛擬子網包裝為宿主機的真實網址進行發送,

# 初始化 manager node,
$ docker swarm init
# 添加 worker node 到 manager,
$ docker swarm join --token <token> <manager_host>:2377
# 新建一個 Overlay 網路
$ docker network create --driver=overlay --attachable overlay
# 分別在不同的 worker node 上啟動一個 busybox 容器,并連接到 Overlay 網路
$ docker run -it --network overlay --name box4 sh
如此的,在同一個 Overlay 網路上的跨主機 Container 就可以互相通信了,
基于 Swarm 我們還可以管理 Containers 集群服務,例如:創建一個具有五副本的連接到 Overlay 網路的 Nginx Cluster,暴露埠為 80:
$ docker service create --name my-nginx --publish target=80,published=80 --replicas=5 --network overlay nginx
在這個 Nginx Cluster 中,如果任一節點結束一個副本,那么集群服務就會重啟一個新的副本,以此保持所有 Worker Node 中的 Nginx 副本數量為五個,
容器埠映射
核心選項:
- -p 宿主機埠:將容器內應用監聽埠映射到物理宿主機的特定埠上,
示例:
- 自定義映射:
docker run -d -p 8888:80 nginx:latest

- 隨機映射
# 需要鏡像支持
docker run -P
轉載請註明出處,本文鏈接:https://www.uj5u.com/qianduan/154082.html
標籤:其他
下一篇:趣談鴻蒙,一文盡始終
