docker(7、容器網絡4) flannel 網絡 1、yum安裝etcd單節點 yum安裝flannel 配置使用vxlan 2、配置使用 flannel host-gw

1、概述

lannel 是 CoreOS 開發的容器網絡解決方案。flannel 爲每個 host 分配一個 subnet,容器從此 subnet 中分配 IP,這些 IP 可以在 host 間路由,容器間無需 NAT 和 port mapping 就可以跨主機通信。
 

每個 subnet 都是從一個更大的 IP 池中劃分的,flannel 會在每個主機上運行一個叫 flanneld 的 agent,其職責就是從池子中分配 subnet。爲了在各個主機間共享信息,flannel 用 etcd(與 consul 類似的 key-value 分佈式數據庫)存放網絡配置、已分配的 subnet、host 的 IP 等信息。

數據包如何在主機間轉發是由 backend 實現的。flannel 提供了多種 backend,最常用的有 vxlan 和 host-gw,其他 backend 請參考 https://github.com/coreos/flannel

Flannel工作原理流程圖如下 (默認的節點間數據通信方式是UDP轉發;  flannel默認使用8285端口作爲UDP封裝報文的端口,VxLan使用8472端口)

對上圖的簡單說明 (Flannel的工作原理可以解釋如下):
-> 數據從源容器中發出後,經由所在主機的docker0虛擬網卡轉發到flannel0虛擬網卡,這是個P2P的虛擬網卡,flanneld服務監聽在網卡的另外一端。
-> Flannel通過Etcd服務維護了一張節點間的路由表,該張表裏保存了各個節點主機的子網網段信息。
-> 源主機的flanneld服務將原本的數據內容UDP封裝後根據自己的路由表投遞給目的節點的flanneld服務,數據到達以後被解包,然後直接進入目的節點的flannel0虛擬網卡,然後被轉發到目的主機的docker0虛擬網卡,最後就像本機容器通信一樣的由docker0路由到達目標容器。

這樣整個數據包的傳遞就完成了,這裏需要解釋三個問題:
1) UDP封裝是怎麼回事?
在UDP的數據內容部分其實是另一個ICMP(也就是ping命令)的數據包。原始數據是在起始節點的Flannel服務上進行UDP封裝的,投遞到目的節點後就被另一端的Flannel服務
還原成了原始的數據包,兩邊的Docker服務都感覺不到這個過程的存在。

2) 爲什麼每個節點上的Docker會使用不同的IP地址段?
這個事情看起來很詭異,但真相十分簡單。其實只是單純的因爲Flannel通過Etcd分配了每個節點可用的IP地址段後,偷偷的修改了Docker的啓動參數。
在運行了Flannel服務的節點上可以查看到Docker服務進程運行參數(ps aux|grep docker|grep "bip"),例如“--bip=182.48.25.1/24”這個參數,它限制了所在節
點容器獲得的IP範圍。這個IP範圍是由Flannel自動分配的,由Flannel通過保存在Etcd服務中的記錄確保它們不會重複。

3) 爲什麼在發送節點上的數據會從docker0路由到flannel0虛擬網卡,在目的節點會從flannel0路由到docker0虛擬網卡?
例如現在有一個數據包要從IP爲172.17.18.2的容器發到IP爲172.17.46.2的容器。根據數據發送節點的路由表,它只與172.17.0.0/16匹配這條記錄匹配,因此數據從docker0
出來以後就被投遞到了flannel0。同理在目標節點,由於投遞的地址是一個容器,因此目的地址一定會落在docker0對於的172.17.46.0/24這個記錄上,自然的被投遞到了docker0網卡。

可以從github 上下載etcd 和 flannel包 安裝原理大致相同可以參考cloudman的部署方式

https://mp.weixin.qq.com/s?__biz=MzIwMTM5MjUwMg==&mid=2653587799&idx=1&sn=a26c6c4a9681997031cd346224d01822&chksm=8d30814eba47085870ac9695411bc1943ee054baeb6920094256215112f5817b7a3874388c89&scene=21#wechat_redirect

 

