Kubernetes中的service使用及說(shuō)明
在 Kubernetes(K8s)生態(tài)中,Service 是核心資源之一,其核心作用是解決 Pod 的動(dòng)態(tài)性問(wèn)題 —— 通過(guò)為一組功能相同的 Pod 提供一個(gè)固定的訪問(wèn)入口(IP 和端口),實(shí)現(xiàn)對(duì) Pod 的負(fù)載均衡和服務(wù)發(fā)現(xiàn),屏蔽 Pod 頻繁創(chuàng)建、銷毀、IP 變化帶來(lái)的訪問(wèn)波動(dòng)。
一、Service 的核心價(jià)值:為何需要 Service?
Pod 是 K8s 中最小的部署單元,但存在天然的 “不穩(wěn)定性”:
- IP 動(dòng)態(tài)變化:Pod 重啟、重建(如 Deployment 擴(kuò)縮容、節(jié)點(diǎn)故障遷移)后,IP 會(huì)重新分配;
- 訪問(wèn)入口不固定:若直接通過(guò) Pod IP 訪問(wèn),一旦 Pod 變化,客戶端需手動(dòng)更新目標(biāo) IP,無(wú)法自動(dòng)化。
Service 正是為解決這些問(wèn)題而生,其核心價(jià)值可概括為三點(diǎn):
- 固定訪問(wèn)入口:Service 創(chuàng)建后會(huì)分配一個(gè)集群內(nèi)固定的虛擬 IP(ClusterIP) 和端口,客戶端只需訪問(wèn)該 IP:Port,無(wú)需關(guān)注后端 Pod 的具體 IP;
- Pod 負(fù)載均衡:Service 會(huì)自動(dòng)將請(qǐng)求分發(fā)到后端健康的 Pod 上(默認(rèn)輪詢策略),實(shí)現(xiàn)流量分?jǐn)偅?/li>
- 服務(wù)發(fā)現(xiàn):結(jié)合 K8s 的 DNS 組件(如 CoreDNS),Service 可通過(guò) “服務(wù)名” 被集群內(nèi)其他 Pod 訪問(wèn)(如
http://<service-name>.<namespace>.svc.cluster.local),無(wú)需硬編碼 IP。
二、Service 的工作原理:流量如何流轉(zhuǎn)?
Service 的實(shí)現(xiàn)依賴 kube-proxy(每個(gè)節(jié)點(diǎn)上運(yùn)行的網(wǎng)絡(luò)代理組件)和 iptables/IPVS(Linux 內(nèi)核的流量轉(zhuǎn)發(fā)機(jī)制),核心流程如下:
- Service 創(chuàng)建:用戶通過(guò) YAML/CLI 創(chuàng)建 Service 后,K8s 控制器會(huì)為其分配 ClusterIP(僅集群內(nèi)可見(jiàn)),并關(guān)聯(lián)后端 Pod(通過(guò)
selector匹配 Pod 標(biāo)簽); - kube-proxy 同步規(guī)則:每個(gè)節(jié)點(diǎn)的 kube-proxy 會(huì)監(jiān)聽(tīng) K8s API,實(shí)時(shí)同步 Service 和 Pod 的信息,并在節(jié)點(diǎn)內(nèi)核中配置 iptables/IPVS 規(guī)則;
- 流量轉(zhuǎn)發(fā):當(dāng)客戶端(如集群內(nèi)其他 Pod)訪問(wèn) Service 的 ClusterIP:Port 時(shí),請(qǐng)求會(huì)被節(jié)點(diǎn)內(nèi)核的 iptables/IPVS 規(guī)則攔截,轉(zhuǎn)發(fā)到后端任意一個(gè)健康的 Pod 的 IP:Port;
- 健康檢查:Service 依賴 Pod 的 就緒探針(Readiness Probe) 判斷 Pod 是否可用 —— 若 Pod 未通過(guò)就緒探針,會(huì)被從 Service 的后端列表中移除,不再接收流量。
三、Service 的核心組成:YAML 配置解析
Service 的配置通過(guò) YAML 文件定義,核心字段如下(以最常見(jiàn)的 ClusterIP 類型為例):
apiVersion: v1 # Service 屬于 v1 版本 API
kind: Service # 資源類型為 Service
metadata:
name: my-service # Service 名稱(集群內(nèi) DNS 解析的核心標(biāo)識(shí))
namespace: default # 所屬命名空間(默認(rèn) default,不同命名空間的 Service 需加命名空間訪問(wèn))
spec:
type: ClusterIP # Service 類型(核心字段,決定訪問(wèn)范圍)
selector: # 標(biāo)簽選擇器:匹配后端 Pod 的標(biāo)簽(關(guān)鍵!Service 僅轉(zhuǎn)發(fā)匹配 Pod 的流量)
app: my-app # 假設(shè)后端 Pod 有標(biāo)簽 app=my-app
ports: # 端口映射規(guī)則(可配置多個(gè) port)
- name: http # 端口名稱(可選,用于區(qū)分多個(gè)端口)
port: 80 # Service 對(duì)外暴露的端口(客戶端訪問(wèn)的端口)
targetPort: 8080 # 后端 Pod 實(shí)際提供服務(wù)的端口(需與 Pod 容器的端口一致)
protocol: TCP # 協(xié)議(默認(rèn) TCP,支持 UDP、SCTP)
sessionAffinity: None # 會(huì)話親和性(默認(rèn) None,可選 ClientIP:同一客戶端請(qǐng)求轉(zhuǎn)發(fā)到同一 Pod)關(guān)鍵字段說(shuō)明:
selector:Service 與 Pod 的 “綁定橋梁”,僅匹配標(biāo)簽的 Pod 會(huì)被加入 Service 后端。- 若不配置
selector(如對(duì)接集群外服務(wù)),需手動(dòng)通過(guò)Endpoints關(guān)聯(lián)后端地址;
ports.port vs targetPort:
port:Service 自身的端口(客戶端訪問(wèn)的入口);targetPort:Pod 容器的端口(流量最終轉(zhuǎn)發(fā)到的端口),支持?jǐn)?shù)字或 Pod 容器的端口名(如targetPort: http,需 Pod 容器定義name: http);sessionAffinity:會(huì)話親和性,用于保證同一客戶端的請(qǐng)求始終轉(zhuǎn)發(fā)到同一 Pod(適用于需要會(huì)話保持的場(chǎng)景,如登錄狀態(tài)存儲(chǔ))。
四、Service 的 5 種核心類型
Service 的 type 字段決定了其訪問(wèn)范圍和暴露方式,K8s 支持 5 種常見(jiàn)類型,適用于不同場(chǎng)景:
| 類型 | 核心特點(diǎn) | 適用場(chǎng)景 |
|---|---|---|
| ClusterIP | 僅集群內(nèi)可見(jiàn)的虛擬 IP,無(wú)法從集群外訪問(wèn) | 集群內(nèi)服務(wù)間通信(如后端 API 給前端提供服務(wù)) |
| NodePort | 在每個(gè)節(jié)點(diǎn)上開(kāi)放一個(gè)靜態(tài)端口,通過(guò) 節(jié)點(diǎn)IP:NodePort 訪問(wèn) Service | 開(kāi)發(fā) / 測(cè)試環(huán)境:快速?gòu)募和庠L問(wèn)服務(wù) |
| LoadBalancer | 借助云廠商 LB(如 AWS ELB、阿里云 SLB),自動(dòng)分配公網(wǎng) IP,轉(zhuǎn)發(fā)流量到 NodePort | 生產(chǎn)環(huán)境:公網(wǎng)暴露服務(wù)(需云廠商支持) |
| ExternalName | 不關(guān)聯(lián) Pod,直接將 Service 映射到集群外的域名(如 xxx.com) | 訪問(wèn)集群外服務(wù)(如數(shù)據(jù)庫(kù)、第三方 API) |
| Headless | 無(wú) ClusterIP,通過(guò) DNS 直接返回后端 Pod 的 IP 列表(不做負(fù)載均衡) | 需自行處理負(fù)載均衡或需直接訪問(wèn) Pod 的場(chǎng)景 |
各類型詳解與配置示例
1. ClusterIP(默認(rèn)類型)
- 特點(diǎn):K8s 自動(dòng)分配一個(gè)集群內(nèi)唯一的虛擬 IP(無(wú)法 ping 通,僅用于流量轉(zhuǎn)發(fā)),僅集群內(nèi) Pod 可訪問(wèn);
- 配置:
type: ClusterIP(或不寫(xiě)type,默認(rèn)為此類型); - 訪問(wèn)方式:
ClusterIP:port或service-name.namespace.svc.cluster.local:port(DNS 解析)。
2. NodePort
- 特點(diǎn):在 ClusterIP 基礎(chǔ)上,在每個(gè)節(jié)點(diǎn)上開(kāi)放一個(gè) 靜態(tài)端口(NodePort)(范圍:30000-32767),通過(guò)
任意節(jié)點(diǎn)IP:NodePort可從集群外訪問(wèn);
配置示例:
spec:
type: NodePort
ports:
- port: 80 # Service 內(nèi)部端口
targetPort: 8080 # Pod 端口
nodePort: 30080 # 手動(dòng)指定 NodePort(可選,不指定則自動(dòng)分配)- 訪問(wèn)方式:
節(jié)點(diǎn)IP:30080(需確保節(jié)點(diǎn) IP 可被外部訪問(wèn),且防火墻開(kāi)放 30080 端口); - 注意:NodePort 本質(zhì)是 “每個(gè)節(jié)點(diǎn)都開(kāi)放相同端口”,外部請(qǐng)求可發(fā)往任意節(jié)點(diǎn),kube-proxy 會(huì)轉(zhuǎn)發(fā)到后端 Pod。
3. LoadBalancer
- 特點(diǎn):依賴云廠商的負(fù)載均衡服務(wù)(如 AWS ELB、GCP LB),K8s 會(huì)自動(dòng)創(chuàng)建云 LB 并關(guān)聯(lián)所有節(jié)點(diǎn)的 NodePort,外部流量通過(guò)云 LB 的公網(wǎng) IP 進(jìn)入,再轉(zhuǎn)發(fā)到 NodePort → Pod;
配置示例:
spec:
type: LoadBalancer
ports:
- port: 80
targetPort: 8080
loadBalancerIP: 1.2.3.4 # 可選,指定云 LB 的靜態(tài)公網(wǎng) IP(需云廠商支持)- 訪問(wèn)方式:云 LB 分配的公網(wǎng) IP:80(無(wú)需記節(jié)點(diǎn) IP,LB 自動(dòng)做節(jié)點(diǎn)級(jí)負(fù)載均衡);
- 注意:僅在云環(huán)境(如 EKS、GKE、ACK)中生效,本地集群(如 Minikube)需用
minikube tunnel模擬 LoadBalancer。
4. ExternalName
- 特點(diǎn):不關(guān)聯(lián)任何 Pod,僅作為 “域名別名”—— 將 Service 名映射到集群外的域名(如
db.example.com),通過(guò) DNS 解析實(shí)現(xiàn)訪問(wèn);
配置示例(訪問(wèn)集群外的 MySQL 服務(wù)):
spec: type: ExternalName externalName: db.example.com # 集群外服務(wù)的域名 ports: - port: 3306 # 外部服務(wù)的端口
- 訪問(wèn)方式:集群內(nèi) Pod 訪問(wèn)
my-service.default.svc.cluster.local:3306,會(huì)自動(dòng)解析為db.example.com:3306; - 適用場(chǎng)景:訪問(wèn)集群外的固定服務(wù)(如托管數(shù)據(jù)庫(kù)、第三方 API),避免硬編碼域名到應(yīng)用中。
5. Headless Service(無(wú)頭服務(wù))
- 特點(diǎn):無(wú) ClusterIP,Service 創(chuàng)建后不分配虛擬 IP;通過(guò) DNS 解析時(shí),直接返回后端所有 Pod 的 IP 列表(而非 Service IP),負(fù)載均衡需客戶端自行實(shí)現(xiàn);
spec:
type: ClusterIP # 關(guān)鍵:將 clusterIP 設(shè)為 None,即 Headless
clusterIP: None
selector:
app: my-app
ports:
- port: 80
targetPort: 8080- 訪問(wèn)方式:集群內(nèi) Pod 訪問(wèn)
my-service.default.svc.cluster.local,DNS 會(huì)返回所有匹配 Pod 的 IP 列表;
適用場(chǎng)景:
- 客戶端需自行控制負(fù)載均衡策略(如 MongoDB 副本集、Elasticsearch 集群,需節(jié)點(diǎn)間直接通信);
- 需通過(guò) DNS 發(fā)現(xiàn)所有后端 Pod 的場(chǎng)景(如 StatefulSet 管理的有狀態(tài)服務(wù),每個(gè) Pod 有固定 hostname)。
五、Service 與 Endpoints 的關(guān)系
Endpoints 是 K8s 中的另一個(gè)核心資源,用于存儲(chǔ) Service 后端的 “實(shí)際訪問(wèn)地址”(IP:Port 列表)。兩者的關(guān)系是:
- 自動(dòng)關(guān)聯(lián):若 Service 配置了
selector,K8s 會(huì)自動(dòng)創(chuàng)建一個(gè)與 Service 同名的 Endpoints 資源,實(shí)時(shí)同步匹配selector的 Pod 的 IP:Port 列表(Pod 就緒則加入,未就緒則移除); - 手動(dòng)關(guān)聯(lián):若 Service 未配置
selector(如訪問(wèn)集群外服務(wù)),需手動(dòng)創(chuàng)建 Endpoints,將外部服務(wù)的 IP:Port 寫(xiě)入 Endpoints,Service 會(huì)通過(guò) Endpoints 轉(zhuǎn)發(fā)流量。
手動(dòng)關(guān)聯(lián) Endpoints 示例(訪問(wèn)集群外服務(wù))
創(chuàng)建無(wú) selector 的 Service:
apiVersion: v1
kind: Service
metadata:
name: external-service
spec:
ports:
- port: 80
targetPort: 80手動(dòng)創(chuàng)建同名 Endpoints,關(guān)聯(lián)集群外服務(wù)的 IP:Port:
apiVersion: v1 kind: Endpoints metadata: name: external-service # 必須與 Service 同名,才能關(guān)聯(lián) subsets: - addresses: - ip: 192.168.1.100 # 集群外服務(wù)的 IP ports: - port: 80 # 集群外服務(wù)的端口
集群內(nèi) Pod 訪問(wèn) external-service.default.svc.cluster.local:80,流量會(huì)轉(zhuǎn)發(fā)到 192.168.1.100:80。
六、Service 的負(fù)載均衡策略
Service 的負(fù)載均衡由 kube-proxy 實(shí)現(xiàn),kube-proxy 支持兩種模式(通過(guò) --proxy-mode 配置),對(duì)應(yīng)不同的負(fù)載均衡策略:
1. iptables 模式(默認(rèn))
- 原理:kube-proxy 在每個(gè)節(jié)點(diǎn)的 iptables 中配置 DNAT 規(guī)則,將 Service 的 ClusterIP:Port 轉(zhuǎn)發(fā)到后端 Pod 的 IP:Port;
- 負(fù)載均衡策略:默認(rèn) 輪詢(Round-Robin),即請(qǐng)求依次分發(fā)到后端 Pod;
優(yōu)缺點(diǎn):
- 優(yōu)點(diǎn):輕量、無(wú)額外進(jìn)程,依賴內(nèi)核轉(zhuǎn)發(fā),性能較好;
- 缺點(diǎn):后端 Pod 數(shù)量多時(shí),iptables 規(guī)則會(huì)急劇增加,導(dǎo)致轉(zhuǎn)發(fā)延遲升高(適合中小規(guī)模集群)。
2. IPVS 模式(推薦大規(guī)模集群)
- 原理:依賴 Linux 內(nèi)核的 IPVS(IP Virtual Server)模塊,kube-proxy 會(huì)創(chuàng)建 IPVS 虛擬服務(wù)(對(duì)應(yīng) Service),并將后端 Pod 作為 IPVS 真實(shí)服務(wù)器;
負(fù)載均衡策略:支持多種策略(可通過(guò) Service 的 externalTrafficPolicy 或 internalTrafficPolicy 配置):
rr:輪詢(默認(rèn));wrr:加權(quán)輪詢(根據(jù) Pod 權(quán)重分配流量);lc:最少連接(請(qǐng)求分發(fā)到當(dāng)前連接數(shù)最少的 Pod);sh:源地址哈希(同 iptables 的 ClientIP 親和性);
優(yōu)缺點(diǎn):
- 優(yōu)點(diǎn):支持更多負(fù)載均衡策略,規(guī)則管理高效(適合大規(guī)模集群,Pod 數(shù)量上千);
- 缺點(diǎn):需提前在節(jié)點(diǎn)上加載 IPVS 內(nèi)核模塊(
modprobe ip_vs)。
七、Service 的常見(jiàn)問(wèn)題與最佳實(shí)踐
1. 常見(jiàn)問(wèn)題
Service 訪問(wèn)不通?
- 檢查
selector是否與 Pod 標(biāo)簽匹配(kubectl describe svc <service-name>查看Endpoints是否有 Pod IP); - 檢查 Pod 的就緒探針是否通過(guò)(未通過(guò)就緒探針的 Pod 不會(huì)加入 Endpoints);
- 檢查 Pod 容器的
targetPort是否與 Service 配置一致; - 檢查網(wǎng)絡(luò)策略(NetworkPolicy)是否阻止了 Service 到 Pod 的流量。
NodePort 端口沖突?
- NodePort 范圍默認(rèn)是 30000-32767,若手動(dòng)指定
nodePort,需確保該端口未被其他 Service 或節(jié)點(diǎn)進(jìn)程占用; - 建議不手動(dòng)指定
nodePort,由 K8s 自動(dòng)分配,避免沖突。
2. 最佳實(shí)踐
- 使用 DNS 名稱訪問(wèn) Service:避免硬編碼 ClusterIP,通過(guò)
service-name.namespace.svc.cluster.local訪問(wèn)(跨命名空間需加命名空間); - 為端口配置名稱:Service 和 Pod 的端口都配置
name(如name: http),避免targetPort數(shù)字寫(xiě)錯(cuò)導(dǎo)致轉(zhuǎn)發(fā)失敗; - 大規(guī)模集群用 IPVS 模式:當(dāng)集群 Pod 數(shù)量超過(guò) 1000 時(shí),建議將 kube-proxy 切換為 IPVS 模式,提升負(fù)載均衡效率;
- 生產(chǎn)環(huán)境用 LoadBalancer + Ingress:LoadBalancer 用于暴露 Ingress Controller,Ingress 用于管理多個(gè)服務(wù)的域名和路由(比直接用 LoadBalancer 暴露多個(gè) Service 更節(jié)省資源);
- 有狀態(tài)服務(wù)用 Headless Service:StatefulSet 管理的服務(wù)(如數(shù)據(jù)庫(kù)集群)需固定網(wǎng)絡(luò)標(biāo)識(shí),搭配 Headless Service 可通過(guò) DNS 發(fā)現(xiàn)所有 Pod。
八、總結(jié)
Service 是 K8s 中連接 “動(dòng)態(tài) Pod” 與 “穩(wěn)定訪問(wèn)” 的核心橋梁,其核心能力是固定入口、負(fù)載均衡、服務(wù)發(fā)現(xiàn)。
在實(shí)際使用中,需根據(jù)場(chǎng)景選擇合適的 Service 類型(如集群內(nèi)用 ClusterIP、公網(wǎng)暴露用 LoadBalancer、訪問(wèn)外部服務(wù)用 ExternalName),并結(jié)合 Endpoints、iptables/IPVS 等組件理解流量轉(zhuǎn)發(fā)邏輯,確保服務(wù)的穩(wěn)定訪問(wèn)。
以上為個(gè)人經(jīng)驗(yàn),希望能給大家一個(gè)參考,也希望大家多多支持腳本之家。
相關(guān)文章
Rainbond云原生部署SpringCloud應(yīng)用架構(gòu)實(shí)踐
這篇文章主要為大家介紹了Rainbond云原生部署SpringCloud應(yīng)用架構(gòu)實(shí)踐,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2022-04-04
玩客云內(nèi)置EMMC存儲(chǔ)刷入Armbian系統(tǒng)(圖文詳解)
Armbian是其他項(xiàng)目可以信賴的單板計(jì)算機(jī)(SBC)的基本操作系統(tǒng)平臺(tái),接下來(lái)通過(guò)本文給大家介紹玩客云內(nèi)置EMMC存儲(chǔ)刷入Armbian系統(tǒng),需要的朋友可以參考下2022-05-05
k8s跨服務(wù)調(diào)用入門(mén)到實(shí)戰(zhàn)示例詳解
這篇文章主要為大家介紹了k8s跨服務(wù)調(diào)用入門(mén)到實(shí)戰(zhàn)示例詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2023-09-09

