Kubernetes(四):Service

目錄

一、定義Service

? 1.1 type=ClusterIP

?? 1.2 type=NodePort

?? 1.3?type=LoadBalancer

?? 1.4?type=ExternalName

?? 1.5 無標簽選擇器的Service

?? 1.6?Headless?Service

二、Kubernetes的服務發現

? ?2.1?環境變量方式

? ?2.2 DNS方式


????????Kubernetes 中 Service 是 將運行在一個或一組?Pod?上的應用程序對外暴露出去的方法。這樣多個相同功能容器可以對外提供統一的訪問入口。

? ? ? ?Service解決了:

  • 避免直接訪問Pod,因為Pod的數量和IP都可能發生變化。而通過Service可以提供穩定的統一入口。
  • 提供了負載均衡機制(包括后端Pod自動注冊和發現)

一、定義Service

? ? 定義Service的yaml常見字段含義說明如下:

apiVersion: v1
kind: Service
metadata:name: namespace:labels: []anotations: []
spec:selector: []             # 標簽選擇器,選擇滿足條件的后端Podtype:                    # Service的公開暴露類型,type可取值(首字母大寫):ClusterIP默認、NodePort、LoadBalancer、ExternalNameclusterIP:               # 分配給該Service的IP地址列表。type=ClusterIP或NodePort時,若不手動指定IP則自動分配(在kubeadm init指定的網段范圍內);若填值None則為Headless服務sessionAffinity:        # 可取值:ClientIP、None默認。若配置為ClientIP表示對收到同個客戶端IP的訪問請求每次都轉發到同個后端Pod上。ports:                   # 端口列表,列表多個須分別指定端口的name- name:                  # 端口名。若僅有一個port,可不設置此字段protocol:              # 協議。可取值: TCP默認、UDP、SCTPport:                  # Service在clusterIP上的監聽端口nodePort:              # 當type=NodePort或LoadBalancer時,在每個節點機器上的分配端口(端口允許范圍30000-32767)。targetPort:            # 轉發至后端Pod上的端口,若未指定則等于port
status:                    # 當type=LoadBalancer時設置外部負載均衡器地址,比如公有云環境loadBalancer:            # 外部負載均衡器ingress:               # 外部負載均衡器ip:                  # 外部負載均衡器的IP地址hostname:            # 外部負載均衡器的主機名

? 1.1 type=ClusterIP

在前文【Kubernetes(三):Workload工作負載-CSDN博客】已經創建Deployment的基礎上(Pod的標簽是app=nginx, Pod內容器端口為80)。然后通過以下nginx-service.yaml文件,創建一個Service:

apiVersion: v1
kind: Service
metadata:name: nginx-service
spec:selector:                # 標簽選擇器,選擇滿足條件的后端Podapp: nginxtype: ClusterIPports:- port: 55580            # Service在clusterIP上的監聽端口targetPort: 80         # 轉發至后端Pod上的端口,若未指定則等于port
kubectl apply -f nginx-service.yaml# 以下service可簡寫svc
kubectl get service -o widekubectl describe service/nginx-service

注:kube-apiserver本身也是一個Service,名字為kubernetes。 該service的ClusterIP是地址池中第一個IP,端口是HTTPS的443。如上圖。

Service中的Endpoints是后端Pod的地址列表。如果Pod發生變化,Kubernetes會自動維護Service的EndPoints地址列表,自動保持最新。

Kubernetes集群內(包括集群節點機器、Pod容器內)可通過命令訪問Service的虛擬IP和端口來訪問后端的Pod:curl http://172.16.242.61:55580

默認情況,訪問請求會被Service均衡分發給后端Pod之一。

?? 1.2 type=NodePort

? ? ?在上文type=ClusterIP的例子中,因為值在服務虛擬IP(clusterIP)上監聽,所以只能在Kubernetes集群內(包括集群節點機器及容器內)才能訪問到該Service。

? ? 若希望從Kubernetes集群外也可以訪問Service,則需把改type=NodePort。NodePort是建立在type=ClusterIP的基礎上,并在每個節點機器上分配一個nodePort端口。通過該nodePort端口訪問的請求,Service也可以分發到與后端Pod的Endpoints。

