02.02 「架構」kubernetes跨集群三層網絡設計

  • 需求提出:

在k8s集群的內部,網絡是互通的,也就是同一個集群內的不同主機、不同pod之間是互通的。不同k8s集群(我以阿里云為例)上的主機物理上是互通的,但是pod之間是不通的。我們要做多集群的管理,就要將管理下沉到不同k8s集群裡的不同pod;

另外,阿里雲上的公網ip是收費的,如果給每個serivce都分配一個公網ip,那麼成本必然是巨大的,所以最好的辦法是通過同一個公網ip進來然後再進行轉發,下沉到具體某個集群的某個pod或者service下面;

如果給每個集群分一個public ip,成本倒是也可以接受,但是如果集群之間互相訪問,那麼走公網ip不僅僅速度會受影響,而且流量費用也不會少。如果集群之間訪問也可以走內網,那就可以省下一大筆費用了。

  • 架構方案

基於以上這些需求,我們設計了雲平臺的網絡和路由架構:


「架構」kubernetes跨集群三層網絡設計

k8s多集群網絡和路由架構

整個架構總結起來就是:三層網絡、二層轉發。

從上向下,這三層網絡依次為公網網絡(一層)、集群之間網絡(二層)、k8s集群內的網絡(三層)。

公網ip只有一個,既節約了成本,也滿足了我們的需求。公網網絡對應的域名為 *.wise-paas.com.cn

集群間網絡其實是iaas平臺提供的。比如在阿里雲,可以為k8s集群的邊緣service申請internal loadballane ip,這些ip位於同一個網絡,可以互相訪問。集群間網絡對應的域名為 *.$clustername.internal

k8s集群通過內部虛擬網絡實現pod和service的扁平化管理,保證了k8s集群內部的pod之間是互通的。集群內部網絡對應的域名為 *.cluster.local

這三層網是不互通的,所以需要在網絡邊緣處做轉發處理。而我們在一層和二層之間用nginx,二層和三層之間則使用了kong。

  • 技術實現

nginx和kong的轉發功能,我們不再贅述。

但是無論是nginx還是kong,轉發都需要通過域名來進行。

二層到三層的轉發比較簡單,因為k8s集群內部已經有coreDNS;但是一層到二層的轉發則需要有額外的dns支持,我們通過dnsmasq來做集群之間的dns查詢。每添加一個k8s集群,都會在dnsmsq裡添加針對此集群的泛域名解析。比如,針對cluster1,它的kong網關的internal load ballance ip為10.10.3.9,那麼我們會通過腳本自動向dnsmasq添加一條泛域名解析:

<code>*.cluster1.internal 10.10.3.9/<code>

這樣針對cluster1集群的一、二層網絡之間的轉發就打通了。

這樣通過二層轉發,從外到內的網絡通信就走通了。

比如,訪問http://scada-namespace1-cluster1.dc1.wise-paas.com.cn,請求就可以到達cluster1下的namespace1下的scada這個service裡(請求過程請參考綠色線條):


「架構」kubernetes跨集群三層網絡設計

從外到內訪問

  • 集群之間訪問

那集群之間如何訪問呢?

比如在cluster2集群的service0裡訪問cluster1集群的scada,參考下圖:


「架構」kubernetes跨集群三層網絡設計

k8s集群之間訪問

無需藉助公網域名,cluster2集群裡的service0只要通過http://scada.namespaces1.cluster1.internal這個域名就可以訪問到cluster1集群裡的scada服務,無需走外網。請求過程參考上圖

紅色線條

但是,需要在cluster2集群裡添加對上述dnsmasq的支持:

<code>internal:53 {
errors
cache 30
forward . dnsmasq's ip
}/<code>

customizing DNS on kubernetes 可以參考這裡:

https://kubernetes.io/docs/tasks/administer-cluster/dns-custom-nameservers/

不同的平臺,比如azure和aliyun的配置方法都不太一樣。

大家有問題可以在評論區提問。

作者簡介:研華科技軟件主管,聚焦linux內核技術和k8s雲平臺架構設計。我會在這裡分享kubernetes雲平臺的架構設計。也會分享我們針對某些開源組件的優劣評估和性能測試以及優化過程。歡迎大家一起探討雲原生技術。


分享到:


相關文章: