docker网络

发布时间 2024-01-07 01:47:59作者: lxd670

docker网络驱动

1.bridge(桥接网络驱动):这是Docker默认使用的网络驱动,它通过docker0网桥连接到宿主机,并为容器分配IP地址,使得容器可以互相通信和与宿主机通信。
2.host(主机网络驱动):使用主机网络驱动时,容器与宿主机共享网络命名空间,容器可以直接使用宿主机的网络接口,不会进行任何网络隔离。
3.overlay(覆盖网络驱动):覆盖网络驱动用于在多个Docker主机上创建跨主机的容器通信网络。它使用VXLAN隧道技术来实现容器之间的通信和网络隔离。
4.macvlan(MACVLAN网络驱动):MACVLAN网络驱动允许你为容器分配真实物理网络上的MAC地址,并使得容器能够直接与物理网络上的其他设备进行通信。
5.ipvlan(IPVLAN网络驱动):IPVLAN网络驱动类似于MACVLAN,但它允许容器共享宿主机的IP地址,并在内部使用不同的MAC地址进行通信。
6.none(无网络驱动):使用无网络驱动时,容器将没有任何网络连接,无法与外部通信。
7.network plugin(docker的网络插件)

docker网络命令

查看network选项

docker network --help
Commands:
  connect     连接一个容器到一个网络
  create      创建网络
  disconnect  将某个容器从某个网络中移除
  inspect     查看网络详情
  ls          列出所有网络
  prune       移除所有没有使用的网络
  rm          删除指定网络

列出所有网络

docker network ls

docker network ls                  
NETWORK ID     NAME      DRIVER    SCOPE
7fa793eb0718   bridge    bridge    local
2f5c8a3d4b33   host      host      local
8b3ed8cd044a   none      null      local

创建网络

自定义默认bridge网络

docker network create <net-work name>

没有指定驱动,默认为bridge

没有指定子网和网关,会使用默认的子网和网关

只创建一个默认的桥接网络,没有指定其他属性。

docker network create mynetwork
e4ce51568b977720b70e4e5e4d1e2083b6023e037b91ac4c07f2a463431e23e7
docker network ls
NETWORK ID     NAME        DRIVER    SCOPE
7fa793eb0718   bridge      bridge    local
2f5c8a3d4b33   host        host      local
e4ce51568b97   mynetwork   bridge    local	# 创建的网络
8b3ed8cd044a   none        null      local

自定义网关bridge网络

docker network create <网络模式> --subnet <子网> --gateway <网关> <net-work name>

一个具有自定义网络属性的桥接网络

docker network create --driver bridge --subnet 192.168.0.0/16 --gateway 192.168.0.1 mynetwork
9f0aaeb6a83031a847763608a8bc37f08556e4522ee427008d570b2fb778d6e3
docker network ls
NETWORK ID     NAME         DRIVER    SCOPE
7fa793eb0718   bridge       bridge    local
2f5c8a3d4b33   host         host      local
132a1fd0cb2e   mynetwork    bridge    local
9f0aaeb6a830   mynetwork1   bridge    local
8b3ed8cd044a   none         null      local

查看网络详情

docker network inspect <net-work name>

docker network inspect mynetwork
[
  {
    "Name": "mynetwork",
    "Id": "132a1fd0cb2e9f620773f3e5e03d63106c7be09e226a8ec61103d3510ee446b7",
    "Created": "2023-09-19T05:41:47.148457639Z",
    "Scope": "local",
    "Driver": "bridge",
    "EnableIPv6": false,
    "IPAM": {
      "Driver": "default",
      "Options": {},
      "Config": [
        {
          "Subnet": "172.21.0.0/16",
          "Gateway": "172.21.0.1"
        }
      ]
    },
    "Internal": false,
    "Attachable": false,
    "Ingress": false,
    "ConfigFrom": {
      "Network": ""
    },
    "ConfigOnly": false,
    "Containers": {},
    "Options": {},
    "Labels": {}
  }
]

删除某个网络

docker network rm <net-work name>

docker network rm mynetwork
mynetwork
docker network ls
# 已经删除了mynetwork网络
NETWORK ID     NAME      DRIVER    SCOPE
7fa793eb0718   bridge    bridge    local
2f5c8a3d4b33   host      host      local
8b3ed8cd044a   none      null      local

