iptables/netfilter 与 路由表 docker 部署 flannel

iptables/netfilter

我们知道,Linux 网络协议栈非常高效,同时比较复杂。如果我们希望 在数据的处理过程中对关心的数据进行一些操作该怎么

做呢? Linux提供了一套机制来为用户实现自定义的数据包处理过程。

在Linux 网络协议栈中一组回调函数 挂节点,通过这些挂接的钩子函数可以在Linux网络栈处理数据包的过程中对数据包进行一些

操作,例如过滤,修改,丢弃等。整个挂节点技术叫做Netfilter 和 Iptables

Netfilter负责在内核中执行各种挂接的规则,运行在内核模式中;而Iptables是在用户模式下运行的进程,负责协助维护内核中Netfilter

的各种规则表。通过二者的配合来实现整个Linux 网络协议栈中灵活的数据包处理机制

 

Netfilter 可以在 的规则 点有 5个,分别 是 INPUT,OUTPUT , FORWARD, PREROUTING, POSTROUTING,这些 挂节点 能挂载的规则

也分 不同的类型 (也就是规则表Table) , 我们可以在不同类型的Table 中加入我们的规则。目前主要支持的Table 类型为:

RAW:

MANGLE:

NAT:

FILTER

 

当Linux协议栈的数据处理运行到挂节点时,它会依次调用挂接点上所有的挂钩函数,直到数据包的处理结构是明确地接收或者拒绝

 

 

处理规则

每个 规则的特性都分为以下 几 部分:

表类型 ( 准备干什么事情 ?)

什么挂接点 (什么时候起作用?)

匹配的参数是什么(针对什么样的数据包?)

匹配后有什么动作 (匹配后具体的操作是什么?)

 

 

 

匹配参数

匹配参数 用于 对数据包或者 TCP 数据连接的状态进行匹配。当有多个条件存在时,它们一起起作用,来达到只针对 某部分 数据进行修改的目的。

常见的匹配参数有:

流入,流出的网络接口;

来源,目的地址;

协议类型;

来源,目的端口。

 

 

匹配动作

一旦 有 数据 匹配上,就会执行相应的动作。动作类型既可以是标准的预定义 的几个动作,也可以是自定义的模块注册的动作,

或者是一个新的规则链,以便更好地组织一组动作

 

iptables 命令

iptables 命令用于协助用户维护各种规则。我们在使用kubernetes,Docker的过程中,通常都会去查看相关的Netfilter 配置。这里只

介绍一下如何查看规则表,详细的介绍请参照Linux的 iptables 帮助文档

查看 系统中已有 的规则的方法 如下。

iptables-save : 按照 命令的方式 打印 iptables 的内容

iptables-vnL : 以 另一种格式显示Netfilter 表的内容

 

 

 

-s : 匹配 源 IP 地址(即可匹配具体IP地址,也可以匹配一个网段地址)

-d : 匹配 目的IP 地址 (即可匹配具体IP地址,也可以是一个网段地址)

-m : 扩展 匹配 , 例 -m tcp -dport 22

-o 接口名: 匹配出接口

-i 接口名: 匹配入接口

 

动作 :

ACCEPT : 允许通过

DROP : 拒绝通过(悄悄丢弃)

REJECT : 明示 拒绝

DNAT : 目的ip 地址转换

SNAT :源 ip 地址转换

MASQUERADE : 源 ip 地址 伪装 (自动匹配出接口上的IP地址)

 

-i eth1 : 匹配封包进入的接口

-o eth0 :匹配封包离开的接口,结合-i,-o两个参数即可匹配封包的目的传送方向。

-p tcp: 匹配TCP协议的封包

--dport 80 : 匹配目的端口为80的封包,补充一点可搭配“!”来代表反向,如“—sport ! 80”代表匹配不是从Web发送的封包。

-j DROP 符合以上4个条件的封包丢弃

 

 

接下来,我们来分析几个例如

(1) 在刚刚启动Docker Daemon,并且 还没有启动任何 容器的时候,网络 协议栈的配置情况 如下

nat

 

第一条 把目标地址类型属于主机系统的本地网络地址的数据包,在数据包进入NAT表PREROUTING链时,都让它们直接jump到一个名为DOCKER的链

第二条 数据报文目标地址段不是 127.0.0.0/8,且是本地网络地址,则 执行 DOCKER 链这个动作

但是 此时 DOCKER 链为空,所有 前两条 是做了框架,并没有实际效果

-A PREROUTING -m addrtype -- dst-type LOCAL -j DOCKER

-A OUTPUT ! -d 127.0.0.0/8 -m addrtype --dst-type LOCAL -j DOCKER

 

 

# 若本地发出 的 数据包不是发往 docker0 的,都需要进行动态地址修改,将源地址从容器的地址 修改维宿主机网卡的IP地址,之后就可以发送给外面的网络了

