• Docker的自定义网络


    参考资料:B站狂神教程
    https://www.bilibili.com/video/BV1og4y1q7M4?p=36

    Docker的网络模式

    root@KitDevVps:~# docker network ls
    NETWORK ID          NAME                DRIVER              SCOPE
    1375b7ef4bbc        bridge              bridge              local
    b29eab4db971        host                host                local
    acfcd6eaf888        none                null                local
    

    有以下几种网络模式:

    • bridge:桥接(docker默认)
    • none:不配置网络
    • host:和宿主机共享网络
    • container:容器网络连通(用的很少,不建议使用,局限性很大)

    我们自己创建网络,也是用bridge桥接模式。

    创建网络

    自己创建网络的命令是docker network create

    我们每次run出容器的时候,默认使用bridge模式,run的命令中默认有--net bridge这么一个选项。因为bridge是docker0的Name。我们自己创建网络的时候就应该避开bridge这个名字。假如我们自己create的网络叫bridge02,我们想让自己的容器加入这个网络的时候,run的时候就加上--net bridge02就可以了。

    我们看一下docker network create这个命令怎么用:

    root@KitDevVps:~# docker network create -h
    Flag shorthand -h has been deprecated, please use --help
    
    Usage:	docker network create [OPTIONS] NETWORK
    
    Create a network
    
    Options:
          --attachable           Enable manual container attachment
          --aux-address map      Auxiliary IPv4 or IPv6 addresses used by Network driver (default map[])
          --config-from string   The network from which copying the configuration
          --config-only          Create a configuration only network
      -d, --driver string        Driver to manage the Network (default "bridge")
          --gateway strings      IPv4 or IPv6 Gateway for the master subnet
          --ingress              Create swarm routing-mesh network
          --internal             Restrict external access to the network
          --ip-range strings     Allocate container ip from a sub-range
          --ipam-driver string   IP Address Management Driver (default "default")
          --ipam-opt map         Set IPAM driver specific options (default map[])
          --ipv6                 Enable IPv6 networking
          --label list           Set metadata on a network
      -o, --opt map              Set driver specific options (default map[])
          --scope string         Control the network's scope
          --subnet strings       Subnet in CIDR format that represents a network segment
    

    其中的subnet子网一定要配,加上掩码;driver默认就是bridge模式,写不写都行;gateway也写一下,就是网关,网络从哪个地方出去。我们模仿路由器配一个:

    root@KitDevVps:~# docker network create --driver bridge --subnet 192.168.0.0/16 --gateway 192.168.0.1 mynet
    0df835de9886ed3cf76b071281ddc521c33502914aeb69a8e1bbc817dbcdff0a
    

    其中网段192.168.0.0,掩码位数16.也就是有255*255个ip可用。如果是24的话就只有255个ip可用,这一块是计算机网络的知识。网关是192.168.0.1。网络取名为mynet。

    docker network ls看一下我们的网络有没有:

    root@KitDevVps:~# docker network ls
    NETWORK ID          NAME                DRIVER              SCOPE
    1375b7ef4bbc        bridge              bridge              local
    b29eab4db971        host                host                local
    0df835de9886        mynet               bridge              local
    acfcd6eaf888        none                null                local
    

    已经有了,在倒数第二行。看一下网络的详细信息:

    root@KitDevVps:~# docker network inspect mynet
    [
        {
            "Name": "mynet",
            "Id": "0df835de9886ed3cf76b071281ddc521c33502914aeb69a8e1bbc817dbcdff0a",
            "Created": "2020-07-05T09:39:03.14488529Z",
            "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": {}
        }
    ]
    

    可以看到子网和网关都是我们自己配置的,没有问题。

    我们启动两个centos容器,放在这个网络里:

    root@KitDevVps:~# docker run -d -it --name centos01 --net mynet centos
    43f47db12bf4a8be9ea6172a89a44c530a23b29de49bf2a5ef95a88308675025
    root@KitDevVps:~# docker run -d -it --name centos02 --net mynet centos
    2a26067838f1724347ef50a1b8988a50603715e514fb288ab86401571dc70173
    root@KitDevVps:~# docker ps
    CONTAINER ID        IMAGE               COMMAND                  CREATED             STATUS              PORTS                NAMES
    2a26067838f1        centos              "/bin/bash"              7 seconds ago       Up 6 seconds                             centos02
    43f47db12bf4        centos              "/bin/bash"              16 seconds ago      Up 15 seconds                            centos01
    1cdd55fd90c5        nginx               "/docker-entrypoint.…"   2 days ago          Up 2 days           0.0.0.0:80->80/tcp   nginx1
    

    再看一下mynet的详细信息:

    root@KitDevVps:~# docker network inspect mynet
    [
        ...
        "Containers": {
            "2a26067838f1724347ef50a1b8988a50603715e514fb288ab86401571dc70173": {
                "Name": "centos02",
                "EndpointID": "83e59d8f388561cb006564de55bb1c76278ab54b0e87f1f7e671a9962efe3608",
                "MacAddress": "02:42:c0:a8:00:03",
                "IPv4Address": "192.168.0.3/16",
                "IPv6Address": ""
            },
            "43f47db12bf4a8be9ea6172a89a44c530a23b29de49bf2a5ef95a88308675025": {
                "Name": "centos01",
                "EndpointID": "b0a1f17acc6a4c835952ae4e764c7f7e26a90fc3ce28be97cf9bb8c2ee0c10a4",
                "MacAddress": "02:42:c0:a8:00:02",
                "IPv4Address": "192.168.0.2/16",
                "IPv6Address": ""
            }
        },
        "Options": {},
        "Labels": {} 
    ]
    

    可以看到containers中有了我们的两个容器,他们的ip地址也是这个网段的。

    使用容器名代替ip地址来ping

    自己创建网络有什么好处呢,好处就是可以直接使用容器名来互ping:

    root@KitDevVps:~# docker exec -it centos01 ping centos02
    PING centos02 (192.168.0.3) 56(84) bytes of data.
    64 bytes from centos02.mynet (192.168.0.3): icmp_seq=1 ttl=64 time=0.099 ms
    64 bytes from centos02.mynet (192.168.0.3): icmp_seq=2 ttl=64 time=0.167 ms
    64 bytes from centos02.mynet (192.168.0.3): icmp_seq=3 ttl=64 time=0.079 ms
    64 bytes from centos02.mynet (192.168.0.3): icmp_seq=4 ttl=64 time=0.090 ms
    ^C
    --- centos02 ping statistics ---
    4 packets transmitted, 4 received, 0% packet loss, time 45ms
    rtt min/avg/max/mdev = 0.079/0.108/0.167/0.036 ms
    

    即现在不使用--link也可以连接成功了。

    我们自定义的网络,docker帮我们维护好了对应的关系,docker0则没有这个功能。

    比如我有一个redis的集群,就可以打一个网络。还有一个mssql的集群,也可以搭一个网络。网络之间是互相隔离的。不同集群使用不同网络,集群都是健康的。

    多个网络之间的连通

    UTOOLS1593944253989.png

    docker0网络中的一个容器如何访问mynet网络?显然也要通过docker network命令来找线索:

    root@KitDevVps:~# docker network -h
    Flag shorthand -h has been deprecated, please use --help
    
    Usage:	docker network COMMAND
    
    Manage networks
    
    Commands:
      connect     Connect a container to a network
      create      Create a network
      disconnect  Disconnect a container from a network
      inspect     Display detailed information on one or more networks
      ls          List networks
      prune       Remove all unused networks
      rm          Remove one or more networks
    
    Run 'docker network COMMAND --help' for more information on a command.
    
    

    可以看到第一条命令connect,介绍是连接一个容器到一个网络。看一下这个命令怎么用:

    root@KitDevVps:~# docker network connect -h
    Flag shorthand -h has been deprecated, please use --help
    
    Usage:	docker network connect [OPTIONS] NETWORK CONTAINER
    
    Connect a container to a network
    
    Options:
          --alias strings           Add network-scoped alias for the container
          --driver-opt strings      driver options for the network
          --ip string               IPv4 address (e.g., 172.30.100.104)
          --ip6 string              IPv6 address (e.g., 2001:db8::33)
          --link list               Add link to another container
          --link-local-ip strings   Add a link-local address for the container
    root@KitDevVps:~# 
    

    显然用法就是docket network connect [可选选项] 网络 容器。现在我们有centos01和02运行在mynet上,我们在docker0上run出个centos03:

    root@KitDevVps:~# docker exec -it centos03 ping centos01
    ping: centos01: Name or service not known
    root@KitDevVps:~# docker exec -it centos03 ping 43f47db12bf4
    ping: 43f47db12bf4: Name or service not known
    

    可以看到无论ping名还是id都ping不通。试一下前面我们查到的命令:

    root@KitDevVps:~# docker network connect mynet centos03
    root@KitDevVps:~# docker exec -it centos03 ping centos01
    PING centos01 (192.168.0.2) 56(84) bytes of data.
    64 bytes from centos01.mynet (192.168.0.2): icmp_seq=1 ttl=64 time=0.163 ms
    64 bytes from centos01.mynet (192.168.0.2): icmp_seq=2 ttl=64 time=0.081 ms
    64 bytes from centos01.mynet (192.168.0.2): icmp_seq=3 ttl=64 time=0.104 ms
    64 bytes from centos01.mynet (192.168.0.2): icmp_seq=4 ttl=64 time=0.107 ms
    ^C
    --- centos01 ping statistics ---
    4 packets transmitted, 4 received, 0% packet loss, time 46ms
    rtt min/avg/max/mdev = 0.081/0.113/0.163/0.032 ms
    

    运行docker network connect mynet centos03后没有返回东西,但centos03已经可以ping通centos01了,而且还是用容器名字直接ping通。

    我们看一下mynet的详细信息:

    root@KitDevVps:~# docker network inspect mynet
    [
    ...
        "Containers": {
            "2a26067838f1724347ef50a1b8988a50603715e514fb288ab86401571dc70173": {
                "Name": "centos02",
                "EndpointID": "83e59d8f388561cb006564de55bb1c76278ab54b0e87f1f7e671a9962efe3608",
                "MacAddress": "02:42:c0:a8:00:03",
                "IPv4Address": "192.168.0.3/16",
                "IPv6Address": ""
            },
            "43f47db12bf4a8be9ea6172a89a44c530a23b29de49bf2a5ef95a88308675025": {
                "Name": "centos01",
                "EndpointID": "b0a1f17acc6a4c835952ae4e764c7f7e26a90fc3ce28be97cf9bb8c2ee0c10a4",
                "MacAddress": "02:42:c0:a8:00:02",
                "IPv4Address": "192.168.0.2/16",
                "IPv6Address": ""
            },
            "62bad532ae1925a4a33388f629931b573bcd1b6fd00e9ab5b99799dbdb17c73b": {
                "Name": "centos03",
                "EndpointID": "763c6c021ae7a05d3099d6c64c3dd28b1a574ecbf46e2689441e17afccc58da6",
                "MacAddress": "02:42:c0:a8:00:04",
                "IPv4Address": "192.168.0.4/16",
                "IPv6Address": ""
            }
        },
        "Options": {},
        "Labels": {}
    ]
    

    可以看到centos03直接被加入到了mynet这个网络里。这样centos03这个容器就拥有了两个ip地址,它在docker0中有一个,在mynet中还有一个。

    centos01能ping通centos03吗?

    root@KitDevVps:~# docker exec -it centos01 ping centos03
    PING centos03 (192.168.0.4) 56(84) bytes of data.
    64 bytes from centos03.mynet (192.168.0.4): icmp_seq=1 ttl=64 time=0.067 ms
    64 bytes from centos03.mynet (192.168.0.4): icmp_seq=2 ttl=64 time=0.081 ms
    64 bytes from centos03.mynet (192.168.0.4): icmp_seq=3 ttl=64 time=0.077 ms
    64 bytes from centos03.mynet (192.168.0.4): icmp_seq=4 ttl=64 time=0.092 ms
    ^C
    --- centos03 ping statistics ---
    4 packets transmitted, 4 received, 0% packet loss, time 42ms
    rtt min/avg/max/mdev = 0.067/0.079/0.092/0.010 ms
    

    02能ping通03吗?

    root@KitDevVps:~# docker exec -it centos02 ping centos03
    PING centos03 (192.168.0.4) 56(84) bytes of data.
    64 bytes from centos03.mynet (192.168.0.4): icmp_seq=1 ttl=64 time=0.094 ms
    64 bytes from centos03.mynet (192.168.0.4): icmp_seq=2 ttl=64 time=0.127 ms
    64 bytes from centos03.mynet (192.168.0.4): icmp_seq=3 ttl=64 time=0.100 ms
    64 bytes from centos03.mynet (192.168.0.4): icmp_seq=4 ttl=64 time=0.115 ms
    ^C
    --- centos03 ping statistics ---
    4 packets transmitted, 4 received, 0% packet loss, time 53ms
    rtt min/avg/max/mdev = 0.094/0.109/0.127/0.012 ms
    

    其实后面这两次都是废话,都在同一个网络里了当然能ping通,而且ping的地址是03在mynet中的地址,不是在docker0中的地址。玩这两次只是为了100%确定这个结论。

  • 相关阅读:
    同一个String在使用不同的charset编码的时候equals仍然是返回true吗
    request的生存期只限于服务器跳转
    flex 客户端缓存SharedObject
    flex NaN
    oracle 任务使用
    oracle 数据泵
    datagrid 用法
    Windows系统中path环境变量详解
    [转]eclipse导入V7包出现错误解决办法
    由多线程引起的map取值为null的分析
  • 原文地址:https://www.cnblogs.com/Kit-L/p/13251786.html
Copyright © 2020-2023  润新知