零入门kubernetes网络实战-30->基于bridge+veth pair+DNAT技术来实现外网可以访问内网的方案

《零入门kubernetes网络实战》视频专栏地址

https://www.ixigua.com/7193641905282875942

本篇文章视频地址(稍后上传)


通过DNAT技术可以将brige虚拟网桥管理的内网中的服务暴露出来,以供外网访问。

1、测试环境介绍

两台centos虚拟机

# 查看操作系统版本
cat /etc/centos-release
# 内核版本
uname -a
uname -r 
# 查看网卡信息
ip a s eth0

在这里插入图片描述

2、网络拓扑

在这里插入图片描述

从Slave节点的用户空间里的curl应用发起请求。

3、操作实战

3.1、第1步:在master上执行下面的命令

brctl addbr br0
ip link set br0 up
ip addr add 10.244.1.3/24 dev br0

ip netns add ns1

ip link add veth1a type veth peer name veth1b

ip link set veth1a netns ns1
ip netns exec ns1 ip addr add 10.244.1.2/24 dev veth1a
ip netns exec ns1 ip link set veth1a up

ip link set veth1b up

brctl addif br0 veth1b

ip netns exec ns1 route add default gw 10.244.1.3
iptables -t nat -A PREROUTING -d 10.211.55.122 -p tcp --dport 8090 -i eth0 -j DNAT --to 10.244.1.2:9090

echo 1 > /proc/sys/net/ipv4/ip_forward

在这里插入图片描述

3.2、第2步:被测试服务

3.2.1、被测试服务代码

package main

import (
	"encoding/json"
	"fmt"
	"net/http"
)

type Stu struct {
	Age int
	Msg string
}

const ip = "0.0.0.0"

func sayHello(w http.ResponseWriter, r *http.Request) {
	stu := Stu{Age: 12, Msg: "hello world! this is DNAT+bridge+Veth pair Test!"}
	stuJson, e := json.Marshal(&stu)
	if e != nil {
		panic(e)
	}

	w.Write(stuJson)

	fmt.Printf("Reply MSG:%v\tlen(Msg):%d\n", string(stuJson), len(stuJson))
}

func main() {
	http.HandleFunc("/", sayHello)
	fmt.Printf(fmt.Sprintf("App URL: http://%s:%d\n", ip, 9090))

	err := http.ListenAndServe(fmt.Sprintf("%s:%d", ip, 9090), nil)
	if err != nil {
		fmt.Printf("http server failed, err:%v\n", err)
		return
	}
}

不用关心测试代码的具体逻辑,主要是关心请求后,是否有正常打印输出即可。

3.2.2、本地编译,上传到Master节点

Makefile

build:
	CGO_ENABLED=0 GOOS=linux GOARCH=amd64 go build -o http-web main.go

scp:
	scp http-web root@10.211.55.122:/root

all:
	make build && make scp

大家可以根据自己的实际情况进行修改。

直接执行

make all

3.3、第3步:在master节点上,ns1命名空间里启动http-web服务

ip netns exec ns1 ./http-web

在这里插入图片描述

3.4、第4步:slave节点上发起curl请求

curl 10.211.55.122:8090

在这里插入图片描述

4、从iptables链的角度,对整个过程进行分析

为了分析整个传输过程,我们添加一些日志埋点,来验证我们的猜测。

如果你已经根据前面的文章安装过了rsyslog服务,就不需要重复操作了

4.1、安装

4.1.1、安装rsyslog服务

yum -y install rsyslog

4.1.2、更新配置文件

echo "kern.*     /var/log/iptables.log" >> /etc/rsyslog.conf 

在这里插入图片描述

.*,表示所有等级的消息都添加到iptables.log文件里

信息等级的指定方式

  • .XXX,表示 大于XXX级别的信息
  • .=XXX,表示等于XXX级别的信息
    • 如,kern.=notice /var/log/iptables.log, 将notice以上的信息添加到iptables.log里
  • .!XXX, 表示在XXX之外的等级信息

4.1.3、重启rsyslog服务

systemctl restart rsyslog

systemctl status  rsyslog

在这里插入图片描述

4.2、日志埋点

4.3、在master节点上,进行日志埋点

将当前的日志统计清零

iptables -t nat -Z
iptables -t filter -Z

插入日志埋点前,先查看一下,当前的现状

iptables -t nat -nvL PREROUTING --line-number
iptables -t nat -nvL INPUT --line-number
iptables -t filter -nvL FORWARD --line-number
iptables -t nat -nvL POSTROUTING --line-number

