9.Docker网络

1、Docker网络简介

作用:

  • 容器间的互联和通信以及端口映射
  • 容器IP变动时候可以通过服务名直接进行网络通信而不受到影响(下面例子证明)

Docker启动后宿主机网络情况如下:

[root@localhost ~]# ifconfig 
docker0: flags=4099<UP,BROADCAST,MULTICAST>  mtu 1500
        inet 172.17.0.1  netmask 255.255.0.0  broadcast 172.17.255.255
        inet6 fe80::42:f1ff:fee7:6e82  prefixlen 64  scopeid 0x20<link>
        ether 02:42:f1:e7:6e:82  txqueuelen 0  (Ethernet)
        RX packets 283  bytes 18529 (18.0 KiB)
        RX errors 0  dropped 0  overruns 0  frame 0
        TX packets 249  bytes 26762 (26.1 KiB)
        TX errors 0  dropped 0 overruns 0  carrier 0  collisions 0

ens33: flags=4163<UP,BROADCAST,RUNNING,MULTICAST>  mtu 1500
        inet 192.168.10.101  netmask 255.255.255.0  broadcast 192.168.10.255
        inet6 fe80::7d22:7ddb:c5c0:943e  prefixlen 64  scopeid 0x20<link>
        ether 00:0c:29:06:ba:14  txqueuelen 1000  (Ethernet)
        RX packets 417482  bytes 390510898 (372.4 MiB)
        RX errors 0  dropped 0  overruns 0  frame 0
        TX packets 316220  bytes 80580892 (76.8 MiB)
        TX errors 0  dropped 0 overruns 0  carrier 0  collisions 0

lo: flags=73<UP,LOOPBACK,RUNNING>  mtu 65536
        inet 127.0.0.1  netmask 255.0.0.0
        inet6 ::1  prefixlen 128  scopeid 0x10<host>
        loop  txqueuelen 1  (Local Loopback)
        RX packets 24  bytes 1554 (1.5 KiB)
        RX errors 0  dropped 0  overruns 0  frame 0
        TX packets 24  bytes 1554 (1.5 KiB)
        TX errors 0  dropped 0 overruns 0  carrier 0  collisions 0

virbr0: flags=4099<UP,BROADCAST,MULTICAST>  mtu 1500
        inet 192.168.122.1  netmask 255.255.255.0  broadcast 192.168.122.255
        ether 52:54:00:4b:82:8e  txqueuelen 1000  (Ethernet)
        RX packets 0  bytes 0 (0.0 B)
        RX errors 0  dropped 0  overruns 0  frame 0
        TX packets 0  bytes 0 (0.0 B)
        TX errors 0  dropped 0 overruns 0  carrier 0  collisions 0

在CentOS7的安装过程中如果有选择相关虚拟化的的服务安装系统后,启动网卡时会发现有一个以网桥连接的私网地址的virbr0网卡(virbr0网卡:它还有一个固定的默认IP地址192.168.122.1),是做虚拟机网桥的使用的,其作用是为连接其上的虚机网卡提供 NAT访问外网的功能

docker0:bridge模式对应的名称默认为docker0.

默认创建3大网络模式:

[root@localhost ~]# docker network ls
NETWORK ID     NAME      DRIVER    SCOPE
44119cc9ea23   bridge    bridge    local
d91b1b0c56a6   host      host      local
b99fab7bcddb   none      null      local

2、常用基本命令

docker network基本命令如下:

