容器网路
docker 容器网络
本质:
利用了linux 上的 网络命名空间和虚拟网络设备 。 docker 用的是虚拟接口(虚拟网络)
三个网卡
虚拟接口:
转发效率极高,即数据转发通过数据复制来实现。
原理:
在本地主机和容器内分别创建一个虚拟接口,并让他们彼此连通(veth pair)
工作方式:
-
新建一对 虚拟接口,分别放在本地主机和新容器的命名空间中
-
本地主机的一个虚拟接口连接在 docker0 网桥 或其他网桥上,如 veth1234
-
另一端放在 新创建的容器中,并修改名字为 eth0,仅在容器命名空间可见
-
从网桥可用地段中获取一个空闲地址分配给eth0,并配置默认路由网关为 docker0 的 ip地址
-
之后容器就通过eth0 这个虚拟网卡来 连接其他容器和访问外部。 可通过 docker network 来查看
-
nat:直连,docker0和物理机值直连
-
容器删除后,虚拟网桥就会消失
简单来说:启动一个容器,docker 服务就会给 容器分配一个ip,并且安装了docker 就会有一个docker0网桥,用的是 evth_pair 技术
evth_pair:就是成对出现的虚拟设备端口,一端连着协议,一端彼此连接。我们经常用其来充当桥梁,连接虚拟网络设备。
所有容器在不指定网络的情况下,都是docker0 路由的,docker 会给我们容器分配一个可用ip
255.255.0.1/16
二进制表示 00000000.00000000.00000000.00000000
16表示的是域,意味着前两段是255,只能在后面取值,范围是255*255-2.
如果是24,就是255.255.255.1
网络模式
可以通过 docker network ls可以查看docker网络
一共四种网络模式
-
host
容器不会获得自己的 网络命名空间,而是和宿主机共用一个命名空间。不使用虚拟网络,用的主机的ip和端口。(仅网络)
使用主机的ip和端口能够和外界直接通信,优点是网络性能好。缺点是网络的隔离性能不好
配置 –net=host
- container
和host类似,容器本身不会再创建新的命名空间,而是 和 之前已经创建过的容器共享 命名空间。(仅网络存在共享)
配置 net=container:NAME_or_ID
- none
容器拥有自己的 网络命名空间,但是没有网络配置(网卡,IP,路由),需要我们自己添加。这种网络类型没办法联网,封闭的网络能更好的保证容器的安全性。
配置:–net=none
- bridge
默认模式
容器创建时会在主机上创建一个 虚拟网桥 docker0 ,当前主机上的docker 会连接到这个网桥(docker0),docker0 分配ip给 容器。并设置docker0的ip为容器的网关。
主机上创建一对 veth pair 设备,docker 将 此设备的一端 放在新创建的容器中,命名为eth0,另一端放在主机中,以 eth*** 命名。并将这个网络放在 docker0 网桥中。 通过 brctl show 命令查看
使用docker run -p时,docker实际是在iptables做了DNAT(目标地址转换)规则,实现端口转发功能。可以使用iptables -t nat -vnL查看。
iptables 相关介绍 : https://www.cnblogs.com/liang2580/articles/8400140.html
配置
配置容器DNS和主机名
容器内的主机名和DNS 都是通过配置文件来维持的
- /etc/resolv.conf
- /etc/hostname
- /etc/hosts
容器内使用 mount 命令 可以查看挂载信息
resolv文件内容和主机上该目录下文件内容一致
hosts 记录容器 地址和名称
hostname 记录容器的主机名
容器内修改配置文件
容器运行时可手动修改以上三个配置文件,但是修改是临时的,仅在当时运行时有效,容器重启后就会失效。(docker 1.2.0 之后)
永久修改容器参数
要想永久更改容器配置,可以在容器创建或者启动的时候,通过参数来修改。
- 指定主机名 -h HOSTNAME 或者 hostname=HOSTNAME 该值会被写到 hostname 和 hosts 文件中,但是这个名字只能在容器内看到,容器外看不到(比如 docker ps)
- 记录其他容器主机名 –link = CONTAINER_NAME:NAME 。 添加一个关联容器到 hosts 文件中。容器可以直接使用主机名来进行通讯
- 指定DNS 服务器 –dns=IP_ADDRESS 添加DNS 服务器到容器内 resolv 文件中。容器 会用指定的服务器去解析所有不在 /etc/hosts 中得主机名
- 指定搜索域 –dns-search = DOMAIN 。 设定容器搜索域。
容器间通信
三种方式 ip、docker dns server 、 joined
IP 通信
前提,拥有属于同一个网络的网卡
容器创建时通过 --network 指定相应的网络,或者通过 docker network connect 将现有容器加到 指定网络
Docker DNS Server 通信
创建时可能不知道具体IP,无法设置IP 访问。就可以通过容器自带的DNS 服务解决
容器启动时 通过 --name 为容器的名字即可
注意:docker DNS 服务必须在 user-defined 中使用,默认的 bridge 无法使用
joined 容器
joined 使两个或者多个容器实现 网络共享。joined 容器之间通过 127.0.0.1 通信