中文字幕av专区_日韩电影在线播放_精品国产精品久久一区免费式_av在线免费观看网站

溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

Docker網絡管理之docker跨主機通信

發布時間:2020-07-30 16:40:28 來源:網絡 閱讀:477 作者:筱振 欄目:云計算

博文大綱:
一、前言
二、Docker的原生網絡
三、自定義bridge網絡
四、Overlay網絡
五、Macvlan網絡
六、使外網可以訪問容器的方法

一、前言

由于docker技術的火爆,導致現在越來越多的企業都在使用docker這種虛擬化技術。企業中使用docker這種虛擬化技術,其目的就是為了讓docker中的容器對外提供服務。因此,我們必須深入了解一下docker的網絡知識,以滿足更高的網絡需求。

二、Docker的原生網絡

當你安裝Docker時,它會自動創建三個網絡。如下:

[root@localhost ~]# docker network ls                      
//查看docker的默認網絡
NETWORK ID          NAME                DRIVER              SCOPE
a38bd52b4cec        bridge              bridge               local
624b3ba70637        host                 host                   local
62f80646f707          none                  null                     local         

Docker內置這三個網絡,運行容器時,你可以使用該“--network”選項來指定容器應連接到哪些網絡。如果沒有指定則默認使用bridge模式。

比如:

host模式:使用 --net=host 指定;
none模式:使用 --net=none 指定;
bridge模式:使用 --net=bridge 指定(默認設置);

下面詳細介紹一下這幾種網絡模式:

雖然docker模式提供三種網絡模式,但其實是有四種網絡模式的!

1.host模式

如果啟動容器時使用host模式,那么這個容器將不會獲得一個獨立的Network Namespace,而是和宿主機共用一個Network Namespace。容器將不會虛擬出自己的網卡,配置自己的IP等,而是使用宿主機的IP和端口。

使用場景:

由于網絡配置與docker宿主機完全一樣,性能較好,但是不便之處就是靈活性不高,容易和宿主機出現端口沖突的問題。最好是單個容器時使用,一般情況下不建議使用。

創建使用host網絡模式的容器示例:

[root@localhost ~]# docker run -it --name host --network host busybox:latest 
//使用busybox鏡像創建一個名為host的容器,網絡采用host模式
/ # ip a 
//進入容器后可以看出容器中的網絡與docker主機的網絡一模一樣
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: ens33: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast qlen 1000
    link/ether 00:0c:29:66:72:13 brd ff:ff:ff:ff:ff:ff
    inet 192.168.1.1/24 brd 192.168.1.255 scope global ens33
       valid_lft forever preferred_lft forever
    inet6 fe80::9f3:b94e:5f5d:8070/64 scope link 
       valid_lft forever preferred_lft forever
3: virbr0: <NO-CARRIER,BROADCAST,MULTICAST,UP> mtu 1500 qdisc noqueue qlen 1000
    link/ether 52:54:00:e1:82:15 brd ff:ff:ff:ff:ff:ff
    inet 192.168.122.1/24 brd 192.168.122.255 scope global virbr0
       valid_lft forever preferred_lft forever
4: virbr0-nic: <BROADCAST,MULTICAST> mtu 1500 qdisc pfifo_fast master virbr0 qlen 1000
    link/ether 52:54:00:e1:82:15 brd ff:ff:ff:ff:ff:ff
5: docker0: <NO-CARRIER,BROADCAST,MULTICAST,UP> mtu 1500 qdisc noqueue 
    link/ether 02:42:3c:06:f8:1d brd ff:ff:ff:ff:ff:ff
    inet 172.17.0.1/16 brd 172.17.255.255 scope global docker0
       valid_lft forever preferred_lft forever

2.none模式

在none模式下,Docker容器擁有自己的Network Namespace,但是,并不為Docker容器進行任何網絡配置。也就是說,這個Docker容器只有一個回環地址,不能與外界通信,稱為被隔離的網絡。
使用場景:

none模式被稱為隔離的網絡,隔離便意味著安全,不能與外部通信,同樣外部也不可以訪問到使用none模式的容器,使用這種網絡模式的容器可以運行于關于安全方面的驗證碼、校驗碼等服務。一般用于對安全性要求較高的場景中!

創建使用none網絡模式的容器示例:

