這篇文章主要解決以下幾個問題:
1.同一個網段的容器互相之間通過ip進行ping通
2.同一個網段的容器互相之間通過容器名,通過使用--link
進行ping通,已放棄這種方法
3.同一個網段的容器互相之間通過容器名,通過創建自定義網絡進行ping通,建議采用這種方法
4.不同網段的容器互相之間通過容器名,通過創建自定義網絡,某個網段內的容器關聯到另一個網段(則該容器有倆IP地址),進行ping通,建議采用這種方法
(容器沒有關聯到另一個網段則沒法ping通)
不同主機之間的docker容器網絡互通查看這個文章:https://www.cnblogs.com/sanduzxcvbnm/p/11578827.html
清空所有環境
# 停止並刪除所有容器
docker stop `docker ps -q`
docker rm `docker ps -a -q`
# 刪除所有鏡像
docker rmi `docker images -q` -f
測試
問題:docker 是如何處理容器網絡訪問的
啟動一個tomcat
docker run -d -P --name tomcat01 tomcat
# 查看ip
[root@iz2zeaet7s13lfkc8r3e2kz ysl]# docker exec -it tomcat01 ip addr
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
146: eth0@if147: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP group default
link/ether 02:42:ac:11:00:02 brd ff:ff:ff:ff:ff:ff link-netnsid 0
inet 172.17.0.2/16 brd 172.17.255.255 scope global eth0
valid_lft forever preferred_lft forever
# 發現容器啟動 eth0@if147 ip地址,docker分配的!
測試,Linux能不能 ping 通容器內部?
Linux宿主機是可以 ping 通 docker容器內部的 (禁ping除外)
原理
每啟動一個docker容器,docker就會給docker容器分配一個ip,我們只要安裝了docker,就會有一個網卡docker0 橋接模式,使用的技術是veth-pair 技術!
再次測試ip addr
再啟動一個容器
docker run -d -P --name tomcat02 tomcat
再次測試ip addr 發現又多了一對網卡
查看ip
# 發現這個容器帶來的網卡都是一對對的
# veth-pair 就是一對的虛擬設備接口,他們都是成對出現的,一端連着協議,一端彼此相連
# veth-pair 充當一個橋梁,鏈接各種虛擬網絡設備的
# OpenStack,Docker容器之間的鏈接,ovs的鏈接,都是使用的 veth-pair 技術
測試 tomcat02 ping tomcat01
結論:容器和容器之間通過ip形式是可以互相ping通的! (都是在同一個網絡命令中,bridge橋接)
小結:Docker使用的是Linux的橋接,宿主機中是一個Docker容器的網橋 docker0,最多能分配約65535
Docker中的所有的網絡接口都是虛擬的。虛擬的轉發效率高!
測試刪掉容器
只要容器刪除,對應的一對網橋就沒了!
希望用名字來訪問容器
啟動tomcat01
直接用名字ping
解決
[root@iz2zeaet7s13lfkc8r3e2kz ysl]# docker run -d -P --name tomcat03 --link tomcat02 tomcat
6eac1dfba29cda8a2a20aea6e820f3b2ebbd85d0d9223b650306b34febb820b0
[root@iz2zeaet7s13lfkc8r3e2kz ysl]# docker exec -it tomcat03 ping tomcat02
PING tomcat02 (172.17.0.3) 56(84) bytes of data.
64 bytes from tomcat02 (172.17.0.3): icmp_seq=1 ttl=64 time=0.127 ms
64 bytes from tomcat02 (172.17.0.3): icmp_seq=2 ttl=64 time=0.092 ms
64 bytes from tomcat02 (172.17.0.3): icmp_seq=3 ttl=64 time=0.088 ms
64 bytes from tomcat02 (172.17.0.3): icmp_seq=4 ttl=64 time=0.087 ms
64 bytes from tomcat02 (172.17.0.3): icmp_seq=5 ttl=64 time=0.098 ms
# 通過 --link 就可以解決
# 但是反向ping就不行了
[root@iz2zeaet7s13lfkc8r3e2kz ysl]# docker exec -it tomcat02 ping tomcat03
ping: tomcat03: Name or service not known
探究: 查看 hosts 文件
現在Docker已經不建議使用 --link 了!
自定義網絡
查看所有的Docker網絡
[root@iz2zeaet7s13lfkc8r3e2kz ysl]# docker network ls
NETWORK ID NAME DRIVER SCOPE
8ce5d63292ee bridge bridge local
b01be88b9d12 host host local
54b9e50084dd none null local
網絡模式
bridge :橋接 docker(默認)
host :和宿主機共享網絡
none :不配置網絡
測試,清空容器
[root@iz2zeaet7s13lfkc8r3e2kz ysl]# docker rm -f $(docker ps -aq)
6eac1dfba29c
4e2db5c641fd
369e4fb8fd1e
# 直接啟動的命令默認會有一個 --net bridge 操作,這個就是docker0
docker run -d -P --name tomcat01 tomcat
docker run -d -P --name tomcat01 --net bridge tomcat
自定義一個網絡
# 自定義一個網段,名稱是mynet
[root@iz2zeaet7s13lfkc8r3e2kz ysl]# docker network create --driver bridge --subnet 192.168.0.0/16 --gateway 192.168.0.1 mynet
ce6c831fa98c8e809096eb37b682abf1ce9b541d73b75f4c7126dfe8748c5971
# 查看docker網絡,多了一個橋接的mynet
[root@iz2zeaet7s13lfkc8r3e2kz ysl]# docker network ls
NETWORK ID NAME DRIVER SCOPE
8ce5d63292ee bridge bridge local
b01be88b9d12 host host local
ce6c831fa98c mynet bridge local
54b9e50084dd none null local
# 查看mynet信息,可以看到沒有關聯的容器
[root@iz2zeaet7s13lfkc8r3e2kz ysl]# docker network inspect mynet
[
{
"Name": "mynet",
"Id": "ce6c831fa98c8e809096eb37b682abf1ce9b541d73b75f4c7126dfe8748c5971",
"Created": "2020-05-27T16:30:22.691575681+08:00",
"Scope": "local",
"Driver": "bridge",
"EnableIPv6": false,
"IPAM": {
"Driver": "default",
"Options": {},
"Config": [
{
"Subnet": "192.168.0.0/16",
"Gateway": "192.168.0.1"
}
]
},
"Internal": false,
"Attachable": false,
"Ingress": false,
"ConfigFrom": {
"Network": ""
},
"ConfigOnly": false,
"Containers": {},
"Options": {},
"Labels": {}
}
]
# 到這里網絡就創建好了
# 用剛才自定義的網絡mynet啟動容器
[root@iz2zeaet7s13lfkc8r3e2kz ysl]# docker run -d -P --name tomcat-net-01 --net mynet tomcat
0dcb6a5f014415cb6c98c93c9dac21b7f5cae21df5cc5e42f331cc6e07a1ec93
[root@iz2zeaet7s13lfkc8r3e2kz ysl]# docker run -d -P --name tomcat-net-02 --net mynet tomcat
eec65d6dc9cdad33f85d3874fcf8291ed46c97893ae1298c7d23d9d85e7dda87
# 再次查看mynet信息,可以看到有兩個關聯的容器
[root@iz2zeaet7s13lfkc8r3e2kz ysl]# docker network inspect mynet
[
{
"Name": "mynet",
"Id": "ce6c831fa98c8e809096eb37b682abf1ce9b541d73b75f4c7126dfe8748c5971",
"Created": "2020-05-27T16:30:22.691575681+08:00",
"Scope": "local",
"Driver": "bridge",
"EnableIPv6": false,
"IPAM": {
"Driver": "default",
"Options": {},
"Config": [
{
"Subnet": "192.168.0.0/16",
"Gateway": "192.168.0.1"
}
]
},
"Internal": false,
"Attachable": false,
"Ingress": false,
"ConfigFrom": {
"Network": ""
},
"ConfigOnly": false,
"Containers": {
"0dcb6a5f014415cb6c98c93c9dac21b7f5cae21df5cc5e42f331cc6e07a1ec93": {
"Name": "tomcat-net-01",
"EndpointID": "2364095efd247b368c6787bef9889fa60e58fa0dbc588e59f3f34894044f158f",
"MacAddress": "02:42:c0:a8:00:02",
"IPv4Address": "192.168.0.2/16",
"IPv6Address": ""
},
"eec65d6dc9cdad33f85d3874fcf8291ed46c97893ae1298c7d23d9d85e7dda87": {
"Name": "tomcat-net-02",
"EndpointID": "1dfd0a22eb575215d2a2b899bf10079fba54cabda082a89b672b8bf4ec0c585e",
"MacAddress": "02:42:c0:a8:00:03",
"IPv4Address": "192.168.0.3/16",
"IPv6Address": ""
}
},
"Options": {},
"Labels": {}
}
]
測試 用名字 ping 一下,可以互相通過容器名稱進行ping通
現在不使用 --link 也可以ping名字了!
不同網段的容器網絡連通
測試
這是不可能的!需要打通
# 測試打通 tomcat01 - mynet
[root@iz2zeaet7s13lfkc8r3e2kz ysl]# docker network connect mynet tomcat01
# 看一下網絡信息
docker network inspect mynet
連通之后就是將tomcat01 放到了 mynet 網絡下!一個容器兩個ip地址
再次ping