一,network的概述
解决痛点(能干什么?):
(1)容器间的互联和通信以及端口映射
(2)容器IP变动时候,可以通过服务名直接网络通信而不受到影响
二,network的基本用法
# 连接容器到网络
docker network connect 网络名
# 创建网络(使用统一网络的容器,肯定可以ping通)
docker network create 网络名
# 断开网络
docker network disconnect 网络名
# 查看网络具体信息
docker network inspect
# 查看所有网络列表
docker network ls
# 删除无用网络
docker network prune
# 删除指定的网络
docker network rm
三,network的五种网络模式
网络模式 | 命令指定方式 | 描述 | 理解 |
---|---|---|---|
bridge | –network bridge | 为每一个容器分配、设置 ip ,并将容器连接到 docker0 虚拟网桥上,虚拟网桥,默认为该网络模式 | 一人一个 |
host | –network host | 容器不会创建自己的网卡,配置 ip 等,而是使用宿主机的 ip 和端口 | 多人一个 |
container | –network 容器名称或id | 新创建的容器不会创建自己的网卡和配置自己的ip,而是和一个指定的容器共享ip、端口范围等 | 自己没有,用别人的 |
none | –network none | 容器有独立的Network namespace,但并没有对其进行任何网络设置,如网桥,ip等 | 有,但是空的 |
(1)桥接模式—— bridge
为每一个容器分配、设置IP等,并将容器连接到docker0的虚拟网桥。若没有特别申明,则为默认自带一个IP以及网络设置。
-
Docker使用Linux桥接的方式,在宿主机虚拟一个Docker容器网桥(docker0)。
Docker每启动一个容器时会根据Docker网桥的网段分配给容器一个ip地址。
同时Docker网桥是每个容器的默认网关。
同一宿主机内的容器都接入同一个网桥,这样容器之间就能够通过容器的Container-IP直接通信。 -
docker run创建容器的时,未指定network的容器默认的网络模式就是bridge,使用的就是docker0。
在宿主机ifconfig,就可以看到docker0和自己创建的network:- eth0,eth1……代表网卡一,网卡二……
- lo代表127.0.0.1(localhost)
- inet addr表示网卡的ip地址
-
网桥docker0会创建一对对等虚拟设备接口:一个叫veth,另一个叫eth0,成对匹配。
整个宿主机的网桥模式都是docker0,类似一个交换机有一堆接口,每个接口叫veth,
在本地主机和容器内分别创建一个虚拟接口,并让他们彼此联通(这样一对接口叫veth pair);
每个容器实例内部也有一块网卡,每个接口叫eth0;
docker0上面的每个veth匹配某个容器实例内部的eth0,两两配对。
[root@localhost ~]# docker network inspect bridge
[
{
"Name": "bridge", # 网络名称
"Id": "73992551d4270844e6aaab67e4d2030e24b5670c1502d34d29070d6a871c4a4e", # 网络ID
"Created": "2024-01-05T16:06:44.585112632+08:00", # 网络创建时间
"Scope": "local", # 网络作用范围
"Driver": "bridge", # 网络驱动
"EnableIPv6": false, # 网络是否支持ipv6
"IPAM": {
"Driver": "default",
"Options": null,
"Config": [
{
"Subnet": "172.17.0.0/16", # 网络网段
"Gateway": "172.17.0.1" # 网络ip
}
]
},
"Internal": false,
"Attachable": false,
"Ingress": false,
"ConfigFrom": {
"Network": ""
},
"ConfigOnly": false,
"Containers": {
"411008ba764f9209982cae4ddda07e12f851d88b00432e5b6819895fabcabfb6": {
"Name": "ubt03", # 使用改网络的容器名称
"EndpointID": "1bdc19dd16fe96a8fe570dd89516f58e58ee54decd7d71f8df51dd483053d1f7",
"MacAddress": "02:42:ac:11:00:03", # 使用改网络的容器的MAC地址
"IPv4Address": "172.17.0.3/16", # 使用改网络的容器的IP地址
"IPv6Address": ""
},
"75e8ed5431da1c1558a440eb26a62648e4ee2bdffa09b68adddcc486b69d8a35": {
"Name": "ubt01", # 使用改网络的容器名称
"EndpointID": "c9756c4ebe3b887fa82baec3c9019ccc4ad23aff6307760b7bab5e52f7dfd9fa",
"MacAddress": "02:42:ac:11:00:02", # 使用改网络的容器的MAC地址
"IPv4Address": "172.17.0.2/16", # 使用改网络的容器的IP地址
"IPv6Address": ""
},
"7b738c8435c3973bf7d23d97bd5a91a9d67b53eb7bf545413935db33af95dc7c": {
"Name": "ubt02", # 使用改网络的容器名称
"EndpointID": "966dfe49dd8c49c44e018bdc84d7a7366c1d1f0d53035a833c367dff62266084",
"MacAddress": "02:42:ac:11:00:04", # 使用改网络的容器的MAC地址
"IPv4Address": "172.17.0.4/16", # 使用改网络的容器的IP地址
"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", # docker0 默认就是bridge网络模式
"com.docker.network.driver.mtu": "1500"
},
"Labels": {}
}
]
(2)主机模式—— host
容器不会虚拟出自己的网卡、IP等,而是使用宿主机的IP和端口。
注意:在创建的时候,将不在指定 -p 8083:8080
,无意义,运行时候会警告,但是不报错。因为该容器和主机ip和端口同步。
[root@localhost ~]# docker network inspect host
[
{
"Name": "host", # 网络名称
"Id": "3aa406c8eaa186507ced3f3ff72710d350b363b5993159449de623188dd7d5e7",
"Created": "2023-12-15T14:18:11.018657826+08:00", # 网络创建时间
"Scope": "local", # 网络作用范围
"Driver": "host", # 网络驱动
"EnableIPv6": false,
"IPAM": {
"Driver": "default",
"Options": null,
"Config": []
},
"Internal": false,
"Attachable": false,
"Ingress": false,
"ConfigFrom": {
"Network": ""
},
"ConfigOnly": false,
"Containers": {
"18720ac44b136684644e17d8deea38b74db76d8ef0f1fc342340180148377310": {
"Name": "redis-node-3", # 使用该网络的容器名称
"EndpointID": "3a18044ac33afd2da1b3cadd1dd28735c278119a1b1b5f1def96f206b84d8efb",
"MacAddress": "",
"IPv4Address": "",
"IPv6Address": ""
},
"2b2987704c6da591e321fe75f9a1518f4e4488285f0c3a20d53d32a8cf9d24da": {
"Name": "redis-node-2", # 使用该网络的容器名称
"EndpointID": "825830dd9adf559a9d99e0e8dad1fd3a4ef14b137e322f2c78d9b090ad0d9390",
"MacAddress": "",
"IPv4Address": "",
"IPv6Address": ""
},
"e2304c8acbd676f76fcde5faf0f26555bedf61148ab858c22bc32c2ab9ff4a9b": {
"Name": "redis-node-1", # 使用该网络的容器名称
"EndpointID": "a255555c3c7f7dffcf2c7e26a3dd752a43b826a8ccebb9f41f65bf400cb5e56d",
"MacAddress": "",
"IPv4Address": "",
"IPv6Address": ""
}
},
"Options": {},
"Labels": {}
}
]
(3)容器模式—— container
新创建的容器不会创建自己的网卡,没有自己的IP,也不会进行相应的配置。而是和一个指定的容器共享IP端口范围等。
说明:当192.168.20.2容器停掉后,192.168.20.3的网络也会同时停掉!
--network container:共享的容器名/ID
注意: 在测试的时候,由于tomcat容器的端口,不可共用,所以在测试的时候,还是用Alpine(简单、小巧、安全)
小插件来测试:
# 创建alpine1
$ docker run -it --name alpine1 alpine /bin/sh
# 创建alpine2,通过--network container:alpine1,共用网络
$ docker run -it --network container:alpine1 --name alpine2 alpine /bin/sh
(4)none模式—— none
容器有自己独立的Network namespace,但是没有进行任何的相关配置。即禁用网络功能,只有lo标识(就是127.0.0.1表示本地回环)
- 在none模式下,并不为Docker容器进行任何网络配置。
也就是说,这个Docker容器没有网卡、IP、路由等信息,只有一个lo。
需要我们自己为Docker容器添加网卡、配置IP等。
[root@localhost ~]# docker network inspect none
[
{
"Name": "none", # 网络名称
"Id": "9939d4b66231cc6e90ffca805518059ab077e5b04d4933a4b69f279e91f314dd", # 网络id
"Created": "2023-12-15T14:18:10.956266297+08:00", # 网络创建时间
"Scope": "local", # 网络作用范围
"Driver": "null", # 网络驱动
"EnableIPv6": false,
"IPAM": {
"Driver": "default",
"Options": null,
"Config": []
},
"Internal": false,
"Attachable": false,
"Ingress": false,
"ConfigFrom": {
"Network": ""
},
"ConfigOnly": false,
"Containers": {},
"Options": {},
"Labels": {}
}
]
(5)自定义网络
为使得众多的容器,进行分门别类,方便管理的情况下,而且通过服务名来ping通,所以采用自定义网络进行管理!
解决痛点:可以通过服务名ping
通。
#创建新的网络,默认为bridge模式
docker network create new_net
# 新创建两个容器tomcat81和tomcat82,并调用新建的自定义网络
docker run -d -p 8081:8080 --network new_net --name tomcat81 billygoo/tomcat8-jdk8
docker run -d -p 8082:8080 --network new_net --name tomcat82 billygoo/tomcat8-jdk8
tomcat81和tomcat82 是在同一个网段,通过ip来ping
肯定能够通,并且通过服务器也可以ping
通。