[root@localhost ~]# docker run -it --name none --network none busybox:latest 
//使用busybox鏡像創建一個名為none的容器,網絡采用none模式
/ # ip a            //可以看到容器中只有一個lo網卡
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

3.bridge模式

bridge模式是Docker默認的網絡設置,此模式會為每一個容器分配Network Namespace、設置IP等,并將一個主機上的Docker容器連接到一個虛擬網卡上。當Docker server啟動時,會在主機上創建一個名為docker0的虛擬網橋,此主機上啟動的Docker容器會連接到這個虛擬網橋上。虛擬網橋的工作方式和物理交換機類似,這樣主機上的所有容器就通過交換機連在了一個二層網絡中。接下來就要為容器分配IP了,Docker會從RFC1918所定義的私有IP網段中,選擇一個和宿主機不同的IP地址和子網分配給docker0,連接到docker0的容器就從這個子網中選擇一個未占用的IP使用。如一般Docker會使用172.17.0.0/16這個網段,并將172.17.0.1/16分配給docker0網橋。

[root@localhost ~]# ifconfig docker0
docker0: flags=4099<UP,BROADCAST,MULTICAST>  mtu 1500
        inet 172.17.0.1  netmask 255.255.0.0  broadcast 172.17.255.255
        ether 02:42:3c:06:f8:1d  txqueuelen 0  (Ethernet)
        RX packets 0  bytes 0 (0.0 B)
        RX errors 0  dropped 0  overruns 0  frame 0
        TX packets 0  bytes 0 (0.0 B)
        TX errors 0  dropped 0 overruns 0  carrier 0  collisions 0
[root@localhost ~]# brctl show             //查看橋接網絡
bridge name bridge id       STP enabled interfaces
docker0     8000.02423c06f81d   no      
//如果沒有創建橋接模式的容器,默認是空的。

創建使用bridge網絡模式的容器示例:

[root@localhost ~]# docker run -itd --name bridge busybox:latest /bin/sh
//創建一個名為bridge的容器,如果沒有指定網絡模式,默認便是bridge模式
[root@localhost ~]# docker exec -it bridge /bin/sh
//進入bridge容器中
/ # 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
6: eth0@if9: <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 brd 172.17.255.255 scope global eth0
       valid_lft forever preferred_lft forever
//可以看出eth0@if9這塊虛擬網卡上的地址與docker宿主機的docker0網絡屬于同一網段
[root@localhost ~]# brctl show
bridge name bridge id       STP enabled interfaces
docker0     8000.02423c06f81d   no      veth811d20c
//可以看到橋接模式的接口下出現了一個新的接口,當創建一個容器便會出現一個接口
//這個接口便是容器在docker宿主機創建一個虛擬網卡,用于容器與docker通信
[root@localhost ~]# ifconfig veth811d20c           //查看這個虛擬網卡是否存在
veth811d20c: flags=4163<UP,BROADCAST,RUNNING,MULTICAST>  mtu 1500
        inet6 fe80::c035:95ff:febf:978b  prefixlen 64  scopeid 0x20<link>
        ether c2:35:95:bf:97:8b  txqueuelen 0  (Ethernet)
        RX packets 0  bytes 0 (0.0 B)
        RX errors 0  dropped 0  overruns 0  frame 0
        TX packets 8  bytes 648 (648.0 B)
        TX errors 0  dropped 0 overruns 0  carrier 0  collisions 0

當使用bridge網絡模式,docker的工作步驟大致為:
(1)在主機上創建一對虛擬網卡veth pair設備。veth設備總是成對出現的,它們組成了一個數據的通道,數據從一個設備進入,就會從另一個設備出來。因此,veth設備常用來連接兩個網絡設備;
(2)Docker將veth pair設備的一端放在新創建的容器中,并命名為eth0。另一端放在主機中,以veth811d20c這樣類似的名字命名,并將這個網絡設備加入到docker0網橋中,可以通過brctl show命令查看(上述實例已經驗證);
(3)從docker0子網中分配一個IP給容器使用,并設置docker0的IP地址為容器的默認網關;

4.container(共享網絡協議棧)模式

這個模式指定新創建的容器和已經存在的一個容器共享一個Network Namespace,而不是和宿主機共享。新創建的容器不會創建自己的網卡,配置自己的IP,而是和一個指定的容器共享IP、端口范圍等。同樣,兩個容器除了網絡方面,其他的如文件系統、進程列表等還是隔離的。兩個容器的進程可以通過lo網卡設備通信。

