K8s新手必看,不可不知的K8s技能,Service發(fā)現(xiàn)全解析!
概念介紹
Kubernetes是一個開源的容器編排平臺,用于自動化部署、擴(kuò)展和管理容器化應(yīng)用。在Kubernetes中,Service是一種抽象,它定義了一組Pod的邏輯集合,并且能夠在這些Pod之間實(shí)現(xiàn)負(fù)載均衡。Service 使得我們可以通過一個固定的IP地址或DNS名稱訪問Pod,即使這些Pod的數(shù)量和位置在不斷變化。
Service實(shí)現(xiàn)方式
1.userspace
在userspace模式下,kube-proxy會為每個Service創(chuàng)建一個監(jiān)聽端口。通過Iptables規(guī)則,發(fā)往Cluster IP的請求被重定向到kube-proxy監(jiān)聽的端口。kube-proxy根據(jù)負(fù)載均衡算法選擇一個服務(wù)的Pod,與其建立連接并將請求轉(zhuǎn)發(fā)給該P(yáng)od。在這種模式下,kube-proxy充當(dāng)四層負(fù)載均衡器的角色。由于kube-proxy在用戶空間運(yùn)行,轉(zhuǎn)發(fā)過程中涉及內(nèi)核與用戶空間之間的數(shù)據(jù)拷貝,雖然這種方式較為穩(wěn)定,但效率相對較低。
kube-proxy userspace模式
2.iptables
在iptables模式下,kube-proxy為每個Service的后端Pod創(chuàng)建相應(yīng)的iptables規(guī)則,將發(fā)往Cluster IP的請求直接重定向到一個Pod IP。這種模式下,kube-proxy并不充當(dāng)四層負(fù)載均衡器的角色,只負(fù)責(zé)創(chuàng)建和維護(hù)iptables規(guī)則。相比于userspace模式,iptables模式的效率更高,但無法提供靈活的負(fù)載均衡策略,并且當(dāng)后端Pod不可用時(shí)也無法進(jìn)行請求重試。
kube-proxy iptables模式
3.ipvs
IPVS模式與 iptables 類似,kube-proxy通過監(jiān)控Pod的變化來創(chuàng)建相應(yīng)的IPVS規(guī)則。與 iptables 相比,IPVS轉(zhuǎn)發(fā)效率更高,并且支持更多的負(fù)載均衡算法。
kube-proxy ipvs模式
Service 的類型
Service的資源清單文件:
kind:Service# 資源類型
apiVersion:v1# 資源版本
metadata:# 元數(shù)據(jù)
name:service# 資源名稱
namespace:dev# 命名空間
spec:# 描述
selector:# 標(biāo)簽選擇器,用于確定當(dāng)前service代理哪些pod
app:nginx
type:# Service類型,指定service的訪問方式
clusterIP:# 虛擬服務(wù)的ip地址
sessionAffinity:# session親和性,支持ClientIP、None兩個選項(xiàng)
ports:# 端口信息
-protocol:TCP
port:3017# service端口
targetPort:5003# pod端口
nodePort:31122# 主機(jī)端口
Kubernetes 提供了幾種類型的 Service,以滿足不同的需求:
- ClusterIP:默認(rèn)類型,創(chuàng)建一個只能在集群內(nèi)部訪問的虛擬IP。
- NodePort:在每個Node上打開一個特定的端口,并將流量轉(zhuǎn)發(fā)到ClusterIP。
- LoadBalancer:使用云提供商的負(fù)載均衡器,將外部流量分發(fā)到NodePort和ClusterIP。
- ExternalName:將服務(wù)映射到外部的DNS名稱。
部署一個簡單的 Web 應(yīng)用
接下來,我們通過一個實(shí)際案例來展示如何創(chuàng)建和使用 Service。假設(shè)我們有一個簡單的 Nginx Web 應(yīng)用,我們將使用 Kubernetes 部署它,并通過 Service 進(jìn)行訪問。
Step 1: 創(chuàng)建 Deployment
首先,我們需要創(chuàng)建一個 Deployment 來部署 Nginx 容器。創(chuàng)建一個名為 nginx-deployment.yaml 的文件,內(nèi)容如下:
apiVersion:apps/v1
kind:Deployment
metadata:
name:nginx-deployment
labels:
app:nginx
spec:
replicas:3
selector:
matchLabels:
app:nginx
template:
metadata:
labels:
app:nginx
spec:
containers:
-name:nginx
image:nginx:1.17.1
ports:
-containerPort:80
使用以下命令來應(yīng)用這個 Deployment:
kubectl apply -f nginx-deployment.yaml
創(chuàng)建完成后,查看每個pod的IP地址,如下圖所示:
Step 2: 創(chuàng)建 Service
現(xiàn)在,我們創(chuàng)建一個 Service 來暴露這個 Deployment。創(chuàng)建一個名為 nginx-service.yaml 的文件,內(nèi)容如下:
apiVersion:v1
kind:Service
metadata:
name:nginx-service
spec:
selector:
app:nginx
ports:
-protocol:TCP
port:80
targetPort:80
type:ClusterIP
使用以下命令來應(yīng)用這個 Service:
kubectl apply -f nginx-service.yaml
Step 3: 驗(yàn)證 Service
應(yīng)用成功后,我們可以使用以下命令來查看 Service 的詳情:
kubectl get services
你應(yīng)該會看到類似如下的輸出:
通過 Service 的CLUSTER-IP,我們可以在集群內(nèi)部訪問 Nginx 服務(wù)。
HeadlessService的概念和應(yīng)用
在某些應(yīng)用場景中,客戶端應(yīng)用不需要通過Kubernetes內(nèi)置 Service 實(shí)現(xiàn)的負(fù)載均衡功能,或需要自行完成對服務(wù)后端各實(shí)例的服務(wù)發(fā)現(xiàn)機(jī)制,或者自行實(shí)現(xiàn)負(fù)載均衡功能。這時(shí),可以創(chuàng)建一種特殊的服務(wù)類型,稱為 Headless Service。
Headless Service的特點(diǎn)是,這種服務(wù)沒有入口訪問地址(即沒有 ClusterIP 地址),kube-proxy不會為其創(chuàng)建負(fù)載轉(zhuǎn)發(fā)規(guī)則。其服務(wù)名(DNS 域名)的解析機(jī)制則取決于該 Headless Service 是否設(shè)置了 Label Selector。
1.已設(shè)置Label Selector
如果Headless Service設(shè)置了Label Selector,Kubernetes則將根據(jù)Label Selector查詢后端Pod列表,自動創(chuàng)建Endpoint列表,將服務(wù)名(DNS域名)的解析機(jī)制設(shè)置為:當(dāng)客戶端訪問該服務(wù)名時(shí),得到的是全部Endpoint列表(而不是一個確定的IP地址)。以下面的Headless Service為例,其設(shè)置了Label Selector:
apiversion:v1
kind:Service
metadata:
name:nginx
labels:
app:nginx
spec:
ports:
-port:80
clusterIP:None
selector:
app:nginx
使用kubectl create命令創(chuàng)建完之后,可以查看該Headless Service的詳細(xì)信息,可以看到后端的Endpoint列表:
用nslookup工具對Headless Service名稱嘗試域名解析,將會看到DNS系統(tǒng)返回的全部Endpoint的IP地址,例如:
結(jié)論
通過本教程,我們學(xué)習(xí)了如何在 Kubernetes 中創(chuàng)建和使用 Service 來暴露應(yīng)用。我們通過一個簡單的 Nginx 部署案例,演示了如何使用 ClusterIP 和 NodePort 類型的 Service。掌握這些基本概念和操作后,可以更輕松地管理和擴(kuò)展 Kubernetes 集群中的應(yīng)用服務(wù)。