目錄
- 一.Docker網路
- 1.橋接網路
- 2.host網路模式
- 3.none模式
- 二.自定義網路
- 1.創建自定義網橋
- 2.自定義網段
- 3.手動指定ip
- 4.雙網卡來實作不同網段間通信
- 三.Docker容器通信
- 1.內部訪問外部
- 2.外部訪問內部
- 3.原理
- 四.創建macvlan網路
- 1.使用eth0網卡來通信
- 測驗
- 2.使用eth1網卡來通信
- 實作不同網段的通信
- 結論
我們需要將前面的docker-compose倉庫停掉
[root@server1 harbor]# docker-compose stop

一.Docker網路
docker的鏡像是令人稱道的地方,但網路功能還是相對薄弱的部分,
docker安裝后會自動創建3種網路:bridge、host、none
1.橋接網路
安裝橋接網路
ip addr show docker0
yum install bridge-utils -y

[root@server1 ~]# brctl show

運行一個容器查看橋接
root@server1 ~]# docker run -d --name demo nginx
[root@server1 ~]# brctl show

當我們洗掉掉容器之后,橋接又消失了!
docker rm -f demo
brctl show

2.host網路模式
需要我們指定network host
我們可以看到我們的橋介面上沒有出現新的橋介面
[root@server1 ~]# docker run -d --name demo --network host nginx
[root@server1 ~]# brctl show
[root@server1 ~]# brctl show docker0

我們查看埠,可以發現docker運行的鏡像nginx占用的是80埠!
[root@server1 ~]# netstat -antlp

這個時候,我們再運行一個容器起名為demo2,注意觀察,啟動之后,查看行程有兩個行程demo,demo2,但是很快在查看行程,demo2消失了!
再也不會出現,
為什么?
因為加上引數–network host會占用虛擬機的80埠,所以剛開始嘗試啟動會看到行程,但是會被demo的80埠擠掉demo2!!
[root@server1 ~]# docker run -d --name demo2 --network host nginx
[root@server1 ~]# docker ps

我們查看日志就知道:
docker logs

3.none模式
none模式是指禁用網路功能,只有lo介面,在容器創建時使用!
先洗掉掉剛才創建的容器,重新運行容器:
[root@server1 ~]# docker rm -f demo
[root@server1 ~]# docker rm -f demo2
[root@server1 ~]# netstat -antlp ##80埠隨之消失!
[root@server1 ~]# docker run -it --rm --network=none busybox
/ # ip addr


我們發現ip addr的時候:只有lo介面

二.自定義網路
1.創建自定義網橋
建議使用自定義的網路來控制哪些容器可以相互通信,還可以自動DNS決議容器名稱到IP地址,
創建網橋!!查看型別為brodge!!
[root@server1 ~]# docker network create mynet1
[root@server1 ~]#docker network ls

測驗:
這時我們發現我們是可以ping demo可以直接成功,說明這模式是可以給提供決議的
[root@server1 ~]# docker run -d --name demo1 --network mynet1 nginx
[root@server1 ~]# docker run -it --rm --network mynet1 busybox
/ # ip addr
/ # ping demo



注意:
我們再開一個nginx,停掉所有的demo,再次開啟時,順序反一下,查看ip變化
[root@server1 ~]# docker run -d --name demo2 --network mynet1 nginx
[root@server1 ~]# docker stop demo1
[root@server1 ~]# docker stop demo2
[root@server1 ~]# docker start demo2
[root@server1 ~]# docker start demo1
[root@server1 ~]# docker inspect demo2
[root@server1 ~]# docker inspect demo1
[root@server1 ~]# docker ps
[root@server1 ~]# docker attach 8095eebc598a ##進入busybox查看
/ # ping demo2
PING demo2 (172.17.0.2):
/ # ping demo
PING demo1 (172.17.0.4):

我們會發現之前的demo1是172.17.0.2,demo2是172.17.0.4,
現在IP地址反過來了! 為什么?
這說明:系統會自動分配ip,按照啟動順序ip單調遞增,但是ping名稱的時候會自動決議地址!
2.自定義網段
創建時指定引數:–subnet 、–gateway
[root@server1 ~]# docker network rm mynet1 ##定義的網路刪掉
[root@server1 ~]# docker network create --subnet 172.20.0.0/24 --gateway 172.20.0.1 mynet1

[root@server1 ~]# docker inspect mynet1

3.手動指定ip
使用–ip引數可以指定容器ip地址,但必須是在自定義網橋上
[root@server1 ~]# docker rm demo
demo
[root@server1 ~]# docker rm demo2
demo2
[root@server1 ~]# docker run -it --rm --ip 172.20.0.10 --network mynet1 busybox
[root@server1 ~]# docker run -it --rm --network mynet1 busybox
ip addr
[root@server1 ~]# docker inspect mynet1