創建使用container網絡模式的容器示例:

[root@localhost ~]# docker run -it --name container --network container:a172b832b531 busybox:latest 
//a172b832b531是bridge容器的ID號
/ # 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
8: eth0@if9: <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 brd 172.17.255.255 scope global eth0
       valid_lft forever preferred_lft forever
//可以看出container容器的IP地址與bridge容器的IP地址一模一樣

關于這四種網絡模式推薦使用默認的bridge網絡模式!

三、自定義bridge網絡

細心一點可以發現,創建的容器默認情況IP地址為172.17.0.0/16網段,那么我們可不可以自定義一個網段供容器使用呢?答案肯定是可以的,方法如下:

[root@localhost ~]# docker network create -d bridge my_net
//創建一個橋接網絡,名稱為my_net,如果沒有指定網段,默認是172.18.0.0/16,按docker0的網段自動遞增
[root@localhost ~]# docker network ls         //查看docker支持的網絡類型
NETWORK ID          NAME                DRIVER              SCOPE
9fba9dc3d2b6        bridge              bridge              local
624b3ba70637        host                host                local
74544573aa67        my_net              bridge              local
62f80646f707        none                null                local
//可以看出,剛才創建的my_net已經出現在列表中
[root@localhost ~]# docker run -itd --name test1 --network my_net busybox:latest /bin/sh
[root@localhost ~]# docker run -itd --name test2 --network my_net busybox:latest /bin/sh
//使用剛才創建的網絡模式創建兩個容器
[root@localhost ~]# docker exec -it test1 /bin/sh
//進入test1
/ # 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
11: eth0@if12: <BROADCAST,MULTICAST,UP,LOWER_UP,M-DOWN> mtu 1500 qdisc noqueue 
    link/ether 02:42:ac:12:00:02 brd ff:ff:ff:ff:ff:ff
    inet 172.18.0.2/16 brd 172.18.255.255 scope global eth0
       valid_lft forever preferred_lft forever
//查看其IP地址,發現確實是172.18.0.0/16網段的
/ # ping test2             //測試通過容器名稱ping test2容器
PING test2 (172.18.0.3): 56 data bytes
64 bytes from 172.18.0.3: seq=0 ttl=64 time=0.079 ms
64 bytes from 172.18.0.3: seq=1 ttl=64 time=0.175 ms
[root@localhost ~]# ifconfig br-74544573aa67
//這張虛擬網卡就是我們創建my_net網絡時產生的
br-74544573aa67: flags=4163<UP,BROADCAST,RUNNING,MULTICAST>  mtu 1500
        inet 172.18.0.1  netmask 255.255.0.0  broadcast 172.18.255.255
        inet6 fe80::42:50ff:fec2:7657  prefixlen 64  scopeid 0x20<link>
        ether 02:42:50:c2:76:57  txqueuelen 0  (Ethernet)
        RX packets 0  bytes 0 (0.0 B)
        RX errors 0  dropped 0  overruns 0  frame 0
        TX packets 0  bytes 0 (0.0 B)
        TX errors 0  dropped 0 overruns 0  carrier 0  collisions 0
//通過IP地址網段就可看出

自定義網絡的優點:

  • 可以通過容器的名稱進行通信;
  • 自定了ContainerDNSserver功能;

以上方法按照默認的方式創建一個橋接模式的網絡,可以發現網段地址并不是我們自定義的。

接下來我們通過指定具體網段的方式創建網卡。方法如下:

[root@localhost ~]# docker network create -d bridge --subnet 200.0.0.0/24 --gateway 200.0.0.1 my_net2
//自定義網絡模式的地址時,必須要明確指定其IP網段及網關信息
[root@localhost ~]# ifconfig br-0ca6770b4a10
//這張虛擬網卡便是我們創建my_net2網絡時產生的
br-0ca6770b4a10: flags=4099<UP,BROADCAST,MULTICAST>  mtu 1500
        inet 200.0.0.1  netmask 255.255.255.0  broadcast 200.0.0.255
        ether 02:42:05:ba:8b:fc  txqueuelen 0  (Ethernet)
        RX packets 0  bytes 0 (0.0 B)
        RX errors 0  dropped 0  overruns 0  frame 0
        TX packets 0  bytes 0 (0.0 B)
        TX errors 0  dropped 0 overruns 0  carrier 0  collisions 0