apiVersion: v1
kind: Service
metadata:name: nginx-service
spec:selector:                # 必選。標簽選擇器,選擇滿足條件的后端Podapp: nginxtype: NodePortports:- port: 55580            # Service在clusterIP上的監聽端口nodePort: 32000        # 當type=NodePort或LoadBalancer時,在每個節點機器上的分配端口(端口允許范圍默認30000-32767)。targetPort: 80         # 轉發至后端Pod上的端口,若未指定則等于port
kubectl apply -f nginx-service.yaml# 以下service可簡寫svc
kubectl get service -o widekubectl describe service/nginx-service

不僅可以從Kubernetes集群內(包括集群節點機器、Pod容器內)可通過命令訪問Service的虛擬IP和端口來訪問后端的Pod:curl http://172.16.167.197:55580

并且還可以從Kubernetes集群外訪問,訪問地址為:任意一個節點機器IP:nodePort? ?如下圖:

雖然可以通過節點機器IP訪問,但在節點機器操作系統上通過netstat命令是無法看到nodePort偵聽端口。這是因為沒有采用通常的直接監聽方式,而是kube-proxy利用操作系統的代理模式來轉發。

kube-proxy的--proxy-mode選項指定轉發的代理模式,當節點機器是Linux則可為ipvs或iptables模式(不手工指定時,若Linux操作系統加載啟用了IPVS內核,kube-proxy會自動優先選擇IPVS模式,否則切換iptables模式);當節點機器是Windows則為kernelspace模式。

?? 1.3?type=LoadBalancer

? ? ?type=LoadBalancer是基于NodePort的基礎上構建并創建一個外部負載均衡器,通過該外部負載均衡器路由到與 clusterIP 相同的 Endpoints。

? ? type=LoadBalancer主要用于云平臺環境。Service使用云平臺負載均衡器,Kubernetes不直接提供負載均衡。這要求云平臺能夠監控Kubernetes的Service資源對象創建過程,云平臺負載均衡器中upstream值自動配置為Service的Endpoints列表,同時云平臺還能對Kubernetes的Service的Status信息補充配置好的負載均衡器的IP地址。這樣外部客戶端就可以通過云平臺負載均衡器IP及Service端口進行訪問后端Pod服務了。

? ? 默認情況:對于type=LoadBalancer的Service會默認開啟節點機器NodePort,這是為了讓負載均衡器能夠通過Node節點IP來訪問內部Pod。 從v1.24版開始,Service配置中提供了一個布爾類型字段allocateLoadBalancerNodePorts來指定是否分配NodePort(默認為true)。僅當云平臺負載均衡器能夠直接將流量路由到 Pod 而無需使用節點機器端口的情況才設置為false。

?? 1.4?type=ExternalName

? ? ?type=ExternalName是將 Service 映射到指定的目標域名或IP。相當于對目標域名或IP設置別名。

??下面externalname-service.yaml

apiVersion: v1
kind: Service
metadata:name: externalname-service
spec:type: ExternalNameexternalName: www.baidu.com
kubectl apply -f externalname-service.yaml# 以下service可簡寫svc
kubectl get service -o widekubectl describe service/externalname-service

注:type=ExternalName的Service沒有Endpoints,也沒有為服務分配ClusterIP。

Kubernetes對服務自動生成的域名格式為:<ServiceName>.<namespace>.svc.<clusterDomain>?

Kubernetes集群內(包括集群節點機器、Pod容器內)可通過該服務域名訪問,既自動訪問externalName指定的目標域名。本例中訪問?curl http://externalname-service.default.svc.cluster.local??相當于訪問www.baidu.com

?? 1.5 無標簽選擇器的Service

? ? 上文type=ExternalName的Service沒有Endpoints,也沒有為服務分配ClusterIP。 除上文外,還可以通過基于type=ClusterIP類型來將外部服務定義為Service,這種將外部服務定義為Service也稱為沒有標簽選擇器的Service (Services without selectors)。

? ? ?普通type=ClusterIP的Service通過selector標簽選擇器對后端Pod的Endpoints列表進行了抽象封裝,如果后端的Endpoints不是由Pod提供,而是在Kubernetes之外的其他服務提供。在Kubernetes里的一些應用也需要訪問這些外部服務,典型場景為:

  • 非Kubernetes管理的服務。例如單獨部署的數據庫、Redis、或者其他服務。
  • 從一個Kubernetes集群訪問另一個Kubernetes集群。

本場景中,在創建Service時不設置selector標簽選擇器(也無后端Pod可選)。由于此 Service 沒有選擇器,因此不會自動創建對應的 EndpointSlice 對象。需要手工在EndpointSlice定義外部服務的IP地址和端口號。