-s 172.17.0.0/16 来自 172.17.0.0/16 网段

! -o docker0 数据报文的流出接口不是 docker0

-A POSTROUTING -s 172.17.0.0/16 ! -o docker0 -j MASQUERADE

 

 

 

 

filter

第一条 由 docker0接收到包 就执行 DOCKER 链这个动作

-A FORWARD -o docker0 -j DOCKER

 

第二条是说,接收到的数据包属于以前已经建立好的连接,那么允许直接通过。这样接收到的数据包自然又走回docker0,并中转到相应的容器

由 -o docker0 docker0 出去,说明有 一个程序 像docker 发送数据包,就是 docker0属于接收方

-A FORWARD -o docker0 -m conntrack -ctstate RELATED , ESTABLISHED -j ACCEPT

 

第三条是,docker0发出的包,如果需要Forward到非docker0的本地IP地址的设备,则是允许的,这样,docker0设备的包就可以根据

路由规则转到宿主机的网卡设备,从而访问外面的网络

- i docker0 由docker0 进去 , 说明这个 包 由 docker0 发出,docker0是发出方

! - o 不是由docker0出去 , 说明不是发送给docker0

-A FORWARD -i docker0 ! -o docker0 -j ACCEPT

 

第四条,docker0的包还可以中转给docker0本身,即连接在docker0网桥上的不同容器之间的通信也是允许的

-i docker0 有docker0 进去 ,

-o docker0 由docker0出去,

docker0 发送给 docker0

-A FORWARD -i docker0 -o docker0 -j ACCEPT

 

 

容器 启动后,并将 容器的5000端口地址 映射到 宿主机的 1180端口地址,路由表的 情况

nat

可以看 到多 了几条 规则

-A POSTROUTING -s 172.17.0.19/32 -d 172.17.0.19/32 -p tcp -m tcp --dport 5000 -j MASQUERADE

属于 172.17.0.19/32 的数据包 且 端口为0 的数据 包 ,都 动态修改

 

-A DOCKER ! -i docker0 -p tcp -m tcp --dport 1180 -j DNAT --to-destination 172.17.0.19:5000

本地发出的, 且 端口 为 1180 的数据包 都 发往 172.17.0.19:5000

 

filter

-A DOCKER -d 172.17.0.19/32 ! -i docker0 -o docker0 -p tcp -m tcp --dport 5000 -j ACCEPT

是 宿主机 像 docker0 网桥 发出 且 发往 172.17.0.19/32 这网段,都允许通过

 

 

 

linux 路由

linux 系统 包含一个完整的路由功能。当IP层在处理数据发送或者转发的时候,会使用路由表来决定发往哪里。

通常情况下,如果主机与目的主机直接相连,那么主机可以直接发送IP报文到目的主机,这个过程比较简单。例如,通过

点对点的链接或通过网络共享。如果主机与目的主机没有直接相连,那么主机会将IP报文发送给默认的路由器,然后由

路由器来决定往哪发送IP报文

路由功能由IP层维护的一张路由表来实现。当主机收到数据报文时,它用此表来决策接下来应该做什么操作。当从网络

侧接收到数据报文时,IP层首先会检查报文的IP地址是否与主机自身的地址相同。如果数据报文中的IP地址是主机自身的地址,

那么报文将被发送到传输层相应的协议中去。如果报文中的IP地址不是主机自身的地址,并且主机配置了路由功能,那么

报文将被转发,否则,报文将被丢弃

 

我们来看看 下面 控制台输出 的 信息

 

[root@linux-node1 ~]# route

Kernel IP routing table

Destination Gateway Genmask Flags Metric Ref Use Iface

default 192.168.255.2 0.0.0.0 UG 100 0 0 eth0

192.168.122.0 0.0.0.0 255.255.255.0 U 0 0 0 virbr0

192.168.255.0 0.0.0.0 255.255.255.0 U 100 0 0 eth0

[root@linux-node1 ~]# route -n

Kernel IP routing table

Destination Gateway Genmask Flags Metric Ref Use Iface

0.0.0.0 192.168.255.2 0.0.0.0 UG 100 0 0 eth0

192.168.122.0 0.0.0.0 255.255.255.0 U 0 0 0 virbr0

192.168.255.0 0.0.0.0 255.255.255.0 U 100 0 0 eth0

 

 

Destination: 目标网络和目标主机。Destination 为default(0.0.0.0)时,表示这个是默认网关

Gateway: 网关地址,0.0.0.0 表示表示当前记录对应的Destination跟本机在同一个网段,通信时不需要经过网关

Genmask: Destination 字段的网络掩码,Destination 是主机时需要设置为 255.255.255.255,是默认路由时会设置为 0.0.0.0