//可以看出其IP地址就是我們指定的IP地址
[root@localhost ~]# docker run -itd --name test3 --network my_net2 --ip 200.0.0.100 busybox:latest 
[root@localhost ~]# docker run -itd --name test4 --network my_net2 --ip 200.0.0.200 busybox:latest 
//基于剛才創建的網絡創建出兩個容器并指定其固定的IP地址
[root@localhost ~]# docker exec -it test3 /bin/sh
//進入test3容器
/ # 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
16: eth0@if17: <BROADCAST,MULTICAST,UP,LOWER_UP,M-DOWN> mtu 1500 qdisc noqueue 
    link/ether 02:42:c8:00:00:64 brd ff:ff:ff:ff:ff:ff
    inet 200.0.0.100/24 brd 200.0.0.255 scope global eth0
       valid_lft forever preferred_lft forever
//發現其IP地址確實我們剛才指定的IP地址           
/ # ping test4                //測試發現確實是可以和test4通信的
PING test4 (200.0.0.200): 56 data bytes
64 bytes from 200.0.0.200: seq=0 ttl=64 time=0.156 ms
64 bytes from 200.0.0.200: seq=1 ttl=64 time=0.178 ms
/ # ping test1
ping: bad address 'test1'
//發現無法與第一次創建的網絡進行通信

使用相同的網絡創建的容器是可以相互通信的,但是發現無法與其他容器進行通信,這主要是因為iptables規則的原因,創建docker網絡時,iptables規則就會隨著自動添加的。