清除无用的网络

docker network prune

echo 'y'| docker network prune
WARNING! This will remove all custom networks not used by at least one container.
Are you sure you want to continue? [y/N] Deleted Networks:
mynetwork

容器连接到网络

容器移除某个网络

1.基本命令

查看本机网络

~ 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
    inet6 ::1/128 scope host 
       valid_lft forever preferred_lft forever
       
# 腾讯云内网地址
2: eth0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP group default qlen 1000
    link/ether 52:54:00:3d:61:06 brd ff:ff:ff:ff:ff:ff
    inet 172.17.0.5/20 brd 172.17.15.255 scope global eth0
       valid_lft forever preferred_lft forever
    inet6 fe80::5054:ff:fe3d:6106/64 scope link 
       valid_lft forever preferred_lft forever
       
# docker0网络
3: docker0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP group default 
    link/ether 02:42:e5:23:98:19 brd ff:ff:ff:ff:ff:ff
    inet 172.18.0.1/16 brd 172.18.255.255 scope global docker0
       valid_lft forever preferred_lft forever
    inet6 fe80::42:e5ff:fe23:9819/64 scope link 
       valid_lft forever preferred_lft forever

创建一个tomcat

apt update && apt install -y iproute2

# 在容器内查看ip addr
root@24ee8d722f8f:/usr/local/tomcat# 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
211: eth0@if212: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP group default 
    link/ether 02:42:ac:12:00:05 brd ff:ff:ff:ff:ff:ff link-netnsid 0
    inet 172.18.0.5/16 brd 172.18.255.255 scope global eth0
       valid_lft forever preferred_lft forever

宿主机可以ping通容器的ip

~ ping 172.18.0.5
PING 172.18.0.5 (172.18.0.5) 56(84) bytes of data.
64 bytes from 172.18.0.5: icmp_seq=1 ttl=64 time=0.053 ms
64 bytes from 172.18.0.5: icmp_seq=2 ttl=64 time=0.051 ms

查看宿主机的ip addr

~ ip addr

# 本机回环地址
......

# 腾讯云内网地址
......
       
# docker0网络
......

# 这个就是对于tomcat的地址
212: veth538d00d@if211: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue master docker0 state UP group default 
    link/ether 1e:06:f3:f1:2a:09 brd ff:ff:ff:ff:ff:ff link-netnsid 3
    inet6 fe80::1c06:f3ff:fef1:2a09/64 scope link 
       valid_lft forever preferred_lft forever
# 我们发现这个容器网卡都是一对一对的,是evth-pair技术实现的
evth-pair就是一对虚拟设备接口,所以都是成对出现的
evth-pair充当一个桥梁
OpenStac、Docker容器之间的连接、OVS连接都是用的evth-pair技术实现的

网络模型图

tomcat01和tomcat02 都是公用一个路由,docker0

所有容器不指定网络的情况下,docker0路由会给容器分配一个可用的ip

docker中所有的网络都是虚拟的,虚拟的转发效率高(内网传递文件)

移除容器会后,对应的网桥会自动删除

image-20220828152007080

docker使用的是linux的桥接,宿主机中是一个docker容器的网桥docker0

image-20220828152458901

了解,真实开发不使用--link,使用之定义网络

如果我们编写了一个微服务,指定了postgresql为某个ip+port

postgresql关闭后重新启动,ip换了,我们希望通过容器名来访问容器

# 通过t2直接ping容器t1不行
~ docker exec -it t2 ping t1
ping: t1: Name or service not known

# 通过t2直接ping t1的ip可以(在通过路由下)
~ docker exec -it t2 ping 172.18.0.5
PING 172.18.0.5 (172.18.0.5) 56(84) bytes of data.
64 bytes from 172.18.0.5: icmp_seq=1 ttl=64 time=0.079 ms
64 bytes from 172.18.0.5: icmp_seq=2 ttl=64 time=0.063 ms

使用--link

# 创建一个t3容器,使用--link链接t1容器
docker run -it -d --name t3 --link t1 6ce88d2075b4

# 在t3内部就可以直接ping容器名了
### 注意,t3可以使用容器名ping通t1,但是t1不能使用容器名ping通t3
root@a14115132f0b:/usr/local/tomcat# ping t1 -c 3
PING t1 (172.18.0.5) 56(84) bytes of data.
64 bytes from t1 (172.18.0.5): icmp_seq=1 ttl=64 time=0.073 ms
64 bytes from t1 (172.18.0.5): icmp_seq=2 ttl=64 time=0.060 ms
64 bytes from t1 (172.18.0.5): icmp_seq=3 ttl=64 time=0.154 ms

--- t1 ping statistics ---
3 packets transmitted, 3 received, 0% packet loss, time 2000ms
rtt min/avg/max/mdev = 0.060/0.095/0.154/0.041 ms

原理

主要在t3容器中/etc/hosts设置了对于的参数

hosts文件格式
ip地址 主机名/域名 [主机别名]

root@a14115132f0b:/usr/local/tomcat# cat /etc/hosts
127.0.0.1       localhost
::1     localhost ip6-localhost ip6-loopback
fe00::0 ip6-localnet
ff00::0 ip6-mcastprefix
ff02::1 ip6-allnodes
ff02::2 ip6-allrouters
172.18.0.5      t1 054b676f5611
172.18.0.7      a14115132f0b

docker0和自定义网络区别

默认桥接网络(docker0):
  Docker的默认桥接网络是docker0。在安装Docker时,会自动创建一个名为docker0的桥接网络。
  默认情况下,使用docker run命令启动的容器将连接到docker0网络。
  docker0网络使用IP地址范围为172.17.0.0/16,并由Docker自动分配和管理。
  容器在docker0网络中可以通过IP地址进行相互通信(不支持容器名连接访问),也可以通过容器名称进行DNS解析。

自定义网络:
	您可以使用docker network create命令创建自定义网络,以满足特定的容器通信需求。
  自定义网络可以是桥接网络、覆盖网络或MACVLAN网络等类型。
  自定义网络可以具有自定义的IP地址范围,您可以使用--subnet选项在创建网络时指定子网。
  自定义网络与默认桥接网络相比,具有以下一些优点和用途:
  隔离性:自定义网络提供了更好的隔离性,可以使容器在独立的网络环境中运行,与其他网络隔离开来。
  容器命名解析:自定义网络允许容器使用其他容器的名称进行DNS解析,以方便容器之间的通信。
  连通性:自定义网络支持容器之间的直接连接,而无需通过主机网络进行通信。
  路由控制:自定义网络允许您在不同的容器网络之间进行路由控制和流量管理。

自定义网络(容器互联)

查看网络

docker network --help
Commands:
  connect     连接一个容器到一个网络
  create      创建网络
  disconnect  Disconnect a container from a network
  inspect     查看网络详情
  ls          列出所有网络
  prune       Remove all unused networks
  rm          删除指定网络

查看网络

~ docker network ls             
NETWORK ID     NAME      DRIVER    SCOPE
191fe38a19f1   bridge    bridge    local
ffeea37e4d9b   host      host      local
3cd2b6dd20b5   none      null      local

创建网络

# docker network create 网络名
~ docker network create tt
641eeceacfbadbbb57261bfd7f78537c8b2193f886b4e25f2b405340a4cbb667
~ docker network ls       
NETWORK ID     NAME      DRIVER    SCOPE
191fe38a19f1   bridge    bridge    local
ffeea37e4d9b   host      host      local
3cd2b6dd20b5   none      null      local
641eeceacfba   tt        bridge    local

删除网络

# docker network rm 网络名/网络ID
~ docker network rm tt    
tt

查看docker网络

默认安装docker后,有三大网络模式

docker network ls
# 默认的网络
NETWORK ID     NAME      DRIVER    SCOPE
191fe38a19f1   bridge    bridge    local
ffeea37e4d9b   host      host      local
3cd2b6dd20b5   none      null      local

查看网络源数据

docker network inspect bridge