Flags:标记

标记含义:

U 路由是活动的

H 目标是一个主机

G 需要经过网关

R 恢复动态路由产生的表项

D 由路由的后台程序动态地安装

M 由路由的后台程序修改

! 拒绝路由

 

Metric:路由距离,到达指定网络所需的中转数,是大型局域网和广域网设置所必需的 (不在Linux内核中使用。)

Ref:路由项引用次数 (不在Linux内核中使用。)

Use:此路由项被路由软件查找的次数

Iface:网卡名字,例如 eth0

 

 

LInux 内核路由种类

主机路由

路由表中指向单个 IP 地址或主机名的路由记录,其 Flags 字段为 H,下面示例中,对于 10.0.0.10 这个主机,通过网关 10.139.128.1网关路由

Destination Gateway Genmask Flags Metric Ref Use Iface

10.0.0.10 10.139.128.1 255.255.255.255 UGH 0 0 0 eth0

 

网络路由

主机可以到达的网络。下面示例中,对于 10.0.0.0/24 这个网络,通过网关 10.139.128.1 网关路由:

Destination Gateway Genmask Flags Metric Ref Use Iface

10.0.0.0 10.139.128.1 255.255.255.0 UG 0 0 0 eth0

 

 

默认路由

当目标主机的 IP 地址或网络不在路由表中时,数据包就被发送到默认路由(默认网关)上。默认路由的 Destination 是 default 或 0.0.0.0

Destination Gateway Genmask Flags Metric Ref Use Iface

default gateway 0.0.0.0 UG 0 0 0 eth0

 

 

route 命令

 

route 命令可以显示或设置 Linux 内核中的路由表,主要是静态路由。

 

对于局域网中的 Linux 主机,要想访问 Internet,需要将局域网的网关 IP 地址设置为这个主机的默认路由。在命令行中通过 route 命令添加的路由在网卡重启或机器重启后失效。可以在 /etc/rc.local 中添加 route 命令来保证路由设置永久有效。

 

选项:

 

-A:设置地址类型

-C:打印 Linux 内核的路由缓存

-v:显示详细信息

-n:不执行 DNS 反向查找,直接显示数字形式的 IP 地址

-e:netstat 格式显示路由表

-net:到一个网络的路由表

-host:到一个主机的路由表

参数:

 

add:增加路由记录

del:删除路由记录

target:目的网络或目的主机

gw:设置默认网关

mss:设置TCP的最大区块长度(MSS),单位MB

window:指定通过路由表的TCP连接的TCP窗口大小

dev:路由记录所表示的网络接口

添加路由 add

 

可以添加一条可用路由,或添加一条要屏蔽的路由。

 

添加路由

 

添加主机路由

 

添加主机路由时,需要指定网络 ID 和主机 ID,此时需要设置 netmask 255.255.255.255:

 

[root@VM_139_74_centos ~]# route add -net 10.0.0.10 netmask 255.255.255.255 gw 10.139.128.1 dev eth0

[root@VM_139_74_centos ~]# route -n

Kernel IP routing table

Destination Gateway Genmask Flags Metric Ref Use Iface

10.0.0.10 10.139.128.1 255.255.255.255 UGH 0 0 0 eth0

 

添加网络路由

 

添加网络路由时,只需指定网络 ID,通过 netmask 设置掩码长度:

 

[root@VM_139_74_centos ~]# route add -net 10.0.0.0 netmask 255.255.255.0 gw 10.139.128.1 dev eth0

[root@VM_139_74_centos ~]# route -n

Kernel IP routing table

Destination Gateway Genmask Flags Metric Ref Use Iface

10.0.0.0 10.139.128.1 255.255.255.0 UG 0 0 0 eth0

 

 

添加添加同一个局域网的主机

 

不指定 gw 选项时,添加的路由记录不使用网关:

 

[root@VM_139_74_centos ~]# route add -net 224.0.0.0 netmask 240.0.0.0 dev eth0

[root@VM_139_74_centos ~]# route -n

Kernel IP routing table

Destination Gateway Genmask Flags Metric Ref Use Iface

224.0.0.0 0.0.0.0 240.0.0.0 U 0 0 0 eth0

 

屏蔽路由

 

[root@VM_139_74_centos ~]# route add -net 224.0.0.0 netmask 240.0.0.0 reject

[root@VM_139_74_centos ~]# route -n

Kernel IP routing table

Destination Gateway Genmask Flags Metric Ref Use Iface

224.0.0.0 - 240.0.0.0 ! 0 - 0 -

 

删除路由记录

 

跟添加路由类似,可以删除一条可用路由,或删除一条屏蔽的路由。

 

删除可用路由

route del -net 224.0.0.0 netmask 240.0.0.0

 