測試環境:方式

1)機器環境(centos7系統)本環境單etcd的部署(可以etcd集羣部署)

1

2

3

192.168.1.121     部署etcd,  也可以安裝flannel,docker    主機名:etcd   

192.168.1.122     部署flannel,docker                主機名:host1  

192.168.1.123               部署flannel,docker                主機名:host1

2)etcd(192.168.1.121)機器操作

設置主機名及綁定hosts
[root@etcd ~]# hostnamectl --static set-hostname  etcd
[root@etcd ~]# vim /etc/hosts
192.168.1.121    etcd
192.168.1.122    host1
192.168.1.123    host2  
關閉防火牆,如果開啓防火牆,則最好打開2379和4001端口
[root@etcd ~]# systemctl disable firewalld.service
[root@etcd ~]# systemctl stop firewalld.service  
安裝etcd
k8s運行依賴etcd,需要先部署etcd,下面採用yum方式安裝:
[root@etcd ~]# yum install etcd -y    
yum安裝的etcd默認配置文件在/etc/etcd/etcd.conf,編輯配置文件:
[root@etcd ~]# cp /etc/etcd/etcd.conf /etc/etcd/etcd.conf.bak

[root@etcd ~]# cat /etc/etcd/etcd.conf
#[member]
ETCD_NAME=etcd                                            #節點名稱
ETCD_DATA_DIR="/var/lib/etcd/default.etcd"                  #數據存放位置
#ETCD_WAL_DIR=""
#ETCD_SNAPSHOT_COUNT="10000"
#ETCD_HEARTBEAT_INTERVAL="100"
#ETCD_ELECTION_TIMEOUT="1000"
#ETCD_LISTEN_PEER_URLS="http://0.0.0.0:2380"
ETCD_LISTEN_CLIENT_URLS="http://0.0.0.0:2379,http://0.0.0.0:4001"             #監聽客戶端地址
#ETCD_MAX_SNAPSHOTS="5"
#ETCD_MAX_WALS="5"
#ETCD_CORS=""
#
#[cluster]
#ETCD_INITIAL_ADVERTISE_PEER_URLS="http://localhost:2380"
# if you use different ETCD_NAME (e.g. test), set ETCD_INITIAL_CLUSTER value for this name, i.e. "test=http://..."
#ETCD_INITIAL_CLUSTER="default=http://localhost:2380"
#ETCD_INITIAL_CLUSTER_STATE="new"
#ETCD_INITIAL_CLUSTER_TOKEN="etcd-cluster"
ETCD_ADVERTISE_CLIENT_URLS="http://etcd:2379,http://etcd:4001"           #通知客戶端地址
#ETCD_DISCOVERY=""
#ETCD_DISCOVERY_SRV=""
#ETCD_DISCOVERY_FALLBACK="proxy"
#ETCD_DISCOVERY_PROXY=""    

啓動etcd並驗證狀態
[root@etcd ~]# systemctl start etcd
[root@etcd ~]# systemctl enable etcd      
[root@etcd ~]# ps -ef|grep etcd
etcd     28145     1  1 14:38 ?        00:00:00 /usr/bin/etcd --name=master --data-dir=/var/lib/etcd/default.etcd --listen-client-urls=http://0.0.0.0:2379,http://0.0.0.0:4001
root     28185 24819  0 14:38 pts/1    00:00:00 grep --color=auto etcd
[root@etcd ~]# lsof -i:2379
COMMAND   PID USER   FD   TYPE  DEVICE SIZE/OFF NODE NAME
etcd    28145 etcd    6u  IPv6 1283822      0t0  TCP *:2379 (LISTEN)
etcd    28145 etcd   18u  IPv6 1284133      0t0  TCP localhost:53203->localhost:2379 (ESTABLISHED)
........
    
