k8s內網和辦公網絡的打通實踐


1、背景

近期工作中出現了一個問題:某個舊服務中用到了redis,但是在前期項目容器化改造部署階段研發同事並沒有說明需要用到redis,直至部署生產prod環境出現問題。
那么疑問來了,為什么在qa環境沒有問題呢?經溝通排查發現,源碼中也就是qa環境連接的是一個古老的虛擬機運行的redis,所以自然研發測試環境都沒問題,至於為什么會連接到這個地址,不得而知!

第一想法:關掉這個redis服務,讓研發“被迫”主動告知;規范要求,在k8s集群內部部署該項目的redis服務集群,保證環境一致性,減少不必要麻煩。

項目多數屬於微服務應用模塊,研發本地無法完整運行全部依賴,希望在本地運行某個服務后,能夠注冊到qa容器環境的依賴服務中進行調試。
例如在k8s中運行的redisrabbitmq等服務,研發在當前環境下無法直接通過客戶端工具連接進行訪問,給研發測試進行聯調帶來了很大麻煩,且k8s內部通過cni插件創建podservice的內部網絡,這類服務無法通過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解析打通。

  • 網絡打通

    於是,在網關和路由器上添加靜態路由,把屬於k8sPodService的子網IP包全轉給其中某個k8s node節點,這樣訪問pod ipservice ip這樣的IP,網絡包會到達某個集群物理節點,而集群內的物理節點或虛擬機,k8s網絡cni插件都會與這些目的地址互通。

  • dns解析打通

    網絡打通后,就可以在辦公網絡通過podserviceip進行連通了。但是每次更新服務,ip通常都會發生變化,我們想通過服務名稱(域名)而不是ip進行通信,解決dns問題主要有以下兩個方向

    • 網絡已經打通了,那么就可以把k8scoredns作為本地的dns服務器
    • 把所有通過辦公網絡請求k8s中的服務(域名)的記錄從內網dns服務器轉發到k8scoredns

    上述兩種方式都可以實現dns的互聯互通。綜合考慮,為了保證兩處dns服務的穩定性,只將經過k8s內部服務的dns請求通過coredns,且減少了PC客戶端dns服務器地址的配置工作,選擇方案二。

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 podk8s 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等組件了。

此方案主要利用局域網靜態路由,在網關進行配置。透明且高效,且開發測試環境無須再部署其他組件。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM