天天看點

《Kubernetes網絡權威指南》讀書筆記 | 從叢集内通路服務

作者:熱愛程式設計的通信人

書籍來源:《Kubernetes網絡權威指南:基礎、原理與實踐》

一邊學習一邊整理讀書筆記,并與大家分享,侵權即删,謝謝支援!

附上彙總貼:《Kubernetes網絡權威指南》讀書筆記 | 彙總_COCOgsta的部落格-CSDN部落格

Kubernetes裡服務(Service)的概念即通常說的微服務(micro-service)。

什麼是Kubernetes的Service呢?在Kubernetes中,使用者可以為任何Kubernetes資源配置設定成為Labels(标簽)的任意鍵值。Kubernetes使用Labels将多個相關的Pod組合成一個邏輯單元,稱為Service。

Service具有穩定的IP位址和端口,并會在一組比對的後端Pod之間提供負載均衡,比對的條件就是Service的Label Selector與Pod的Labels相比對。

3.5.1KubernetesService詳解

Kubernetes的Service代表的是Kubernetes後端服務的入口,它主要包含服務的通路IP(虛IP)和端口,是以工作在L4。

被Service選中的Pod,當它們運作且能對外提供服務後,Kubernetes的Endpoints Controller會生成一個新的Endpoints對象,記錄Pod的IP和端口。

Service的通路IP和Endpoints/Pod IP都會在Kubernetes的DNS伺服器裡存儲域名和IP的映射關系,是以使用者可以在叢集内通過域名的方式通路Service和Pod。Service與Endpoints的關系如圖3-16所示。

《Kubernetes網絡權威指南》讀書筆記 | 從叢集内通路服務

圖3-16 Service與Endpoints的關系

Kubernetes會從叢集的可用服務IP池中為每個新建立的服務配置設定一個穩定的叢集内通路IP位址,稱為Cluster IP。Kubernetes還會通過添加DNS條目為Cluster IP配置設定主機名。Cluster IP和主機名在叢集内是獨一無二的,并且在服務的整個生命周期内不會更改。

使用者不用擔心服務出現單點故障問題,Kubernetes會盡可能均勻地将流量分布到在多個節點上運作的Pod,是以一個或若幹個(但不是所有)節點的服務中斷情況不會影響服務的整體可用性。

Kubernetes使用Kube-proxy元件管理各服務與之後端Pod的連接配接,該元件在每個節點上運作。Kube-proxy落實到主機上就是iptables/IPVS等路由規則。通路服務的IP會被這些路由規則直接DNAT到Pod IP,然後走底層容器網絡送到對應的Pod。

一個最簡單的Kubernetes Service的定義如下所示:

《Kubernetes網絡權威指南》讀書筆記 | 從叢集内通路服務

其中,spec.ClusterIP就是Service的(其中一個)通路IP,俗稱虛IP(Virtual IP,即VIP)。如果使用者不指定的話,那麼Kubernetes Master會自動從一個配置範圍内随機配置設定一個。

該Service的selector是app:nginx,即比對那些被打上app=nginx标簽的Pod。

spec.ports[].port是Service的通路端口,而與之對應的spec.ports[].targetPort是後端Pod的端口,Kubernetes會自動做一次映射(80->8080)。

當Service的後端Pod準備就緒後,Kubernetes會生成一個新的Endpoints對象,而且這個Endpoints對象和Service同名。一個Endpoints的定義如下所示:

《Kubernetes網絡權威指南》讀書筆記 | 從叢集内通路服務

使用者可以通過以下指令得到這個Endpoints對象:

《Kubernetes網絡權威指南》讀書筆記 | 從叢集内通路服務

其中,subsets[].addresses[].ip是後端Pod的IP,subsets[].ports是後端Pod的端口,與Service的targetPort對應。

3.5.2Service的三個port

先來看一個最簡單的Service定義:

《Kubernetes網絡權威指南》讀書筆記 | 從叢集内通路服務

Service的幾個port的概念很容易混淆,它們分别是port、targetPort和NodePort。

port表示Service暴露的服務端口,也是叢集内部用戶端通路用的端口。

NodePort是提供給叢集外部通路Service入口的一種方式(另一種方式是Load Balancer)。

targetPort是應用程式實際監聽Pod内流量的端口,從port和NodePort上到來的資料,最終經過Kube-proxy流入後端Pod的targetPort進入容器。

在配置服務時,可以選擇定義port和targetPort的值重新映射其監聽端口,這也被稱為Service的端口重映射。

3.5.3 你的服務适合哪種釋出形式

  1. Cluster IP

Kubernetes Service有幾種類型:Cluster IP、Load Balancer和NodePort。其中,Cluster IP是預設類型。一個典型的Cluster IP類型的Service如下:

《Kubernetes網絡權威指南》讀書筆記 | 從叢集内通路服務

Cluster IP主要在每個node節點使用iptables,将發向Cluster IP對應端口的資料轉發到後端Pod中。針對iptables的更詳細分析見後面章節。

  1. Load Balancer

Load Balancer(簡稱LB)類型的Service需要Cloud Provider的支援。Kubernetes原生支援的Cloud Provider有GCE和AWS,是以和不同雲平台的網絡方案耦合較大,而且隻能在特定的雲平台上使用,局限性也較大。

建立Service時,通過配置serviceSpec.loadBalancerSourceRanges字段,可以限制哪些IP位址範圍可以通路叢集内的服務。Kube-proxy會配置該節點的iptables規則。以拒絕與指定loadBalancerSourceRanges不比對的所有流量。

一個Load Balancer類型Service的定義如下所示:

《Kubernetes網絡權威指南》讀書筆記 | 從叢集内通路服務

檢視這個服務的細節:

《Kubernetes網絡權威指南》讀書筆記 | 從叢集内通路服務

内部可以使用Cluster-IP加端口來通路該服務。在我們這個例子中就是19.97.121.42:8086。

外部可以使用EXTERNAL-IP加端口來通路該服務,這是一個雲供應商提供的負載均衡器IP,在我們這個例子中就是10.13.242.236:8086。

Load Balancer類型Service的原理如圖3-17所示。

《Kubernetes網絡權威指南》讀書筆記 | 從叢集内通路服務

圖3-17 Load Balancer類型Service的原理

  1. NodePort

NodePort類似Service,被稱為乞丐版的Load Balancer類型Service。

NodePort為Service在Kubernetes叢集的每個節點上配置設定一個真實的端口,即NodePort。叢集内/外部可基于叢集内任何一個節點的IP:NodePort的形式通路Service。NodePort預設端口範圍是30000-32767,可以修改API Server的--service-node-port-range的參數自行定義。

一個典型的NodePort類型Service如下:

《Kubernetes網絡權威指南》讀書筆記 | 從叢集内通路服務

使用kubectl describe service可以看到,雖然Service的類型是NodePort,但是Kubernetes依然為其配置設定了一個Cluster IP,輸出如下:

《Kubernetes網絡權威指南》讀書筆記 | 從叢集内通路服務

以上輸出的IP字段即該Service的Cluster IP。

NodePort的實作機制是Kube-proxy會建立一個iptables規則,所有通路本地NodePort的網絡包都會被直接轉發至後端Port。

NodePort是解決服務對外暴露的最簡單方法,但NodePort的問題集中展現在性能和可對主控端端口占用方面。一旦服務多起來,NodePort在每個節點上開啟的端口會變得非常龐大且難以維護。

3.5.4KubernetesService發現

Kubernetes Service建立好後,如何使用它,即如何進行服務發現呢?

在Kubernetes中使用域名服務,即假設Service(my-svc)在namespace(my-ns)中,暴露名為http的TCP端口,那麼在Kubernetes的DNS伺服器中會生成兩種記錄,分别是A記錄:域名(my-svc.my-ns)到Cluster IP的映射和SRV記錄,例如_http._tcp.my-svc.my-ns到一個http端口号的映射。

3.5.5 特殊的無頭Service

所謂的無頭(headless)Service即沒有selector的Service。

在任何場景中,都能夠定義沒有selector的Service:

《Kubernetes網絡權威指南》讀書筆記 | 從叢集内通路服務

這個Service沒有selector,就不會建立相關的Endpoints對象。可以手動将Service映射到指定的Endpoints:

《Kubernetes網絡權威指南》讀書筆記 | 從叢集内通路服務

通路沒有selector的Service,與有selector的Service的原理相同。請求将被路由到使用者定義的Endpoint(該示例中為1.2.3.4:9376)。

3.5.6 怎麼通路本地服務

當通路NodePort或Load Balancer類型Service的流量到達時,流量可能會被轉發到其他節點上的Pod。這可能需要額外一跳的網絡。如果要避免額外的躍點,則使用者可以指定流量必須轉到最初接收流量的節點上的Pod。

要指定流量必須轉到同一節點上的Pod,可以将serviceSpec.externalTrafficPolicy設定為Local(預設是Cluster):

《Kubernetes網絡權威指南》讀書筆記 | 從叢集内通路服務

将externalTrafficPolicy設定為Local時,負載平衡器僅将流量發送到具有屬于服務的正常Pod所在的節點。