容器技术是最近几年最流行的技术之一,将程序所依赖的环境打包成一个镜像文件,并可以跨平台部署,真正做到了一次编译,处处运行,对研发和运维体系都产生了巨大的影响。
01 开篇
某天一元戎网络萌新正在学习Docker容器,他看见书上有段这样描述:
通过Docker镜像可以将运行环境固化,但最终运行的时候还需要运行时的隔离技术,一种是空间的隔离,另一种是资源的隔离。先说一下空间的隔离,每一个容器都有自己独立的命名空间,主要包括网络命名空间......
萌新:“嗯?是对每个容器的网络环境进行隔离吗?是怎么实现的呢?”
萌新思索一阵子后——
萌新:“算了,想不明白,找波哥问问去”
02 Docker的网络方案
此时的波哥正在家里悠闲逛着Stack Overflow,突然电话响起。
萌新:“喂!波哥,在干嘛呢?问你些小问题。”
波哥:“正在养生冲浪呢,啥问题你说。”
萌新:“就想找你了解下Docker的网络方案,我家断网了!”
波哥:“好吧,那我给你讲讲吧!”
Docker的默认网络模式可以分为:Host 模式、Bridge 模式或者 None 模式。
Host 模式就是和宿主机共享协议栈,那么就可以在容器里面看到宿主机的网络 IP 等信息,可以通过 localhost 访问宿主机上面的服务。
这里需要注意下,在容器内启动服务需要避免和宿主机的端口冲突。
None 模式是不连接网络的,这个主要有两个用途——
a. 是有些业务场景,容器是不需要联网的,例如一些本地批处理任务等;
b. 是可以让用户自己添加网络,用户可以通过 ovs-docker 等工具为容器自定义网卡。
而 Bridge 模式是Docker的默认网络模式,也是最常用的模式,这种模式下的容器会被分配一个172.17.0.0/16网段的IP。并且容器和主机/其他Bridge模式容器可以互相访问,容器也能访问外网,但是外网不能直接访问容器。
萌新:“那Bridge模式是怎么实现的呢?”
03 背景知识
波哥:“你了解过Network Namespace、veth、linux的bridge模块、Netfilter...吗?”
萌新:“没有诶,这是啥?”
波哥:“好吧,那给你讲Bridge模式实现原理前,得先给简单介绍下这几个前置知识点啦!”
Network Namespace
Network Namespace 是linux内核提供的一种资源隔离机制,它能创建多个隔离的网络空间,它们有独自的网络栈信息。不管是虚拟机还是容器,运行的时候仿佛自己就在独立的网络中。
我们可以使用 ip netns 去管理namespace,例如可以使用 ip netns add 去创建一个namespace,被创建的network namespace 会出现在 /var/run/netns 下;
使用