Docker网络详解
Docker网络详解
Docker0网络
准备工作:清空所有的容器,清空所有的镜像
docker rm -f $(docker ps -a -q) # 删除所有容器
docker rmi -f $(docker images -qa) # 删除全部镜像
本地干净的网络
[root@kuangshenlinux ~]# 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
# 网卡地址 wifi
2: enp0s3: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP group default qlen 1000
link/ether 08:00:27:e0:aa:73 brd ff:ff:ff:ff:ff:ff
inet 192.168.0.111/24 brd 192.168.0.255 scope global noprefixroute enp0s3
valid_lft forever preferred_lft forever
inet6 fe80::3202:526:12cb:70ec/64 scope link noprefixroute
valid_lft forever preferred_lft forever
# docker 0 ,docker创建的网络
3: docker0: <NO-CARRIER,BROADCAST,MULTICAST,UP> mtu 1500 qdisc noqueue state DOWN group default
link/ether 02:42:f8:9d:a8:42 brd ff:ff:ff:ff:ff:ff
inet 172.17.0.1/16 brd 172.17.255.255 scope global docker0
valid_lft forever preferred_lft forever
1、微服务这么多,访问怎么解决? (容器名)
2、docker每启动一个容器,就会给他分配一个ip。docker0是docker默认给的。我们不指定网络的情况下,创建容器都在docker0中,未来开发,我们要自定义网络。
[root@kuangshenlinux ~]# docker run -itd --name web01 centos
Unable to find image 'centos:latest' locally
latest: Pulling from library/centos
a1d0c7532777: Already exists
Digest: sha256:a27fd8080b517143cbbbab9dfb7c8571c40d67d534bbdee55bd6c473f432b177
Status: Downloaded newer image for centos:latest
53231c3adf0423ed2d0577ead987507c12978416349a51445d663c9536c9b4ff
# docker每启动一个容器,就会给他分配一个ip。这个ip就是归docker0 管理
[root@kuangshenlinux ~]# docker exec -it web01 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
4: eth0@if5: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP group default
link/ether 02:42:ac:11:00:02 brd ff:ff:ff:ff:ff:ff link-netnsid 0
inet 172.17.0.2/16 brd 172.17.255.255 scope global eth0
valid_lft forever preferred_lft forever
# 容器外本地可以ping到容器里面
[root@kuangshenlinux ~]# ping 172.17.0.2
PING 172.17.0.2 (172.17.0.2) 56(84) bytes of data.
64 bytes from 172.17.0.2: icmp_seq=1 ttl=64 time=0.058 ms
分析原理
1、本来有三个网络,启动容器后,多了一个,这个网络和容器内部的网络是配对的。
# 再次启动一个容器查看
[root@kuangshenlinux ~]# docker exec -it web02 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
6: eth0@if7: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP group default
link/ether 02:42:ac:11:00:03 brd ff:ff:ff:ff:ff:ff link-netnsid 0
inet 172.17.0.3/16 brd 172.17.255.255 scope global eth0
valid_lft forever preferred_lft forever
[root@kuangshenlinux ~]# ip addr
....
3: docker0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP group default
link/ether 02:42:f8:9d:a8:42 brd ff:ff:ff:ff:ff:ff
inet 172.17.0.1/16 brd 172.17.255.255 scope global docker0
valid_lft forever preferred_lft forever
inet6 fe80::42:f8ff:fe9d:a842/64 scope link
valid_lft forever preferred_lft forever
5: veth3b4847e@if4: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue master docker0 state UP group default
link/ether 0e:58:71:93:42:18 brd ff:ff:ff:ff:ff:ff link-netnsid 0
inet6 fe80::c58:71ff:fe93:4218/64 scope link
valid_lft forever preferred_lft forever
7: veth13568df@if6: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue master docker0 state UP group default
link/ether 9a:3c:71:70:e2:a0 brd ff:ff:ff:ff:ff:ff link-netnsid 1
inet6 fe80::983c:71ff:fe70:e2a0/64 scope link
valid_lft forever preferred_lft forever
# 总结观察:
1、web1 -- linux 主机 5: veth3b4847e@if4: 4: eth0@if5
2、web2 -- linux 主机 7: veth13568df@if6: 6: eth0@if7
# 只要启动一个容器,默认就会分配一对网卡。
# 虚拟接口 # veth-pair 就是一对的虚拟设备接口,它都是成对出现的。一端连着协议栈,一端彼此相连着。
# 就好比一个桥梁,可以连通容器内外。
# 测试容器之间的访问,ip访问没有问题
[root@kuangshenlinux ~]# docker exec -it web02 ping 172.17.0.2
PING 172.17.0.2 (172.17.0.2) 56(84) bytes of data.
64 bytes from 172.17.0.2: icmp_seq=1 ttl=64 time=0.058 ms
64 bytes from 172.17.0.2: icmp_seq=2 ttl=64 time=0.064 ms
^C
--- 172.17.0.2 ping statistics ---
2 packets transmitted, 2 received, 0% packet loss, time 1001ms
rtt min/avg/max/mdev = 0.058/0.061/0.064/0.003 ms
[root@kuangshenlinux ~]# docker exec -it web01 ping 172.17.0.3
PING 172.17.0.3 (172.17.0.3) 56(84) bytes of data.
64 bytes from 172.17.0.3: icmp_seq=1 ttl=64 time=0.043 ms
64 bytes from 172.17.0.3: icmp_seq=2 ttl=64 time=0.071 ms
64 bytes from 172.17.0.3: icmp_seq=3 ttl=64 time=0.092 ms
^C
--- 172.17.0.3 ping statistics ---
3 packets transmitted, 3 received, 0% packet loss, time 2005ms
rtt min/avg/max/mdev = 0.043/0.068/0.092/0.022 ms
小结
Docker使用Linux桥接,在宿主机虚拟一个Docker容器网桥(docker0),Docker启动一个容器时会根据Docker网桥的网段分配给容器一个IP地址,称为Container-IP,同时Docker网桥是每个容器的默认网关。因为在同一宿主机内的容器都接入同一个网桥,这样容器之间就能够通过容器的Container-IP直接通信。
Docker容器网络就很好的利用了Linux虚拟网络技术,在本地主机和容器内分别创建一个虚拟接口,并让他们彼此联通(这样一对接口叫veth pair);
Docker中的网络接口默认都是虚拟的接口。虚拟接口的优势就是转发效率极高(因为Linux是在内核中进行数据的复制来实现虚拟接口之间的数据转发,无需通过外部的网络设备交换),对于本地系统和容器系统来说,虚拟接口跟一个正常的以太网卡相比并没有区别,只是他的速度快很多。
–link
mysql: 服务名地址链接 ip会变化
[root@kuangshenlinux ~]# docker exec -it web02 ping web01
ping: web01: Name or service not known
# 但是可以通过 --link在启动容器的时候连接到另一个容器网络中,可以通过域名ping了
[root@kuangshenlinux ~]# docker run -itd --name web03 --link web02 centos
6f67f9f7407edb8c48ce2d3ca413aef414a2a8628080fd69605e4ce2c3bea6ab
[root@kuangshenlinux ~]# docker exec -it web03 ping web02
PING web02 (172.17.0.3) 56(84) bytes of data.
64 bytes from web02 (172.17.0.3): icmp_seq=1 ttl=64 time=0.062 ms
64 bytes from web02 (172.17.0.3): icmp_seq=2 ttl=64 time=0.064 ms
64 bytes from web02 (172.17.0.3): icmp_seq=3 ttl=64 time=0.064 ms
^C
--- web02 ping statistics ---
3 packets transmitted, 3 received, 0% packet loss, time 2005ms
rtt min/avg/max/mdev = 0.062/0.063/0.064/0.006 ms
# 但是反向也ping不通。
[root@kuangshenlinux ~]# docker exec -it web02 ping web03
ping: web03: Name or service not known
# 底层原理
域名:
--link hosts 添加了一条记录
172.17.0.3 web02
[root@kuangshenlinux ~]# docker exec -it web03 cat /etc/hosts
127.0.0.1localhost
::1localhost ip6-localhost ip6-loopback
fe00::0ip6-localnet
ff00::0ip6-mcastprefix
ff02::1ip6-allnodes
ff02::2ip6-allrouters
172.17.0.3web02 325795bd6df8
172.17.0.46f67f9f7407e
[root@kuangshenlinux ~]#
–link是以前的方法,不方便了。
自定义网络
[root@kuangshenlinux ~]# 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
Run 'docker network COMMAND --help' for more information on a command.
# 查看所有的网络
[root@kuangshenlinux ~]# docker network ls
NETWORK ID NAME DRIVER SCOPE
defce6912c4a bridge bridge local
e6e26ff63dfe host host local
8a592709b443 none null local
所有网络模式
网络模式 | 配置 | 说明 |
---|---|---|
bridge模式 | –net=bridge | 默认值,在Docker网桥docker0上为容器创建新的网络栈 |
none模式 | –net=none | 不配置网络,用户可以稍后进入容器,自行配置 |
container模式 | –net=container:name/id | 容器和另外一个容器共享Network namespace。 kubernetes中的pod就是多个容器共享一个Network namespace。 |
host模式 | –net=host | 容器和宿主机共享Network namespace |
用户自定义 | –net=自定义网络 | 用户自己使用network相关命令定义网络,创建容器的时候可以指定为自己定义的网络 |
[root@kuangshenlinux ~]# docker network inspect bridge
[
{
"Name": "bridge",
"Id": "defce6912c4ae8b16d6f02a6eee0650c79c7d39cba26597de32648f936c0cd43",
"Created": "2023-12-12T19:57:25.572880728+08:00",
"Scope": "local",
"Driver": "bridge",
"EnableIPv6": false,
"IPAM": {
"Driver": "default",
"Options": null,
"Config": [
{
// 网络配置: config配置,子网网段 255*255. 65534 个地址
"Subnet": "172.17.0.0/16",
// docker0 网关地址
"Gateway": "172.17.0.1"
}
]
},
"Internal": false,
"Attachable": false,
"Ingress": false,
"ConfigFrom": {
"Network": ""
},
"ConfigOnly": false,
// 在这个网络下的容器地址。Name就是容器的名字
"Containers": {
"325795bd6df82e6ef18ff027f43a189c4ef886a25b95fdc9c5793bc9d7827179": {
"Name": "web02",
"EndpointID": "9ab43d4cd786b8c79d78fd3bf3f05c6dfbd6f1665ca5bc9e74646f1d6f758508",
"MacAddress": "02:42:ac:11:00:03",
"IPv4Address": "172.17.0.3/16",
"IPv6Address": ""
},
"53231c3adf0423ed2d0577ead987507c12978416349a51445d663c9536c9b4ff": {
"Name": "web01",
"EndpointID": "b891d5b8213b8241b5438c60afc08054c0c4c48490a3715f21fe5591b28b65fc",
"MacAddress": "02:42:ac:11:00:02",
"IPv4Address": "172.17.0.2/16",
"IPv6Address": ""
},
"6f67f9f7407edb8c48ce2d3ca413aef414a2a8628080fd69605e4ce2c3bea6ab": {
"Name": "web03",
"EndpointID": "651e2d1b9dcd72fc7339c687904cf763aaa524bd79cc5945888dfec8829a62b6",
"MacAddress": "02:42:ac:11:00:04",
"IPv4Address": "172.17.0.4/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": {}
}
]
自定义一个网络
[root@kuangshenlinux ~]# docker run -itd --name web01 --net bridge centos
552223f74f163f94238bf536040aa0c683b1ab0fbfbcabdd1ed28644e40f1b9f
# docker0网络的特点
1.它是默认的
2.域名访问不通
3.--link 域名通了,但是删了又不行
create命令创建一个新的网络
[root@kuangshenlinux ~]# docker network create \
--driver bridge \
--subnet 192.169.0.0/16 \
--gateway 192.169.0.1 \
mynet
d37ec2853507c3e6159db06e4c8a33e39a45edff4ac69949c96f981d7aca9a79
[root@kuangshenlinux ~]# docker network ls
NETWORK ID NAME DRIVER SCOPE
defce6912c4a bridge bridge local
e6e26ff63dfe host host local
d37ec2853507 mynet bridge local
8a592709b443 none null local
使用的逻辑
# 未来可以通过网络来隔离项目
docker network create \
--driver bridge \
--subnet 192.169.0.0/16 \
--gateway 192.169.0.1 \
kuangstudynet
mysql
redis
web
admin
mq
# 部署集群挽环境,也可以这样定义网络
mysql 3-5个容器
docker network create \
--driver bridge \
--subnet 192.169.0.0/16 \
--gateway 192.169.0.1 \
mysqlnet
--net mysqlnet
# 启动两个服务在自己的网络下。 --net mynet
[root@kuangshenlinux ~]# docker run -itd --name wen01-net --net mynet centos
e16726178e4ee3b61b0dc47f16d112ba0426bcf040b84949811ebc8607d94555
[root@kuangshenlinux ~]# docker run -itd --name wen02-net --net mynet centos
17fae7a2c0bb66c2834ad7d3dc338c0a5707aea5caf4337138f15c6f2079713e
# 测试互相ping,可以使用域名ping通了
[root@kuangshenlinux ~]# docker exec -it wen01-net ping 192.169.0.3
PING 192.169.0.3 (192.169.0.3) 56(84) bytes of data.
64 bytes from 192.169.0.3: icmp_seq=1 ttl=64 time=0.063 ms
64 bytes from 192.169.0.3: icmp_seq=2 ttl=64 time=0.091 ms
64 bytes from 192.169.0.3: icmp_seq=3 ttl=64 time=0.066 ms
^C
--- 192.169.0.3 ping statistics ---
3 packets transmitted, 3 received, 0% packet loss, time 2001ms
rtt min/avg/max/mdev = 0.063/0.073/0.091/0.014 ms
[root@kuangshenlinux ~]# docker exec -it wen01-net ping wen02-net
PING wen02-net (192.169.0.3) 56(84) bytes of data.
64 bytes from wen02-net.mynet (192.169.0.3): icmp_seq=1 ttl=64 time=0.041 ms
64 bytes from wen02-net.mynet (192.169.0.3): icmp_seq=2 ttl=64 time=0.064 ms
64 bytes from wen02-net.mynet (192.169.0.3): icmp_seq=3 ttl=64 time=0.106 ms
64 bytes from wen02-net.mynet (192.169.0.3): icmp_seq=4 ttl=64 time=0.088 ms
^C
--- wen02-net ping statistics ---
4 packets transmitted, 4 received, 0% packet loss, time 3007ms
rtt min/avg/max/mdev = 0.041/0.074/0.106/0.026 ms
[root@kuangshenlinux ~]# docker exec -it wen02-net ping wen01-net
PING wen01-net (192.169.0.2) 56(84) bytes of data.
64 bytes from wen01-net.mynet (192.169.0.2): icmp_seq=1 ttl=64 time=0.052 ms
64 bytes from wen01-net.mynet (192.169.0.2): icmp_seq=2 ttl=64 time=0.092 ms
^C
--- wen01-net ping statistics ---
2 packets transmitted, 2 received, 0% packet loss, time 1002ms
rtt min/avg/max/mdev = 0.052/0.072/0.092/0.020 ms
# 未来在项目中,直接使用容器名来连接服务,ip无论怎么变,都不会发生变化
docker run -itd --name mysql --net mynet mysql
mysql:3306/rbms
网络连通
由于我们现在是跨网络的,容器之间无法访问
[root@kuangshenlinux ~]# docker exec -it web01 ping wen01-net
ping: wen01-net: Name or service not known
[root@kuangshenlinux ~]# docker exec -it web01 ping 192.169.0.2
docker0和自定义网络肯定不通,我们使用自定义网络的好处就是网络隔离:
大家公司项目部署的业务都非常多,假设我们有一个商城,我们会有订单业务(操作不同数据),会有订单业务购物车业务(操作不同缓存)。如果在一个网络下,有的程序猿的恶意代码就不能防止了,所以我们就在部署的时候网络隔离,创建两个桥接网卡,比如订单业务(里面的数据库,redis,mq,全部业务 都在order-net网络下)其他业务在其他网络。
那关键的问题来了,如何让 web-net-01 访问 web01?
[root@kuangshenlinux ~]# docker network connect --help
Usage: docker network connect [OPTIONS] NETWORK CONTAINER
Connect a container to a network
# 第一个参数 网络
# 第二个参数 容器
[root@kuangshenlinux ~]# docker network connect mynet web01
[root@kuangshenlinux ~]# docker network inspect mynet
[
{
"Name": "mynet",
"Id": "d37ec2853507c3e6159db06e4c8a33e39a45edff4ac69949c96f981d7aca9a79",
"Created": "2023-12-12T20:34:57.1073687+08:00",
"Scope": "local",
"Driver": "bridge",
"EnableIPv6": false,
"IPAM": {
"Driver": "default",
"Options": {},
"Config": [
{
"Subnet": "192.169.0.0/16",
"Gateway": "192.169.0.1"
}
]
},
"Internal": false,
"Attachable": false,
"Ingress": false,
"ConfigFrom": {
"Network": ""
},
"ConfigOnly": false,
"Containers": {
"17fae7a2c0bb66c2834ad7d3dc338c0a5707aea5caf4337138f15c6f2079713e": {
"Name": "wen02-net",
"EndpointID": "cd4963c8bc9e64182fffc5f7b202495c3c2b28d46da8e17d73d3a94359fd7c1d",
"MacAddress": "02:42:c0:a9:00:03",
"IPv4Address": "192.169.0.3/16",
"IPv6Address": ""
},
# web01 这个容器进入了 mynet 网络
"552223f74f163f94238bf536040aa0c683b1ab0fbfbcabdd1ed28644e40f1b9f": {
"Name": "web01",
"EndpointID": "d684b0ab3142219939957cbbd47a4a254d2459cbcac6fe9f9ae5aed0b7f32370",
"MacAddress": "02:42:c0:a9:00:04",
"IPv4Address": "192.169.0.4/16",
"IPv6Address": ""
},
"e16726178e4ee3b61b0dc47f16d112ba0426bcf040b84949811ebc8607d94555": {
"Name": "wen01-net",
"EndpointID": "574b3b469f3c2f2f5c21725b720adeaa8640a47618f1d7d7ad8f279343f54c2b",
"MacAddress": "02:42:c0:a9:00:02",
"IPv4Address": "192.169.0.2/16",
"IPv6Address": ""
}
},
"Options": {},
"Labels": {}
}
]
[root@kuangshenlinux ~]# docker network inspect bridge
[
{
"Name": "bridge",
"Id": "defce6912c4ae8b16d6f02a6eee0650c79c7d39cba26597de32648f936c0cd43",
"Created": "2023-12-12T19:57:25.572880728+08: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": {
"26b67bff513034805ec998da0d36ff3b22eb27d2d5f93709f81adc7cc642d935": {
"Name": "web02",
"EndpointID": "db5229124ae6aee60f2fadd30c59fa0ec38dbde2a6ea325e50a943af9c97618c",
"MacAddress": "02:42:ac:11:00:03",
"IPv4Address": "172.17.0.3/16",
"IPv6Address": ""
},
// web01 依旧存在
"552223f74f163f94238bf536040aa0c683b1ab0fbfbcabdd1ed28644e40f1b9f": {
"Name": "web01",
"EndpointID": "d114e6a65bb580713542121454c5e5c9bb3d1151959cf40ec1e2c80e416240bb",
"MacAddress": "02:42:ac:11:00:02",
"IPv4Address": "172.17.0.2/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": {}
}
]
连接之后,web01这个容器拥有了两个ip。一个容器是可以有多个ip的。
#通过连接之后,网络就完全可以打通了
[root@kuangshenlinux ~]# docker exec -it web01 ping wen02-net
PING wen02-net (192.169.0.3) 56(84) bytes of data.
64 bytes from wen02-net.mynet (192.169.0.3): icmp_seq=1 ttl=64 time=0.047 ms
64 bytes from wen02-net.mynet (192.169.0.3): icmp_seq=2 ttl=64 time=0.064 ms
64 bytes from wen02-net.mynet (192.169.0.3): icmp_seq=3 ttl=64 time=0.140 ms
64 bytes from wen02-net.mynet (192.169.0.3): icmp_seq=4 ttl=64 time=0.069 ms
^C
--- wen02-net ping statistics ---
4 packets transmitted, 4 received, 0% packet loss, time 3014ms
rtt min/avg/max/mdev = 0.047/0.080/0.140/0.035 ms
[root@kuangshenlinux ~]# docker exec -it web02-net ping wen01
Error response from daemon: No such container: web02-net
[root@kuangshenlinux ~]# docker exec -it wen02-net ping web01
PING web01 (192.169.0.4) 56(84) bytes of data.
64 bytes from web01.mynet (192.169.0.4): icmp_seq=1 ttl=64 time=0.031 ms
64 bytes from web01.mynet (192.169.0.4): icmp_seq=2 ttl=64 time=0.063 ms
64 bytes from web01.mynet (192.169.0.4): icmp_seq=3 ttl=64 time=0.092 ms
^C
--- web01 ping statistics ---
3 packets transmitted, 3 received, 0% packet loss, time 2001ms
rtt min/avg/max/mdev = 0.031/0.062/0.092/0.024 ms
结论:如果要跨网络操作别人,就需要使用 docker network connect [OPTIONS] NETWORK CONTAINER
连接。
原文地址:https://blog.csdn.net/qq_45371023/article/details/140408596
免责声明:本站文章内容转载自网络资源,如本站内容侵犯了原著者的合法权益,可联系本站删除。更多内容请关注自学内容网(zxcms.com)!