【Kubernetes】Kubernetes的Service外部訪問方式:NodePort和LoadBalancer

Kubernetes的Pod的壽命是有限的,它們不會復活,所以儘管每一個Pod都有本身的IP地址,可是這些IP地址是不可靠的,會隨着Pod的消亡而消失。前端

這就帶來一個問題,若是一些Pod的集合(稱之爲backends)爲集羣的其餘的Pod(稱之爲frontends),這些frontends應該如何找到並一直知道哪些backends在這樣的集合中呢?node

 

這就須要引入Service, 一個kubernetes的service是一種抽象,它定義了一個Pod的邏輯集合和一個用於訪問它們的策略。一個Service的目標Pod的集合一般是由Label Selector來決定的。後端

舉個例子,想象一個處理圖片的後端運行了三個副本。這些副本都是能夠替代的,前端不關心它們使用的是哪個後端。儘管實際組成後端集合的Pod可能會變化,前端的客戶端卻不須要知道這個變化,也不須要本身有一個列表來記錄這些後端服務。Service抽象能讓你達到這種解耦。api

 

對於那些Kubernetes原生的應用,Kubernetes提供了一個簡單的Endpoints API,會在Service中的Pod集合發生改變的時候更新。對於非Kubernetes原生的應用,Kubernetes爲Service提供了一種基於虛擬IP的橋接方式使其重定向到後端的Pods。網絡

 

定義一個Service

Kubernetes中的Service是一個REST對象,這點與Pod相似。正如全部的REST對象同樣,向apiserver POST一個Service的定義就能建立一個新的實例。例如,假設你有一組Pods,每個Pod都開放了9376端口,而且都有一個"app=MyApp"的標籤。app

 

{ "kind": "Service", "apiVersion": "v1", "metadata": { "name": "my-service" }, "spec": { "selector": { "app": "MyApp" }, "ports": [ { "protocol": "TCP", "port": 80, "targetPort": 9376 } ] } }

 

這個定義會建立一個新的Service對象,名字爲」my-service」,它指向全部帶有」app=MyApp」標籤的Pod上面的9376端口。這個Service同時也會被分配一個IP地址(有時被稱做」cluster ip」),它會被服務的代理所使用(見下面)。這個Service的選擇器,會不斷的對Pod進行篩選,並將結果POST到名字一樣爲「my-service」的Endpoints對象。負載均衡

注意一個Service能將一個來源的端口映射到任意的targetPort。默認狀況下,targetPort會被設置成與port字段同樣的值。可能更有意思的地方在於,targetPort能夠是一個字符串,能引用一個後端Pod中定義的端口名。實際指派給該名稱的端口號在每個Pod中可能會不一樣。這爲部署和更新你的Service提供了很大的靈活性。例如,你能夠在你的後端的下一個版本中更改開放的端口,而無需致使客戶出現故障。frontend

Kubernetes的Service支持TCP和UDP協議。默認是TCP。異步

 

 

發佈 services - service的類型

Kubernetes的ServiceTypes能讓你指定你想要哪種服務。默認的和基礎的是ClusterIP,這會開放一個服務能夠在集羣內部進行鏈接。NodePort 和LoadBalancer是兩種會將服務開放給外部網絡的類型。spa

ServiceType字段的合法值是:

ClusterIP: 僅僅使用一個集羣內部的IP地址 - 這是默認值。選擇這個值意味着你只想這個服務在集羣內部才能夠被訪問到。

NodePort: 在集羣內部IP的基礎上,在集羣的每個節點的端口上開放這個服務。你能夠在任意<NodeIP>:NodePort地址上訪問到這個服務。

LoadBalancer: 在使用一個集羣內部IP地址和在NodePort上開放一個服務以外,向雲提供商申請一個負載均衡器,會讓流量轉發到這個在每一個節點上以<NodeIP>:NodePort的形式開放的服務上。

在使用一個集羣內部IP地址和在NodePort上開放一個Service的基礎上,還能夠向雲提供者申請一個負載均衡器,將流量轉發到已經以NodePort形式開發的Service上。

注意儘管NodePort能夠是TCP或者UDP的,對於Kubernetes 1.0來講,LoadBalancer還支持TCP。

 

NodePort類型

若是你把type字段設置爲"NodePort",Kubernetes的master就會從由啓動參數配置的範圍(默認是:30000-32767)中分配一個端口,而後每個Node都會將這個端口(在每個Node上相同的端口)代理到你的Service。這個端口會被寫入你的Service的spec.ports[*].nodePort字段中。

若是你想要一個特定的端口號,你能夠在nodePort字段中指定一個值,確保系統能爲你分配這個端口,不然API請求將會失敗(例如你須要本身處理可能出現的端口衝突)。你指定的值必須在節點端口配置的範圍內。

這給了開發者了設置他們本身的負載均衡器的自由,配置那些沒有被Kubernetes徹底支持的雲環境,或者甚至能夠直接開放一個或者多個節點的IP。

這種Service能夠同時以<NodeIP>:spec.ports[*].nodePort和spec.clusterIp:spec.ports[*].port的形式訪問。

 

LoadBalancer類型

在那些支持外部負載均衡器的雲提供者上面,將type字段設置爲"LoadBalancer"會爲你的Service設置好一個負載均衡器。該負載均衡器的實際的建立是異步進行的,而且該設置好均衡器會在該Service的status.loadBalancer字段中顯示出來。例如:

 

{ "kind": "Service", "apiVersion": "v1", "metadata": { "name": "my-service" }, "spec": { "selector": { "app": "MyApp" }, "ports": [ { "protocol": "TCP", "port": 80, "targetPort": 9376, "nodePort": 30061 } ], "clusterIP": "10.0.171.239", "loadBalancerIP": "78.11.24.19", "type": "LoadBalancer" }, "status": { "loadBalancer": { "ingress": [ { "ip": "146.148.47.155" } ] } }

 

從外部負載均衡器的流量將會被引到後端的Pod,然而具體這個如何實現則要看雲提供商。一些雲提供商容許指定loadBalancerIP。在這種場景,負載均衡器將隨用戶指定的loadBalancerIP一塊兒建立。若是字段loadBalancerIP沒有指定,該負載均衡器會被指定一個短暫性的IP。若是指定了loadBalancerIP,可是雲提供商不支持這個特性,這個字段會被忽略。

相關文章
相關標籤/搜索