注意:從v1.33版開始,Endpoints已被標記為deprecated。所以低版本Kubernetes可使用Endpoints,高版本Kubernetes應當使用EndpointSlice。

為演示,先通過python啟動簡易Web,模擬已存在的外部服務

# 若python版本為2.x
python -m SimpleHTTPServer 9999# 若python版本為3.x
python -m http.server 9999

下面outside-service.yaml

---
apiVersion: v1
kind: Service
metadata:name: outside-service
spec:ports:- port: 21212            # Service在clusterIP上的監聽端口targetPort: 1111       # 此情況因為不使用targetPort,所以配成什么端口都無所謂
---
apiVersion: discovery.k8s.io/v1
kind: EndpointSlice
metadata:name: outside-service    # 習慣上,將Service名稱作為EndpointSlice名稱前綴labels:# 須設置 "kubernetes.io/service-name" 標簽,以選擇匹配Servicekubernetes.io/service-name: outside-service
addressType: IPv4          # 取值范圍:IPv4、IPv6、FQDN
ports:                     # 若列表多個須分別指定端口name(且name值須與Service中spec.ports.name字段值匹配一致)- port: 9999
endpoints:  # 此列表中的 IP 地址可以按任何順序顯示- addresses:- "192.168.43.49"
kubectl apply -f outside-service.yaml# 以下service可簡寫svc
kubectl get service -o widekubectl describe service/outside-servicekubectl get endpointslices

可以在Kubernetes集群內(包括集群節點機器、Pod容器內)可通過命令訪問Service的虛擬IP和端口來訪問外部服務。curl http://172.16.155.209:21212

?? 1.6?Headless?Service

? ? 在某些場景場景中,不需要Service提供負載均衡功能,也不需要Service的ClusterIP。而是直接對后端Pod進行指定訪問,因此只需要Service為后端每個Pod生成一個子域名。這是可以創建一個與普通Service不同的Headless Service。Headless Service既是沒有入口訪問地址(服務無ClusterIP),kube-proxy不會為其創建負載轉發規則。

? ? 有標簽選擇器的Headless Service

? ? 如果Headless Service配置了標簽選擇器,則Kubernetes根據匹配選擇的后端Pod,自動創建Endpoints列表。此Headless Service會將DNS解析機制設為:①服務域名可得到后端所有Pod的IP列表(而不是單獨的一個ClusterIP);②還會為每個Pod都創建一個子域名,便于對特定某個Pod進行指定訪問或識別。

? ?示例可以參考:https://blog.csdn.net/zyplanke/article/details/150985065?中StatefulSet章節。

? ? 無標簽選擇器的Headless Service

? ? 如果Headless Service沒有配置標簽選擇器,則Kubernetes不會自動創建對應的Endpoints列表。Kubernetes的DNS會根據如下條件嘗試對該Service設置DNS解析:

  • 對于 type=ExternalName,將配置的externalName嘗試作為對應的?CNAME 記錄。
  • 對所有其他類型的 Service,對Service后端處于Ready狀態的Endpoints既Endpointslices創建DNS記錄。對于 IPv4 端點,DNS 系統創建 A 記錄;?對于 IPv6 端點,DNS 系統創建 AAAA 記錄。

二、Kubernetes的服務發現

? ? 對于在集群內運行的客戶端,Kubernetes 支持兩種Service發現模式:環境變量和DNS。

? ?2.1?環境變量方式

? ??當 Pod 運行時,kubelet 會自動為其注入以“KUBERNETES_”開頭的環境變量。

? ? ?除此環境變量外,根據當前已經存在且活躍?Service,kubelet還會對新創建的Pod自動為已存在的Service生成一組環境變量添加到Pod容器中。 kubelet添加的環境變量包括:

  • {SVCNAME}_SERVICE_HOST
  • {SVCNAME}_SERVICE_PORT
  • {SVCNAME}_PORT

這里 Service 名稱被轉為大寫字母,橫線被轉換成下劃線。

在新創建Pod容器中,可以從環境變量獲取需要訪問的目的Service的地址了。

? ?2.2 DNS方式

? ? 對于環境變量方式,要求Service必須先于Pod創建好。這實際上對部署順序提出了較為苛刻的要求,而使用DNS方式就不存在此問題。 ?對于客戶端而言,DNS域名方式提供了一種穩定的、不變的訪問方式,可以簡化客戶端配置,是Kubernetes推薦的方式

? ?Service遵從DNS命名規范:

Service的DNS域名命名規則:<ServiceName>.<namespace>.svc.<clusterDomain>?

