目錄
Service的定義
核心定義
Service 的類型
關鍵組件與機制
工作流程示例
高級特性
?Service工作原理
核心工作原理
標簽選擇器(Label Selector)
Endpoints 對象
網絡代理與負載均衡(kube-proxy)
userspace 模式(已淘汰)
iptables 模式(默認)
IPVS 模式(推薦高性能場景)
Service 類型與流量路由
ClusterIP(默認)
NodePort
LoadBalancer
ExternalName
Service的定義
在 Kubernetes(K8s)中,Service?是一個核心抽象資源,用于為一組具有相同功能的 Pod 提供穩定的網絡訪問入口,并實現服務發現、負載均衡和抽象隔離。
核心定義
- 邏輯抽象層:Service 將一組動態變化的 Pod(通過標簽選擇器匹配)抽象為一個邏輯服務單元,客戶端無需關心后端 Pod 的具體數量、IP 地址或位置。
- 穩定訪問入口:為 Pod 分配一個固定的 ClusterIP(虛擬 IP),該 IP 在 Service 生命周期內不變,即使后端 Pod 重建或擴縮容。
- 負載均衡:自動將客戶端請求分發到匹配的 Pod,支持輪詢(默認)、隨機、會話保持等策略。
Service 的類型
根據網絡訪問方式,Service 分為以下四種類型:
類型 | 訪問范圍 | 適用場景 |
---|---|---|
ClusterIP | 僅集群內部訪問(默認) | 內部服務間通信(如微服務調用、數據庫訪問)。 |
NodePort | 集群外部通過節點 IP+端口訪問 | 開發測試或臨時暴露服務(需手動指定節點端口,范圍通常為 30000-32767)。 |
LoadBalancer | 外部負載均衡器(云環境) | 生產環境暴露服務,自動創建云廠商的負載均衡器(如 AWS ALB、GCP Load Balancer)。 |
ExternalName | 通過 DNS CNAME 映射外部服務 | 訪問集群外部服務(如數據庫、第三方 API),無需在集群內運行 Pod。 |
關鍵組件與機制
- 標簽選擇器(Label Selector):
- 通過?
spec.selector
?字段匹配 Pod 的標簽(如?app: nginx
),動態關聯后端 Pod。 - 示例:
apiVersion: v1 kind: Service metadata:name: nginx-service spec:selector:app: nginx # 匹配所有標簽為 app=nginx 的 Podports:- protocol: TCPport: 80 # Service 暴露的端口targetPort: 80 # Pod 的容器端口
- Endpoints 對象:
- K8s 自動為每個 Service 創建同名的 Endpoints 資源,記錄當前匹配的 Pod IP 和端口。
- 通過?
kubectl get endpoints nginx-service
?可查看實時關聯的 Pod。
- ClusterIP:
- 虛擬 IP,僅在集群內路由有效,由 kube-proxy 通過 iptables/IPVS 實現。
- 客戶端訪問?
ClusterIP:Port
?時,請求會被轉發到后端 Pod。
- DNS 解析:
- 集群內服務可通過?
<service-name>.<namespace>.svc.cluster.local
?域名訪問(如?nginx-service.default.svc.cluster.local
)。 - 簡化配置,避免硬編碼 IP。
- 集群內服務可通過?
- 通過?
工作流程示例
- 創建 Deployment:部署 3 個 Nginx Pod,標簽為?
app=nginx
。 - 創建 Service:
apiVersion: v1 kind: Service metadata:name: nginx-service spec:selector:app: nginxports:- protocol: TCPport: 80targetPort: 80
- 訪問服務:
- 集群內其他 Pod 可通過?
nginx-service:80
?或其 ClusterIP 訪問。 - 若為 NodePort 類型,外部可通過?
http://<節點IP>:<節點端口>
?訪問。
- 集群內其他 Pod 可通過?
高級特性
- 會話保持(Session Affinity):
- 通過?
sessionAffinity: ClientIP
?確保同一客戶端請求始終路由到同一 Pod。
- 通過?
- 外部流量策略:
externalTrafficPolicy: Local
?保留客戶端源 IP,避免經過 NAT 丟失信息(僅 NodePort/LoadBalancer 有效)。
- 無頭服務(Headless Service):
- 設置?
clusterIP: None
,不分配 ClusterIP,直接返回 Pod IP 列表(適用于 StatefulSet 或需要直接訪問 Pod 的場景)。
- 設置?
?Service工作原理
?Kubernetes(K8s)中的?Service?通過抽象一組動態變化的 Pod,提供穩定的網絡訪問入口和負載均衡能力。其工作原理涉及?標簽選擇、Endpoint 管理、網絡代理(kube-proxy)和負載均衡?等核心機制。
核心工作原理
標簽選擇器(Label Selector)
- 作用:Service 通過?
spec.selector
?字段匹配一組 Pod 的標簽(如?app=nginx
),動態關聯后端 Pod。 - 動態性:當匹配的 Pod 數量或 IP 變化時(如擴容、重建),Service 會自動更新關聯的 Endpoint,無需手動干預。
- 示例:
apiVersion: v1 kind: Service metadata:name: nginx-service spec:selector:app: nginx # 匹配所有標簽為 app=nginx 的 Podports:- protocol: TCPport: 80 # Service 暴露的端口targetPort: 80 # Pod 的容器端口
Endpoints 對象
- 自動生成:K8s 為每個 Service 創建一個同名的?Endpoints 資源(如?
nginx-service
),記錄當前匹配的 Pod IP 和端口。 - 實時更新:當 Pod 狀態變化(如新增、刪除、IP 變更),Endpoints 會同步更新,確保流量始終路由到健康的 Pod。
- 查看 Endpoints:
kubectl get endpoints nginx-service
? ? ? ? 輸出實例:
NAME ENDPOINTS AGE
nginx-service 10.244.1.3:80,10.244.2.5:80 5m
網絡代理與負載均衡(kube-proxy)
kube-proxy?是運行在每個節點上的網絡代理,負責實現 Service 的負載均衡和流量轉發。它支持三種工作模式:
userspace 模式(已淘汰)
- 原理:kube-proxy 作為用戶態進程,通過 iptables 捕獲 Service 的 ClusterIP 流量,然后轉發到后端 Pod。
- 缺點:性能較差(上下文切換開銷大),已逐漸被棄用。
iptables 模式(默認)
- 原理:
- kube-proxy 監聽 Service 和 Endpoint 的變化,動態生成 iptables 規則。
- 當客戶端訪問 Service 的 ClusterIP 時,iptables 隨機選擇一個后端 Pod IP,并將請求轉發過去。
- 特點:
- 純內核態轉發,性能較高。
- 支持基本的輪詢負載均衡。
- 無法處理會話保持(需通過?
sessionAffinity: ClientIP
?實現)。
- 查看 iptables 規則:
?kubectl get svc nginx-service -o yaml # 獲取 ClusterIP iptables -t nat -L | grep <ClusterIP>
IPVS 模式(推薦高性能場景)
- 原理:
- kube-proxy 調用 Linux 內核的 IPVS 模塊(基于哈希表的負載均衡器)。
- IPVS 支持多種負載均衡算法(如輪詢、加權輪詢、最少連接等),性能優于 iptables。
- 啟用方式:
- 修改 kube-proxy 啟動參數:
--proxy-mode=ipvs
。 - 確保節點已加載 IPVS 內核模塊(如?
ip_vs_rr
,?ip_vs_wrr
)。
- 修改 kube-proxy 啟動參數:
- 查看 IPVS 規則:
ipvsadm -Ln
?
Service 類型與流量路由
根據訪問范圍,Service 分為四種類型,其流量路由方式如下:
ClusterIP(默認)
- 訪問范圍:僅集群內部。
- 路由過程:
- 客戶端訪問?
nginx-service:80
?或 ClusterIP。 - kube-proxy 通過 iptables/IPVS 將請求轉發到匹配的 Pod。
- 客戶端訪問?
- 適用場景:內部服務間通信(如微服務調用)。
ClusterIP實例:
apiVersion: v1
kind: Service
metadata:name: my-service # 服務名稱namespace: default # 命名空間(可選)labels:app: my-app # 服務標簽
spec:type: ClusterIP # 指定為ClusterIP類型(默認可省略)selector:app: my-app # 匹配Pod的標簽ports:- protocol: TCP # 協議類型(TCP/UDP)port: 80 # 服務暴露的端口(集群內部訪問)targetPort: 8080 # 后端Pod的端口
NodePort
- 訪問范圍:外部通過節點 IP + 端口訪問。
- 路由過程:
- 客戶端訪問?
<節點IP>:<NodePort>
(如?192.168.1.100:30080
)。 - 節點上的 iptables/IPVS 將請求轉發到 Service 的 ClusterIP,再路由到 Pod。
- 客戶端訪問?
- 特點:
- NodePort 范圍默認 30000-32767。
- 外部流量需手動配置負載均衡器(如 Nginx)分發到多個節點。
NodePort實例:
apiVersion: v1
kind: Service
metadata:name: my-nodeport-servicenamespace: defaultlabels:app: my-app
spec:type: NodePort # 指定為NodePort類型selector:app: my-app # 匹配Pod的標簽ports:- protocol: TCPport: 80 # 服務內部端口(供集群內部訪問)targetPort: 8080 # 后端Pod的端口nodePort: 30080 # 節點上暴露的端口(可選,默認自動分配30000-32767)
LoadBalancer
- 訪問范圍:外部通過云廠商負載均衡器訪問。
- 路由過程:
- 創建 Service 時指定?
type: LoadBalancer
。 - 云控制器(Cloud Controller Manager)自動創建外部負載均衡器(如 AWS ALB)。
- 外部流量通過負載均衡器分發到節點,再路由到 Pod。
- 創建 Service 時指定?
- 適用場景:生產環境暴露服務。
loadBalancer實例:
apiVersion: v1
kind: Service
metadata:name: my-loadbalancer-servicenamespace: defaultlabels:app: my-appannotations:# 可選:云服務商特定的注解(如AWS、GKE)service.beta.kubernetes.io/aws-load-balancer-type: "nlb"
spec:type: LoadBalancer # 指定為LoadBalancer類型selector:app: my-app # 匹配Pod的標簽ports:- protocol: TCPport: 80 # 服務暴露的端口(負載均衡器端口)targetPort: 8080 # 后端Pod的端口nodePort: 30080 # 可選:自動分配的NodePort(LoadBalancer依賴NodePort實現)externalTrafficPolicy: Cluster # 可選:Cluster(默認)或Local
ExternalName
- 訪問范圍:通過 DNS CNAME 映射外部服務。
- 路由過程:
- 客戶端訪問 Service 的 DNS 名稱(如?
my-db.default.svc.cluster.local
)。 - DNS 解析返回外部服務的 CNAME(如?
mysql.example.com
)。
- 客戶端訪問 Service 的 DNS 名稱(如?
- 適用場景:訪問集群外部數據庫或 API。
?創建101命名空間所需要的yaml文件
[root@k8s-master opt]# cat myapp01.yaml
apiVersion: apps/v1
kind: Deployment
metadata:name: myapp01namespace: test01
spec:replicas: 1selector: #標簽選擇器matchLabels: #匹配的標簽為app: myapp01release: canarytemplate:metadata:labels:app: myapp01 #和上面的myapp要匹配release: canaryspec:containers:- name: myappimage: ikubernetes/myapp:v1ports:- name: http01containerPort: 80
[root@k8s-master opt]# cat myapp-svc-extername01.yaml
kind: Service
apiVersion: v1
metadata:name: myapp-svcname02namespace: test01
spec:type: ExternalNameexternalName: myapp-svc02.test02.svc.cluster.local
[root@k8s-master opt]# cat myapp-svc-headless01.yaml
apiVersion: v1
kind: Service
metadata:name: myapp-svc01namespace: test01
spec:selector:app: myapp01 #挑選的pod還是myapp01。一個pod可以有多個servicerelease: canaryclusterIP: None #None表示是無頭serviceports:- port: 39320 #service ip中的端口targetPort: 80 #容器ip中的端口
?創建102命名空間所需要的yaml文件
[root@k8s-master opt]# cat myapp-svc-headless02.yaml
apiVersion: v1
kind: Service
metadata:name: myapp-svc02namespace: test02
spec:selector:app: myapp02 #挑選的pod還是myapp。一個pod可以有多個servicerelease: canaryclusterIP: None #None表示是無頭serviceports:- port: 39320 #service ip中的端口targetPort: 80 #容器ip中的端口
[root@k8s-master opt]# cat myapp-svc-extername02.yaml
kind: Service
apiVersion: v1
metadata:name: myapp-svcname01namespace: test02
spec:type: ExternalNameexternalName: myapp-svc01.test01.svc.cluster.local
[root@k8s-master opt]# cat myapp02.yaml
apiVersion: apps/v1
kind: Deployment
metadata:name: myapp02namespace: test02
spec:replicas: 1selector: #標簽選擇器matchLabels: #匹配的標簽為app: myapp02release: canarytemplate:metadata:labels:app: myapp02 #和上面的myapp要匹配release: canaryspec:containers:- name: myapp02image: ikubernetes/myapp:v1ports:- name: http02containerPort: 80
驗證:
##查看test01容器的ip地址
[root@k8s-master opt]# ku get pods -n test01 -o wide
NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES
myapp01-696c886d6b-bbvrn 1/1 Running 0 30m 10.244.36.80 k8s-node1 <none> <none>##登陸到test02命名空間的容器,訪問test01容器的ip
[root@k8s-master opt]# ku exec -it myapp02-55ffcd5f64-xmgq8 -n test02 -- sh
/ # ping 10.244.36.80
PING 10.244.36.80 (10.244.36.80): 56 data bytes
64 bytes from 10.244.36.80: seq=0 ttl=63 time=0.059 ms
64 bytes from 10.244.36.80: seq=1 ttl=63 time=0.121 ms
?
?
?
?
?
?