Docker網絡解決方案-Calico部署記錄
阿新 • • 發佈:2018-02-07
name urn 而且 導入 created lease aml modprobe class Calico簡單簡介
Calico是一個純三層的協議,為OpenStack虛機和Docker容器提供多主機間通信。Calico不使用重疊網絡比如flannel和libnetwork重疊網絡驅動, 它是一個純三層的方法,使用虛擬路由代替虛擬交換,每一臺虛擬路由通過BGP協議傳播可達信息(路由)到剩余數據中心。
Calico 架構
Calico 是一個三層的數據中心網絡方案,而且方便集成 OpenStack 這種 IaaS 雲架構,能夠提供高效可控的 VM、容器、裸機之間的通信。
結合上面這張圖,我們來過一遍 Calico 的核心組件: Felix,Calico agent,跑在每臺需要運行 workload 的節點上,主要負責配置路由及 ACLs 等信息來確保 endpoint 的連通狀態; etcd,分布式鍵值存儲,主要負責網絡元數據一致性,確保 Calico 網絡狀態的準確性; BGP Client(BIRD), 主要負責把 Felix 寫入 kernel 的路由信息分發到當前 Calico 網絡,確保 workload 間的通信的有效性; BGP Route Reflector(BIRD), 大規模部署時使用,摒棄所有節點互聯的 mesh 模式,通過一個或者多個BGP Route Reflector來完成集中式的路由分發; 通過將整個互聯網的可擴展 IP 網絡原則壓縮到數據中心級別,Calico 在每一個計算節點利用Linux kernel實現了一個高效的vRouter來負責數據轉發而每個vRouter通過BGP 協議負責把自己上運行的 workload 的路由信息像整個 Calico 網絡內傳播 - 小規模部署可以直接互聯,大規模下可通過指定的 BGP route reflector 來完成。 這樣保證最終所有的 workload 之間的數據流量都是通過 IP 包的方式完成互聯的。
Calico原理
Calico 節點組網可以直接利用數據中心的網絡結構(支持 L2 或者 L3),不需要額外的 NAT,隧道或者 VXLAN overlay network。
如上圖所示,這樣保證這個方案的簡單可控,而且沒有封包解包,節約 CPU 計算資源的同時,提高了整個網絡的性能。
此外,Calico 基於 iptables 還提供了豐富而靈活的網絡 policy, 保證通過各個節點上的 ACLs 來提供 workload 的多租戶隔離、安全組以及其他可達性限制等功能。
calico網絡通信模型
calico是純三層的SDN 實現,它基於BPG 協議和Linux自身的路由轉發機制,不依賴特殊硬件,容器通信也不依賴iptables NAT或Tunnel 等技術。 能夠方便的部署在物理服務器、虛擬機(如 OpenStack)或者容器環境下。同時calico自帶的基於iptables的ACL管理組件非常靈活,能夠滿足比較復雜的安全隔離需求。 在主機網絡拓撲的組織上,calico的理念與weave類似,都是在主機上啟動虛擬機路由器,將每個主機作為路由器使用,組成互聯互通的網絡拓撲。當安裝了calico的主機組成集群後, 其拓撲如下圖所示:
每個主機上都部署了calico/node作為虛擬路由器,並且可以通過calico將宿主機組織成任意的拓撲集群。當集群中的容器需要與外界通信時, 就可以通過BGP協議將網關物理路由器加入到集群中,使外界可以直接訪問容器IP,而不需要做任何NAT之類的復雜操作。 當容器通過calico進行跨主機通信時,其網絡通信模型如下圖所示:
從上圖可以看出,當容器創建時,calico為容器生成veth pair,一端作為容器網卡加入到容器的網絡命名空間,並設置IP和掩碼,一端直接暴露在宿主機上, 並通過設置路由規則,將容器IP暴露到宿主機的通信路由上。於此同時,calico為每個主機分配了一段子網作為容器可分配的IP範圍,這樣就可以根據子網的 CIDR為每個主機生成比較固定的路由規則。 當容器需要跨主機通信時,主要經過下面的簡單步驟: 1)容器流量通過veth pair到達宿主機的網絡命名空間上。 2)根據容器要訪問的IP所在的子網CIDR和主機上的路由規則,找到下一跳要到達的宿主機IP。 3)流量到達下一跳的宿主機後,根據當前宿主機上的路由規則,直接到達對端容器的veth pair插在宿主機的一端,最終進入容器。 從上面的通信過程來看,跨主機通信時,整個通信路徑完全沒有使用NAT或者UDP封裝,性能上的損耗確實比較低。但正式由於calico的通信機制是完全基於三層的,這種機制也帶來了一些缺陷,例如: 1)calico目前只支持TCP、UDP、ICMP、ICMPv6協議,如果使用其他四層協議(例如NetBIOS協議),建議使用weave、原生overlay等其他overlay網絡實現。 2)基於三層實現通信,在二層上沒有任何加密包裝,因此只能在私有的可靠網絡上使用。 3)流量隔離基於iptables實現,並且從etcd中獲取需要生成的隔離規則,有一些性能上的隱患。
Calico實現Docker跨主機容器通信的示例配置說明
1)環境準備
機器信息 node1:10.10.172.201 centos7.2 安裝Docker、etcd、calicoctl node2:10.10.172.202 centos7.2 安裝Docker、etcd、calicoctl node3:10.10.172.203 centos7.2 安裝Docker、etcd、calicoctl 設置三臺機器的主機名 node1 [root@node1 ~]# hostnamectl --static set-hostname node1 node2 [root@node2 ~]# hostnamectl --static set-hostname node2 node3 [root@node3 ~]# hostnamectl --static set-hostname node3 關閉三臺主機的防火墻。若開啟iptables防火墻,則需要打開2380端口通信。 [root@node1 ~]# systemctl disable firewalld.service [root@node1 ~]# systemctl stop firewalld.service 在三臺機器上都要設置hosts,均執行如下命令: [root@node1 ~]# vim /etc/hosts 10.10.172.201 node1 10.10.172.202 node2 10.10.172.203 node3
2)安裝docker環境
三個節點都要安裝docker [root@node1 ~]# yum install -y docker [root@node1 ~]# systemctl start docker [root@node1 ~]# docker pull nginx [root@node1 ~]# docker images REPOSITORY TAG IMAGE ID CREATED SIZE docker.io/nginx latest 3448f27c273f 6 days ago 109.4 MB 在三個節點上配置docker網橋,三個網橋指定為不同的網絡,網絡配置細節如下: node1節點,Docker網橋網絡指定為192.168.10.1/24 [root@node1 ~]# systemctl stop docker [root@node1 ~]# ip link set dev docker0 down [root@node1 ~]# brctl delbr docker0 [root@node1 ~]# brctl addbr bridge0 [root@node1 ~]# ip addr add 192.168.10.1/24 dev bridge0 //註意,這個192.168.10.1就是所建容器的網關地址。通過docker inspect container_id能查看到 [root@node1 ~]# ip link set dev bridge0 up [root@node1 ~]# ip addr show bridge0 [root@node1 ~]# vim /etc/sysconfig/docker //即將虛擬的橋接口由默認的docker0改為bridge0 將 OPTIONS='--selinux-enabled --log-driver=journald' 改為 OPTIONS='--selinux-enabled --log-driver=journald -b=bridge0' //即添加-b=bridge0 [root@node1 ~]# systemctl restart docker [root@node1 ~]# ifconfig //發現只有bridge0虛擬網橋,沒有默認的docker0網橋了。(如果還有docker0,就再次執行"ip link set dev docker0 down && brctl delbr docker0 && systemctl restart docker) 與上面操作同理: node2節點的網橋網絡指定為192.168.20.1/24 node3節點的網橋網絡指定為192.168.30.1/24
3)安裝並配置etcd(這裏采用的是集群模式,建議做集群)
etcd 是一個分布式一致性k-v存儲系統,可用於服務註冊發現與共享配置,具有以下優點: 1)簡單:相比於晦澀難懂的paxos算法,etcd基於相對簡單且易實現的raft算法實現一致性,並通過gRPC提供接口調用 2)安全:支持TLS通信,並可以針對不同的用戶進行對key的讀寫控制 3)高性能:10,000/秒的寫性能 etcd是一個分布式高可用的鍵值(key/value)存儲系統,主要用於服務註冊發現與共享配置,etcd 會在集群的各個節點中復制這些數據並保證這些數據始終正確。具有以下優點: 1)簡單:相比於晦澀難懂的paxos算法,etcd基於相對簡單且易實現的raft算法實現一致性,並通過gRPC提供接口調用 2)安全:支持TLS通信,並可以針對不同的用戶進行對key的讀寫控制 3)高性能:10,000/秒的寫性能 etcd是由CoreOS開發並維護的,靈感來自於 ZooKeeper 和 Doozer,它使用Go語言編寫,並通過Raft一致性算法處理日誌復制以保證強一致性,有基於HTTP+JSON的API接口。 Raft是一個來自Stanford的新的一致性算法,適用於分布式系統的日誌復制,Raft通過選舉的方式來實現一致性,在Raft中,任何一個節點都可能成為Leader。Google的容器 集群管理系統Kubernetes、開源PaaS平臺Cloud Foundry和CoreOS的Fleet都廣泛使用了etcd。raft 共識算法的優點在於可以在高效的解決分布式系統中各個節點日誌內容一致 性問題的同時,也使得集群具備一定的容錯能力。即使集群中出現部分節點故障、網絡故障等問題,仍可保證其余大多數節點正確的步進。甚至當更多的節點(一般來說超過集 群節點總數的一半)出現故障而導致集群不可用時,依然可以保證節點中的數據不會出現錯誤的結果。 ---------------------------------------------------------------------------------------------------------------------------------- 在三個節點機上都要安裝etcd,構成etcd集群環境 (etcd下載:https://pan.baidu.com/s/1jIsTV3C 密碼:djcv) [root@node1 ~]# curl -L https://github.com/coreos/etcd/releases/download/v2.3.6/etcd-v2.3.6-linux-amd64.tar.gz -o etcd-v2.3.6-linux-amd64.tar.gz [root@node1 ~]# tar zxvf etcd-v2.3.6-linux-amd64.tar.gz [root@node1 ~]# cd etcd-v2.3.6-linux-amd64/ [root@node1 etcd-v2.3.6-linux-amd64]# 如上在三個節點機上安裝好etcd後,進行etcd靜態配置。 靜態配置主要預先將集群的配置信息分配好,然後將集群分布啟動,集群將根據配置信息組成集群。這裏按如下的配置信息分別啟動三個etcd。 在node1上的etcd配置: [root@node1 ~]# ./etcd --name node1 --initial--advertise-peer-urls http://10.10.172.201:2380 --listen-peer-urls http://0.0.0.0:2380 --listen-client-urls http://0.0.0.0:2379,http://127.0.0.1:4001 --advertise-client-urls http://0.0.0.0:2379 --initial-cluster-token etcd-cluster --initial-cluster node1=http://10.10.172.201:2380,node2=http://10.10.172.202:2380,node3=http://10.10.172.203:2380--initial-cluster-state new 在node2上的etcd配置: [root@node2 ~]# ./etcd --name node2 --initial--advertise-peer-urls http://10.10.172.202:2380 --listen-peer-urls http://0.0.0.0:2380 --listen-client-urls http://0.0.0.0:2379,http://127.0.0.1:4001 --advertise-client-urls http://0.0.0.0:2379 --initial-cluster-token etcd-cluster --initial-cluster node1=http://10.10.172.201:2380,node2=http://10.10.172.202:2380,node3=http://10.10.172.203:2380--initial-cluster-state new 在node3上的etcd配置: [root@node3 ~]# ./etcd --name node3 --initial--advertise-peer-urls http://10.10.172.203:2380 --listen-peer-urls http://0.0.0.0:2380 --listen-client-urls http://0.0.0.0:2379,http://127.0.0.1:4001 --advertise-client-urls http://0.0.0.0:2379 --initial-cluster-token etcd-cluster --initial-cluster node1=http://10.10.172.201:2380,node2=http://10.10.172.202:2380,node3=http://10.10.172.203:2380--initial-cluster-state new 按如上配置分別啟動集群,啟動集群後,將會進入集群選舉狀態,若出現大量超時,則需要檢查主機的防火墻是否關閉,或主機之間是否能通過2380端口通信,集群建立後通過以下命令檢查集群狀態。 特別註意一個細節: 上面的命令執行後會一直在前臺執行中,不能關閉當前終端窗口,關閉當前窗口後,上面啟動的etcd集群程序就會關閉!! 正確的做法是將其切到後臺執行,在上面etcd集群程序啟動後,依次: 1)按鍵ctrl+z 將其程序掛起,會出現一個序列號,一般為1 2)執行命令:bg 1 1就是上面掛起後出現的序列號 3)執行命令disown -a 這樣就將這個程序切到後臺運行了 然後關閉當前程序運行的終端窗口,然後ps -ef|grep etcd,會發現etcd的集群程序還在運行中: [root@node1 ~]# ps -ef|grep etcd root 13138 1 1 14:33 ? 00:00:07 ./etcd -name node1 --initial--advertise-peer-urls http://10.10.172.201:2380 --listen-peer-urls http://0.0.0.0:2380 --listen-client-urls http://0.0.0.0:2379,http://127.0.0.1:4001 --advertise-client-urls http://0.0.0.0:2379 --initial-cluster-token etcd-cluster --initial-cluster node1=http://10.10.172.201:2380,node2=http://10.10.172.202:2380,node3=http://10.10.172.203:2380 --initial-cluster-state new root 13226 13186 0 14:40 pts/1 00:00:00 grep --color=auto etcd [root@node1 ~]# lsof -i:2380 COMMAND PID USER FD TYPE DEVICE SIZE/OFF NODE NAME etcd 13138 root 5u IPv6 1827574 0t0 TCP *:2380 (LISTEN) etcd 13138 root 8u IPv6 1831276 0t0 TCP node1:2380->node3:60886 (ESTABLISHED) etcd 13138 root 11u IPv4 1827581 0t0 TCP node1:49991->node2:2380 (ESTABLISHED) 以上配置項說明(/root/etcd-v2.3.6-linux-amd64/etcd --help 查看幫助信息): --name etcd集群中的節點名,這裏可以隨意,可區分且不重復就行 ---listen-peer-urls 監聽的用於節點之間通信的url,可監聽多個,集群內部將通過這些url進行數據交互(如選舉,數據同步等) ---initial--advertise-peer-urls 建議用於節點之間通信的url,節點間將以該值進行通信。 ---listen-client-urls 監聽的用於客戶端通信的url,同樣可以監聽多個。 ---advertise-client-urls 建議使用的客戶端通信url,該值用於etcd代理或etcd成員與etcd節點通信。 ---initial-cluster-token etcd-cluster-1 節點的token值,設置該值後集群將生成唯一id,並為每個節點也生成唯一id,當使用相同配置文件再啟動一個集群時,只要該token值不一樣,etcd集群就不會相互影響。 ---initial-cluster 也就是集群中所有的initial--advertise-peer-urls 的合集 ---initial-cluster-state new 新建集群的標誌 查看集群成員(在三個節點機任意一個上面查看都可以,因為做的是集群環境): [root@node1 etcd-v2.3.6-linux-amd64]# ./etcdctl member list //如下,發現node1節點目前是leader 4590a741acf3f320: name=node1 peerURLs=http://10.10.172.201:2380 clientURLs=http://0.0.0.0:2379 isLeader=true 5e984e2093d56d63: name=node3 peerURLs=http://10.10.172.203:2380 clientURLs=http://0.0.0.0:2379 isLeader=false 951afc93e5278fdc: name=node2 peerURLs=http://10.10.172.202:2380 clientURLs=http://0.0.0.0:2379 isLeader=false 檢查集群健康狀態(在三個節點中的任意一個上面都可以查看) [root@node1 etcd-v2.3.6-linux-amd64]# ./etcdctl cluster-health member 4590a741acf3f320 is healthy: got healthy result from http://0.0.0.0:2379 member 5e984e2093d56d63 is healthy: got healthy result from http://0.0.0.0:2379 member 951afc93e5278fdc is healthy: got healthy result from http://0.0.0.0:2379 cluster is healthy 如上集群搭建成功。
4)啟動Calico服務(這是安裝最新版的做法,新版和老版的命令已有所改變)
首先在三個節點機上下載calico的命令管理工具calicoctl(百度雲下載地址:https://pan.baidu.com/s/1pKKTGbL 密碼:r7sm) [root@node1 ~]# wget http://www.projectcalico.org/builds/calicoctl [root@node1 ~]# chmod +x calicoctl [root@node1 ~]# mv calicoctl /usr/local/bin/ [root@node1 ~]# calicoctl --help //查看幫助信息 啟動Calico服務 在Docker環境中Calico服務是做為容器來運行的,使用host的網絡配置。所有容器配置使用Calico服務,做為calico節點互相通信。 Calico在每個主機上通過一個自己的container與其他主機或者網絡通訊,即calico-node的container,這個container裏面包含了Bird路由管理、Felix協議等。 千萬別忘了在三個節點上都要下載calico的node鏡像 (可以先在一個節點上下載鏡像,然後將鏡像通過docker save導出保存到本地,再將鏡像拷貝到其他節點上通過docker load導入,這樣對於其他節點來說,比使用docker pull要快) [root@node1 ~]# docker pull calico/node [root@node1 ~]# docker pull calico/node-libnetwork [root@node1 ~]# docker images REPOSITORY TAG IMAGE ID CREATED SIZE docker.io/calico/node latest 1e0928760e74 11 hours ago 255.2 MB docker.io/nginx latest 3448f27c273f 6 days ago 109.4 MB docker.io/calico/node-libnetwork latest 84d99cab9fc4 7 months ago 70.2 MB 下面分別在三個節點上,以Docker方式啟動calico-node(這個命令會執行一段時間,耐心等待......) node1 [root@node1 ~]# calicoctl node run --ip=10.10.172.201 Running command to load modules: modprobe -a xt_set ip6_tables Enabling IPv4 forwarding ....... Using node name: node1 Starting libnetwork service Calico node started successfully node2 [root@node2 ~]# calicoctl node run --ip=10.10.172.202 node3 [root@node3 ~]# calicoctl node run --ip=10.10.172.203 可以在三個節點上查看calico-node啟動情況 [root@node1 ~]# docker ps CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES 2ac613b1af9a quay.io/calico/node:latest "start_runit" 22 seconds ago Up 17 seconds calico-node [root@node1 ~]# ps -ef|grep calico root 14339 14336 0 15:43 ? 00:00:00 svlogd -tt /var/log/calico/bird6 root 14340 14336 0 15:43 ? 00:00:00 bird6 -R -s /var/run/calico/bird6.ctl -d -c /etc/calico/confd/config/bird6.cfg root 14341 14337 0 15:43 ? 00:00:00 svlogd /var/log/calico/confd root 14342 14337 0 15:43 ? 00:00:00 confd -confdir=/etc/calico/confd -interval=5 -watch -no-discover --log-level=debug -node=http://127.0.0.1:2379 -client-key= -client-cert= -client-ca-keys= root 14343 14334 0 15:43 ? 00:00:00 svlogd /var/log/calico/felix root 14344 14334 2 15:43 ? 00:00:03 calico-felix root 14346 14338 0 15:43 ? 00:00:00 svlogd /var/log/calico/libnetwork root 14349 14335 0 15:43 ? 00:00:00 svlogd -tt /var/log/calico/bird root 14350 14335 0 15:43 ? 00:00:00 bird -R -s /var/run/calico/bird.ctl -d -c /etc/calico/confd/config/bird.cfg root 14597 13854 0 15:45 pts/2 00:00:00 grep --color=auto calico 查看節點狀態信息(在三個節點上都可以查看) [root@node1 ~]# calicoctl node status Calico process is running. IPv4 BGP status +----------------+-------------------+-------+----------+-------------+ | PEER ADDRESS | PEER TYPE | STATE | SINCE | INFO | +----------------+-------------------+-------+----------+-------------+ | 10.10.172.202 | node-to-node mesh | up | 07:47:20 | Established | | 10.10.172.203 | node-to-node mesh | up | 07:52:55 | Established | +----------------+-------------------+-------+----------+-------------+ IPv6 BGP status No IPv6 peers found. [root@node2 ~]# calicoctl node status Calico process is running. IPv4 BGP status +----------------+-------------------+-------+----------+-------------+ | PEER ADDRESS | PEER TYPE | STATE | SINCE | INFO | +----------------+-------------------+-------+----------+-------------+ | 10.10.172.201 | node-to-node mesh | up | 07:46:19 | Established | | 10.10.172.203 | node-to-node mesh | up | 07:51:54 | Established | +----------------+-------------------+-------+----------+-------------+ IPv6 BGP status No IPv6 peers found. [root@node3 ~]# calicoctl node status Calico process is running. IPv4 BGP status +----------------+-------------------+-------+----------+-------------+ | PEER ADDRESS | PEER TYPE | STATE | SINCE | INFO | +----------------+-------------------+-------+----------+-------------+ | 10.10.172.201 | node-to-node mesh | up | 09:51:54 | Established | | 10.10.172.202 | node-to-node mesh | up | 09:51:54 | Established | +----------------+-------------------+-------+----------+-------------+ IPv6 BGP status No IPv6 peers found. 使用calicoctl創建ipPool 在啟動別的容器之前,我們需要配置一個IP地址池帶有ipip和nat-outgoing選項。所以帶有有效配置的容器就可以訪問互聯網,在每個節點上運行下面的命令: 先查看calico的ip池(任意一個節點上都能查看) [root@node1 ~]# calicoctl get ipPool CIDR 192.168.0.0/16 fd80:24e2:f998:72d6::/64 [root@node1 ~]# calicoctl get ippool -o wide CIDR NAT IPIP 192.168.0.0/16 true false fd80:24e2:f998:72d6::/64 true false 上面查出的192.168.0.0/16是calico默認的網絡。 可以使用命令"calicoctl delete ippool 192.168.0.0/16"刪除calico默認的網絡,這是非必要操作,可以保留calico默認的網絡! 現在開始在三個節點機器上使用calicoctl創建ipPool 創建ip pool首先定義一個資源文件ipPool.yaml,如下: node1節點機器上 [root@node1 ~]# vim ipPool.yaml apiVersion: v1 kind: ipPool metadata: cidr: 192.168.10.1/24 spec: ipip: enabled: true nat-outgoing: true disabled: false [root@node1 ~]# calicoctl create -f ipPool.yaml Successfully created 1 'ipPool' resource(s) [root@node1 ~]# calicoctl get ippool -o wide CIDR NAT IPIP 192.168.0.0/16 true false 192.168.10.1/24 true true //兩個true,說明使用了IPIP fd80:24e2:f998:72d6::/64 true false -------------------------------------------------------------------------------- 上面在創建ipPool的時候,使用了IPIP。也可以選擇不使用IPIP,如下:(這裏我選擇的是使用IPIP) [root@node1 ~]# vim ipPool.yaml apiVersion: v1 kind: ipPool metadata: cidr: 192.168.10.1/24 spec: ipip: enabled: false nat-outgoing: true disabled: false ------------------------------------------------------------------------------- 同理,node2節點機器上 [root@node2 ~]# vim ipPool.yaml apiVersion: v1 kind: ipPool metadata: cidr: 192.168.20.1/24 spec: ipip: enabled: true nat-outgoing: true disabled: false [root@node2 ~]# calicoctl create -f ipPool.yaml Successfully created 1 'ipPool' resource(s) [root@node2 ~]# calicoctl get ippool -o wide CIDR NAT IPIP 192.168.0.0/16 true false 192.168.10.1/24 true true 192.168.20.1/24 true true fd80:24e2:f998:72d6::/64 true false node3節點機器上 [root@node3 ~]# vim ipPool.yaml apiVersion: v1 kind: ipPool metadata: cidr: 192.168.30.1/24 spec: ipip: enabled: true nat-outgoing: true disabled: false [root@node3 ~]# calicoctl create -f ipPool.yaml Successfully created 1 'ipPool' resource(s) [root@node3 ~]# calicoctl get ippool -o wide CIDR NAT IPIP 192.168.0.0/16 true false 192.168.10.1/24 true true 192.168.20.1/24 true true 192.168.30.1/24 true true fd80:24e2:f998:72d6::/64 true false 由上面可以看出,當三個節點都創建了ipPool後,再次查看calico的ip池,就會發現三個節點的Docker網橋網絡ip都顯示出來了。
5)容器網絡配置
在3個節點上啟動容器 ------------node1節點上創建容器-------------- [root@node1 ~]# docker run -itd --name=my-test1 docker.io/nginx 0f09da38cb1a9b0155bcb1ed9fe8192676355e06ed474d411fc31f1207a20a63 [root@node1 ~]# docker exec -ti my-test1 /bin/bash //登陸my-test1容器,發現容器ip是安裝指定的docker網橋網絡分配的 root@0f09da38cb1a:/# ip addr 1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN group default 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: tunl0@NONE: <NOARP> mtu 1480 qdisc noop state DOWN group default link/ipip 0.0.0.0 brd 0.0.0.0 2964: eth0@if2965: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP group default link/ether 02:42:c0:a8:0a:02 brd ff:ff:ff:ff:ff:ff link-netnsid 0 inet 192.168.10.2/24 scope global eth0 valid_lft forever preferred_lft forever inet6 fe80::42:c0ff:fea8:a02/64 scope link valid_lft forever preferred_lft forever ------------node2節點上創建容器-------------- [root@node2 ~]# docker run -itd --name=my-test2 docker.io/nginx 707a1e64a3072b1c49dad3009e63b7307ab725fa43147c1ad3c809f5214c761b [root@node2 ~]# docker exec -ti my-test2 /bin/bash root@707a1e64a307:/# ip addr 1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN group default qlen 1 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: tunl0@NONE: <NOARP> mtu 1480 qdisc noop state DOWN group default qlen 1 link/ipip 0.0.0.0 brd 0.0.0.0 15: eth0@if16: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP group default link/ether 02:42:c0:a8:14:02 brd ff:ff:ff:ff:ff:ff link-netnsid 0 inet 192.168.20.2/24 scope global eth0 valid_lft forever preferred_lft forever inet6 fe80::42:c0ff:fea8:1402/64 scope link valid_lft forever preferred_lft forever ------------node3節點上創建容器-------------- [root@node3 ~]# docker run -itd --name=my-test3 docker.io/nginx d52d18d9e1eb0e309ece7cc20c76654c195db5aee609cb3a2075dfcb1aff2425 [root@node3 ~]# docker exec -ti my-test3 /bin/bash root@d52d18d9e1eb:/# ip addr 1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN group default 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: tunl0@NONE: <NOARP> mtu 1480 qdisc noop state DOWN group default link/ipip 0.0.0.0 brd 0.0.0.0 39: eth0@if40: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP group default link/ether 02:42:c0:a8:1e:02 brd ff:ff:ff:ff:ff:ff link-netnsid 0 inet 192.168.30.2/24 scope global eth0 valid_lft forever preferred_lft forever inet6 fe80::42:c0ff:fea8:1e02/64 scope link valid_lft forever preferred_lft forever root@d52d18d9e1eb:/# ping 192.168.10.2 PING 192.168.10.2 (192.168.10.2): 56 data bytes 64 bytes from 192.168.10.2: icmp_seq=0 ttl=62 time=0.799 ms ^C--- 192.168.10.2 ping statistics --- 1 packets transmitted, 1 packets received, 0% packet loss round-trip min/avg/max/stddev = 0.799/0.799/0.799/0.000 ms root@d52d18d9e1eb:/# ping 192.168.20.2 PING 192.168.20.2 (192.168.20.2): 56 data bytes 64 bytes from 192.168.20.2: icmp_seq=0 ttl=62 time=1.021 ms ^C--- 192.168.20.2 ping statistics --- 1 packets transmitted, 1 packets received, 0% packet loss round-trip min/avg/max/stddev = 1.021/1.021/1.021/0.000 ms 可以發現,在三個節點上創建的容器都是按照指定的docker網橋網絡分配的ip,並且各節點機上的容器間的ip是可以相互ping通的! 除此之外: 1)容器可以訪問外網(默認采用的是bridge網橋模式,只要宿主機能訪問外網,容器也就可以)。 2)宿主機可以ping通任意一個節點上的容器ip 3)容器可以ping通任意一個節點ip
Docker網絡解決方案-Calico部署記錄