[
    {
        "Name": "bridge",
        "Id": "191fe38a19f1ded27d57da1b1a0752a0feb0857192df11dbaaa71a9b2177fc1e",
        "Created": "2022-05-01T23:30:58.498175094+08:00",
        "Scope": "local",
        "Driver": "bridge",
        "EnableIPv6": false,
        "IPAM": {
            "Driver": "default",
            "Options": null,
            "Config": [
                {
                    "Subnet": "172.18.0.0/16",
                    "Gateway": "172.18.0.1"
                }
            ]
        },
        "Internal": false,
        "Attachable": false,
        "Ingress": false,
        "ConfigFrom": {
            "Network": ""
        },
        "ConfigOnly": false,
        "Containers": {
            "191cfe71b8f9486cff5e602e4542b205ce46033584455c0557b833a877481840": {
                "Name": "nginx",
                "EndpointID": "bfc51ea5507bbde178f828d8051118f769b8cd37e95ae6449deb71650a1a19f8",
                "MacAddress": "02:42:ac:12:00:02",
                "IPv4Address": "172.18.0.2/16",
                "IPv6Address": ""
            },
            "7c9f77bc94e4110876ad859e18156a7825cab30d33b412e0b9ab8ab3b22e91eb": {
                "Name": "mysql01",
                "EndpointID": "78247da644193d2ff778ae6b1c8b9f514dd4f8492483edee17eaa40978ee4bbf",
                "MacAddress": "02:42:ac:12:00:03",
                "IPv4Address": "172.18.0.3/16",
                "IPv6Address": ""
            },
            "8b36c8f0abde9f8ec216dde26bda6b31752bbd14bf374e5f11920cf533f4189b": {
                "Name": "postgres01",
                "EndpointID": "67f2141f2aaa14d25bb5f004ea76f846181fd7bd0a3f376df909ba07e95887a4",
                "MacAddress": "02:42:ac:12:00:04",
                "IPv4Address": "172.18.0.4/16",
                "IPv6Address": ""
            },
            "f3285f6e8e763ef4719670b5680081ca1441c25478be6a354329d5f77768d48f": {
                "Name": "infallible_leavitt",
                "EndpointID": "9156bf16524d09583f166eea9809bba6edfde0d7dfc02e9385f0b1ebbd842993",
                "MacAddress": "02:42:ac:12:00:06",
                "IPv4Address": "172.18.0.6/16",
                "IPv6Address": ""
            }
        },
        "Options": {
            "com.docker.network.bridge.default_bridge": "true",
            "com.docker.network.bridge.enable_icc": "true",
            "com.docker.network.bridge.enable_ip_masquerade": "true",
            "com.docker.network.bridge.host_binding_ipv4": "0.0.0.0",
            "com.docker.network.bridge.name": "docker0",
            "com.docker.network.driver.mtu": "1500"
        },
        "Labels": {}
    }
]

创建网络

~ docker network create aaa
c10e945a4f04aac919d0ca481ef4fa871a1558a5edffe2ab91e3ec3157470b4a
~ docker network ls
NETWORK ID     NAME      DRIVER    SCOPE
c10e945a4f04   aaa       bridge    local
191fe38a19f1   bridge    bridge    local
ffeea37e4d9b   host      host      local
3cd2b6dd20b5   none      null      local

删除网络

~ docker network rm aaa
aaa
~ docker network ls    
NETWORK ID     NAME      DRIVER    SCOPE
191fe38a19f1   bridge    bridge    local
ffeea37e4d9b   host      host      local
3cd2b6dd20b5   none      null      local

2.网络能干嘛

1.容器间的互联和通讯,以及映射端口
2.容器IP变动时候可以通过服务名直接网络通讯,而不受影响

3.网络模式

网络模式 作用
bridge 为每一个容器分配、设置IP等,并将容器连接到docker0虚拟网桥,默认模式
host 容器不会生出自己的虚拟网卡,配置自己的IP等,而是使用宿主机的IP和端口
none 容器有独立的Network namespace,但并没有对其进行任何网络设置
container 容器内网络连通(用的少,局限性很大)

之前直接启动的命令

# 以前启动的命令
docker run -d -P --name t1 tomcat
# 相当于默认加了--net bridge,而这个就是docker0
docker run -d -P --name t1 --net bridge tomcat

创建自定义网络

# 创建网络
~ docker network create --driver bridge --subnet 192.168.0.0/16 --gateway 192.168.0.1 mynet
94296b994dbc7b769382385817a30df092b25287ce3d138f46c2f5c600578c42