[root@etcd ~]# etcdctl set testdir/testkey0 0
0
[root@etcd ~]# etcdctl get testdir/testkey0
0
[root@etcd ~]# etcdctl -C http://etcd:4001 cluster-health
member 8e9e05c52164694d is healthy: got healthy result from http://etcd:2379
cluster is healthy
[root@etcd ~]# etcdctl -C http://etcd:2379 cluster-health
member 8e9e05c52164694d is healthy: got healthy result from http://etcd:2379
cluster is healthy
  
配置flannel的網絡信息
配置etcd中關於flannel的key(這個只在安裝了etcd的機器上操作)
Flannel使用Etcd進行配置,來保證多個Flannel實例之間的配置一致性,所以需要在etcd上進行如下配置('/atomic.io/network/config'這個key與上文/etc/sysconfig/flannel中的配置項FLANNEL_ETCD_PREFIX是相對應的,錯誤的話啓動就會出錯):
[root@etcd ~]# etcdctl mk /atomic.io/network/config '{ "Network": "182.48.0.0/16" }'
{ "Network": "182.48.0.0/16" }
獲取配置的網絡信息
[root@etcd ~]# etcdctl get /atomic.io/network/config 
{ "Network": "172.18.0.0/16" }
刪除網絡信息
[root@etcd ~]# etcdctl rm  /atomic.io/network/config
溫馨提示:上面flannel設置的ip網段可以任意設定,隨便設定一個網段都可以。容器的ip就是根據這個網段進行自動分配的,ip分配後,容器一般是可以對外聯網的(網橋模式,只要宿主機能上網就可以)
上面配置的知識網段和子網要是配置網段的最大範圍和支持的網絡支持的後端模式
#####################################################
etcdctl  set /atomic.io/network/config '{"NetWork":"10.0.0.0/16", "SubnetMin": "10.0.1.0", "SubnetMax": "10.0.20.0","Backend": {"Type": "vxlan"}}'

Network: 用於指定Flannel地址池, 整個overlay網絡爲10.0.0.0/16網段.
SubnetLen: 用於指定分配給單個宿主機的docker0的ip段的子網掩碼的長度
SubnetMin: 用於指定最小能夠分配的ip段
SudbnetMax: 用於指定最大能夠分配的ip段,在上面的示例中,表示每個宿主機可以分配一個24位掩碼長度的子網,可以分配的子網從10.0.1.0/24到10.0.20.0/24,也就意味着在這個網段中,最多隻能有20臺宿主機
Backend: 用於指定數據包以什麼方式轉發,默認爲udp模式, 這裏使用的是vxlan模式


############
############
可以在etcd的節點上安裝和配置flannel和docker
安裝覆蓋網絡Flannel
[root@etcd ~]# yum install flannel -y   
配置Flannel
[root@etcd ~]# cp /etc/sysconfig/flanneld /etc/sysconfig/flanneld.bak
[root@etcd ~]# vim /etc/sysconfig/flanneld
# Flanneld configuration options
   
# etcd url location.  Point this to the server where etcd runs
FLANNEL_ETCD_ENDPOINTS="http://etcd:2379"
   
# etcd config key.  This is the configuration key that flannel queries
# For address range assignment
FLANNEL_ETCD_PREFIX="/atomic.io/network"
   
# Any additional options that you want to pass
#FLANNEL_OPTIONS="" 
啓動Flannel
[root@etcd ~]# systemctl enable flanneld.service
[root@etcd ~]# systemctl start flanneld.service
[root@etcd ~]# ps -ef|grep flannel
root      9305  9085  0 09:12 pts/2    00:00:00 grep --color=auto flannel
root     28876     1  0 May15 ?        00:00:07 /usr/bin/flanneld -etcd-endpoints=http://etcd:2379 -etcd-prefix=/atomic.io/network
[root@etcd ~]# yum install docker -y