? ?如果Service中的port端口號指定了名稱name,則該端口號也擁有DNS域名:

Service端口的DNS域名命名規則:_<PortName>._<Protocal>.<ServiceName>.<namespace>.svc.<clusterDomain>?

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/news/921805.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/921805.shtml
英文地址,請注明出處:http://en.pswp.cn/news/921805.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

在 Python 中實現觀察者模式的具體步驟是什么?

在 Python 中實現觀察者模式可以遵循以下具體步驟&#xff0c;這些步驟清晰地劃分了角色和交互流程&#xff1a; 步驟 1&#xff1a;定義主題&#xff08;Subject&#xff09;基類 主題是被觀察的對象&#xff0c;負責管理觀察者和發送通知。需實現以下核心方法&#xff1a; 存…

分布式方案 一 分布式鎖的四大實現方式

Java分布式鎖實現方式詳解 什么是分布式鎖 基于數據庫的分布式鎖基于Redis的分布式鎖基于ZooKeeper的分布式鎖基于Etcd的分布式鎖 各種實現方式對比最佳實踐建議多節點/線程調用結果展示 基于數據庫的分布式鎖 - 多線程測試基于Redis的分布式鎖 - 多節點測試基于ZooKeeper的分…

基于Room+RESTful的雙權限Android開機時間監控方案

概述 以下是使用Kotlin實現的商業級Android開機時間記錄功能&#xff0c;包含現代Android開發最佳實踐。 系統架構 組件設計 // BootReceiver - 接收開機廣播 class BootReceiver : BroadcastReceiver() {override fun onReceive(context: Context, intent: Intent?) {if (int…

水庫大壩安全監測系統的作用

水庫大壩作為重要的水利基礎設施&#xff0c;承擔著防洪、供水、發電、灌溉等多重功能&#xff0c;其安全性直接關系到人民生命財產安全和社會經濟發展。然而&#xff0c;由于自然環境變化、材料老化、荷載作用以及人為因素的影響&#xff0c;大壩在長期運行過程中可能出現裂縫…

《Kubernetes 構建 MySQL MGR 集群實戰教程》

#### 一、前言 MySQL Group Replication (MGR) 是 MySQL 官方提供的高可用集群方案&#xff0c;基于 Paxos 協議實現多節點數據強一致性。本教程將指導如何在 Kubernetes 上部署 MySQL MGR 集群&#xff0c;適用于生產級高可用場景。---#### 二、環境準備 1. **Kubernetes 集…

影視APP源碼 SK影視 安卓+蘋果雙端APP 反編譯詳細視頻教程+源碼

內容目錄一、詳細介紹二、效果展示1.部分代碼2.效果圖展示三、學習資料下載一、詳細介紹 影視APP源碼 SK影視 安卓蘋果雙端APP 反編譯詳細視頻教程源碼 自帶對接優效SDK廣告&#xff08;已失效&#xff09;。域名和IP都可以搭建。 自帶一起看和短劇頁面功能&#xff0c;三種…

pyqt+python之二進制生肖占卜

目錄 一、引言 二、GUI界面設計 1.效果演示 2.相關提示 3.界面設計.py 三、主要程序詳解 1.導入相關模塊 2.初始化設置 3.組內判斷 4.猜測過程 四、總程序代碼 一、引言 在數字時代&#xff0c;傳統文化與編程語言的碰撞總能迸發奇妙火花。本項目以PyQtPython為技術…

人工智能-python-深度學習-經典網絡模型-LeNets5

文章目錄LeNet-5&#xff08;詳解&#xff09;—— 從原理到 PyTorch 實現&#xff08;含訓練示例&#xff09;簡介LeNet-5 的核心思想LeNet-5 逐層結構詳解逐層計算舉例&#x1f4cc; 輸入層&#x1f4cc; C1 卷積層&#x1f4cc; S2 池化層&#x1f4cc; C3 卷積層&#x1f4…

機器視覺的手機柔性屏貼合應用

在智能手機制造領域&#xff0c;柔性屏逐漸成為智能手機的主流選擇&#xff0c;柔性屏因其輕便、易于彎曲的特性&#xff0c;已成為現代電子設備的重要組成部分&#xff0c;但同時也帶來了前所未有的制造挑戰。柔性屏與傳統剛性玻璃屏有本質區別&#xff0c;它容易形變&#xf…

貪心算法應用:數字孿生同步問題詳解

