.NET Core + Kubernetes:Service
通過 .NET Core + Kubernetes:Deployment 文章的介紹,我們可以通過 Deployment 控制器快速創建一組 Pod 來提供服務,每個 Pod 都會被分配一個集群內可見的虛擬 IP 地址,然后通過一個獨立的 Endpoint(Pod IP + ContainerPort)進行訪問。但在提供服務時,并不能依賴 Pod ?的 Endpoint,首先 Pod IP 會隨著 Pod 的重建而變化,另外同一組 Pod 更希望是以整體對外提供高可用服務,組內的 Pod 在進行動態伸縮、滾動更新等操作后并不能影響服務穩定性。
因此,Kubernetes 中的 Service 對象就是解決此問題的核心,Service 代理 Pod 集合對外表現是為一個訪問入口,它提供了一個虛擬的 IP 地址(ClusterIP)和端口,來自 ClusterIP + 端口 ?的請求將被負載均衡器 (kube-proxy)轉發到后端某個 Pod 中的容器。所以借助 Service 的能力,非常方便的實現了服務發現與負載均衡。
本文將主要介紹 Kubernetes 中各 Service 類型的使用,目前有以下四種類型:
ClusterIP:默認類型,自動分配一個僅集群內部可以訪問的虛擬 IP,也可使用 ClusterIP 字段指定固定 IP,選擇此類型意味著只想這個服務在集群內部才可以被訪問
NodePort:在 ClusterIP 基礎上,在集群的每一個節點綁定一個端口,這樣就可以通過任意的:NodePort 來訪問服務
LoadBalancer:在 NodePort 的基礎上,通過創建一個外部的負載均衡器,將流量轉發到每個節點:NodePort。因為如果外部所有客戶端都訪問一個 NodeIP,該節點的壓力將會很大,LoadBalancer 則可解決此問題
ExternalName:把集群外部的服務引入到集群內部來,在集群內部直接使用。沒有任何類型代理被創建,這只有 kubernetes 1.7 或更高版本的 kube-dns 才支持
下面分別對這幾種類型的使用方式進行介紹,在創建 Service 之前,還是先通過 Deployment 控制器創建一組 Pod,配置文件 k8sdemo-deployment.yaml 如下:
apiVersion: apps/v1 kind: Deployment metadata:name: k8sdemo-deployment spec:replicas: 3selector:matchLabels:name: k8sdemotemplate:metadata:labels:name: k8sdemospec:containers:- name: k8sdemoimage: beckjin/k8sdemo:1.0.0ports:- containerPort: 80imagePullPolicy: IfNotPresentClusterIP 類型
創建 k8sdemo-service.yaml 文件,配置如下,主要是 ?ports 和 selector 字段的設置,指定了 80 端口(port) 映射到 Pod ContainerPort (targetPort) 端口,最終將通過 ClusterIP:80 訪問服務。selector 字段指定將 label 含 name:k8sdemo 的 Pod 作為這個 Service 指向的目標服務。
apiVersion: v1 kind: Service metadata:name: k8sdemo-service spec:ports:- port: 80 # Service PorttargetPort: 80 # Pod ContainerPortselector:name: k8sdemo# clusterIP: 10.1.19.92 # 取消注釋指定IP執行命令 kubectl apply -f k8sdemo-service.yaml 創建 Service,然后通過 kubectl get service 查看服務狀態:
從上圖可以看出 k8sdemo-service 被分配的 ClusterIP 是 10.1.19.96,所以可以在服務器上通過 curl http://10.1.19.96/WeatherForecast 來訪問接口。
因為 ClusterIP 默認是自動分配的,所以每次重建會變化,如果需要固定,可通過 ClusterIP 字段設置。對于只需在集群內部提供的服務,ClusterIP 類型已足夠。
NodePort 類型
基于 ClusterIP 類型中使用的配置文件 k8sdemo-service.yaml,增加 type: NodePort 配置,重新創建 Service,如下:
apiVersion: v1 kind: Service metadata:name: k8sdemo-service spec:ports:- port: 80targetPort: 80# nodePort: 30080 # 取消注釋指定端口selector:name: k8sdemotype: NodePort從上圖可以看出,除了類型變了, PORT(S)也變成了 80:30231/TCP,即將 Service 的 80 端口與集群中各節點的 30231 端口進行映射,所以最終可以通過集群內任意的 NodeIP:30231 來訪問,整個過程為:Client > NodeIP:NodePort > ClusterIP:ServicePort > PodIP:ContainerPort。NodePort 默認分配的是 30000-32767 范圍內隨機選擇的一個端口,實際使用時可以通過 nodePort 字段指定。請求結果如下:
注:192.168.124.10 是集群內某一臺的 IP
LoadBalancer 類型
通過 NodePort 類型的使用介紹,已經了解可以通過 NodeIP:NodePort 方式來服務訪問,而且 NodeIP 可以是集群內任意任何一臺的 IP。而 LoadBalancer 則是在外層附加的負載均衡器,使請求能分攤到集群內各個節點上。
MetalLB 搭建
要使用 LoadBalancer 類型會稍微復雜一些,并不能只單純的修改配置文件,因為一般自建的 Kubernetes 集群默認并不支持 LoadBalancer,所以它需要借助外部的負載均衡器來實現,這里將使用 MetalLB[1] (v0.9.3),安裝請參考 Installation By Manifest[2] ,步驟不復雜,但需要確保依賴鏡像下載順利,完成后查看 Pod 狀態:
另外需要為 Metallb 設置地址池以及協議相關配置,Metallb 會監控服務對象的變化,當有新的 LoadBalancer 服務運行,但沒有可申請的負載均衡器時,就會從配置的地址池中分配一個給該服務。這里以 Metallb Layer2 工作模式為例(Metallb 支持 Layer2/BGP 兩種工作模式),創建一個資源類型為 ConfigMap 的配置文件 metallb-layer2-config.yaml,內容如下:
apiVersion: v1 kind: ConfigMap metadata:namespace: metallb-systemname: config data:config: |address-pools:- name: defaultprotocol: layer2addresses:- 192.168.124.200-192.168.124.210 # IP 地址范圍需與自己的集群環境對應Layer2 ?工作模式原理圖:
配置修改
有了以上的準備工作后,只需要在 Service 配置文件將 type 修改為 LoadBalancer ,然后重新創建 Service,如下:
apiVersion: v1 kind: Service metadata:name: k8sdemo-service spec:ports:- port: 80targetPort: 80selector:name: k8sdemotype: LoadBalancer從上圖可以看出,TYPE 已是 LoadBalancer,另外 EXTERNAL-IP 被分配為地址池中的 192.168.124.200,接下來就可以通過這個 IP 進行訪問了,結果如下:
ExternalName
ExternalName 類型比較特殊,它沒有 selector,也沒有定義任何的端口, 對于運行在集群外部的服務,它通過返回該外部服務的別名這種方式來提供服務,如下:
apiVersion: v1 kind: Service metadata:name: k8sdemo-external-service spec:type: ExternalNameexternalName: mingdao.com當訪問 k8sdemo-external-service.default.svc.cluster.local 時,集群的 DNS 服務將返回值為 mingdao.com 的 CNAME 記錄,訪問這種類型的服務與其它的唯一不同的是重定向發生在 DNS 層,而且不會進行代理或轉發。
進入 Kubernetes 集群的任意一個 Pod 中(必須是集群內部才可訪問),如:kubectl exec -it k8sdemo-deployment-68cb864ff6-fzzdq -- /bin/bash,執行 curl -L http://k8sdemo-external-service.default.svc.cluster.local/ 即會重定向請求到 mingdao.com,結果如下:
參考資料
[1]
MetalLB: https://metallb.universe.tf/
[2]Installation By Manifest: https://metallb.universe.tf/installation/#installation-by-manifest
總結
以上是生活随笔為你收集整理的.NET Core + Kubernetes:Service的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 第五站 使用winHex利器加深理解数据
- 下一篇: EventBus/EventQueue