(五)docker的网络

本文涉及的产品
云防火墙,500元 1000GB
公网NAT网关,每月750个小时 15CU
简介: (这里只考虑单机通信,不考虑集群跨宿主通信) 网络模式 Docker支持的五种网络模式查看docker支持的网络模式docker network ps Brige 这个是默认网络 , docker的主进程会默认创建一个docker0的网卡,docker0与宿主机的网卡是桥接的,容器的默认网段是172.0.0.1/ 因此宿主机与容器可以互ping,但是外部不能直接访问到。

(这里只考虑单机通信,不考虑集群跨宿主通信)

网络模式

Docker支持的五种网络模式
查看docker支持的网络模式
docker network ps

Brige
这个是默认网络 , docker的主进程会默认创建一个docker0的网卡,docker0与宿主机的网卡是桥接的,容器的默认网段是172.0.0.1/ 因此宿主机与容器可以互ping,但是外部不能直接访问到。但是可以通过iptables规则转发到里面

host
容器不会获得一个独立的network namespace 而是与宿主机公用一个IP 。实际没与网络命名空间隔离,不需要做net转发,跟直接在真机上跑服务没有什么区别。

none
获取独立的network namespace 但不为容器进行任何配置

container
与指定的容器使用同一个network namespace 网卡配置也相同

自定义
自定义网桥 默认与brige网络一样

之前有一次公司某测试服务器上的规则全部失效,容器之间不能通信,于是重装网桥
yum -y remove firewalld  >/dev/null 2>&1
echo "firewalld remove success"
yum -y install iptables-service > /dev/null 2>&1
echo "iptables install success"
yum install  bridge-utils > /dev/null 2>&1
echo "echo bridge-utils install success"
iptables -t nat -F
ifconfig docker0 down
brctl delbr docker0

默认的桥接模式其实就是弄明白两个问题
1.容器如何与真机建立通信?
Countainer(eth0)->veth容器虚拟网卡->桥接网卡docker0(172.0.0.0/16)
docker0桥接到真机eth0上 到此解决了docker与真机的通信
2.外部请求如何到docker内部呢?
eth0 -> NAT ->docker0

容器网络的访问原理

Linux防火墙概述
Linux防火墙实际指的是Linux下的Netfilter/Iptables。
Linux内核集成的IP信息包过滤系统。
Netfilter/Iptables 信息包过滤系统可以当成一个整体,netfilter是内核的模块实现,iptables是对上层操作工具。

Netfilter是Linux核心中的一个通用架构,工作于内核空间。

Netfilter支持一下方式对数据包进行分类:

源IP地址
目标IP地址
使用接口
使用协议
端口号
连接状态
其提供了一系列的表(tables),每个表由若干个链(chains)组成,每条链可以由一条或若干条规则(rules)组成,其规则由一些信息包过滤表组成,这些表包含内核用来控制信息包过滤处理的规则集。

chain的本质是Netfilter定义的不同过滤点。总共定义了5个过滤点。INPUT,FORWARDING,OUTPUT,PREROUTING,POSTROUTIONG。

Table的本质是Netfilter定义的不同功能的划分。

filter用于执行基本过滤。

nat是对数据IP进行修改。

mangle是对数据包进行高级修改。

不同的Table只能用于特定的Chain。

Iptables 是一个管理内核包过滤的工具,可以用来配置核心包过滤表格中的规则。运行于用户空间。

1.1 Linux防火墙的应用
Linux防火墙在企业应用中非常有用,举例如下:

中小企业与网吧里有iptables作为企业的NAT路由器,可以用来代替传统路由器,而节约成本。
IDC机房一般没有硬件防火墙,IDC机房的服务器可以用Linux防火墙代替硬件防火墙。
iptables可以结合squid作为企业内部上网的透明代理。传统代理需要在浏览器里配置代理服务器信息,而iptables+squid的透明代理则可以把客户端的请求重定向到代理服务器的端口。客户端不要作任何设置,而感觉不到代理的存在。
将iptables作为企业NAT路由器时,可以使用iptables的扩展模块屏蔽P2P流量,还可以禁止非法网页。
iptables可以用于外网IP向内网IP映射。
iptables可以轻松防止轻量级DOS攻击,比如ping攻击及SYN洪水攻击。
综述,Iptables有两种应用模式:主机防火墙,NAT路由器。

参考:
http://www.cnblogs.com/shijiaqi1066/p/3812510.html

四表五链:
表: filter(过滤)

    nat(地址转换)                
    mangle(拆包 改包 封装)
    raw (数据包状态跟踪)

链(对应上表):
input output forword
prerouting postrouting outputing
input output prerouting postrouting output
prerouting output

docker能访问到外部的原因:
iptables -t nat -A POSTROUTING -s 172.17.0.0/16 -j MASQUERADE
注意 MASQUERADE与snat的区别是可以动态的找到你的宿主机的网卡并且将请求转发出去
同样可以换一种写法
iptables -t nat POSTROUTING -s 172.0.0.10/24 -j NAT --to 真机ip