[root@localhost ~]# docker network --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
  1. 查看网络

    [root@localhost ~]# docker network ls
    NETWORK ID     NAME      DRIVER    SCOPE
    44119cc9ea23   bridge    bridge    local
    d91b1b0c56a6   host      host      local
    b99fab7bcddb   none      null      local
    
  2. 查看网络源数据

    [root@localhost ~]# docker network inspect bridge
    [
        {
            "Name": "bridge",
            "Id": "44119cc9ea23b265d7a358c044b6347a07eda61e1b950194b1268d80a6a1130f",
            "Created": "2024-05-21T08:10:03.116073617-04:00",
            "Scope": "local",
            "Driver": "bridge",
            "EnableIPv6": false,
            "IPAM": {
                "Driver": "default",
                "Options": null,
                "Config": [
                    {
                        "Subnet": "172.17.0.0/16",
                        "Gateway": "172.17.0.1"
                    }
                ]
            },
            "Internal": false,
            "Attachable": false,
            "Ingress": false,
            "ConfigFrom": {
                "Network": ""
            },
            "ConfigOnly": false,
            "Containers": {},
            "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": {}
        }
    ]
    
  3. 创建和删除网络

    [root@localhost ~]# docker network create aa
    a74705857db0820cb65a4f2bc478dc3076759b5a7227d9c43191a36810c5a8be
    [root@localhost ~]# docker network ls
    NETWORK ID     NAME      DRIVER    SCOPE
    a74705857db0   aa        bridge    local
    44119cc9ea23   bridge    bridge    local
    d91b1b0c56a6   host      host      local
    b99fab7bcddb   none      null      local
    [root@localhost ~]# docker network inspect aa
    [
        {
            "Name": "aa",
            "Id": "a74705857db0820cb65a4f2bc478dc3076759b5a7227d9c43191a36810c5a8be",
            "Created": "2024-05-21T08:19:34.484538348-04:00",
            "Scope": "local",
            "Driver": "bridge",
            "EnableIPv6": false,
            "IPAM": {
                "Driver": "default",
                "Options": {},
                "Config": [
                    {
                        "Subnet": "172.18.0.0/16",
                        "Gateway": "172.18.0.1"
                    }
                ]
            },
            "Internal": false,
            "Attachable": false,
            "Ingress": false,
            "ConfigFrom": {
                "Network": ""
            },
            "ConfigOnly": false,
            "Containers": {},
            "Options": {},
            "Labels": {}
        }
    ]
    [root@localhost ~]# docker network rm aa
    aa
    [root@localhost ~]# docker network ls
    NETWORK ID     NAME      DRIVER    SCOPE
    44119cc9ea23   bridge    bridge    local
    d91b1b0c56a6   host      host      local
    b99fab7bcddb   none      null      local
    

3、网络模式对比

举例

通过实验验证容器实例内默认网络IP生产规则。

  1. 启动两个ubuntu容器实例

    [root@localhost ~]# docker run -it --name u1 ubuntu bash
    root@08193b3d0329:/# [root@localhost ~]# 
    
    [root@localhost ~]# docker run -it --name u2 ubuntu bash
    root@4ab9fe4de68c:/#
    root@4ab9fe4de68c:/# [root@localhost ~]# 
    
    [root@localhost ~]# docker ps
    CONTAINER ID   IMAGE     COMMAND   CREATED          STATUS          PORTS     NAMES
    4ab9fe4de68c   ubuntu    "bash"    16 seconds ago   Up 15 seconds             u2
    08193b3d0329   ubuntu    "bash"    34 seconds ago   Up 33 seconds             u1
    
  2. docker inspect 容器ID/容器名称

    [root@localhost ~]# docker inspect u1 | tail -n 20
                    "bridge": {
                        "IPAMConfig": null,
                        "Links": null,
                        "Aliases": null,
                        "MacAddress": "02:42:ac:11:00:02",
                        "NetworkID": "44119cc9ea23b265d7a358c044b6347a07eda61e1b950194b1268d80a6a1130f",
                        "EndpointID": "fb78c785caa067f9e1be3f7db8a8f4aa8c5e4fb90c7d036f82397801df5bedf4",
                        "Gateway": "172.17.0.1",
                        "IPAddress": "172.17.0.2",
                        "IPPrefixLen": 16,
                        "IPv6Gateway": "",
                        "GlobalIPv6Address": "",
                        "GlobalIPv6PrefixLen": 0,
                        "DriverOpts": null,
                        "DNSNames": null
                    }
                }
            }
        }
    ]
    [root@localhost ~]# docker inspect u2 | tail -n 20
                    "bridge": {
                        "IPAMConfig": null,
                        "Links": null,
                        "Aliases": null,
                        "MacAddress": "02:42:ac:11:00:03",
                        "NetworkID": "44119cc9ea23b265d7a358c044b6347a07eda61e1b950194b1268d80a6a1130f",
                        "EndpointID": "230a54ffdc3efea8bde3989bdee6d4238ec1d3f8eb387c1d1ee099bd3809d0d2",
                        "Gateway": "172.17.0.1",
                        "IPAddress": "172.17.0.3",
                        "IPPrefixLen": 16,
                        "IPv6Gateway": "",
                        "GlobalIPv6Address": "",
                        "GlobalIPv6PrefixLen": 0,
                        "DriverOpts": null,
                        "DNSNames": null
                    }
                }
            }
        }
    ]
    

    发现u1的IP为172.17.0.2,u2的IP为172.17.0.3

  3. 关闭u2实例,新建u3实例,查看IP变化

    [root@localhost ~]# docker stop u2
    u2
    [root@localhost ~]# docker ps
    CONTAINER ID   IMAGE     COMMAND   CREATED         STATUS         PORTS     NAMES
    08193b3d0329   ubuntu    "bash"    5 minutes ago   Up 5 minutes             u1
    [root@localhost ~]# docker run -it --name u3 ubuntu bash
    root@f68bf70d8921:/# [root@localhost ~]# 
    [root@localhost ~]# docker inspect u3 | tail -n 20
                    "bridge": {
                        "IPAMConfig": null,
                        "Links": null,
                        "Aliases": null,
                        "MacAddress": "02:42:ac:11:00:03",
                        "NetworkID": "44119cc9ea23b265d7a358c044b6347a07eda61e1b950194b1268d80a6a1130f",
                        "EndpointID": "66087aa062483842ac5e1028e03cbacfde64c6b0a0ee49c586b42f0650db858f",
                        "Gateway": "172.17.0.1",
                        "IPAddress": "172.17.0.3",
                        "IPPrefixLen": 16,
                        "IPv6Gateway": "",
                        "GlobalIPv6Address": "",
                        "GlobalIPv6PrefixLen": 0,
                        "DriverOpts": null,
                        "DNSNames": null
                    }
                }
            }
        }
    ]
    

    此时u3的IP为172.17.0.3