啓動Flannel後,一定要記得重啓docker,這樣Flannel配置分配的ip才能生效,即docker0虛擬網卡的ip會變成上面flannel設定的ip段
[root@etcd ~]# systemctl restart docker

3)host1(192.168.1.122)和 host2(192.168.1.123)機器操作

設置主機名及綁定hosts
[root@host1 ~]# hostnamectl --static set-hostname  host1
[root@host1 ~]# vim /etc/hosts
192.168.1.121    etcd
192.168.1.122    host1
192.168.1.123    host2  
關閉防火牆,如果開啓防火牆,則最好打開2379和4001端口
[root@host1 ~]# systemctl disable firewalld.service
[root@host1 ~]# systemctl stop firewalld.service 
安裝覆蓋網絡Flannel
[root@host1 ~]# yum install flannel -y  
配置Flannel
[root@host1 ~]# cp /etc/sysconfig/flanneld /etc/sysconfig/flanneld.bak
[root@host1 ~]# vim /etc/sysconfig/flanneld
# Flanneld configuration options
   
# etcd url location.  Point this to the server where etcd runs
FLANNEL_ETCD_ENDPOINTS="http://etcd:2379"
   
# etcd config key.  This is the configuration key that flannel queries
# For address range assignment
FLANNEL_ETCD_PREFIX="/atomic.io/network"
   
# Any additional options that you want to pass
#FLANNEL_OPTIONS=""  
啓動Flannel
[root@host1 ~]# systemctl enable flanneld.service
[root@host1 ~]# systemctl start flanneld.service
[root@host1 ~]# ps -ef|grep flannel
root      3841  9649  0 09:11 pts/0    00:00:00 grep --color=auto flannel
root     28995     1  0 May15 ?        00:00:07 /usr/bin/flanneld -etcd-endpoints=http://etcd:2379 -etcd-prefix=/atomic.io/network
安裝docker環境
[root@host1 ~]# yum install -y docker
啓動Flannel後,一定要記得後安裝重啓docker,這樣Flannel配置分配的ip才能生效,即docker0虛擬網卡的ip會變成上面flannel設定的ip段 etcd節點先安裝docker後重啓不會出現docker0還是172.17.0.1的ip
[root@host1 ~]# systemctl restart docker

 注意事項

指定網卡出口,還有啓動flannel時會報"Failed to get default interface: Unable to find default route"錯誤

 

1、指定網卡出口 ;例如FLANNEL_OPTIONS="iface=ens33"

2、這裏需要特別注意,如果對機子的網卡進行了一些修改,用於連接外網的網卡名比較特殊(比如機子用的是萬兆網卡,網卡名即爲p6p1),啓動flannel時會報"Failed to get default interface: Unable to find default route"錯誤,則FLANNEL_OPTIONS需要添加參數:iface=<用於連接的網卡名>。例如100機的網卡名爲em1則 iface=em1;萬兆網卡的網卡名爲p6p1則 iface=p6p1。

注意:有些人重啓docker和flannel後發現ip還是172.17.0.1 

處理方式1 先安裝flannel 在安裝docker

處理方式2 修改vi /usr/lib/systemd/system/docker.service

①查看本臺安裝重啓flannel分配給本臺機器的網絡信息

cat /run/flannel/subnet.env 發現本機分配網絡信息是182.48.0.1/24  這個信息應該在docker0 網卡上

② vi /usr/lib/systemd/system/docker.service

 給ExecStart命令的參數中添加--bip和--mtu,分別對應subnet.env的 FLANNEL_SUBNET 與FLANNEL_MTU

-H tcp://0.0.0.0 是允許其他客戶端連接

測試兩個node中容器跨網絡通信 可以看到不同node節點的容器之間可以正常通信

host1網絡信息