容器桥接宿主机以及容器配置固定IP

1、容器默认网络配置过程
先创建一个docker0的网桥,使用Veth pair创建一对虚拟网卡,一端放到新创建的容器中,并重命名eth0,另一端放到宿主机中,以veth+随机7个字符串名字命名,并将这个网络设备加入到docker0网桥中,网桥自动为容器分配一个IP,并设置docker0的IP为容器默认网关。同时在iptables添加SNAT转换网桥段IP,以便容器访问外网。
Veth par是用于不同network namespace间进行通信的方式,而network namespace是实现隔离网络。

2、容器桥接宿主机网络
关闭docker并设置桥接模式:
yum -y install bridge-utils
sudo service docker stop

关闭默认网桥

$ sudo ip link set dev docker0 down

删除默认网桥

$ sudo brctl delbr docker0

创建桥接网卡:
$ sudo brctl addbr br0 #创建网桥
$ sudo vi /etc/network/interfaces #将原有宿主机IP配置到新创建的网桥上

auto eth0
iface eth0 inet manual
auto br0
iface br0 inet static

address 192.168.10.10   #宿主机IP
netmask 255.255.255.0
gateway 192.168.10.1
dns-nameservers 192.168.10.1

$ sudo /etc/init.d/networking restart
重启网卡后,再通过ifconfig命令查看,多了br0网桥,并且IP地址也绑定在了上面。

修改docker桥接网桥,并重启

sudo vi /etc/default/docker
DOCKER_OPTS="-b=br0"
sudo service docker restart
接下来启动一个容器,先不配置网络信息:
sudo docker run -itd --name=ubuntu_test --net=none ubuntu

不配置ip的原因是:容器启动后自动随机分配一个网桥段的IP,这个IP不管你宿主机网络中是否已经分配,它都会根据自身的算法来分配IP,docker有自己的一套分配算法。
所以既然选择桥接网络,就要事先规划好IP分配。

4、创建容器没配置网络,该怎么配置呢?
pipework是一个LXC网络管理工具,用shell写的,有200多行代码。可以给容器配置固定IP地址:
$ git clone https://github.com/jpetazzo/pipework.git
sudo cp pipework/pipework /usr/local/bin/
sudo pipework br0 ubuntu_test 192.168.18.29/24@192.168.18.1
Warning: arping not found; interface may not be immediately reachable
这一步是给配置容器网络并连接网桥,@左边是与宿主机同网段IP,右边是网关。
提示arping命令没发现,可以通过apt-get install arping来安装。
sudo brctl show #查看虚拟网卡veth开头的已加入网桥
sudo docker attach ubuntu_test

进入容器用ifconfig命令查看,IP信息已经配置上,通过ping百度及同网段IP是相通的,配置成功。

pipework工具怎么实现配置的IP呢?
pipework是通过ip netns exec进入容器的net命名空间,来配置容器net命名空间的网络参数。

博客地址:http://lizhenliang.blog.51cto.com

5、简单讲下怎么SSH连接容器
根据上面的配置后,简单配置下SSH服务即可实现SSH远程登录:

进入容器

$ sudo docker attach ID/NAME

安装SSH

$ sudo apt-get update
$ sudo apt-get install openssh-server

修改SSH配置文件(/etc/ssh/sshd_config)

PermitRootLogin yes #运行root登录
UsePAM no #不使用验证模块

启动SSH

/etc/init.d/ssh restart

查看是否启动成功

ps -ef |grep ssh
此时已经可以像连接虚拟机那样SSH连接容器了!

在docker默认网络模式情况下,由于容器是docker分配docker0网段的IP,这时又该怎么SSH连接容器呢?
当创建新容器时有选项可以指定宿主机到容器端口,那就是-p选项。

例如:sudo docker run -itd --name=ubuntu_test -p 2222:22 ubuntu
2222是宿主机端口,22是容器内部ssh服务端口。这样就可以通过"ssh -p 2222 root@宿主机IP"连接容器了。不但ssh服务可以这样做,比如web、mysql等服务也同样方式实现容器对外提供服务。
当使用-p时,docker实际是在iptables做了DNAT规则,实现端口转发功能。可以使用iptables -t nat -vnL查看,出现最下面的一条记录:

sudo iptables -t nat -A PREROUTING -d 192.168.18.231 -p tcp --dport 2222 -j DNAT --to 172.17.0.1:22