删除屏蔽的路由

route del -net 224.0.0.0 netmask 240.0.0.0 reject

 

删除和添加设置默认网关

 

添加或删除默认网关时,Linux 会自动检查网关的可用性:

[root@VM_139_74_centos ~]# route add default gw 192.168.1.1

SIOCADDRT: Network is unreachable

[root@VM_139_74_centos ~]# route del default gw 192.168.1.1

SIOCDELRT: No such process

 

 

 

 

部署 flannel

flannel 采用 叠加网络(Overlay Network模型来完成网络的打通

环境 :

192.168.255.128

192.168.255.129

 

(1) 确认 etcd 已经安装,由于 flannel 使用 etcd作为数据库,所以需要预先安装好etcd

 

(2) 需要在每台Node 上都安装flannel。 flannel 软件的下载地址为 https://github.com/coreos/flannel/releases, 将下载的压缩包解压

,把二进制文件 flanneld 和 mk-docker-opts.sh 复制到/usr/bin , 获取其他 PATH变量中的目录,即可完成对flannel 的安装

 

(3) 配置flannel

此处 以使用systemd 系统为例 对flanneld服务进行配置。 编辑服务配置文件 /usr/lib/systemd/system/flanneld.service

 

[root@linux-node2 sysconfig]# vim /usr/lib/systemd/system/flanneld.service

[Unit]

Description=flanneld overlay address etcd agent

Documentation=https://github.com/coreos/flannel

After=network.service

Before=docker.service

 

 

[Service]

Type=notify

EnvironmentFile=/etc/sysconfig/flannel

ExecStart=/usr/bin/flanneld --etcd-endpoints=${FLANNEL_ETCD} $FLANNEL_OPTIONS

 

 

[Install]

RequiredBy=docker.service

WantedBy=multi-user.target

 

 

[root@linux-node2 sysconfig]# vim /etc/sysconfig/flannel

#flanneld configuration options

 

#etcd url location. Point this to the server where etcd runs

 

FLANNEL_ETCD="http://192.168.255.128:2379"

 

# etcd config key. this is the configuration key that flannel queries

# for address range assignment

FLANNEL_ETCD_KEY="/coreos.com/network"

 

 

(4) 在 启动 flannel 之前,需要 在etcd 中添加 一条网络记录,这个配置将用于 flannel 分配 给

每个docker 的 虚拟IP地址段

etcdctl set /coreos.com/network/config '{ "Network": "10.1.0.0/16" }'

 

(5)由于 flannel 将覆盖 docker0 网桥,所有如果docker 服务已经启动,则停止docker服务

 

(6)启动 flannel 服务

systemctl restart flannel

 

(7)在每个Node 节点执行以下命令 来完成对docker0网桥的设置

mk-docker-opts.sh -i

source /run/flannel/subnet.env

ifconfig docker0 ${FLANNEL_SUBNET}

 

(9)完成 后 使用 ifconfig 查看

flannel0: <POINTOPOINT,MULTICAST,NOARP,UP,LOWER_UP> mtu 1472 qdisc pfifo_fast state UNKNOWN group default qlen 500

link/none

inet 10.1.80.0/16 scope global flannel0

 

docker0: <NO-CARRIER,BROADCAST,MULTICAST,UP> mtu 1500 qdisc noqueue state DOWN group default

link/ether 02:42:89:ff:c3:04 brd ff:ff:ff:ff:ff:ff

inet 172.17.0.1/16 scope global docker0

 

(10)我们 使用 ping 命令 验证 各Node 上 docker0 之间 的相互访问

 

 

[root@linux-node1 ~]# ping 10.1.78.1

PING 10.1.78.1 (10.1.78.1) 56(84) bytes of data.

64 bytes from 10.1.78.1: icmp_seq=1 ttl=62 time=4.77 ms

64 bytes from 10.1.78.1: icmp_seq=2 ttl=62 time=1.39 ms

64 bytes from 10.1.78.1: icmp_seq=3 ttl=62 time=1.14 ms

64 bytes from 10.1.78.1: icmp_seq=4 ttl=62 time=0.958 ms

64 bytes from 10.1.78.1: icmp_seq=5 ttl=62 time=1.36 ms

64 bytes from 10.1.78.1: icmp_seq=6 ttl=62 time=1.43 ms

64 bytes from 10.1.78.1: icmp_seq=7 ttl=62 time=1.05 ms

64 bytes from 10.1.78.1: icmp_seq=8 ttl=62 time=0.949 ms

64 bytes from 10.1.78.1: icmp_seq=9 ttl=62 time=1.06 ms

 

 

出自

http://www.linuxeye.com/Linux/2065.html

https://blog.csdn.net/kikajack/article/details/80457841

《kubernetes 权威指南》

 

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值