[root@host1 ~]# cat /run/flannel/subnet.env
FLANNEL_NETWORK=172.18.0.0/16
FLANNEL_SUBNET=172.18.89.1/24
FLANNEL_MTU=1472
FLANNEL_IPMASQ=false
[root@host1 ~]# ip a
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN group default 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: ens33: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP group default qlen 1000
    link/ether 00:0c:29:99:bb:09 brd ff:ff:ff:ff:ff:ff
    inet 192.168.1.123/24 brd 192.168.1.255 scope global noprefixroute ens33
       valid_lft forever preferred_lft forever
    inet6 fe80::6fc0:38a2:3482:c75f/64 scope link noprefixroute 
       valid_lft forever preferred_lft forever
3: flannel0: <POINTOPOINT,MULTICAST,NOARP,UP,LOWER_UP> mtu 1472 qdisc pfifo_fast state UNKNOWN group default qlen 500
    link/none 
    inet 172.18.89.0/16 scope global flannel0
       valid_lft forever preferred_lft forever
    inet6 fe80::7a1:bc34:a125:5d98/64 scope link flags 800 
       valid_lft forever preferred_lft forever
4: docker0: <NO-CARRIER,BROADCAST,MULTICAST,UP> mtu 1500 qdisc noqueue state DOWN group default 
    link/ether 02:42:4b:a8:9d:62 brd ff:ff:ff:ff:ff:ff
    inet 172.18.89.1/24 scope global docker0
       valid_lft forever preferred_lft forever
[root@host1 ~]# ip r 
#發現沒有172.17.0.1的docker網絡了 是因爲獲取了flannel的網段
default via 192.168.1.1 dev ens33 proto static metric 100 
172.18.0.0/16 dev flannel0 proto kernel scope link src 172.18.89.0 
172.18.89.0/24 dev docker0 proto kernel scope link src 172.18.89.1 
192.168.1.0/24 dev ens33 proto kernel scope link src 192.168.1.122 metric 100 

 host2網絡信息

[root@host2 ~]# cat /run/flannel/subnet.env
FLANNEL_NETWORK=172.18.0.0/16
FLANNEL_SUBNET=172.18.92.1/24
FLANNEL_MTU=1472
FLANNEL_IPMASQ=false
[root@host2 ~]# ip a
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN group default 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: ens33: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP group default qlen 1000
    link/ether 00:0c:29:99:bb:09 brd ff:ff:ff:ff:ff:ff
    inet 192.168.1.123/24 brd 192.168.1.255 scope global noprefixroute ens33
       valid_lft forever preferred_lft forever
    inet6 fe80::6fc0:38a2:3482:c75f/64 scope link noprefixroute 
       valid_lft forever preferred_lft forever
3: flannel0: <POINTOPOINT,MULTICAST,NOARP,UP,LOWER_UP> mtu 1472 qdisc pfifo_fast state UNKNOWN group default qlen 500
    link/none 
    inet 172.18.92.0/16 scope global flannel0
       valid_lft forever preferred_lft forever
    inet6 fe80::7a1:bc34:a125:5d98/64 scope link flags 800 
       valid_lft forever preferred_lft forever
4: docker0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1472 qdisc noqueue state UP group default 
    link/ether 02:42:4b:a8:9d:62 brd ff:ff:ff:ff:ff:ff
    inet 172.18.92.1/24 scope global docker0
       valid_lft forever preferred_lft forever
    inet6 fe80::42:4bff:fea8:9d62/64 scope link 
       valid_lft forever preferred_lft forever
6: vethd448622@if5: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1472 qdisc noqueue master docker0 state UP group default 
    link/ether 06:85:1e:64:64:a9 brd ff:ff:ff:ff:ff:ff link-netnsid 0
    inet6 fe80::485:1eff:fe64:64a9/64 scope link 
       valid_lft forever preferred_lft forever
[root@host2 ~]# ip r
#發現沒有172.17.0.1的docker網絡了 是因爲獲取了flannel的網段
default via 192.168.1.1 dev ens33 proto static metric 100 
172.18.0.0/16 dev flannel0 proto kernel scope link src 172.18.92.0 
172.18.92.0/24 dev docker0 proto kernel scope link src 172.18.92.1 
192.168.1.0/24 dev ens33 proto kernel scope link src 192.168.1.123 metric 100 

