开始了解 docker
一开始,咱们思考一下,宿主机怎么和容器通信呢?
说容器之间是互相隔离的,那么他们是否能够通信?又是如何通信的呢?
开始摸索
咱们先来看看咱环境中的镜像都有些啥,有 xmtubuntu
# docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
xmtubuntu latest c3e95388a66b 38 seconds ago 114MB
再来看看宿主机的网卡信息
ip addr
来查看咱们宿主机的网卡信息
咱们发现有一个 docker0
,是因为咱们的宿主机下面装置了 docker 的服务,docker 会给我生成一个虚构网卡,图中的这个 docker0
就是虚构网卡信息
创立并启动一个 docker 命名为 ubuntu1
docker run -it --name ubuntu1 -P xmtubuntu
查看一下宿主机网卡信息
查看宿主机的网卡信息
再查看 ubuntu1
的网卡信息,docker 也会默认给咱们的容器调配ip
地址
能够发现宿主机的网卡信息 docker0
上面多了 117: veth838e165@if116:
,ubuntu1
的网卡信息上也正好有116: eth0@if117
咱们发现这些 veth
的编号是成对呈现的,咱们的宿主机就能够和 ubuntu1
进行通信了
应用宿主机(docker0)和 ubuntu1
相互 ping
docker0
pingubuntu1
ok
ubuntu1
pingdocker0
,同样的 ok
咱们能够尝试再创立并启动一个 docker 命名为 ubuntu2,办法和上述完全一致
# docker run -it -P --name ubuntu2 xmtubuntu
进入容器,应用 ip a
查看到 ubuntu2
的网卡信息
宿主机下面查看网信息
宿主机下面又多了一个 veth,119: veth0b29558@if118
ubuntu2
上的网卡信息是118: eth0@if119
,他们同样是成对呈现的,小伙伴看到这里应该明确了吧
ubuntu1
ping ubuntu2
呢?
ubuntu1 对应 172.18.0.2
ubuntu2 对应 172.18.0.3
# docker exec -it ubuntu1 ping 172.18.0.3
PING 172.18.0.3 (172.18.0.3) 56(84) bytes of data.
64 bytes from 172.18.0.3: icmp_seq=1 ttl=64 time=0.071 ms
64 bytes from 172.18.0.3: icmp_seq=2 ttl=64 time=0.070 ms
64 bytes from 172.18.0.3: icmp_seq=3 ttl=64 time=0.077 ms
依然是能够通信,十分 nice
原理是什么?
上述的摸索,咱们发现宿主机创立的容器,都能够间接 ping
通宿主机,那么他们的原理是啥呢?
仔细的 xdm 应该能够看进去,上述的例子中,veth
是成对呈现的,上述宿主机和容器可能进行网络通信,得益于这个技术veth-pair
veth-pair
veth-pair 是一对虚构设施接口,他们都是成对呈现的,一段连着协定,一段彼此相连
正是因为这个个性,veth-pair
在此处就是充当了一个桥梁,连贯各种虚构设施
通过上图咱们能够得出如下论断:
ubuntu1
和ubuntu2
他们是专用一个路由器,也就是 docker0,ubuntu1 能 ping 通ubuntu2
是因为 docker0 帮忙其转发的- 所有的容器在不指定路由的状况下,都是以 docker0 作为路由,docker 也会给咱们的容器调配一个可用的 ip
- docker0 是在宿主机下面装置 docker 服务就会存在的
那么通过上图咱们就晓得,容器和宿主机之前是通过桥接的形式来买通网络的。
Dcoker 中所有的网络接口都是虚构的,因为虚构的转发效率高呀,当咱们删除某一个容器的时候,这个容器对应的网卡信息,也会被随之删除掉
那么咱们能够思考一下 ,如果都是通过找 ip
地址来通信,如果 ip
变动了,那么咱们岂不是找不到正确的容器了吗?咱们是否能够通过服务名来拜访容器呢?
–link
当然是能够的,当咱们在创立和启动容器的时候加上 –link
就能够达到这个成果
咱们再创立一个容器 ubuntu3
,让他 link 到 ubuntu2
# docker run -it --name ubuntu3 -P --link ubuntu2 xmtubuntu
# docker exec -it ubuntu3 ping ubuntu2
PING ubuntu2 (172.18.0.3) 56(84) bytes of data.
64 bytes from ubuntu2 (172.18.0.3): icmp_seq=1 ttl=64 time=0.093 ms
64 bytes from ubuntu2 (172.18.0.3): icmp_seq=2 ttl=64 time=0.085 ms
64 bytes from ubuntu2 (172.18.0.3): icmp_seq=3 ttl=64 time=0.092 ms
64 bytes from ubuntu2 (172.18.0.3): icmp_seq=4 ttl=64 time=0.073 ms
很显著,咱们能够到看到 ubuntu3
能够通过服务名 ubuntu2
间接和 ubuntu2
通信,然而反过来是否能够呢?
# docker exec -it ubuntu2 ping ubuntu3
ping: ubuntu3: Name or service not known
不行?这是为什么呢?
咱们来查看一下 ubuntu3
的本地 /etc/hosts
文件就分明了
看到这里,这就分明了 link 的原理了吧,就是在本人的 /etc/hosts
文件中,退出一个 host
而已,这个知识点咱们能够都知悉一下,然而这个 link 还是好搓,不好,他须要在创立和启动容器的时候应用,用起来不不便
那么咱们有没有更好的方法的呢?
自定义网络
能够应用 docker network ls
查看宿主机 docker 的网络状况
:~# docker network ls
NETWORK ID NAME DRIVER SCOPE
8317183dfc58 bridge bridge local
997107487c6b host host local
ab130876cbe6 none null local
网络模式
- bridge
桥接,docker0 默认应用 bridge 这个名字
- host
和宿主机共享网络
- none
不配置网络
- container
容器网络连通,这个模式用的非常少,因为局限性很大
当初咱们能够自定义个网络,来连通两个容器
自定义网络
自定义一个 mynet 网络
# docker network create --driver bridge --subnet 192.168.0.0/16 --gateway 192.168.0.1 mynet
9a597fc31f1964d434181907e21ff7010738f3f7dc35ba86bf7434f05a6afc4a
- docker network create
创立一个网络
- –driver
指定驱动是 bridge
- –subnet
指定子网
- –gateway
指定网关
此处咱们设置子网是 --subnet 192.168.0.0/16
,网关是192.168.0.1
,那么咱们剩下能够应用的ip
就是 192.168.0.2 – 192.168.255.254
,192.168.255.255
是播送地址
清空已有的容器
清空所有测试的容器,减去烦扰
创立并启动 2 个容器,别离是 ubuntu1 和 ubuntu2
# docker run -it -P --name ubuntu1 --net mynet xmtubuntu
# docker run -it -P --name ubuntu2 --net mynet xmtubuntu
此时咱们能够查看一下宿主机的网卡信息,并验证两个容器间接通过容器名字是否能够通信
咱们思考一下自定义网络的益处
咱们自定义 docker 网络,曾经帮咱们保护好了对应关系,这样做的益处是容器之间能够做到网络隔离,
例如
一堆 redis 的容器,应用 192.168.0.0/16 网段,网关是 192.168.0.1
一堆 mongodb 的容器,应用 192.167.0.0/16 网段,网关是 192.167.0.1
这样就能够做到子网很好的隔离开来,不同的集群应用不同的子网,互不影响
那么子网间是否能够买通呢?
网络连通
两个不同子网内的容器如何连通了呢?
咱们相对不可能让不同子网的容器不通过路由的转发而间接通信,这是不可能的,子网之间是互相隔离的
然而咱们有方法让 ubuntu3 这个容器通过和 mynet 买通,进而转发到 ubuntu1 或者 ubuntu2 中就能够了
买通子网
咱们查看 docker network 的帮忙手册
docker network -h
能够应用 docker network connect
命令实现,在查看一下帮忙文档
# docker network connect -h
Flag shorthand -h has been deprecated, please use --help
Usage: docker network connect [OPTIONS] NETWORK CONTAINER
Connect a container to a network
开始买通
docker network connect mynet ubuntu3
这个时候咱们能够查看一下 mynet 网络的详情
# docker network inspect mynet
能够看到在 mynet 网络上,又减少了一个容器,ip 是 192.168.0.4
没错,docker 解决这种网络买通的事件就是这么简略粗犷,间接在 ubuntu3 容器上减少一个虚构网卡,让 ubuntu3 可能和 mynet 网络买通
宿主机当然也相应的多了一个veth
当初,要跨网络操作他人的容器,咱们就能够应用 docker network connect
的形式将网络买通,开始干活了
大家对网络还感兴趣吗,哈哈,对于 docker 的前几期文章链接如下,能够逐渐学习,缓缓深刻,多多回顾
【Docker 系列】docker 学习 五,咱们来看看容器数据卷到底是个啥
【Docker 系列】docker 学习 四,一起学习镜像相干原理
【Docker 系列】docker 学习 三,docker 初步实战和 docker 可视化管理工具试炼
【Docker 系列】docker 学习 二,docker 常用命令,镜像命令,容器命令,其余命令
【Docker 系列】docker 学习 一,Docker 的装置应用及 Docker 的根本工作原理 | 8 月更文挑战
参考资料:
docker docs
欢送点赞,关注,珍藏
敌人们,你的反对和激励,是我保持分享,提高质量的能源
好了,本次就到这里
技术是凋谢的,咱们的心态,更应是凋谢的。拥抱变动,背阴而生,致力向前行。
我是 小魔童哪吒,欢送点赞关注珍藏,下次见~