Java中的貪心算法應用&#xff1a;數字孿生同步問題詳解 貪心算法是一種在每一步選擇中都采取在當前狀態下最好或最優&#xff08;即最有利&#xff09;的選擇&#xff0c;從而希望導致結果是全局最好或最優的算法。下面我將全面詳細地講解貪心算法在數字孿生同步問題中的應用。…

UOS20系統安裝與 SSH/XRDP 遠程訪問功能配置指南

UOS20系統安裝與 SSH/XRDP 遠程訪問功能配置指南 一、UOS 20 系統安裝? ?1. 下載系統鏡像? 訪問統信官網下載 UOS 20 專業版鏡像&#xff08;推薦適配當前硬件的版本&#xff09;&#xff1a; https://www.chinauos.com/resource/download-professional 2. 系統安裝與硬件配…

【Python】S1 基礎篇 P5 字典模塊指南

目錄字典的本質與底層實現基礎語法結構使用字典訪問字典中的值添加鍵值對修改字典中的值刪除鍵值對使用 get() 來訪問值遍歷字典遍歷所有鍵值對遍歷字典中的所有鍵遍歷字典中的所有值嵌套字典列表在字典中存儲列表字典&#xff08;Dictionary&#xff09;是Python中靈活且強大的…

計算機視覺之多模板匹配

簡介 計算機視覺第一課opencv&#xff08;四&#xff09;保姆級教學 之前說過模糊匹配只是對于單個目標進行匹配&#xff0c;今天我們就來學習一下如何對多個目標進行匹配 一、多目標匹配 對于這個圖片我們要匹配下面那個箭頭&#xff0c;我們可以發現圖中是有兩個位置相同的…

封裝日期選擇器組件,帶有上周,下周按鈕

ui圖組件代碼如下&#xff1a; <template><div><el-date-pickerv-model"dateRange"type"daterange"align"right"size"mini":editable"false"unlink-panelsrange-separator"至"start-placeholder&q…

基于SpringBoot+MYSQL開發的AI智能大數據醫療診斷平臺

角色&#xff1a; 管理員、醫生、居民 技術&#xff1a; SpringBoot、MyBatis、MySQL、Shiro、Beetl、Swagger、jQuery、Bootstrap 核心功能&#xff1a; 這是一個基于SpringBoot的社區醫療管理平臺&#xff0c;旨在為管理員提供用戶、角色、部門、菜單、日志等系統管理功能&am…

【MFC 小白日記】對話框編輯器里“原型圖像”到底要不要勾?3 分鐘看懂!

摘要&#xff1a;本文解析了MFC中Picture Control的"原型圖像(Prototype Image)"屬性的真實作用。該屬性僅在設計時提供可視化的占位圖預覽&#xff0c;方便UI布局&#xff0c;運行時不會影響程序表現。文章通過對比實驗驗證&#xff0c;勾選后會在對話框編輯器中顯示…

微信開放平臺第三方平臺,可以管理多個微信小程序

大家好&#xff0c;我是小悟。 這個系統可以幫助服務商更好地管理多個商家小程序&#xff0c;無需管理多個商家小程序的賬號密碼或者appId和secret&#xff0c;大大提升效率。 不需要頻繁登錄小程序后臺就能完成上傳代碼、認證、備案、提交代碼審核、發布小程序等操作。 這里錄…

Java全棧學習筆記32

-- drop table t_stu;-- unique 唯一約束的列允許為null-- 如果在之后的操作中。需要某列必須為key&#xff0c;才能做一些操作的情況下。也可以使用唯一約束代替主鍵約束-- create table t_stu(-- studId int,-- tel varchar(11) unique,-- sex varchar(1),-- addr va…

linux升級系統,重啟出現Minimal BASH-like line editingis supported

文章目錄一.問題背景二.解決步驟2.1確認系統分區2.2手動引導2.3 重建grub引導2.4 還原軟件包 一.問題背景 閑來無事&#xff0c;把ubuntu25.04通過sudo do-release-upgrade命令升級到了ubuntu25.10.在升級的過程會出現以下問題 1.自動替換flatpak程序為snap2.請求是否清除舊依賴…

type(類型別名)和 interface的區別和最佳實踐

核心結論在大多數情況下&#xff0c;它們可以互換使用&#xff0c;都能描述對象的結構。它們的區別更多在于設計和擴展能力上。主要區別總結表特性interface (接口)type (類型別名)擴展方式使用 extends 繼承interface A extends B {}使用 & 交叉類型type A B & C合并…