Docker-网络模式
1. docker-网络模式
网络模式 | 简介 |
---|---|
bridge | 为每一个容器分配、设置IP等、并将容器连接到一个docker0中、这个叫虚拟网桥,默认为该模式 |
host | 容器将不会虚拟出自己的网卡,配置自己的IP等,而是使用宿主机的IP和端口 |
none | 容器有独立的Nerwork namespace 但并没有对其进行任何网络设置,如分配veth pair和网桥连接、IP等 |
container | 新创建的容器不会创建自己的网卡和配置自己的IP,而是和一个指定的容器共享IP,端口范围 |
- 命令
bridge模式:使用--network bridge指定,默认使用docker0
host模式:使用--network host指定
none模式:使用--network none指定
container模式:使用--network container:NAME或者容器ID指定
- docker网络能干什么
1.容器间的互联和通信以及端口映射
2.容器IP变动时候可以通过服务名直接网络通信而不受到影响
- docker bridge默认网络模式是会变动的
#先运行 u1 u2 然后关闭u2,启动u3 然后就会发现u2上面的IP地址就会变到u3上面
docker run -itd -name u1 ubuntu
docker run -itd -name u2 ubuntu
docker run -itd -name u3 ubuntu
1)网卡-docker0
docker服务默认会创建一个docker0网桥(其上有一个docker0内部接口),该桥接网络的名称为docker0,它在内核层连通了其他的物理或虚拟网卡,这就将所有容器和本地主机都放到同一个物理网络,docker默认指定了docker0接口的IP地址和子网掩码,让主机和容器之间可以通过网桥相互通信。
- 查看bridge网络的详细信息,并通过grep获取名称项
#容器网卡
[root@harbor ~]# docker network inspect bridge | grep name
"com.docker.network.bridge.name": "docker0",
#虚拟器网卡
[root@harbor ~]# ifconfig | grep docker
docker0: flags=4163<UP,BROADCAST,RUNNING,MULTICAST> mtu 1500
1.docker run的时候,没有指定network的话默认使用的网桥模式就是bridge,使用的就是docker0,在宿主机ifocnfig,就可以看到docker0和自己create的network eth0,eth1,eth2 代表网卡一,网卡二,网卡三,lo代表127.0.0.1 ,即localhost net addr用来表示的IP地址
2.网桥docker0创建一对对等虚拟设备接口一个叫veth,另一个叫eth0,成对匹配
1)整个宿主机的网桥模式都是docker0,类似一个交换机有一堆接口,每个接口veth,在本地主机和容器内分别创建一个虚拟接口,并让他们彼此联通(这样一对接口叫veth pair)
2) 每个容器实例内部也有一块网卡,每个接口叫eth0
3) docker)上面的每个veth匹配某个容器实例内部的eth0,两两配对,一一匹配
通过上述,将宿主机上的所有容器都连接到这个内部网络,两个容器在同一个网络下,会从这个网关下各自拿到分配的IP,此时两个容器的网络是互通的
2)bridge
- 最终启动容器网卡之间都是一对的
[root@harbor ~]# docker run -d -p 8082:8080 --name tomcat82 billygoo/tomcat8-jdk8
[root@harbor ~]# docker run -d -p 8081:8080 --name tomcat81 billygoo/tomcat8-jdk8
3)host
- 直接使用宿主机的IP地址与外界进行通信,不在需要额外进行NAT转换
容器将不会获得一个独立的Network Namespace 而是和宿主机共用一个Network Namespace 容器将不会虚拟自己的网卡而是使用宿主机的IP和端口
- 命令
[root@harbor ~]# docker run -d -p 8083:8080 --network host --name tomcat83 billygoo/tomcat8-jdk8
#docker启动这里会提示一个警告
原因:
docker启动时指定--network=host或--net=host,如果还指定了-p映射端口,那这个时候就会有此警告,
并且通过-p设置的参数将不会起到任何作用,端口号会以主机端口号为主,重复时则递增
解决:
解决的办法就是使用docker的其它网络模式,例如--network=bridge,这样就可以解决问题,或者直接无视
WARNING: Published ports are discarded when using host network mode
#容器内部的网卡根宿主机一样
[root@harbor ~]# docker run -d --network host --name tomcat83 billygoo/tomcat8-jdk8
[root@harbor ~]# docker inspect tomcat83 | tail -n 20
启动信息查看网络,显示没有ip地址与网关 这是host特点
- 没有设置-p的端口映射了,如何访问启动的tomcat83
#直接访问这个即可,使用的端口默认就是宿主机端口
容器内的tomcat83看到访问成功,是因为此时容器的IP借用主机的,所以容器共享宿主机网络IP,这样的好处是外部主机与容器可以直接通信
http://10.0.0.91:8080/
4)none
- 概述
禁用网络功能,只有lo标识(就是127.0.0.1标识本地回环)
在none模式下,并不为docker容器进行任何网络配置,也就是说,这个docker容器没有网卡、IP、路由等信息,只有一个lo需要我们自己为docker容器添加网卡,配置IP等
- 测试
[root@harbor ~]# docker run -d -p 8084:8080 --network none --name tomcat84 billygoo/tomcat8-jdk8
[root@harbor ~]# docker inspect tomcat84 | tail -n 20
"Networks": {
"none": {
"IPAMConfig": null,
"Links": null,
"Aliases": null,
"NetworkID": "e920c97813ad814fc5695cb682fc245ea4484776945448e05237312b01d64f84",
"EndpointID": "70bc07f7e4f947ba4892ece0b591146dfa491b2a219582635b3210480d850462",
"Gateway": "",
"IPAddress": "",
"IPPrefixLen": 0,
"IPv6Gateway": "",
"GlobalIPv6Address": "",
"GlobalIPv6PrefixLen": 0,
"MacAddress": "",
"DriverOpts": null
}
}
}
}
]
#容器内部只有lo
[root@harbor ~]# docker exec -it tomcat84 bash
root@2ca96aa1659d:/usr/local/tomcat# ip a
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)container
- container网络模式
新建的容器和已经存在的一个容器共享一个网络ip配置而不是和宿主机共享,新创建的容器不会创建自己的网卡,
配置自己的IP,而是和一个指定的容器共享IP,端口范围等,同样,两个容器除了网络方面,其它的如文件系统,进程列表等还是隔离的
- 案例--坑
[root@harbor ~]# docker run -d -p 8086:8080 --network container:tomcat85 --name tomcat86 billygoo/tomcat8-jdk8
docker: Error response from daemon: conflicting options: port publishing and the container type network mode.
See 'docker run --help'.
#这个错误是
相当于tomcat86和tomcat85公用同一个ip同一个端口,导致端口冲突
- 案例-1 演示坑
#演示错误 不能继续下执行
[root@harbor ~]# docker run -d -p 8085:8080 --name tomcat85 billygoo/tomcat8-jdk8
8eb6e2ef6675d896906f2f1e77ebee4bd32b1c7811b6c1acd053a6d2ad011e4e
[root@harbor ~]# docker run -d -p 8086:8080 --network container:tomcat85 --name tomcat86 billygoo/tomcat8-jdk8
- 案例2
[root@harbor ~]# docker run -itd --name alpine1 alpine
#基于容器的继承,如果alpine2关闭了 那么alpine1的网络就会自动关闭
[root@harbor ~]# docker run -itd --network container:alpine1 --name alpine2 alpine
#alpine1
35: eth0@if36: <BROADCAST,MULTICAST,UP,LOWER_UP,M-DOWN> mtu 1500 qdisc noqueue state UP
link/ether 02:42:ac:11:00:05 brd ff:ff:ff:ff:ff:ff
inet 172.17.0.5/16 brd 172.17.255.255 scope global eth0
valid_lft forever preferred_lft forever
#alpine2
35: eth0@if36: <BROADCAST,MULTICAST,UP,LOWER_UP,M-DOWN> mtu 1500 qdisc noqueue state UP
link/ether 02:42:ac:11:00:05 brd ff:ff:ff:ff:ff:ff
inet 172.17.0.5/16 brd 172.17.255.255 scope global eth0
valid_lft forever preferred_lft forever
5)自定义网络
[root@harbor ~]# docker run -d -p 8081:8080 --name tomcat81 billygoo/tomcat8-jdk8
[root@harbor ~]# docker run -d -p 8082:8080 --name tomcat82 billygoo/tomcat8-jdk8
-
测试容器之间网络是可以相互ping通
- 要是ping 容器名是不通的
#tomcat1
root@df2ade497b8b:/usr/local/tomcat# ping tomcat82
ping: tomcat2: Name or service not known
#tomcat2
root@fb0f3778eea2:/usr/local/tomcat# ping tomcat81
ping: tomcat1: Name or service not known
- 创建自定义网络
[root@harbor ~]# docker network create quyi_network
63b9df9e1769a053c6a414b569fe50338febcd5fa5953ef4b996a35fd6f5d206
#可以看到还是bridge驱动
[root@harbor ~]# docker network ls
NETWORK ID NAME DRIVER SCOPE
e974819aec73 bridge bridge local
1fbbaa051868 host host local
e920c97813ad none null local
63b9df9e1769 quyi_network bridge local
#重新启动容器-并加入这个网络
[root@harbor ~]# docker run -d -p 8081:8080 --network quyi_network --name tomcat81 billygoo/tomcat8-jdk8
6f63f3bc1c005013dfddbdf199daa82edd0db6a86c6be1a547d8ba4548074fb5
[root@harbor ~]# docker run -d -p 8082:8080 --network quyi_network --name tomcat82 billygoo/tomcat8-jdk8
#tomcat1
root@6f63f3bc1c00:/usr/local/tomcat# ping tomcat82
PING tomcat82 (172.18.0.3) 56(84) bytes of data.
64 bytes from tomcat82.quyi_network (172.18.0.3): icmp_seq=1 ttl=64 time=0.032 ms
64 bytes from tomcat82.quyi_network (172.18.0.3): icmp_seq=2 ttl=64 time=0.039 ms
64 bytes from tomcat82.quyi_network (172.18.0.3): icmp_seq=3 ttl=64 time=0.041 ms
64 bytes from tomcat82.quyi_network (172.18.0.3): icmp_seq=4 ttl=64 time=0.042 ms
64 bytes from tomcat82.quyi_network (172.18.0.3): icmp_seq=5 ttl=64 time=0.043 ms
#tomcat2
root@9804d1590c9d:/usr/local/tomcat# ping tomcat1
ping: tomcat1: Name or service not known
root@9804d1590c9d:/usr/local/tomcat# ping tomcat81
PING tomcat81 (172.18.0.2) 56(84) bytes of data.
64 bytes from tomcat81.quyi_network (172.18.0.2): icmp_seq=1 ttl=64 time=0.106 ms
64 bytes from tomcat81.quyi_network (172.18.0.2): icmp_seq=2 ttl=64 time=0.042 ms
#然后就可以ping通了
自定义网络本身就维护好了主机名和ip的对应关系(ip和域名都能通)