Docker网络
清空本地镜像以及容器
清空本地镜像以及容器,仅仅是为了放止在学习网络时出现干扰,仅在学习使使用
清空本地所有容器:docker rm -f $(docker ps -aq)
清空本地所有镜像:docker rmi -f $(docker images -aq)
理解 Docker 网络
三个问题:
#问题一: docker 是如何让处理容器网络访问的?
# 启动 tomcat
[root]# docker run -d -p 9090:8080 --name tomcat01 tomcat
#查看容器的内部网络地址 ip addr 我们发现容器启动的时候容器会给他分配一个 eth0@if75 地址,这个ip地址是 docker 分配的。
[root@iZ2zehqn8uqylq6ei48mb2Z /]# docker exec -it tomcat01 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
74: eth0@if75: <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
#思考:linux服务器能不能 ping 通容器内部
[root@iZ2zehqn8uqylq6ei48mb2Z /]# 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.081 ms
64 bytes from 172.17.0.2: icmp_seq=2 ttl=64 time=0.055 ms
64 bytes from 172.17.0.2: icmp_seq=3 ttl=64 time=0.053 ms
# linux 可以 ping 通 docker 容器内部
原理
我们每启动一个docker容器,docker就会给docker容器分配一个ip,我们只要安装了docker,就会有一个网卡docker0的桥接模式,使用的技术是evth-pair技术!
# 我们发现这个容器带来的网卡,都是一对一对的
# evth-pair 就是一对的虚拟设备接口,他们都是成对出现的,一端连接着协议,一端彼此相连
#正因为有这个特性,evth-pair 充当一个桥梁,连接各种虚拟网络设备的
#OpenStac,Dokcer容器之间的连接,OVS的连接,都是使用evth-pair技术
而我的docker0地址是 172.17.0.1 <=> tomcat容器地址是 172.17.0.2
很明显他们是在同一个网段中的,他们是可以相互 ping 通的
绘制一个网络模型图:
==结论==:tomcat01 和 tomcat02 是公用的一个路由器,即是docker01
所有的容器在不指定网络的情况下,都是dockers0路由的,docker会给哦我们的容器分配一个可用IP
IP: 255.255.0.1/16 (十进制) ip后面的16是指 域 --> 局域网
IP:00000000.00000000.00000000.00000000(二进制)
小结
Docker是使用的linux 的桥接,网络宿主机中是一个Docker容器的网桥 docker0
Docker中的所有网络接口都是虚拟的。虚拟的转发效率高。(内网传递文件)
只要容器删除,对应的网桥就没有了!
思考一个场景,我们编写了一个微服务,database url=ip;项目不重启,数据库ip被换掉了,我们希望可以处理掉这个问题,可以使用名字来进行访问容器?
( --link) ⇒ 容器互联 (不推荐使用)
[root]# docker exec -it tomcat01 ping tomcat02
ping: tomcat02: Name or service not known
#如何进行解决呢? 我们可以通过 --link 来解决网络联通问题
[root]# docker run -d -P --name tomcat03 --link tomcat01 tomcat
8ecccd33f9bdb847d198050d9350112eabc07bb669d9b1da8585f9b8be8796cf
[root]# docker exec -it tomcat03 ping tomcat01
PING tomcat01 (172.17.0.2) 56(84) bytes of data.
64 bytes from tomcat01 (172.17.0.2): icmp_seq=1 ttl=64 time=0.114 ms
64 bytes from tomcat01 (172.17.0.2): icmp_seq=2 ttl=64 time=0.084 ms
64 bytes from tomcat01 (172.17.0.2): icmp_seq=3 ttl=64 time=0.078 ms
64 bytes from tomcat01 (172.17.0.2): icmp_seq=4 ttl=64 time=0.081 ms
#但是反向可以 ping 通吗? 很明显是不行的
[root]# docker exec -it tomcat01 ping tomcat03
ping: tomcat03: Name or service not known
原因
# 查看 hosts 配置,原来在这里将 tomcat01 进行了配置
[root]# docker exec -it tomcat03 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.17.0.2 tomcat01 9f4b805323b4
172.17.0.4 8ecccd33f9bd
--link 就是我们在hosts配置中增加了一个172.18.0.2 tomcat01 9f4b805323b4
现在使用docker已经不推荐使用 --link 了
自定义网络!不适用docker0!
docker0问题:不支持容器名连接!
自定义网络
查看所有的docker网络
网络模式:
- bridge:桥接网络 docker(默认)
- none :不配置网络
- host :和宿主机共享网络
- container: 容器网络联通!(用的比较少!局限性比较大!)
测试:
#我们直接启动的命令 --net bridge,而这个就剩我们的docker0
[root]# docker run -d -P --name tomcat01 tomcat
[root]# docker run -d -P --name tomcat01 --net bridge tomcat
#docker0 的特点:默认的,域名不能够访问 --link可以打通进行访问
# 我们可以去自定义一个网络
#--driver bridge 连接方式
#--subnet 192.168.0.0/16 子网
#--gateway 192.168.0.1 路由
[root]# docker network create --driver bridge --subnet 192.168.0.0/16 --gateway 192.168.0.1 mynet
34eadfafc706e751178fe19911715c3c096c47371532169ab4c2e58d468b15a8
[root]# docker network ls
NETWORK ID NAME DRIVER SCOPE
b4b6cd239a5b bridge bridge local
1e58121d1057 host host local
34eadfafc706 mynet bridge local
7268f4a43fd8 none null local
我们自己的网络就构建成功了!
#我们在自定义网络中 运行两个tomcat(tomcat01、tomcat02)
[root]# docker run -d -P --name tomcat01 --network mynet tomcat
1318c3bab6fcaacd873de517ee0442957c73d4739d76def7eff25a1dea9b235e
[root]# docker run -d -P --name tomcat02 --network mynet tomcat
0e660fa4e743a90f441edf6e743fe6416e4e2f86ea049392c51c65d9f2ed440d
接下来查看我们的自定义网络: 发现两个容器已经添加成功
"Containers": {
"0e660fa4e743a90f441edf6e743fe6416e4e2f86ea049392c51c65d9f2ed440d": {
"Name": "tomcat02",
"EndpointID": "af41cfff0fa000de232d9676439c6509612f1a2c6d10f6155fe5a984bdc72188",
"MacAddress": "02:42:c0:a8:00:03",
"IPv4Address": "192.168.0.3/16",
"IPv6Address": ""
},
"1318c3bab6fcaacd873de517ee0442957c73d4739d76def7eff25a1dea9b235e": {
"Name": "tomcat01",
"EndpointID": "261eb41c7c6b01cefbe2ae56b8e06ab0bc87fdcbba8ae73d7b50817a831d1c42",
"MacAddress": "02:42:c0:a8:00:02",
"IPv4Address": "192.168.0.2/16",
"IPv6Address": ""
}
},
}
# 在这里我们可以通过容器名 ping 通,可以不使用--link
[root]# docker exec -it tomcat01 ping tomcat02
PING tomcat02 (192.168.0.3) 56(84) bytes of data.
64 bytes from tomcat02.mynet (192.168.0.3): icmp_seq=1 ttl=64 time=0.105 ms
64 bytes from tomcat02.mynet (192.168.0.3): icmp_seq=2 ttl=64 time=0.086 ms
我们自定义的网络docker都已经帮我们维护好了对应的关系,推荐我们平时使用这种网络!
好处:搭建多个子网,每个集群使用一个子网
redis: -不同的集群使用不同的网络,保证集群是安全和健康的
mysql:-不同的集群使用不同的网络,保证集群是安全和健康的
网络联通
#测试打通 (网卡与网卡之间不可以,但是容器与网卡之间可以)
[root]docker network connect mynet mysql01
#联通之后就将 mysql01 放到了 mynet 下
#一个容器两个ip地址 ==> 阿里云服务: 公网ip 私网ip
假设要跨网络操控别人,就要使用docker network connect 连通!
树苗如果因为怕痛而拒绝修剪,那就永远不会成材。