舉例說:嘗試把iptables規則清空,是可以實現我們想要的效果的。但是這種命令的作用不亞于“rm -rf /*”,顯然在現實環境中是不可以使用的!

那么就需要使用下面的方法來實現了,方法如下:

[root@localhost ~]# docker network connect my_net2 test1
//這條命令就是在test1容器中添加一塊虛擬網卡(my_net2分配的)
[root@localhost ~]# docker exec -it test1 /bin/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
11: eth0@if12: <BROADCAST,MULTICAST,UP,LOWER_UP,M-DOWN> mtu 1500 qdisc noqueue 
    link/ether 02:42:ac:12:00:02 brd ff:ff:ff:ff:ff:ff
    inet 172.18.0.2/16 brd 172.18.255.255 scope global eth0
       valid_lft forever preferred_lft forever
20: eth2@if21: <BROADCAST,MULTICAST,UP,LOWER_UP,M-DOWN> mtu 1500 qdisc noqueue 
    link/ether 02:42:c8:00:00:02 brd ff:ff:ff:ff:ff:ff
    inet 200.0.0.2/24 brd 200.0.0.255 scope global eth2
       valid_lft forever preferred_lft forever
//可以查詢到確實多了一塊虛擬網卡,網段確實和my_net2屬于同一網段             
/ # ping test3
PING test3 (200.0.0.100): 56 data bytes
64 bytes from 200.0.0.100: seq=0 ttl=64 time=0.171 ms
64 bytes from 200.0.0.100: seq=1 ttl=64 time=0.237 ms
^C
--- test3 ping statistics ---
2 packets transmitted, 2 packets received, 0% packet loss
round-trip min/avg/max = 0.171/0.204/0.237 ms
/ # ping test4
PING test4 (200.0.0.200): 56 data bytes
64 bytes from 200.0.0.200: seq=0 ttl=64 time=0.097 ms
^C
--- test4 ping statistics ---
1 packets transmitted, 1 packets received, 0% packet loss
round-trip min/avg/max = 0.097/0.097/0.097 ms
//測試與test3、test4通信,通信正常

注意:此時test2容器并不可以與test3、test4進行通信!如果需要其通信,還需給test2添加虛擬my_net2網卡地址(使用案例中的命令即可)!

注意:

  • 容器之間可以使用容器名進行通信,但前提必須是使用自定義網絡,比如案例中創建的my_net、my_net2;
  • 如果在創建自定義網絡時,指定了該網絡的網段,那么使用此時的容器也可以指定容器的IP地址,若沒有指定該網絡的網段,則不可指定容器的IP地址;

四、Overlay網絡

使用overlay網絡需事先部署好consul服務!

consul:是一個服務網格(微服務間的 TCP/IP,負責服務之間的網絡調用、限流、熔斷和監控)解決方案,它是一個一個分布式的,高度可用的系統,而且開發使用都很簡便。它提供了一個功能齊全的控制平面,主要特點是:服務發現、健康檢查、鍵值存儲、安全服務通信、多數據中心。

通過一個小案例來驗證consul服務的特性!

1.案例環境

Docker網絡管理之docker跨主機通信

2.準備工作

(1)關閉防火墻與SELinux(實驗環境);
(2)更改主機名,避免發生沖突;

3.案例實施

(1)Docker1

[root@Docker1 ~]# docker pull progrium/consul
//下載consul鏡像
[root@Docker1 ~]# docker run -d -p 8500:8500 -h consul --name consul  --restart=always progrium/consul -server -bootstrap
//-d:后臺運行;              
//-p:將容器中的8500端口映射到宿主機的8500端口;
//-h:表示consul容器的主機名;
//--name:表示運行的容器名;
//--restart=always:隨docker服務的啟動而啟動;
//-server -bootstrap:添加這兩個選項,則表示在群集環境中可以使其以master的身份出現;
[root@Docker1 ~]# netstat -anpt | grep 8500
tcp6       0      0 :::8500                 :::*                    LISTEN      2442/docker-proxy   
//確定其8500端口正在監聽

(2)Docker2

[root@Docker2 ~]# vim /usr/lib/systemd/system/docker.service 
//編寫Docker的主配置文件
 13 ExecStart=/usr/bin/dockerd -H unix:///var/run/docker.sock -H tcp://0.0.0.0:2376 --cluster-store=consul://192.168.1.1:8500 --cluster-advertise=ens33:2376
//在第13行上原本的基礎添加以上內容,各個配置項含義如下:
# /var/run/docker.sock:Docker的一個套接字;
# “ -H tcp://0.0.0.0:2376 ” :使用本機的tcp2376端口;
# “ --cluster-store=consul://192.168.1.1:8500”:指定運行著consul服務的docker服務器IP及端口;
# “ --cluster-advertise=ens33:2376”:從本機的ens33網卡通過2376端口搜集網絡信息,存儲在consul上
[root@Docker2 ~]# systemctl daemon-reload 
[root@Docker2 ~]# systemctl restart docker                   //重新啟動docker服務

(3)Docker3
Docker3與Docker2的操作就是一模一樣的,所以這里就不多做解釋了!

[root@Docker3 ~]# vim /usr/lib/systemd/system/docker.service 
 13 ExecStart=/usr/bin/dockerd -H unix:///var/run/docker.sock -H tcp://0.0.0.0:2376 --cluster-store=consul://192.168.1.1:8500 --cluster-advertise=ens33:2376
[root@Docker3 ~]# systemctl daemon-reload 
[root@Docker3 ~]# systemctl restart docker

(4)使用瀏覽器訪問consul服務的web頁面

如圖:
Docker網絡管理之docker跨主機通信
Docker網絡管理之docker跨主機通信
Docker網絡管理之docker跨主機通信

(5)將Docker1服務器也加入到consul群集

[root@Docker1 ~]# vim /usr/lib/systemd/system/docker.service 
 13 ExecStart=/usr/bin/dockerd -H unix:////var/run/docker.sock -H tcp://0.0.0.0:2376 --cluster-store=consul://192.168.1.1:8500 --cluster-advertise=ens33:2376
[root@Docker1 ~]# systemctl daemon-reload 
[root@Docker1 ~]# systemctl restart docker
//解釋上面都已經解釋的很清楚,這里就不做解釋了

再次訪問consul的web頁面,如圖:
Docker網絡管理之docker跨主機通信
如果在此過程中,訪問web頁面如果出現“500”的錯誤頁面,將運行consul服務的容器刪除重新創新即可!

(6)創建一個 overlay網絡

[root@Docker1 ~]#  docker network create -d overlay my_olay   
//創建一個名為my_olay的voerlay網絡 
//以上操作不管在那臺docker主機上操作都可以
[root@Docker1 ~]# docker network create -d overlay --subnet 200.0.0.0/24 --gateway 200.0.0.1 lv_olay
//也可以在創建overlay網卡時,指定其IP網段及網關
[root@Docker1 ~]# docker network ls          //查看docker所支持的網絡

Docker網絡管理之docker跨主機通信
而且在另外兩臺docker服務器上也可看到,自行驗證!

在docker 1上創建的網絡,可以看到其SPOCE(范圍)定義的是global(全局),那么這就意味著加入consul這個服務群集的其他docker服務器也可以看到這張網卡!

如果在創建網卡時,沒有指定其網段,則默認是10.0.0.0網段,由于是自定義網絡,所以滿足自定義網絡的特征(比如支持容器之間的通信)!

(7)在不同的docker服務器各自創建一個容器,驗證是否可以通信!

[root@Docker1 ~]# docker run -itd --name t1 --network lv_olay --ip 200.0.0.10 busybox:latest
//在docker1服務器上創建一個名為t1的容器并指定其IP地址
[root@Docker2 ~]#  docker run -itd --name t2 --network lv_olay --ip 200.0.0.20 busybox:latest
//在docker2上創建一個容器并指定IP地址
[root@Docker3 ~]# docker run -itd --name t3 --network lv_olay --ip 200.0.0.30 busybox:latest
//在docker3上創建一個容器并指定IP地址
[root@Docker1 ~]# docker exec -it t1 /bin/sh
//隨便在一臺docker服務器上進入其創建的容器中,進行測試

如圖:
Docker網絡管理之docker跨主機通信

五、Macvlan網絡

Macvlan是linux kernel比較新的特性,可以通過以下方法判斷當前系統是否支持:

[root@localhost ~]# modprobe macvlan        
[root@localhost ~]# lsmod | grep macvlan
macvlan                19239  0 

如果是第一個命令報錯,或者第二個命令沒有返回信息,則說明當前系統不支持macvlan,需要升級內核。

[root@docker01 ~]# modprobe 8021q         //加載內核模塊
[root@docker01 ~]# modinfo 8021q           //如果有信息返回則表示開啟8021q模塊,如果沒有使用上條命令   

這兩組命令所支持的效果一樣!

以上命令主要驗證Linux內核是否支持macvlan功能!

macvlan允許在主機的一個網絡接口上配置多個虛擬的網絡接口,這些網絡接口有自己獨立的mac地址,也可以配置IP地址進行通信。macvlan下的虛擬機或者容器網絡和主機在同一網段中,共享一個廣播域。macvlan和bridge比較相似,但因為它省去了bridge的存在,所以在配置和調試時比較簡單,而且效率較高。除此之外,macvlan自身也完美支持VLAN。

如果希望容器或者虛擬機放在主機相同的網絡中,享受已經存在網絡棧的各種優勢,可以考慮macvlan。

macvlan和overlay網絡不同,overlay的作用范圍是global;而macvlan的作用范圍是local。global類型的網絡其作用于一組docker daemon集群,local類型的網絡只作用于單一主機。

每臺主機創建的macvlan網絡是獨立的,A機器行創建的macvlan網絡并不影響B機器上的網絡。

兩臺主機在網卡配置混雜模式、兩臺主機上macvlan存在overlap、兩個macvlan網絡沒有分配過同樣的IP,以上三個條件滿足后,同樣可以實現跨主機通信!

1.環境準備

如圖:
Docker網絡管理之docker跨主機通信

2.準備工作

(1)關閉Linux防火墻和SELinux;
(2)修改主機名;

3.案例實施

關于macvlan單網絡通信這里就不介紹了,直接介紹macvlan多網絡通信!方法如下:

(1)開啟網卡混雜模式

[root@dockerA ~]#  ip link set ens33 promisc on       //開啟網卡的混雜模式
[root@dockerA ~]#  ip link show ens33                //查詢網卡已經支持PROMISC
2: ens33: <BROADCAST,MULTICAST,PROMISC,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP mode DEFAULT group default qlen 1000
    link/ether 00:0c:29:66:72:13 brd ff:ff:ff:ff:ff:ff

[root@dockerA ~]# modprobe 8021q                  /加載8021q內核模塊
[root@dockerA ~]# modinfo 8021q                   //有返回信息則表示支持8021q內核模塊

(2)創建虛擬網卡

由于一個網卡最好創建出一個macvlan網卡,所以需創建虛擬網卡以滿足要求!

[root@dockerA ~]# cd /etc/sysconfig/network-scripts/
[root@dockerA network-scripts]# sed -i 's/static/manual/g' ifcfg-ens33
[root@dockerA network-scripts]# cp -p ifcfg-ens33 ifcfg-ens33.10
[root@dockerA network-scripts]# cp -p ifcfg-ens33 ifcfg-ens33.20
[root@dockerA network-scripts]# vim ifcfg-ens33.10 
BOOTPROTO=none
NAME=ens33.10
DEVICE=ens33.10
ONBOOT=yes
IPADDR=192.168.10.1
NETMASK=255.255.255.0
GATEWAY=192.168.10.254
VLAN=yes                
//保證和原本的物理網卡不在同一網段,并且打開vlan的支持模式
[root@dockerA network-scripts]# vim ifcfg-ens33.20
BOOTPROTO=none
NAME=ens33.20
DEVICE=ens33.20
ONBOOT=yes
IPADDR=192.168.20.1
NETMASK=255.255.255.0
GATEWAY=192.168.20.254
VLAN=yes
[root@dockerA network-scripts]# ifup ifcfg-ens33.10
[root@dockerA network-scripts]# ifup ifcfg-ens33.20
[root@dockerA network-scripts]# ifconfig ens33.10
ens33.10: flags=4163<UP,BROADCAST,RUNNING,MULTICAST>  mtu 1500
        inet 192.168.10.1  netmask 255.255.255.0  broadcast 192.168.10.255
        inet6 fe80::20c:29ff:fe66:7213  prefixlen 64  scopeid 0x20<link>
        ether 00:0c:29:66:72:13  txqueuelen 1000  (Ethernet)
        RX packets 0  bytes 0 (0.0 B)
        RX errors 0  dropped 0  overruns 0  frame 0
        TX packets 29  bytes 4052 (3.9 KiB)
        TX errors 0  dropped 0 overruns 0  carrier 0  collisions 0

[root@dockerA network-scripts]# ifconfig ens33.20
ens33.20: flags=4163<UP,BROADCAST,RUNNING,MULTICAST>  mtu 1500
        inet 192.168.20.1  netmask 255.255.255.0  broadcast 192.168.20.255
        inet6 fe80::20c:29ff:fe66:7213  prefixlen 64  scopeid 0x20<link>
        ether 00:0c:29:66:72:13  txqueuelen 1000  (Ethernet)
        RX packets 0  bytes 0 (0.0 B)
        RX errors 0  dropped 0  overruns 0  frame 0
        TX packets 28  bytes 3987 (3.8 KiB)
        TX errors 0  dropped 0 overruns 0  carrier 0  collisions 0
//確保虛擬網卡已經生效

dockerB主機上的操作與dockerA主機上的操作一致(注意IP不一樣)!要保證兩臺docker主機的虛擬網卡可以通信!

[root@dockerB network-scripts]# ifconfig ens33.10
ens33.10: flags=4163<UP,BROADCAST,RUNNING,MULTICAST>  mtu 1500
        inet 192.168.10.2  netmask 255.255.255.0  broadcast 192.168.10.255
        inet6 fe80::20c:29ff:feb7:1bbd  prefixlen 64  scopeid 0x20<link>
        ether 00:0c:29:b7:1b:bd  txqueuelen 1000  (Ethernet)
        RX packets 0  bytes 0 (0.0 B)
        RX errors 0  dropped 0  overruns 0  frame 0
        TX packets 29  bytes 4100 (4.0 KiB)
        TX errors 0  dropped 0 overruns 0  carrier 0  collisions 0

[root@dockerB network-scripts]# ifconfig ens33.20
ens33.20: flags=4163<UP,BROADCAST,RUNNING,MULTICAST>  mtu 1500
        inet 192.168.20.2  netmask 255.255.255.0  broadcast 192.168.20.255
        inet6 fe80::20c:29ff:feb7:1bbd  prefixlen 64  scopeid 0x20<link>
        ether 00:0c:29:b7:1b:bd  txqueuelen 1000  (Ethernet)
        RX packets 0  bytes 0 (0.0 B)
        RX errors 0  dropped 0  overruns 0  frame 0
        TX packets 29  bytes 4100 (4.0 KiB)
        TX errors 0  dropped 0 overruns 0  carrier 0  collisions 0

(3)創建macvlan網卡

[root@dockerA ~]# docker network create -d macvlan --subnet 172.16.10.0/24 --gateway 172.16.10.1 -o parent=ens33.10 mac_net10
[root@dockerA ~]# docker network create -d macvlan --subnet 172.16.20.0/24 --gateway 172.16.20.1 -o parent=ens33.20 mac_net20
//創建虛擬網卡并針對其網段、網關
//-d:指令網卡驅動類型,-o parent:綁定在那張網卡上
[root@dockerA ~]# docker network ls
NETWORK ID          NAME                DRIVER              SCOPE
0a74599fef51        bridge              bridge              local
624b3ba70637        host                host                local
cb81dde7685d        mac_net10           macvlan             local
983927dbcae8        mac_net20           macvlan             local
62f80646f707        none                null                local

dockerB主機上的創建虛擬網卡時,命令一模一樣,指定的網段、名稱必須一樣,因為要保證其通過虛擬網卡可以通信!

[root@dockerB ~]# docker network create -d macvlan --subnet 172.16.10.0/24 --gateway 172.16.10.1 -o parent=ens33.10 mac_net10
[root@dockerB ~]# docker network create -d macvlan --subnet 172.16.20.0/24 --gateway 172.16.20.1 -o parent=ens33.20 mac_net20

(4)基于創建的macvlan網卡創建容器,驗證是否可以通信!

dockerA主機創建容器:

[root@dockerA ~]# docker run -itd --name box10 --network mac_net10 --ip 172.16.10.10 busybox
[root@dockerA ~]# docker run -itd --name box20 --network mac_net20 --ip 172.16.20.10 busybox

dockerB主機創建容器:

[root@dockerB ~]# docker run -itd --name box11 --network mac_net10 --ip 172.16.10.20 busybox
[root@dockerB ~]# docker run -itd --name box21 --network mac_net20 --ip 172.16.20.20 busybox

進入容器進行驗證:

[root@dockerA ~]# docker exec -it box10 /bin/sh
/ # ping 172.16.10.20
PING 172.16.10.20 (172.16.10.20): 56 data bytes
64 bytes from 172.16.10.20: seq=0 ttl=64 time=0.653 ms
64 bytes from 172.16.10.20: seq=1 ttl=64 time=0.966 ms
[root@dockerA ~]# docker exec -it box20 /bin/sh/ # ping 172.16.20.20
PING 172.16.20.20 (172.16.20.20): 56 data bytes
64 bytes from 172.16.20.20: seq=0 ttl=64 time=0.734 ms
64 bytes from 172.16.20.20: seq=1 ttl=64 time=0.718 ms

注意:實驗環境驗證時,應使用虛擬機橋接模式;并且,測試時,只能ping通另一條docker host容器的ip,因為創建的虛擬macvlan的范圍是local!

六、使外網可以訪問容器的方法

(1)手動指定映射端口

[root@localhost ~]# docker run -itd --name web1 -p 90:80 nginx
//將一個容器的nginx服務映射到宿主機的90端口

(2)隨機映射端口

[root@localhost ~]# docker run -itd --name web2 -p 80 nginx   
//如果-p之后只有一個端口,則是容器中的端口(宿主機會隨機映射一個端口)從32768端口開始

(3)將容器中的端口全部映射到宿主機上

[root@localhost ~]# docker run -itd --name web4 -P nginx 
//注意:大寫的P
//從宿主機隨機映射端口到容器,容器內所有暴露的端口,都會一一映射

以上操作,個人驗證沒有問題,這里就不截圖示范了!

—————————本文到此結束,感謝觀看—————————

向AI問一下細節

免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。

AI

巨野县| 额敏县| 江油市| 仁布县| 铜陵市| 拜泉县| 务川| 屏南县| 济阳县| 湘西| 罗定市| 柘城县| 芮城县| 平江县| 高陵县| 宜黄县| 开阳县| 额尔古纳市| 敦化市| 康保县| 象山县| 蒙阴县| 新兴县| 随州市| 巧家县| 新和县| 财经| 梁河县| 县级市| 巴青县| 思南县| 和平县| 浦东新区| 广丰县| 曲阳县| 中西区| 开阳县| 江阴市| 九龙城区| 荆门市| 平乡县|