结论:

docker容器内部的ip是可能会发生变化的。

3.1、bridge模式

使用--network bridge指定,默认使用docker0。

Docker 服务默认会创建一个docker0 网桥(其上有一个 docker0 内部接口),该桥接网络的名称为docker0。它在内核层连通了其他的物理或虚拟网卡,这就将所有容器和本地主机都放到同一个物理网络。Docker默认指定了docker0接口的IP地址和子网掩码,让主机和容器之间可以通过网桥相互通信。

查看 bridge 网络的详细信息,并通过 grep 获取名称项如下:

[root@localhost ~]# docker network inspect bridge | grep name
            "com.docker.network.bridge.name": "docker0",
[root@localhost ~]# ifconfig | grep docker
docker0: flags=4163<UP,BROADCAST,RUNNING,MULTICAST>  mtu 1500

详细原理:

  1. Docker使用Linux桥接,在宿主机虚拟一个Docker容器网桥(docker0),Docker启动一个容器时会根据Docker网桥的网段分配给容器一个IP地址,称为Container-IP,同时Docker网桥是每个容器的默认网关。因为在同一宿主机内的容器都接入同一个网桥,这样容器之间就能够通过容器的Container-IP直接通信。
  2. docker run的时候,没有指定network默认使用的网桥模式就是bridge,使用的就是docker0。在宿主机ifconfig就可以看到docker0和自己create的network(后面讲)eth0,eth1,eth2……代表网卡一,网卡二,网卡三……。lo代表127.0.0.1,即localhost。inet addr用来表示网卡的IP地址。
  3. 网桥docker0创建一对对等虚拟设备接口,网桥端叫veth,容器端叫eth0,成对匹配。
    • 整个宿主机的网桥模式都是docker0,类似一个交换机有一堆接口,每个接口叫veth,在本地主机和容器内分别创建一个虚拟接口,并让他们彼此联通(这样一对接口叫veth pair);即docker0上面的每个veth匹配某个容器实例内部的eth0,两两配对,一一匹配。
    • 每个容器实例内部也有一块网卡,每个接口叫eth0。

通过上述,将宿主机上的所有容器都连接到这个内部网络上,两个容器在同一个网络下会从这个网关下各自拿到分配的ip,此时两个容器的网络是互通的。

在这里插入图片描述

实验验证:

[root@localhost ~]# docker run -d -p 8081:8080 --name tomcat81 billygoo/tomcat8-jdk8
3f29cf92d37828ddb82b2d6f14e98a876f007505cee9732a0cc39269bf9e2812
[root@localhost ~]# docker run -d -p 8082:8080 --name tomcat82 billygoo/tomcat8-jdk8
d11c5d7e24f4c749db8fdecec62ba81ba25bc9f565bfb1b8e6267dfdc3181179
[root@localhost ~]# docker exec -it tomcat81 bash
root@3f29cf92d378:/usr/local/tomcat# ip addr
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN group default qlen 1
    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
