Docker网络

1 - 理解Docker0

1、清空所有容器与镜像,净化环境

# 清空所有容器
docker rm -f $(docker ps -aq)

# 清空所有镜像
docker rmi -f $(docker images -aq)

2、思考:Docker是如何处理容器网络访问的?

# 启动一个Tomcat
[root@VM-0-17-centos /]# docker run -d -P --name tomcat01 tomcat

# 查看容器内部网络地址。追加一个命令 ip addr  发现容器启动的时候会得到一个 eth0@if81 ip地址,docker分配的
[root@VM-0-17-centos /]# 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
80: eth0@if81: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP group default 
    link/ether 02:42:ac:12:00:02 brd ff:ff:ff:ff:ff:ff link-netnsid 0
    inet 172.18.0.2/16 brd 172.18.255.255 scope global eth0 # docker0地址
       valid_lft forever preferred_lft forever

# 思考,Linux能不能 ping 通容器内部?
# 测试
[root@VM-0-17-centos /]# ping 172.18.0.2
PING 172.18.0.2 (172.18.0.2) 56(84) bytes of data.
64 bytes from 172.18.0.2: icmp_seq=1 ttl=64 time=0.072 ms
64 bytes from 172.18.0.2: icmp_seq=2 ttl=64 time=0.048 ms

# 说明:Linux 可以ping 通docker容器内部 

3、docker0原理

  1、我们每启动一个容器,docker就会给docker容器分配一个ip,我们只要安装了docker,就会有一个网卡docker0

    桥接模式,使用的技术是 evth-pair

  

   

# 我们发现这个容器带来的网卡,都是一对对的
# veth-pair 就是一对的虚拟设备接口,他们都是成对存在的,一段连接着协议,一段彼此相连
# 因为有这个特性,veth-pair 充当一个桥梁,连接各种虚拟网络设备的
# OpenStac,Docker容器之间的连接,OVS的连接,都是使用veth-pair技术

4、我们来测试下tomcat01和tomcat02是否可以ping通

[root@VM-0-17-centos /]# docker exec -it tomcat01 ip addr    #  获取 tomcat01 的ip
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
80: eth0@if81: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP group default 
    link/ether 02:42:ac:12:00:02 brd ff:ff:ff:ff:ff:ff link-netnsid 0
    inet 172.18.0.2/16 brd 172.18.255.255 scope global eth0
       valid_lft forever preferred_lft forever
[root@VM-0-17-centos /]# docker exec -it tomcat02 ping 172.18.0.2     # 让tomcat02 ping tomcat01
PING 172.18.0.2 (172.18.0.2) 56(84) bytes of data.
64 bytes from 172.18.0.2: icmp_seq=1 ttl=64 time=0.122 ms
64 bytes from 172.18.0.2: icmp_seq=2 ttl=64 time=0.059 ms

# 测试结果发下,容器之间可以ping 通

5、docker0网络通信原理图(桥连接)

结论:tomcat01tomcat02公用一个路由器,docker0

所有的容器不指定网络的情况下,都是docker0路由的,docker会给我们的容器分配一个默认的可用ip

小结: Docker使用的是Linux的桥接,宿主机是一个Docker容器的网桥 docker0。Docker中所有的网路接口都是虚拟的,虚拟的转发效率高(内网传递文件)

只要容器删除,对应的网桥对就没有了

2 - 容器互联之 --link

思考一个场景:我们编写了一个微服务,database url=ip: 项目不重启,数据ip换了,我们希望可以处理这个问题,可以通过名字来进行访问容器?

$ docker exec -it tomcat02 ping tomca01   # ping不通
ping: tomca01: Name or service not known
# 运行一个tomcat03 --link tomcat02 
$ docker run -d -P --name tomcat03 --link tomcat02 tomcat
5f9331566980a9e92bc54681caaac14e9fc993f14ad13d98534026c08c0a9aef
# 用tomcat03 ping tomcat02 可以ping通
$ 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.115 ms
64 bytes from tomcat02 (172.17.0.3): icmp_seq=2 ttl=64 time=0.080 ms

# 用tomcat02 ping tomcat03 ping不通

探究: docker network inspect 网络id 网段相同

docker inspect tomcat03

 查看tomcat03里面的/etc/hosts发现有tomcat02的配置

–link 本质就是在hosts配置中添加映射

现在使用Docker已经不建议使用–link了!

自定义网络,不适用docker0!

docker0问题:不支持容器名连接访问!

3 - 容器互联之自定义网络

1、查看所有的docker网络

[root@VM-0-17-centos /]# docker network ls
NETWORK ID          NAME                DRIVER              SCOPE
c4119baf1ba2        bridge              bridge              local
c42cab1b38db        host                host                local
b5c1e156330a        none                null                local

网络模式

bridge    # 桥连接 docker默认,自己创建也使用 bridge 模式

host    # 不配置网络

none    # 和宿主机共享网络

container    # 容器内网络联通(用的少)

自定义网络

# 我们直接启动的命令 --net bridge 而这个就是我们的docker0
docker run -d -P --name tomcat01 tomcat
docker run -d -P --name tomcat01 --net bridge tomcat

# docker0的特点:默认,容器名不能访问。--link 可以打通容器间连接,但是也有一些弊端

# 我们可以自定义
# --driver bridge
# --subnet 192.168.0.0/16
# --gateway 192.168.0.1
[root@VM-0-17-centos /]# docker network create --driver bridge --subnet 192.168.0.0/16 --gateway 192.168.0.1 mynet
051c657ae074e244437a7fc7a606187efd9a96ad8214e32ae375adc689c08103
[root@VM-0-17-centos /]# docker network ls
NETWORK ID          NAME                DRIVER              SCOPE
c4119baf1ba2        bridge              bridge              local
c42cab1b38db        host                host                local
051c657ae074        mynet               bridge              local
b5c1e156330a        none                null                local

# 启动两个tomcat
[root@VM-0-17-centos /]# docker run -d -P --name tomcat-mynet01 --net mynet tomcat
6538cf23ba9ffbb40dbb61ce978fc796a6145035379056cfa7822370637e279f
[root@VM-0-17-centos /]# docker run -d -P --name tomcat-mynet02 --net mynet tomcat
c568b7da687c0ae3b19983444aa0c4b0268313a30c433a84ccd8b88ebe59784a


# 此时可以查看以自定义的网络配置 docker network inspect mynet
[root@VM-0-17-centos /]# docker network inspect mynet
[
    {
        "Name": "mynet",
        "Id": "051c657ae074e244437a7fc7a606187efd9a96ad8214e32ae375adc689c08103",
        "Created": "2020-10-05T19:53:44.245591371+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": {
            "6538cf23ba9ffbb40dbb61ce978fc796a6145035379056cfa7822370637e279f": {
                "Name": "tomcat-mynet01",
                "EndpointID": "1c394d71dfd9abcf88fefc981cf985d5b42cc368cbb9d03e07e297b3fa87b8c3",
                "MacAddress": "02:42:c0:a8:00:02",
                "IPv4Address": "192.168.0.2/16",
                "IPv6Address": ""
            },
            "c568b7da687c0ae3b19983444aa0c4b0268313a30c433a84ccd8b88ebe59784a": {
                "Name": "tomcat-mynet02",
                "EndpointID": "4100b2e8c9c35460e41e8212b428d6c558055e6176b502a18a3f8e6e20038f8c",
                "MacAddress": "02:42:c0:a8:00:03",
                "IPv4Address": "192.168.0.3/16",
                "IPv6Address": ""
            }
        },
        "Options": {},
        "Labels": {}
    }
]

测试两个 tomcat 通过ip地址或者容器名 能不能 ping 通

