k8s内网和办公网络的打通实践
目录
1、背景
2、环境说明
3、总体思路
4、网络打通的具体实现
4.5.1 web界面检查
4.5.2 pc网络检查
4.1.1 办公网络和k8s node
4.1.2 k8s node和pod及svc
4.1 检查现有网络连通情况
4.2 添加地址
4.3 配置静态路由
4.4 配置策略
4.5 验证配置
5、dns解析打通的具体实现
5.1 配置dns条件转发
5.2 验证配置
6、小结
1、背景
近期工作中出现了一个问题:某个旧服务中用到了redis,但是在前期项目容器化改造部署阶段研发同事并没有说明需要用到redis,直至部署生产prod环境出现问题。
那么疑问来了,为什么在qa环境没有问题呢?经沟通排查发现,源码中也就是qa环境连接的是一个古老的虚拟机运行的redis,所以自然研发测试环境都没问题,至于为什么会连接到这个地址,不得而知!
第一想法:关掉这个redis服务,让研发“被迫”主动告知;规范要求,在k8s集群内部部署该项目的redis服务集群,保证环境一致性,减少不必要麻烦。
项目多数属于微服务应用模块,研发本地无法完整运行全部依赖,希望在本地运行某个服务后,能够注册到qa容器环境的依赖服务中进行调试。
例如在k8s中运行的redis、rabbitmq等服务,研发在当前环境下无法直接通过客户端工具连接进行访问,给研发测试进行联调带来了很大麻烦,且k8s内部通过cni插件创建pod和service的内部网络,这类服务无法通过ingress进行7层暴露,如果通过NodePort模式暴露给研发,不仅使用有限而且会导致端口管理困难从而工作量加大。因此打通开发和测试环境k8s集群内网和办公局域网络是有很大必要性的。
2、环境说明
相关网络拓扑如下
ip地址情况如下
办公子网:172.16.0.0/24
DMZ区域服务器子网:172.16.1.0/24、172.16.2.0/24
k8s pod子网:172.20.0.0/16
k8s service子网:10.68.0.0/16
其他涉及到的相关服务及ip说明
k8s网络插件:flannel,对应网络模式为host-gw
k8s kube-dns service ip:10.68.0.2
内网dns服务:ms(windows) server dns
内网dns ip:172.16.2.3
FortiGate ip:172.16.2.254
3、总体思路
k8s集群部署在测试机房,整个局域网链路、外网、防火墙由飞塔防火墙FortiGate设备统一控制,除k8s集群内部网络外,其他网络均已通过FortiGate打通,所以目前面临的问题就是网络打通和dns解析打通。
网络打通
于是,在网关和路由器上添加静态路由,把属于k8s的Pod和Service的子网IP包全转给其中某个k8s node节点,这样访问pod ip和service ip这样的IP,网络包会到达某个集群物理节点,而集群内的物理节点或虚拟机,k8s网络cni插件都会与这些目的地址互通。
dns解析打通
网络打通后,就可以在办公网络通过pod或service的ip进行连通了。但是每次更新服务,ip通常都会发生变化,我们想通过服务名称(域名)而不是ip进行通信,解决dns问题主要有以下两个方向
上述两种方式都可以实现dns的互联互通。综合考虑,为了保证两处dns服务的稳定性,只将经过k8s内部服务的dns请求通过coredns,且减少了PC客户端dns服务器地址的配置工作,选择方案二。
网络已经打通了,那么就可以把k8s的coredns作为本地的dns服务器
把所有通过办公网络请求k8s中的服务(域名)的记录从内网dns服务器转发到k8s的coredns
4、网络打通的具体实现
4.1 检查现有网络连通情况
4.1.1 办公网络和k8s node
在本地pc电脑上操作
➜ ~ ping 172.16.1.106 -c 4 PING 172.16.1.106 (172.16.1.106): 56 data bytes 64 bytes from 172.16.1.106: icmp_seq=0 ttl=63 time=1.621 ms 64 bytes from 172.16.1.106: icmp_seq=1 ttl=63 time=1.568 ms 64 bytes from 172.16.1.106: icmp_seq=2 ttl=63 time=1.221 ms 64 bytes from 172.16.1.106: icmp_seq=3 ttl=63 time=1.338 ms --- 172.16.1.106 ping statistics --- 4 packets transmitted, 4 packets received, 0.0% packet loss round-trip min/avg/max/stddev = 1.221/1.437/1.621/0.164 ms
4.1.2 k8s node和pod及svc
在k8s任意一台node上操作,通过nslookup同时检查网络和dns功能是否正常,这里以172.16.1.106这台node为例
[root@k8s-qa-node-02 ~]# nslookup -q=A kubernetes.default.svc.cluster.local 10.68.0.2 Server: 10.68.0.2 Address: 10.68.0.2#53 Name: kubernetes.default.svc.cluster.local Address: 10.68.0.1
查看node的路由
[root@k8s-qa-node-02 ~]# ip route default via 172.16.1.254 dev eth0 169.254.0.0/16 dev eth0 scope link metric 1002 172.16.1.0/24 dev eth0 proto kernel scope link src 172.16.1.106 172.17.0.0/16 dev docker0 proto kernel scope link src 172.17.0.1 linkdown 172.20.0.0/24 via 172.16.1.100 dev eth0 172.20.1.0/24 via 172.16.1.101 dev eth0 172.20.2.0/24 via 172.16.1.110 dev eth0 172.20.3.0/24 dev cni0 proto kernel scope link src 172.20.3.1 172.20.4.0/24 via 172.16.1.107 dev eth0 172.20.5.0/24 via 172.16.1.108 dev eth0 172.20.6.0/24 via 172.16.1.109 dev eth0 # ...省略部分条目
4.2 添加地址
网络打通主要在网关和路由器设备上进行操作,这里仅以FortiGate为例进行记录。
为了配置流程清晰,通过终端命令行进行配置而不是web界面操作,首先通过console或者ssh连接上FortiGate的终端
添加k8s pod和k8s service两个子网的地址
FortiGate # config firewall address FortiGate (address) # edit k8s_SERVICE_CIDR new entry 'k8s_SERVICE_CIDR' added FortiGate (clientnet) # set subnet 10.68.0.0 255.255.0.0 FortiGate (clientnet) # next FortiGate (address) # edit k8s_POD_CIDR new entry 'k8s_POD_CIDR' added FortiGate (clientnet) # set subnet 172.20.0.0 255.255.0.0 FortiGate (clientnet) # next FortiGate (address) # end FortiGate #
4.3 配置静态路由
配置到达k8s svc子网的路由
FortiGate # config router static # 新增一条静态路由,id尽量大,不与已有的冲突 FortiGate (static) # edit 10 new entry '10' added # 配置目标地址和掩码 FortiGate (2) # set dst 10.68.0.0 255.255.0.0 # 配置网关(下一跳) FortiGate (2) # set gateway 172.16.1.106 # 配置接口名 FortiGate (2) # set device Test FortiGate (2) # next FortiGate (static) # end FortiGate #
同理,配置到达k8s pod子网的路由
FortiGate # config router static FortiGate (static) # edit 11 FortiGate (2) # set dst 172.20.0.0/16 255.255.0.0 FortiGate (2) # set gateway 172.16.1.106 FortiGate (2) # set device Test FortiGate (2) # next FortiGate (static) # end FortiGate #
检查配置的静态路由
FortiGate # get router info routing-table static # ...省略部分条目 S 10.68.0.0/16 [10/0] via 172.16.1.106, Test S 172.20.0.0/16 [10/0] via 172.16.1.106, Test
4.4 配置策略
配置到达k8s service网络放行策略
FortiGate # config firewall policy # 新增一条网络策略,id尽量大,不与已有的冲突 FortiGate (policy) # edit 100 # 配置源接口 FortiGate (100) # set srcintf internal # 配置目的接口 FortiGate (100) # set dstintf Test # 配置源地址 FortiGate (100) # set srcaddr 172.16.0.0/24 # 配置目的地址 FortiGate (100) # set dstaddr k8s_SERVICE_CIDR # 配置动作类型 FortiGate (100) # set action accept # 配置动作时间 FortiGate (100) # set schedule always # 配置服务(协议类型) FortiGate (100) # set service ALL_TCP # 配置是否开启日志 FortiGate (100) # set logtraffic disable # 配置是否开启nat FortiGate (100) # set nat disable end
同理,配置到达k8s pod网络放行策略
FortiGate # config firewall policy FortiGate (policy) # edit 101 FortiGate (100) # set srcintf internal FortiGate (100) # set dstintf Test FortiGate (100) # set srcaddr 172.16.0.0/24 FortiGate (100) # set dstaddr k8s_POD_CIDR FortiGate (100) # set action accept FortiGate (100) # set schedule always FortiGate (100) # set service ALL_TCP FortiGate (100) # set logtraffic disable FortiGate (100) # set nat disable end
4.5 验证配置
4.5.1 web界面检查
登录到FortiGate界面,查看配置的静态路由
网络策略
4.5.2 pc网络检查
在pc端检查pod网络是否可达并在上文中选取的网关node上抓包
5、dns解析打通的具体实现
5.1 配置dns条件转发
上面已经将网络进行了打通,dns解析的打通在内网dns服务器上设置dns转发即可。
打开ms(windows) server类型的dns管理器配置界面,新增条件转发器,如下所示,dns域填写k8s集群中兼容所有命名空间的搜索域。当然,为了安全,建议单独设置允许可达的命名空间下的服务,例如default,则填为default.svc.cluster.local。
5.2 验证配置
在本地终端上测试解析k8s service域名,成功解析
➜ ~ nslookup redis-abc-gns.default.svc.cluster.local Server: 172.16.2.3 Address: 172.16.2.3#53 Non-authoritative answer: Name: redis-dkj-gns.default.svc.cluster.local Address: 172.20.4.222
6、小结
至此,就成功的将办公网络和k8s内网进行打通,研发以后就可以在开发机器上利用和qa环境一样配置的svc name连接对应依赖的redis等组件了。
此方案主要利用局域网静态路由,在网关进行配置。透明且高效,且开发测试环境无须再部署其他组件。