6、容器跨主机通信
由于docker自身还未支持跨主机容器通信,需要借助docker网络开源解决方案。这里利用OpenVSwich即开放式虚拟交换机实现,简称OVS,OVS在云计算领域应用广泛,值得我们去学习使用。
什么是OpenVSwich?
OpenVSwich是一种开源软件,通过软件的方式实现二层交换机功能,专门管理多租赁云计算网络环境,提供虚拟网络中的访问策略、网络隔离、流量监控等。
既然是虚拟交换机,自然与传统的物理交换机有着相同的特性,操作中可以按照理解物理交换机的方式去操作,有助于对虚拟交换机的认识。
实验环境:
操作系统:ubuntu14.04_x64
宿主机1:192.168.18.16 容器网段:172.17.1.0/24
宿主机2:192.168.18.17 容器网段:172.17.2.0/24
开始创建网络环境(两台宿主机做相同的操作,部分要适当修改,已注明):

安装openvswitch

$ sudo apt-get install openvswitch-switch bridge-utils

添加网桥obr0(理解为添加了一个交换机)

$ sudo ovs-vsctl add-br obr0

将gre0接口加入到网桥obr0, 远程IP写对端IP(创建一个GRE隧道并添加到网桥中)

$ sudo ovs-vsctl add-port obr0 gre0 -- set Interface gre0 type=gre options:remote_ip=192.168.18.17

查看ovs信息

$ sudo ovs-vsctl show

添加docker网桥

$ sudo brctl addbr kbr0

将obr0网桥加入kbr0网桥,并启动

$ sudo brctl addif kbr0 obr0
$ sudo ip link set dev kbr0 up

查看网桥信息

$ sudo brctl show

添加docker网桥配置信息(18.17宿主机按照这种方式配置自己)

$ vi /etc/network/interfaces
auto eth0
iface eth0 inet static

address 192.168.18.16
netmask 255.255.255.0
gateway 192.168.18.1
dns-nameservers 192.168.18.1

auto kbr0
iface kbr0 inet static

address 172.17.1.1
netmask 255.255.255.0
gateway 172.17.1.0

删除默认docker网桥

sudo ip link set dev docker0 down
sudo ip link delete dev docker0

关键一点,添加路由条目,否则无法通讯(同样在18.17上面这样添加路由,写对端IP)

via从哪个网关出去,写对端IP。dev由哪个设备出去

$ sudo ip route add 172.17.2.0/24 via 192.168.18.17 dev eth0

至此容器跨主机通信配置完成,两边各创建一个容器来验证吧!

里面涉及到一个GRE隧道,什么是GRE隧道呢?
GRE即通用路由协议封装,隧道技术是一种封装技术,将网络层协议(如IP)的数据报文进行封装,使这些封装的数据报文能够在另一个网络层协议中传输。可以看作是一个虚拟点到点连接,所以建立隧道时,要配置好隧道源地址和目的地址。

相关文章
|
2月前
|
Docker 容器
docker swarm启动服务并连接到网络
【10月更文挑战第16天】
36 5
|
2月前
|
调度 Docker 容器
docker swarm创建覆盖网络
【10月更文挑战第16天】
35 5
|
2月前
|
负载均衡 网络协议 关系型数据库
docker swarm 使用网络启动服务
【10月更文挑战第15天】
32 4
|
2月前
|
应用服务中间件 nginx Docker
docker swarm创建覆盖网络
【10月更文挑战第14天】
25 3
|
2月前
|
数据安全/隐私保护 Docker 容器
docker swarm创建网络
【10月更文挑战第15天】
28 1
|
2月前
|
Docker 容器
docker swarm 在服务中使用网络
【10月更文挑战第14天】
31 2
|
28天前
|
Docker 容器
【赵渝强老师】Docker的None网络模式
Docker容器在网络方面实现了逻辑隔离,提供了四种网络模式:bridge、container、host和none。其中,none模式下容器具有独立的网络命名空间,但不包含任何网络配置,仅能通过Local Loopback网卡(localhost或127.0.0.1)进行通信。适用于不希望容器接收任何网络流量或运行无需网络连接的特殊服务。
|
28天前
|
Docker 容器
【赵渝强老师】Docker的Host网络模式
Docker容器在网络环境中是隔离的,可通过配置不同网络模式(如bridge、container、host和none)实现容器间或与宿主机的网络通信。其中,host模式使容器与宿主机共享同一网络命名空间,提高性能但牺牲了网络隔离性。
|
28天前
|
Kubernetes Docker 容器
【赵渝强老师】Docker的Container网络模式
Docker容器在网络环境中彼此隔离,但可通过配置不同网络模式实现容器间通信。其中,container模式使容器共享同一网络命名空间,通过localhost或127.0.0.1互相访问,提高传输效率。本文介绍了container模式的特点及具体示例。
|
28天前
|
Linux Docker 容器
【赵渝强老师】Docker的Bridge网络模式
本文介绍了Docker容器的网络隔离机制及其四种网络模式:bridge、container、host和none。重点讲解了默认的bridge模式,通过示例演示了如何创建自定义bridge网络并配置容器的网络信息。文中还附有相关图片和视频讲解,帮助读者更好地理解Docker网络的配置和使用方法。