# 测试通过ip 地址能不能ping 通
[root@VM-0-17-centos /]# docker exec -it tomcat-mynet01 ip addr    # 获取tomcat-mynet01 的ip地址
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
87: eth0@if88: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP group default 
    link/ether 02:42:c0:a8:00:02 brd ff:ff:ff:ff:ff:ff link-netnsid 0
    inet 192.168.0.2/16 brd 192.168.255.255 scope global eth0
       valid_lft forever preferred_lft forever
# 测试
[root@VM-0-17-centos /]# docker exec -it tomcat-mynet02 ping 192.168.0.2
PING 192.168.0.2 (192.168.0.2) 56(84) bytes of data.
64 bytes from 192.168.0.2: icmp_seq=1 ttl=64 time=0.088 ms
64 bytes from 192.168.0.2: icmp_seq=2 ttl=64 time=0.075 ms
# 通过容器名 ping 通
[root@VM-0-17-centos /]# docker exec -it tomcat-mynet02 ping tomcat-mynet02
PING tomcat-mynet02 (192.168.0.3) 56(84) bytes of data.
64 bytes from c568b7da687c (192.168.0.3): icmp_seq=1 ttl=64 time=0.030 ms
64 bytes from c568b7da687c (192.168.0.3): icmp_seq=2 ttl=64 time=0.047 ms

好处:

redis -不同的集群使用不同的网络,保证集群是安全和健康的

mysql-不同的集群使用不同的网络,保证集群是安全和健康的

4 - 网络连通

1、为什么需要网络连通?两个属于不同网卡的容器之间实现互联!

2、网络连通命令

3、测试

#  测试两个不同的网络连通  再启动两个tomcat 使用默认网络,即docker0
[root@VM-0-17-centos /]# docker run -d -P --name tomcat01 tomcat
9248bf34255630899658d334423c6a5b946e5b8dbd4807d96425ff8027263f32
[root@VM-0-17-centos /]# docker run -d -P --name tomcat02 tomcat
b7daa6950ce761a92af859f8f4590a754bab633e4ce79811560beeed70bb8d78
[root@VM-0-17-centos /]# docker ps
CONTAINER ID        IMAGE               COMMAND             CREATED             STATUS              PORTS                     NAMES
b7daa6950ce7        tomcat              "catalina.sh run"   8 seconds ago       Up 7 seconds        0.0.0.0:32778->8080/tcp   tomcat02
9248bf342556        tomcat              "catalina.sh run"   16 seconds ago      Up 16 seconds       0.0.0.0:32777->8080/tcp   tomcat01

# 此时ping不通

# 要将tomcat01 连通 tomcat—mynet01 ,连通就是将 tomcat01加到 mynet网络
[root@VM-0-17-centos /]# docker run -d -P --name tomcat-mynet01 --net mynet tomcat
347517e4ac2d18e252a2003af1d0cd5aeeec812466e7ad93621b74b46211e3eb

# 连通命令:docker network connect 网络模式 容器名
[root@VM-0-17-centos /]# docker network connect mynet tomcat01
# 测试
[root@VM-0-17-centos /]# docker exec -it tomcat01 ping tomcat-mynet01
PING tomcat-mynet01 (192.168.0.2) 56(84) bytes of data.
64 bytes from tomcat-mynet01.mynet (192.168.0.2): icmp_seq=1 ttl=64 time=0.068 ms
64 bytes from tomcat-mynet01.mynet (192.168.0.2): icmp_seq=2 ttl=64 time=0.059 ms

# 原因:使用连通命令时,将tomcat01 放到了 mynet下。可用 docker network inspect mynet 查看

# 总结:一个容器两个ip,网卡之间不能直接打通

结论:假设要跨网络操作别人的容器,就需要使用docker network connect 连通!

posted @ 2020-10-05 13:57  赖正华  阅读(151)  评论(0编辑  收藏  举报