4.雙網卡來實作不同網段間通信
橋接到不同網橋上的容器,彼此是不通信的,
如何使兩個不同網橋的容器通信呢:
使用 docker network connect命令為demo添加一塊mynet1 的網卡,
[root@server1 ~]# docker rm -f demo1
[root@server1 ~]# docker network rm mynet1
[root@server1 ~]# docker network create --subnet 172.20.0.0/24 --gateway 172.20.0.1 mynet2

[root@server1 ~]#docker run -d --name demo --network mynet1 --ip 172.20.0.10 nginx

[root@server1 ~]#docker run -it --rm --network mynet1 busybox
ip addr

[root@server1 ~]#docker run -it --rm --network mynet2 busybox
ip addr

docker inspect demo 查看id
[root@server1 ~]# docker inspect demo
[root@server1 ~]# docker network connect mynet1 demo(或1b22f***)
[root@server1 ~]# docker attach 1b22f******
ip addr
我們可以看到mynet1,mynet2的ip都出現在了里面!說明通信成功!

然后可以直接在容器里面:ping demo成功!

三.Docker容器通信
容器之間除了使用ip通信外,還可以使用容器名稱通信,
dns決議功能必須在自定義網路中使用,
在容器創建時使用–network=container:vm1指定,(vm1指定的是運行的容器名)
[root@server1 ~]# docker run -it --rm --network container:demo busybox
/ # ip addr

處于這個模式下的 Docker 容器會共享一個網路堆疊,這樣兩個容器之間可以使用localhost高效快速通信,
–link 可以用來鏈接2個容器,
–link的格式:
–link **:alias
name是源容器的name,alias是源容器在link下的別名,
[root@server1 ~]# docker pull nginx:latest
[root@server1 ~]# docker run -d --name demo nginx
[root@server1 ~]# docker run -it --rm --link demo:web busybox
/ # ping demo
/ # env


我們再次打開一個終端鏈接server1:
[root@server1 ~]# docker stop demo
[root@server1 ~]# docker run -d --name test nginx
[root@server1 ~]# docker start demo


我們再一次ping,發現ip變了(由 172.17.02 >>172.17.0.4),但是仍然可以ping名字demo成功!說明它i的名字隨著IP實時更新變化的!!

這時我們查看/etc/hosts,發現他已經給我們自動修改了決議

1.內部訪問外部
容器內部也是可以訪問外部網路的
sysctl -a | grep ip_forward
可以看到路由轉發功能是開啟的為1

那么我們在容器里面可以ping baidu.com
docker run -it --rm --link demo:web busybox
ping baidu.com

2.外部訪問內部
容器如何訪問外網是通過iptables的SNAT實作的
外網如何訪問容器:
埠映射
-p 選項指定映射埠
[root@server1 ~]# docker rm -f demo
[root@server1 ~]# docker rm -f test
docker history nginx 看到本身的埠為80
[root@server1 ~]# docker run -d --name demo -p 80:80 nginx
[root@server1 ~]# docker port demo
[root@server1 ~]# iptables -t nat -nL
[root@server1 ~]#netstat -antlp



netstat -antlp查看埠發現有docker-proxy

3.原理
外網訪問容器用到了docker-proxy和iptables DNAT
宿主機訪問本機容器使用的是iptables DNAT
外部主機訪問容器或容器之間的訪問是docker-proxy實作
測驗:
[root@server1 ~]# curl 172.25.0.1
[root@server1 ~]# curl localhost
都是nginx的發布頁面

現在嘗試將iptables里面的策略時洗掉,再次測驗
iptables -t nat -D DOCKER 6

已經刪掉了策略!
[root@server1 ~]# iptables -t nat -nL

[root@server1 ~]# curl localhost
發現nginx發布頁面還在

但是如果將docker-proxy行程殺掉,再次訪問查看效果

已經訪問不到了

當我們重新添加iptables策略
[root@server1 ~]# iptables -t nat -A DOCKER -p tcp --dport 80 -j DNAT --to-det 172.17.0.2:80

再次在真機上訪問curl 172.25.0.1
或者在server1上訪問本地localhost
發現又可以訪問到nginx的發布頁面了!!!
所以總結:docker-proxy,iptables里面的策略至少需要存在一個才可以!!
四.創建macvlan網路
1.使用eth0網卡來通信
需要兩臺虛擬機server1,server2:
在兩臺docker主機上各創建macvlan網路
我們先用eth0網卡連作為兩臺虛擬機通信的網卡!
首先在server1上操作:
[root@server1 ~]# ip addr show eth0
[root@server1 ~]#ip link set eth1 promisc on
[root@server1 ~]# ip addr show eth0