~ docker network inspect mynet
[
    {
        "Name": "mynet",
        "Id": "94296b994dbc7b769382385817a30df092b25287ce3d138f46c2f5c600578c42",
        "Created": "2022-08-28T18:10:11.7440679+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": {}
    }
]
# 创建t1
~ docker run -d -P --name t1 --net mynet tomcat:7
7596e15311636587707c43451773323ba7c102ff432677ddf4133b51c7e2f691
# 创建t2
~ docker run -d -P --name t2 --net mynet tomcat:7
0812dc984c5930bd143178686299643df482a57d2ef73818a8af6a957b53a92a
# 查看容器
~ docker ps   
CONTAINER ID   IMAGE         COMMAND                  CREATED          STATUS          PORTS                                         NAMES
0812dc984c59   tomcat:7      "catalina.sh run"        6 seconds ago    Up 5 seconds    0.0.0.0:49166->8080/tcp, :::49166->8080/tcp   t2
7596e1531163   tomcat:7      "catalina.sh run"        11 seconds ago   Up 10 seconds   0.0.0.0:49165->8080/tcp, :::49165->8080/tcp   t1

# 测试t1 ping t2
~ docker exec -it t1 ping t2 -c 2
PING t2 (192.168.0.3) 56(84) bytes of data.
64 bytes from t2.mynet (192.168.0.3): icmp_seq=1 ttl=64 time=0.052 ms
64 bytes from t2.mynet (192.168.0.3): icmp_seq=2 ttl=64 time=0.048 ms
# 测试t2 ping t1
~ docker exec -it t2 ping t1 -c 2
PING t1 (192.168.0.2) 56(84) bytes of data.
64 bytes from t1.mynet (192.168.0.2): icmp_seq=1 ttl=64 time=0.038 ms
64 bytes from t1.mynet (192.168.0.2): icmp_seq=2 ttl=64 time=0.090 ms

网络连通

~ docker run -d -P --name tt1 tomcat:7
bb81068780bb29a1c006db845d1e25903c7e51151793731b48ff727c92e6dda2
~ docker run -d -P --name tt2 tomcat:7
2df90bce4613fae9f51c1f49caf6e4d7cc953dadd91564adc3c5e64db97e6383

~ docker ps
CONTAINER ID   IMAGE         COMMAND                  CREATED          STATUS          PORTS                                         NAMES
2df90bce4613   tomcat:7      "catalina.sh run"        18 seconds ago   Up 17 seconds   0.0.0.0:49168->8080/tcp, :::49168->8080/tcp   tt2
bb81068780bb   tomcat:7      "catalina.sh run"        23 seconds ago   Up 22 seconds   0.0.0.0:49167->8080/tcp, :::49167->8080/tcp   tt1
0812dc984c59   tomcat:7      "catalina.sh run"        7 minutes ago    Up 7 minutes    0.0.0.0:49166->8080/tcp, :::49166->8080/tcp   t2
7596e1531163   tomcat:7      "catalina.sh run"        7 minutes ago    Up 7 minutes    0.0.0.0:49165->8080/tcp, :::49165->8080/tcp   t1

# tt1 ping t1不行
~ docker exec -it tt1 ping t1
ping: t1: Name or service not known

连通

连通之后就是将tt1容器放到了mynet网络下

相当于tt1有自己的172.18.0.5/16192.168.0.4/16(一个容器两个IP)

# docker network connect 网络名 容器名字
~ docker network connect mynet tt1
~ docker exec -it tt1 ping t1      
PING t1 (192.168.0.2) 56(84) bytes of data.
64 bytes from t1.mynet (192.168.0.2): icmp_seq=1 ttl=64 time=0.141 ms
64 bytes from t1.mynet (192.168.0.2): icmp_seq=2 ttl=64 time=0.050 ms

image-20220829113534343

容器内部获取其他容器ip

在同个网络下,容器内使用py脚本获取其它容器名对应的ip

import socket

def get_container_ip(container_name):
    ip_address = socket.gethostbyname(container_name)
    return ip_address

# 使用容器名获取IP地址
ip_address = get_container_ip('other_container_name')
print(ip_address)