[root@host2 ~]# ps aux|grep docker|grep "bip"
root      10723  0.1  3.5 666700 35100 ?        Ssl  05:28   0:17 /usr/bin/dockerd-current --add-runtime docker-runc=/usr/libexec/docker/docker-runc-current --default-runtime=docker-runc --exec-opt native.cgroupdriver=systemd --userland-proxy-path=/usr/libexec/docker/docker-proxy-current --init-path=/usr/libexec/docker/docker-init-current --seccomp-profile=/etc/docker/seccomp.json --selinux-enabled --log-driver=journald --signature-verification=false --storage-driver overlay2 --bip=172.18.92.1/24 --ip-masq=true --mtu=1472
#“--bip=172.18.92.1/24”這個參數,它限制了所在節點容器獲得的IP範圍。 該IP範圍是由Flannel自動分配的,由Flannel通過保存在Etcd服務中的記錄確保它們不會重複。

創建容器,驗證跨主機容器之間的網絡聯通性

host1上的容器host1.test 的ip是172.18.89.2

host2上的容器host2.test的ip是172.18.92.2

[root@host1 ~]# docker run -it --name host1.test busybox
Unable to find image 'busybox:latest' locally
Trying to pull repository docker.io/library/busybox ... 
latest: Pulling from docker.io/library/busybox
0669b0daf1fb: Already exists 
Digest: sha256:b26cd013274a657b86e706210ddd5cc1f82f50155791199d29b9e86e935ce135
Status: Downloaded newer image for docker.io/busybox:latest
/ # 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
5: eth0@if6: <BROADCAST,MULTICAST,UP,LOWER_UP,M-DOWN> mtu 1472 qdisc noqueue 
    link/ether 02:42:ac:12:59:02 brd ff:ff:ff:ff:ff:ff
    inet 172.18.89.2/24 scope global eth0
       valid_lft forever preferred_lft forever
    inet6 fe80::42:acff:fe12:5902/64 scope link 
       valid_lft forever preferred_lft forever
/ # 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
5: eth0@if6: <BROADCAST,MULTICAST,UP,LOWER_UP,M-DOWN> mtu 1472 qdisc noqueue 
    link/ether 02:42:ac:12:59:02 brd ff:ff:ff:ff:ff:ff
    inet 172.18.89.2/24 scope global eth0
       valid_lft forever preferred_lft forever
    inet6 fe80::42:acff:fe12:5902/64 scope link 
       valid_lft forever preferred_lft forever
/ # ping 172.18.92.2
PING 172.18.92.2 (172.18.92.2): 56 data bytes
64 bytes from 172.18.92.2: seq=15 ttl=60 time=12.671 ms
64 bytes from 172.18.92.2: seq=16 ttl=60 time=1.132 ms
64 bytes from 172.18.92.2: seq=17 ttl=60 time=2.450 ms
64 bytes from 172.18.92.2: seq=18 ttl=60 time=2.030 ms
64 bytes from 172.18.92.2: seq=19 ttl=60 time=1.314 ms
64 bytes from 172.18.92.2: seq=20 ttl=60 time=3.762 ms
^C
--- 172.18.92.2 ping statistics ---
21 packets transmitted, 6 packets received, 71% packet loss
round-trip min/avg/max = 1.132/3.893/12.671 ms

 