我們發現ip link set eth1 promisc on打開之后,ip addr的eth0出現了promisc模式!!
將之前實驗的網路橋接洗掉掉!
docker network ls
docker network rm mynet1
docker network rm mynet2
cd harbor/
docker-compose stop


先在server1上創建指定條件的容器然后運行容器:
[root@server1 ~]#docker network create -d macvlan --subnet 172.20.0.0/24 --gateway=172.20.0.1 -o parent=eth0 macvlan1
[root@server1 ~]# docker run -it --rm --network macvlan1 --ip 172.20.0.10 busybox
ip addr

接著在server2上操作:
洗掉不用的橋接網路,本人是因為做過實驗所以需要洗掉!
[root@server2 ~]#ip link set eth1 promisc on
[root@server2 ~]# ip addr show eth0
[root@server2 ~]#docker network ls
[root@server2 ~]#docker network rm macvlan1
[root@server2 ~]#docker network rm mynet1


接著創建容器并運行和server1操作一樣(只有IP不一致!)!
[root@server2 ~]#docker network create -d macvlan --subnet 172.20.0.0/24 --gateway=172.20.0.1 -o parent=eth0 macvlan1
[root@server2 ~]#docker network ls
[root@server2 ~]# docker run -it --rm --network macvlan1 --ip 172.20.0.11 busybox
ip addr

``
這個時候已經完成了兩臺docker主機網卡的通信:
測驗
在server1上的docker去ping一下server2的docker的ip地址:
發現可以通信!
ping 172.20.0.11

同理在server2上的docker去ping一下server2的docker的ip地址
也是可以成功的!
ping 172.20.0.10
2.使用eth1網卡來通信
首先需要在server1,2上再添加一塊網卡:
virt-manager
分別選擇兩個虛擬機
添加網卡:add hardware
network網卡:virtio橋接的模式
finish


添加網卡之后,查看eth1可以看到沒有ip只是一個網卡
ip link set up eth1讓它啟用!
ip addr show eth1
ip link set up eth1

我們需要編輯網卡的組態檔
cd /etc/sysconfig/network-scripts
cp ifcfg-eth0 ifcfg-eth1
vim ifcfg-eth1


讓eth0網卡不能獲得ip,隨網路服務啟動

重新激活網卡
ifup eth1

我們查看一下eth1
ip addr show eth1
發現已經激活但是promisc模式還沒有打開!

開啟promisc模式
ip link set eth1 promisc on

創建容器并運行,注意網段需要改變一下和前面eth0不一樣172.21..
[root@server1 ~]#docker network create -d macvlan --subnet 172.21.0.0/24 --gateway=172.21.0.1 -o parent=eth1.1 macvlan2
[root@server1 ~]# docker run -it --rm --network macvlan2 --ip 172.21.0.10 busybox
ip addr

在server2也需要激活網卡打開promisc模式
ip link set up eth1
ip link set eth1 promisc on
ip addr show eth1


在server2也需要創建容器并運行:
[root@server2 ~]#docker network create -d macvlan --subnet 172.21.0.0/24 --gateway=172.21.0.1 -o parent=eth1.1 macvlan2
[root@server2 ~]# docker run -it --rm --network macvlan2 --ip 172.21.0.11 busybox
ip addr

測驗:
server1里可以ping通server2 的ip;172.21.0.11
ping 172.21.0.11

同理server2也可以ping通server1
ping 172.21.0.10

實作不同網段的通信
我們在server2上運行前面的macvlan1
[root@server2 ~]# docker run --rm --network macvlan1 --ip 172.20.0.11 busybox

在server1上
如何使兩個不同網橋的容器通信呢:
使用 docker network connect命令為demo添加一塊macvlan1 的網卡,
先將macvlan2剛才的行程結束:
docker ps
docker rm -f ********
docker run -d --name demo --network macvlan2 --ip 172.21.0.10 nginx
docker network connect macvlan1 demo
docker inspect demo


然后運行容器,為demo添加一塊macvlan1 的網卡,
我們可以看到demo的資訊中會自動生成和 macvlan1同網段172.20.*.*的ip:172.20.0.2

測驗:
我們發現不同網段 172.21.0.10還是不能通信,但是生成的Ip172.20.0.2可以訪問,
ping 172.21.0.10
ping 172.20.0.2

結論
我們得出結論:不同網段的ip是無法互通的,但是兩個處于不同網段的容器可以通過docker network connect macvlan1 demo的方式來生成同一網段IP地址的方式來實作容器間的通信!!
在server2上去訪問172.25.0.2
curl 172.25.0.2
成功!

轉載請註明出處,本文鏈接:https://www.uj5u.com/qita/289802.html
標籤:其他
下一篇:Nginx詳細介紹、安裝與部署
