docker的网络

一、docker的网络

1、docker 的网络模式

Docker 支持 5 种 网络模式

1.  bridge
默认网络,Docker启动后默认创建一个docker0网桥,默认创建的容器也是添加到这个网桥中。

2.  host
容器不会获得一个独立的network namespace,而是与宿主机共用一个。

3.  none
获取独立的network namespace,但不为容器进行任何网络配置。

4.  container
与指定的容器使用同一个network namespace,网卡配置也都是相同的。

5.  自定义
自定义网桥,默认与bridge网络一样。
docker 的 bridge 网络

Docker 容器默认使用 bridge 模式的网络。其特点如下:

使用一个 linux bridge,默认为 docker0
使用 veth 对,一头在容器的网络 namespace 中,一头在 docker0 上
该模式下Docker Container不具有一个公有IP,因为宿主机的IP地址与veth pair的 IP地址不在同一个网段内
Docker采用 NAT 方式,将容器内部的服务监听的端口与宿主机的某一个端口port 进行“绑定”,使得宿主机以外的世界可以主动将网络报文发送至容器内部
外界访问容器内的服务时,需要访问宿主机的 IP 以及宿主机的端口 port
NAT 模式由于是在三层网络上的实现手段,故肯定会影响网络的传输效率。
容器拥有独立、隔离的网络栈;让容器和宿主机以外的世界通过NAT建立通信

host 模式

docker run -tid --name centos_host1_test --net host centos_test

会与宿主机公用一个网络

none 模式

docker run -tid --name centos1_none --net none centos_test

这个模式下面是单独的网络,没有IP 地址

 

二、docker容器网络访问原理

Linux IP 信息包过滤原理:
Docker主要通过netfilter/iptables实现网络通信。
iptables由netfilter和iptables组成,netfilter组件是Linux内核集成的信息包过滤系统,它维护一个信息包过滤表,这个表用于控制信息包
过滤处理的规则集。而iptables只是一个在用户空间的工具,用于增删改查这个过滤表的规则。

2.1、容器网络访问原理

容器 访问外部
# iptables -t nat -nL
Chain POSTROUTING (policy ACCEPT)
target prot opt source destination
MASQUERADE all -- 172.17.0.0/16 0.0.0.0/0

外部 访问容器
# iptables -t nat -nL
Chain DOCKER (2 references)
target prot opt source destination
DNAT tcp -- 0.0.0.0/0 0.0.0.0/0 tcp dpt:88 to:172.18.0.2:80

创建一个容器:

docker run -ti --name centos_test /bin/bash 

2.2、桥接宿主机网络与配置固定IP地址

临时网络

# 网桥名称
br_name=br0
# 添加网桥
brctl addbr $br_name
# 给网桥设置IP
ip addr add 192.168.0.211/24 dev $br_name
# 删除已存在的eth0网卡配置
ip addr del 192.168.0.211/24 dev eth0
# 激活网桥
ip link set $br_name up
# 添加eth0到网桥
brctl addif $br_name eth0
# 添加路由
ip route add default via 192.168.0.1 dev br0

-----

还需要在Docker启动时桥接这个网桥:
# vi /usr/lib/systemd/system/docker.service
ExecStart=/usr/bin/dockerd -b=br0
# systemctl restart docker

永久生效:
# vi /etc/sysconfig/network-scripts/ifcfg-eth0
DEVICE=eth0
TYPE=Ethernet
ONBOOT=yes
BRIDGE=br0
# vi /etc/sysconfig/network-scripts/ifcfg-br0
DEVICE=br0
TYPE=Bridge
ONBOOT=yes
BOOTPROTO=static
IPADDR=192.168.0.211
NETMASK=255.255.255.0
GATEWAY=192.168.0.1
DNS1=114.114.114.114
配置 固定 IP
C_ID=$(docker run -itd --net=none ubuntu)
C_PID=$(docker inspect -f '{{.State.Pid}}' $C_ID)
# 创建network namespace目录并将容器的network namespace软连接到此目录,以便ip netns命令读取
mkdir -p /var/run/netns
ln -s /proc/$C_PID/ns/net /var/run/netns/$C_PID
# 添加虚拟网卡veth+容器PID,类型是veth pair,名称是vp+容器PID
ip link add veth$C_PID type veth peer name vp$C_PID
# 添加虚拟网卡到br0网桥
brctl addif br0 veth$C_PID
# 激活虚拟网卡
ip link set veth$C_PID up
# 设置容器网络信息
IP='192.168.0.123/24'
GW='192.168.0.1'
# 给进程配置一个network namespace
ip link set vp$C_PID netns $C_PID
# 在容器进程里面设置网卡信息
ip netns exec $C_PID ip link set dev vp$C_PID name eth0
ip netns exec $C_PID ip link set eth0 up
ip netns exec $C_PID ip addr add $IP dev eth0
ip netns exec $C_PID ip route add default via 192.168.1.1

备注:这种方法一般不采用
采取的方法: 

pipework 工具配置容器固定 IP
git clone https://github.com/jpetazzo/pipework.git
cp pipework/pipework /usr/local/bin/
docker run -tid --name centos1_none --net none centos_test
pipework br0 centos1_none 172.17.100.11/24@172.17.100.2
进入这个容器
docker exec -ti e95dff5 bash

这个只是临时配置的,重启容器就丢了,docker 不建议这样做。

 

posted @ 2019-05-26 11:55  努力哥  阅读(239)  评论(0)    收藏  举报