10.Service資源發現
Kubernetes Pods是不可控的
。每當一個pod停止後,他不是重啟,而是重建。ReplicaSets
特別是Pods
動態地創建和銷毀(例如,當向外擴展或向內擴展時)。雖然每個Pod
IP地址都有自己的IP地址,但即使這些IP地址也不能依賴它們保持穩定。這會導致一個問題:如果某些Pods
(讓我們稱之為後端)Pods
在Kubernetes集群內向其他人(讓我們稱之為前端)提供功能,那些前端如何找出並跟蹤該集合中的哪些後端?
依靠Service
Kubernetes Service
是一個抽象,它定義了一個邏輯集Pods
和一個訪問它們的策略 - 有時稱為微服務。Pods
a 的目標集合Service
例如,考慮一個運行3個副本的圖像處理後端。那些復制品是可替代的 - 前端並不關心它們使用哪個後端。雖然Pods
組成後端集的實際情況可能會發生變化,但前端客戶端不應該知道這一點,也不需要跟蹤後端列表本身。該Service
抽象可實現這種分離。
對於Kubernetes本地應用程序,Kubernetes提供了一個簡單的Endpoints
被更新的API,每當一組Pods
中Service
的變化。對於非本機應用程序,Kubernetes提供了一個基於虛擬IP的橋接服務,可以重定向到後端Pods
。
定義服務
Service
在Kubernetes是一個REST對象,類似於
Pod
。與所有REST對象一樣,Service
可以將定義POST到apiserver以創建新實例。例如,假設您有一組Pods
每個公開端口9376並帶有標簽"app=MyApp"
。
kind: Service apiVersion: v1 metadata: name: my-service spec: selector: app: MyApp ports: - protocol: TCP port: 80 targetPort: 9376
此規範將創建一個Service
名為“my-service” Pod
帶有"app=MyApp"
標簽的TCP端口9376為目標。這Service
也將被分配一個IP地址(有時稱為“ClusterIP”),由服務代理使用。本Service
的選擇將不斷進行評估,其結果將被張貼到一個Endpoints
還名為‘我的服務’的對象。
請註意,Service
可以將傳入端口映射到任何端口targetPort
。默認情況下,targetPort
將設置為與port
字段相同的值。也許更有趣的是,它targetPort
可以是一個字符串,指的是後端端口的名稱Pods
。分配給該名稱的實際端口號在每個後端可以不同Pod
。這為您的部署和發展提供了很大的靈活性Services
。例如,您可以更改pod在下一版本的後端軟件中公開的端口號,而不會破壞客戶端。
註意: SCTP支持是自Kubernetes 1.12以來的alpha功能
沒有選擇器的服務
服務通常抽象訪問Kubernetes Pods
,但它們也可以抽象其他類型的後端。例如:
- 您希望在生產中擁有外部數據庫集群,但在測試中您使用自己的數據庫。
- 您希望將服務指向另一個
Namespace
或另一個群集上的服務 。 - 您正在將工作負載遷移到Kubernetes,並且您的一些後端在Kubernetes之外運行。
在任何這些場景中,您都可以定義不帶選擇器的服務:
kind: Service
apiVersion: v1
metadata:
name: my-service
spec:
ports:
- protocol: TCP
port: 80
targetPort: 9376
由於此服務沒有選擇器,因此Endpoints
不會創建相應的對象。您可以手動將服務映射到您自己的特定端點:
kind: Endpoints
apiVersion: v1
metadata:
name: my-service
subsets:
- addresses:
- ip: 1.2.3.4
ports:
- port: 9376
註意:端點IP可能不是環回(127.0.0.0/8),鏈路本地(169.254.0.0/16)或鏈路本地多播(224.0.0.0/24)。它們不能是其他Kubernetes服務的集群IP,因為該kube-proxy
組件尚不支持虛擬IP作為目標。
訪問Service
沒有選擇器的方法與具有選擇器的方式相同。流量將路由到用戶定義的端點(1.2.3.4:9376
在此示例中)。
ExternalName服務是一種特殊情況的服務,它沒有選擇器而是使用DNS名稱。有關詳細信息,請參閱本文檔後面的 ExternalName部分。
虛擬IP和服務代理
Kubernetes集群中的每個節點都運行一個kube-proxy
。kube-proxy
負責實現Services
除以外類型的虛擬IP形式ExternalName
。
在Kubernetes v1.0中,Services
是一個“第4層”(TCP / UDP over IP)構造,代理純粹在用戶空間。在Kubernetes v1.1中,Ingress
添加了API(beta)來表示“第7層”(HTTP)服務,也添加了iptables代理,並成為自Kubernetes v1.2以來的默認操作模式。在Kubernetes v1.8.0-beta.0中,添加了ipvs代理。
代理模式:用戶空間
在這種模式下,KUBE代理手表的添加和去除Kubernetes主Service
和Endpoints
對象。對於每個Service
它,它在本地節點上打開一個端口(隨機選擇)。與此“代理端口”的任何連接都將代理到其中一個Service
後端Pods
(如報告中所述 Endpoints
)。使用哪個後端Pod
是基於 SessionAffinity
的Service
。最後,它安裝的防火墻規則,其捕獲流量的Service
的clusterIP
(這是虛擬的),並Port
和重定向的流量到代理服務器與後端的代理端口Pod
。默認情況下,後端的選擇是循環
代理模式:iptables
在這種模式下,KUBE代理手表的添加和去除Kubernetes主Service
和Endpoints
對象。對於每一個Service
,它安裝的防火墻規則,其捕獲業務到Service
的clusterIP
(這是虛擬的)和Port
與該通信重定向到的一個Service
的後端集。對於每個Endpoints
對象,它會安裝選擇後端的iptables規則Pod
。默認情況下,後端的選擇是隨機的。
顯然,iptables不需要在用戶空間和內核空間之間切換,它應該比用戶空間代理更快,更可靠。但是,與用戶空間proxier不同,如果iptables proxier Pod
最初選擇的那個沒有響應,則它不能自動重試另一個 ,因此它取決於具有工作就緒探測器
代理模式:ipvs
特征狀態:Kubernetes v1.9
在此模式下,kube-proxy監視Kubernetes服務和端點,調用netlink
接口以相應地創建ipvs規則並定期與Kubernetes服務和端點同步ipvs規則,以確保ipvs狀態與期望一致。訪問服務時,流量將被重定向到其中一個後端Pod。
與iptables類似,Ipvs基於netfilter鉤子函數,但使用哈希表作為底層數據結構並在內核空間中工作。這意味著ipvs可以更快地重定向流量,並且在同步代理規則時具有更好的性能。此外,ipvs為負載均衡算法提供了更多選項,例如:rr 輪詢 lc 最少連接 nq 沒有隊列 sha 源哈希 dha目標哈希 sed(最少時間)
多端口服務
許多人Services
需要暴露多個端口。對於這種情況,Kubernetes支持Service
對象的多個端口定義。使用多個端口時,必須提供所有端口名稱,以便可以消除端點的歧義。例如:
kind: Service apiVersion: v1 metadata: name: my-service spec: selector: app: MyApp ports: - name: http protocol: TCP port: 80 targetPort: 9376 - name: https protocol: TCP port: 443 targetPort: 9377
請註意,端口名稱只能包含小寫字母數字字符-
,並且必須以字母數字字符開頭和結尾。123-abc
並且web
是有效的,但123_abc
並-web
不能有效名稱。
發現服務
兩種方式一個實在pod的鏡像模板中指出Service的具體地址
REDIS_MASTER_SERVICE_HOST=10.0.0.11 REDIS_MASTER_SERVICE_PORT=6379 REDIS_MASTER_PORT=tcp://10.0.0.11:6379 REDIS_MASTER_PORT_6379_TCP=tcp://10.0.0.11:6379 REDIS_MASTER_PORT_6379_TCP_PROTO=tcp REDIS_MASTER_PORT_6379_TCP_PORT=6379 REDIS_MASTER_PORT_6379_TCP_ADDR=10.0.0.11
另一種是采用DNS解析方式
Serviename+namespace+集群默認域 通常為 svc.cluster.local.
發布服務 - 服務類型
對於應用程序的某些部分(例如前端),您可能希望將服務公開到外部(群集外部)IP地址。
Kubernetes ServiceTypes
允許您指定所需的服務類型。默認是ClusterIP
。
Type
價值觀及其行為是:
ClusterIP
:在集群內部IP上公開服務。選擇此值使服務只能從群集中訪問。這是默認值ServiceType
。NodePort
:在靜態端口(NodePort
)上公開每個節點IP上的服務。一個ClusterIP
服務,該NodePort
服務將路由,自動創建。您可以NodePort
通過請求從群集外部聯系服務<NodeIP>:<NodePort>
。LoadBalancer
:使用雲提供商的負載均衡器在外部公開服務。NodePort
和ClusterIP
服務,其外部負載平衡器將路線,自動創建。ExternalName
:通過返回包含其值的記錄,將服務映射到externalName
字段的內容 (例如foo.bar.example.com
)CNAME
。沒有設置任何類型的代理。這需要1.7或更高版本kube-dns
10.Service資源發現