43: eth0@if44: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP group default 
    link/ether 02:42:ac:11:00:04 brd ff:ff:ff:ff:ff:ff link-netnsid 0
    inet 172.17.0.4/16 brd 172.17.255.255 scope global eth0
       valid_lft forever preferred_lft forever
    inet6 fe80::42:acff:fe11:4/64 scope link 
       valid_lft forever preferred_lft forever
root@3f29cf92d378:/usr/local/tomcat# read escape sequence
[root@localhost ~]# docker exec -it tomcat82 bash
root@d11c5d7e24f4:/usr/local/tomcat# ip addr
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN group default qlen 1
    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
45: eth0@if46: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP group default 
    link/ether 02:42:ac:11:00:05 brd ff:ff:ff:ff:ff:ff link-netnsid 0
    inet 172.17.0.5/16 brd 172.17.255.255 scope global eth0
       valid_lft forever preferred_lft forever
    inet6 fe80::42:acff:fe11:5/64 scope link 
       valid_lft forever preferred_lft forever
root@d11c5d7e24f4:/usr/local/tomcat# read escape sequence

[root@localhost ~]# ip addr | tail -n 8
44: veth73a16b8@if43: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue master docker0 state UP 
    link/ether a2:fb:75:9a:05:56 brd ff:ff:ff:ff:ff:ff link-netnsid 2
    inet6 fe80::a0fb:75ff:fe9a:556/64 scope link 
       valid_lft forever preferred_lft forever
46: vethefa7573@if45: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue master docker0 state UP 
    link/ether 26:50:1f:5e:9d:7e brd ff:ff:ff:ff:ff:ff link-netnsid 3
    inet6 fe80::2450:1fff:fe5e:9d7e/64 scope link 
       valid_lft forever preferred_lft forever

从宿主机及两个容器的IP信息可验证,在bridge模式下veth和eth0两两匹配。

3.2、host模式

使用--network host指定,该容器与主机IP一致,共用主机端口。

host模式容器直接使用宿主机的 IP 地址与外界进行通信,不再需要额外进行NAT转换。

容器将不会获得一个独立的Network Namespace, 而是和宿主机共用一个Network Namespace。容器将不会虚拟出自己的网卡而是使用宿主机的IP和端口。

在这里插入图片描述

实验验证:

命令1:docker run -d -p 8083:8080 --network host --name tomcat83 billygoo/tomcat8-jdk8

在这里插入图片描述

问题:

docke启动时总是遇见标题中的警告

原因:

docker启动时指定–network=host或-net=host,如果还指定了-p映射端口,那这个时候就会有此警告,并且通过-p设置的参数将不会起到任何作用,端口号会以主机端口号为主,重复时则递增。

解决:

解决的办法就是使用docker的其他网络模式,例如–network=bridge,这样就可以解决问题,或者直接无视。

命令2:docker run -d --network host --name tomcat83 billygoo/tomcat8-jdk8

容器详情如下图所示

在这里插入图片描述

​ 通过访问http://宿主机IP:8080/,进行测试。在CentOS里面用默认的火狐浏览器访问容器内的tomcat83看到访问成功,因为此时容器的IP借用主机的,所以容器共享宿主机网络IP,这样的好处是外部主机与容器可以直接通信。

3.3、none模式

使用--network none指定。

在none模式下,并不为Docker容器进行任何网络配置。 也就是说,这个Docker容器没有网卡、IP、路由等信息,只有一个lo(127.0.0.1)需要我们自己为Docker容器添加网卡、配置IP等。

验证实验:

docker run -d -p 8084:8080 --network none --name tomcat84 billygoo/tomcat8-jdk8

进入容器内部查看

在这里插入图片描述

在容器外部查看

在这里插入图片描述

3.4、container模式

使用--network container:Name或者--network container:容器ID指定,该容器和指定容器共用IP和端口

新建的容器和已经存在的一个容器共享一个网络ip配置而不是和宿主机共享。新创建的容器不会创建自己的网卡,配置自己的IP,而是和一个指定的容器共享IP、端口范围等。同样,两个容器除了网络方面,其他的如文件系统、进程列表等还是隔离的。

在这里插入图片描述

错误案例:

docker run -d -p 8085:8080 --name tomcat85 billygoo/tomcat8-jdk8
docker run -d -p 8086:8080 --network container:tomcat85 --name tomcat86 billygoo/tomcat8-jdk8

报错,相当于tomcat86和tomcat85公用同一个ip同一个端口,导致端口冲突。

本案例使用该镜像演示不适合。

实验验证:

docker run -it --name alpine1 alpine /bin/sh
docker run -it --network container:alpine1 --name alpine1 alpine /bin/sh

运行结果,验证共用搭桥

在这里插入图片描述

假如此时关闭alpine1,再看看alpine2

在这里插入图片描述

结论:依赖容器(alpine2)的网络需要保证该容器(alpine1)的稳定运行,否则依赖容器(alpine2)网络将会瘫痪。

3.5、自定义网络

自己创建一个network并使用。

before实验验证:

docker run -d -p 8081:8080 --name tomcat81 billygoo/tomcat8-jdk8
docker run -d -p 8082:8080 --name tomcat82 billygoo/tomcat8-jdk8

上述成功启动并用docker exec进入各自容器实例内部。

按照IP地址ping是OK的

在这里插入图片描述

按照服务名ping是失败的
在这里插入图片描述

after实验验证:

自定义桥接网络,自定义网络默认使用的是桥接网络bridge

  1. 新建自定义网络
[root@zyn01 ~]# docker network create zzyy_network
7bf416ce963c26e39682b1259694ae7c05bebbb0d97b30b46c9169cf952a9dd8
[root@zyn01 ~]# docker network ls
NETWORK ID     NAME           DRIVER    SCOPE
52da5ad0d3c8   bridge         bridge    local
5068ece9f839   host           host      local
0b3a4f577ba6   none           null      local
7bf416ce963c   zzyy_network   bridge    local
  1. 新建容器加入上一步新建的自定义网络
docker run -d -p 8081:8080 --network zzyy_network --name tomcat81 billygoo/tomcat8-jdk8
docker run -d -p 8082:8080 --network zzyy_network --name tomcat82 billygoo/tomcat8-jdk8
  1. 互相ping测试

在这里插入图片描述

结论:自定义网络本身就维护了主机名和ip的对应关系(ip和域名都能ping通)

  • 19
    点赞
  • 23
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
1. docker build:构建镜像 2. docker run:启动容器 3. docker ps:查看正在运行的容器 4. docker images:查看本地镜像列表 5. docker pull:从远程仓库拉取镜像 6. docker push:将本地镜像推送到远程仓库 7. docker exec:在运行中的容器中执行命令 8. docker stop:停止正在运行的容器 9. docker start:启动已经停止的容器 10. docker restart:重启容器 11. docker rm:删除容器 12. docker rmi:删除镜像 13. docker inspect:查看容器或镜像的详细信息 14. docker logs:查看容器的日志 15. docker network create:创建网络 16. docker network connect:将容器连接到网络 17. docker network disconnect:将容器网络中断开连接 18. docker network ls:列出所有网络 19. docker volume create:创建数据卷 20. docker volume ls:列出所有数据卷 21. docker volume rm:删除数据卷 22. docker-compose up:启动服务 23. docker-compose down:停止服务 24. docker-compose build:构建服务 25. docker-compose logs:查看服务日志 26. docker-compose ps:查看服务运行情况 27. docker-compose restart:重启服务 28. docker-compose stop:停止服务 29. docker-compose rm:删除停止的服务容器 30. docker-compose pull:拉取服务镜像 31. docker-compose push:推送服务镜像 32. docker swarm init:初始化swarm集群 33. docker swarm join:加入swarm集群 34. docker swarm leave:离开swarm集群 35. docker service create:创建服务 36. docker service ls:列出所有服务 37. docker service rm:删除服务 38. docker service update:更新服务 39. docker node ls:列出所有节点 40. docker node rm:删除节点 41. docker stack deploy:部署stack 42. docker stack ls:列出所有stack 43. docker stack rm:删除stack 44. docker stack services:列出stack中的服务 45. docker stack ps:列出stack中的任务 46. docker save:将镜像保存为tar文件 47. docker load:将tar文件导入为镜像 48. docker attach:附加到运行中的容器 49. docker cp:在容器和主机之间复制文件 50. docker diff:查看容器文件系统中的更改 51. docker export:将容器导出为tar文件 52. docker history:查看镜像历史 53. docker login:登录到远程仓库 54. docker logout:退出远程仓库 55. docker network inspect:查看网络详细信息 56. docker node inspect:查看节点详细信息 57. docker service inspect:查看服务详细信息 58. docker stats:查看容器资源使用情况 59. docker top:查看容器中正在运行的进程 60. docker wait:阻塞容器,直到容器停止运行。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

MelodyYN

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值