插入日志埋点

iptables -t nat -I PREROUTING -d 10.211.55.0/24 -p tcp --dport 8090 -j LOG --log-prefix "Test-nat-PREROUTING-2-"
iptables -t filter -A FORWARD -d 10.244.1.0/24 -p tcp -j LOG --log-prefix "Test-filter-FORWARD-1-"
iptables -t nat -I POSTROUTING -p tcp -d 10.244.1.0/24 -j LOG --log-prefix "Test-nat-POSTROUTING-2-"

iptables -t filter -A FORWARD -d 10.211.55.0/24 -p tcp --sport 9090 -j LOG --log-prefix "Test-filter-FORWARD-333-"

在这里插入图片描述

也可以查看一下,ns1命名空间的iptables规则链情况

ip netns exec ns1 iptables -t nat -nvL

查看日志文件

tail -f /var/log/iptables.log

在这里插入图片描述

4.3.1、在slave节点上,进行日志埋点

将当前的日志统计清零

iptables -t nat -Z
iptables -t filter -Z

插入日志埋点前,先查看一下,当前的现状

iptables -t nat -nvL OUTPUT --line-number
iptables -t filter -nvL OUTPUT --line-number
iptables -t nat -nvL POSTROUTING --line-number
iptables -t nat -nvL PREROUTING --line-number
iptables -t filter -nvL INPUT --line-number

插入日志埋点


iptables -t nat -I OUTPUT -d 10.211.55.0/24 -p tcp --dport 8090 -j LOG --log-prefix "Test-nat-OUTPUT-1-"
iptables -t filter -I OUTPUT -d 10.211.55.0/24 -p tcp --dport 8090 -j LOG --log-prefix "Test-filter-OUTPUT-1-"
iptables -t nat -I POSTROUTING -d 10.211.55.0/24 -p tcp --dport 8090 -j LOG --log-prefix "Test-nat-POSTROUTING-1-"

iptables -t filter -I INPUT -d 10.211.55.0/24 -p tcp --sport 8090 -j LOG --log-prefix "Test-nat-INPUT-1-"

在这里插入图片描述

查看日志文件

tail -f /var/log/iptables.log

在这里插入图片描述

4.4、测试

4.4.1、在slave节点,发起请求

curl 10.211.55.122:8090

在这里插入图片描述

4.4.2、查看一下,master上日志

tail -f /var/log/iptables.log

在这里插入图片描述

4.4.3、查看一下,slave上日志

在这里插入图片描述

4.5、整个传输过程,数据包经过了哪些iptables链呢?

下图是 从slave节点通过curl发起请求的路线
在这里插入图片描述

这个图,主要是要明白一点,外部数据包进入到eth0网卡后,经过了哪些链才能到达br0

需要经过PRETOUTING链,FORWARD链,POSTROUTING链,才能到达虚拟网桥br0

下图是 master节点上的http-web服务接收到请求后的,反馈路线
在这里插入图片描述

备注:
反馈路线,仅供参考。
我个人是有疑问的。
比方说,Master节点上,eth0接收到反馈数据包后,没有走nat表中的PREROUTING链,当然,走了raw,mangle表中的PREROUTING链。

5、传输过程中,数据包是否被修改过?

5.1、针对master节点上的eth0进行抓包

tcpdump -nn -i eth0 -p tcp and dst port 8090
tcpdump -nn -i eth0 -p tcp and dst port 8090 -w icmp-eth0.pcap

在这里插入图片描述

5.2、针对master节点上的br0网桥进行抓包

tcpdump -nn -i br0  -w icmp-br0.pcap

在这里插入图片描述

5.3、传输过程中数据包的报文内容变化

在这里插入图片描述

即,经过DNAT操作后数据包的变化,如下

在这里插入图片描述

6、总结

  • 通过DNAT操作,可以将内网的服务暴露到外面,以供外网访问。端口映射
  • 通过SNAT或者MASQUERADE操作,可以允许内网去访问外网的服务。
  • DNAT和SNAT刚好相反,
  • 因此,在实际中,要明白到底用哪个?还是一起使用。
  • 比方说,kube-proxy里都使用了DNAT、MASQUERADE操作。
  • 即,通过DNAT将POD里的服务暴露出来,通过MASQUERADE允许POD内部的服务去访问外网服务。

<<零入门kubernetes网络实战>>技术专栏之文章目录


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

码二哥

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值