[root@host2 ~]# docker run -it --name host2.test busybox
Unable to find image 'busybox:latest' locally
Trying to pull repository docker.io/library/busybox ... 
latest: Pulling from docker.io/library/busybox
0669b0daf1fb: Pull complete 
Digest: sha256:b26cd013274a657b86e706210ddd5cc1f82f50155791199d29b9e86e935ce135
Status: Downloaded newer image for docker.io/busybox:latest
/ # 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
5: eth0@if6: <BROADCAST,MULTICAST,UP,LOWER_UP,M-DOWN> mtu 1472 qdisc noqueue 
    link/ether 02:42:ac:12:5c:02 brd ff:ff:ff:ff:ff:ff
    inet 172.18.92.2/24 scope global eth0
       valid_lft forever preferred_lft forever
    inet6 fe80::42:acff:fe12:5c02/64 scope link 
       valid_lft forever preferred_lft forever
/ # ping 172.18.89.2
PING 172.18.89.2 (172.18.89.2): 56 data bytes
64 bytes from 172.18.89.2: seq=0 ttl=60 time=52.863 ms
64 bytes from 172.18.89.2: seq=1 ttl=60 time=1.743 ms
^C
--- 172.18.89.2 ping statistics ---
2 packets transmitted, 2 packets received, 0% packet loss
round-trip min/avg/max = 1.743/27.303/52.863 ms
如上面操作後,發現各容器內分配的ip之間相互ping不通,基本就是由於防火牆問題引起的!
可是明明已經在前面部署的時候,通過"systemctl stop firewalld.service"關閉了防火牆,爲什麼還有防火牆問題??
這是因爲linux還有底層的iptables,所以解決辦法是在各節點上執行下面操作:
[root@host1 ~]# iptables -P INPUT ACCEPT
[root@host1 ~]# iptables -P FORWARD ACCEPT
[root@host1 ~]# iptables -F
[root@host1 ~]# iptables -L -n
 
執行上面操作後,基本各容器間就能相互ping通了。
docker通過Flannel可以實現各容器間的相互通信,即宿主機和容器,容器和容器之間都能相互通信。

flannel 網絡隔離

flannel 爲每個主機分配了獨立的 subnet,但 flannel.1 將這些 subnet 連接起來了,相互之間可以路由。本質上,flannel 將各主機上相互獨立的 docker0 容器網絡組成了一個互通的大網絡,實現了容器跨主機通信。flannel 沒有提供隔離。

flannel 與外網連通性

因爲 flannel 網絡利用的是默認的 bridge 網絡,所以容器與外網的連通方式與 bridge 網絡一樣,即:

  1. 容器通過 docker0 NAT 訪問外網

  2. 通過主機端口映射,外網可以訪問容器

使用 flannel host-gw

與 vxlan 不同,host-gw 不會封裝數據包,而是在主機的路由表中創建到其他主機 subnet 的路由條目,從而實現容器跨主機通信

etcdctl  set /atomic.io/network/config '{"NetWork":"10.0.0.0/16",,"Backend": {"Type": "host-gw"}}'

/run/flannel/subnet.env 可以看到 host-gw 使用的 MTU 爲 1500

[root@host2 ~]# cat /run/flannel/subnet.env
FLANNEL_NETWORK=10.0.0.0/16
FLANNEL_SUBNET=10.2.0.1/24
FLANNEL_MTU=1500
FLANNEL_IPMASQ=false

這與 vxlan MTU=1450 不同,所以應該修改 docker 啓動參數 --mtu=1500並重啓 docker daemon。

vi /usr/lib/systemd/system/docker.service

 給ExecStart命令的參數中添加--bip和--mtu,分別對應subnet.env的 FLANNEL_SUBNET 與FLANNEL_MTU

下面對 host-gw 和 vxlan 這兩種 backend 做個簡單比較。

  1. host-gw 把每個主機都配置成網關,主機知道其他主機的 subnet 和轉發地址。vxlan 則在主機間建立隧道,不同主機的容器都在一個大的網段內(比如 10.2.0.0/16)。

  2. 雖然 vxlan 與 host-gw 使用不同的機制建立主機之間連接,但對於容器則無需任何改變,bbox1 仍然可以與 bbox2 通信。

  3. 由於 vxlan 需要對數據進行額外打包和拆包,性能會稍遜於 host-gw。

 

 

 

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章