您好,登錄后才能下訂單哦!
本篇內(nèi)容介紹了“Service和Endpoint的原理和作用是什么”的有關(guān)知識(shí),在實(shí)際案例的操作過(guò)程中,不少人都會(huì)遇到這樣的困境,接下來(lái)就讓小編帶領(lǐng)大家學(xué)習(xí)一下如何處理這些情況吧!希望大家仔細(xì)閱讀,能夠?qū)W有所成!
Srevice
Service 是將運(yùn)行在一組 Pods 上的應(yīng)用程序公開(kāi)為網(wǎng)絡(luò)服務(wù)的抽象方法。如果我們使用 Deployment 部署 pod,則可以以 Deployment 為對(duì)象創(chuàng)建 Service。
在 K8S 中,每個(gè) Pod 都有其自己唯一的 ip 地址,而 Service 可以為多個(gè) Pod(一組)提供相同的 DNS 名,并且可以在他們直接進(jìn)行負(fù)載均衡。
假如有一組 nginx pod,如果 nginx 動(dòng)態(tài)伸縮改變或因?yàn)槟承┰?ip/端口發(fā)生改變,那么其 ip 和 端口都不是固定的,而且我們很難確定它新擴(kuò)容的 pod 的地址是什么,又萬(wàn)一 pod 被刪除,ip 不再可用。
又假如一組 pod 稱為前端,如 web 服務(wù),另一組 pod 稱為后端,例如 mysql。那么 前端 如何查找并跟蹤要連接的 ip 地址,以便前端可以使用工作負(fù)載的后端部分?
這真是 Service 要解決的問(wèn)題。Kubernetes Service 定義了一種抽象:邏輯上的一組 Pod,一種可以訪問(wèn)它們的策略 —— 通常稱為微服務(wù)。當(dāng)使用 Service 為一組 pod (Deployment 的方式創(chuàng)建的)創(chuàng)建服務(wù)時(shí),無(wú)論我們創(chuàng)建了多少個(gè) pod 副本,這些 pod 怎么變化,前端不需要關(guān)心它們調(diào)用了哪個(gè)后端副本,而且不需要知道后端 pod 的狀態(tài)也不需要跟蹤 pod。Service 把前后端的這種關(guān)聯(lián)抽象化,把它們解耦了。
Service 的創(chuàng)建及現(xiàn)象
現(xiàn)在按照下面的命令快速創(chuàng)建 pod,pod 將會(huì)在各個(gè)節(jié)點(diǎn)中部署運(yùn)行。
kubectl create deployment nginx --image=nginx:latest --replicas=3
kubectl expose deployment nginx --type=LoadBalancer --port=80
然后執(zhí)行命令查看 Service:
kubectl get services
也就是說(shuō)外部訪問(wèn)端口是 30424。
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
kubernetes ClusterIP 10.96.0.1 443/TCP 3d6h
nginx LoadBalancer 10.101.132.236 80:30424/TCP 39s
這時(shí),我們可以通過(guò)公網(wǎng)和端口訪問(wèn)這個(gè) Service。
我們可以查看此 Service 的 yaml 文件:
kubectl get service nginx -o yaml
apiVersion: v1kind: Servicemetadata:
creationTimestamp: "2021-04-23T07:40:35Z"
labels:
app: nginx
name: nginx
namespace: default
resourceVersion: "369738"
uid: 8dc49805-2fc8-4407-adc0-8e31dc24fa79spec:
clusterIP: 10.101.132.236
clusterIPs:
- 10.101.132.236
externalTrafficPolicy: Cluster
ipFamilies:
- IPv4
ipFamilyPolicy: SingleStack
ports:
- nodePort: 30424
port: 80
protocol: TCP
targetPort: 80
selector:
app: nginx
sessionAffinity: None
type: LoadBalancerstatus:
loadBalancer: {}
有了標(biāo)準(zhǔn)的 yaml 文件模板,我們可以很方便地修改并定制一個(gè) Service。
我們查看通過(guò) Deployment 創(chuàng)建的 pod:
kubectl get pods -o wide
NAME IP NODE NOMINATED NODE READINESS GATESnginx-55649fd747-9fzlr 192.168.56.56 instance-2 nginx-55649fd747-ckhrw 192.168.56.57 instance-2 nginx-55649fd747-ldzkf 192.168.23.138 instance-1
注:pod 在哪個(gè)節(jié)點(diǎn)中運(yùn)行,我們是不一樣的。
當(dāng)我們通過(guò)外部網(wǎng)絡(luò)訪問(wèn)時(shí),Service 會(huì)自動(dòng)提供其中一個(gè) pod 給我們,但是這個(gè)過(guò)程較為復(fù)雜,我們這里先將表面現(xiàn)象。
------------
| |
--- 公網(wǎng)ip --> | pod1 |
| pod2 |
| pod3 |
------------
然后我們通過(guò)命令查看 iptables 配置:
iptables-save
然后查找 random 關(guān)鍵字:
你可以看到有三個(gè) default/nginx, 第一個(gè) pod 被訪問(wèn)的機(jī)會(huì)都是 0.33333...,然后 2/3 的概率中,2/3 的 0.5 的概率選擇第二個(gè) pod,剩下的 1/3 概率選擇第三個(gè) pod。
如果要訪問(wèn) pod,可以以任意部署了 nginx pod 的節(jié)點(diǎn)的 ip 進(jìn)行訪問(wèn)。由于 master 不能部署 pod,所以不能通過(guò) master 的 ip 進(jìn)行訪問(wèn)。
當(dāng)然,它并不是直接都是 0.33333.. 這樣的,iptables 的規(guī)則有點(diǎn)復(fù)雜,這里難以講清楚,我們只需要知道 外網(wǎng)能夠訪問(wèn) Service,而 Service 通過(guò) iptable 為我們轉(zhuǎn)發(fā)流量。即使 Deployment 部署的 pod 不在同一個(gè)節(jié)點(diǎn)上, k8s 的 dns 服務(wù)等會(huì)正確處理的,我們不需要手動(dòng)配置這些網(wǎng)絡(luò)。
Service 定義
在上一小節(jié)中,介紹了 Service 的創(chuàng)建方法(kubectl expose ...),也介紹了其依賴的 iptables,這里將繼續(xù)學(xué)習(xí) Service 的定義方法。
因?yàn)橹拔覀兪峭ㄟ^(guò) Deployment 進(jìn)行操作,直接為一個(gè) deployment 中的 pod (副本)統(tǒng)一映射。當(dāng)然我們也可以為不同的 pod 進(jìn)行網(wǎng)絡(luò)映射。
apiVersion: v1kind: Servicemetadata:
name: my-servicespec:
selector:
app: MyApp
ports:
- protocol: TCP
port: 6666
targetPort: 80
這里我們使用了 selector 選擇器,一般 pod 的 Label 都會(huì)有 app,表示此 pod 的名稱(一般是鏡像名稱)。port、targetPort 分別是 pod 端口、提供給外界訪問(wèn)的端口。
當(dāng)我們不通過(guò) Deployment 或者 job 等對(duì)象處理 pod 時(shí),可以通過(guò) selector 來(lái)選擇合適的 pod。
Service 能夠?qū)⒁粋€(gè)接收 容器或者 pod 的端口 targetPort 映射到任意的 port 端口,port 是外部可以訪問(wèn)的端口。 如果使用 kubectl expose 去映射端口,會(huì)默認(rèn)隨機(jī)提供一個(gè) 30xxx 端口。而使用 yaml ,默認(rèn)情況下,targetPort 將被設(shè)置為與 port 字段相同的值。
Endpoint slices
”端點(diǎn)切片(Endpoint Slices) 提供了一種簡(jiǎn)單的方法來(lái)跟蹤 Kubernetes 集群中的網(wǎng)絡(luò)端點(diǎn) (network endpoints)。它們?yōu)?Endpoints 提供了一種可伸縮和可拓展的替代方案。“
在 Kubernetes 中,EndpointSlice 包含對(duì)一組網(wǎng)絡(luò)端點(diǎn)的引用。 指定選擇器后控制面會(huì)自動(dòng)為設(shè)置了 選擇算符 的 Kubernetes 服務(wù)創(chuàng)建 Endpoint。
也就是說(shuō)創(chuàng)建 Service(帶選擇運(yùn)算符) 會(huì)自動(dòng)創(chuàng)建 Endpiont。
我們查看默認(rèn)命名空間的 endpoint:
kubectl get endpoints
NAME ENDPOINTS AGEkubernetes 10.170.0.2:6443 3d7hnginx 192.168.56.24:80,192.168.56.25:80,192.168.56.26:80 59m
這些都是 pod 的 ip 和端口,也就是說(shuō),通過(guò) Endpoint 我們跟蹤 Kubernetes 集群中的網(wǎng)絡(luò)端點(diǎn) (network endpoints)變得更加任意。不過(guò)這樣解釋是很難明白的,筆者翻了很多次資料,一點(diǎn)點(diǎn)試錯(cuò)才搞懂。接下來(lái)我們一步步來(lái)上手操作,然后一點(diǎn)點(diǎn)理解這些操作的含義。
創(chuàng)建 Endpoint、Service
接下來(lái)我們手動(dòng)創(chuàng)建 Service 和 Endpoint 和 ,需要先創(chuàng)建 Service ,再創(chuàng)建 Endpoint (這兩者創(chuàng)建順序可以隨意)。
Service
我們先刪除之前創(chuàng)建的 service。
kubectl delete service nginx
編寫(xiě) service.yaml 文件內(nèi)容如下如下:
apiVersion: v1kind: Servicemetadata:
name: nginxspec:
ports:
- protocol: TCP
port: 6666
targetPort: 80
應(yīng)用這個(gè) Service:
kubectl apply -f service.yaml
查看 service :
kubectl get services
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGEkubernetes ClusterIP 10.96.0.1 443/TCP 3d12hnginx ClusterIP 10.98.113.242 6666/TCP 6s
由于此 Service 沒(méi)有映射任何 pod 等,因此沒(méi)有任何用處,但是此時(shí)已經(jīng)可以給開(kāi)發(fā)人員一個(gè)交待了,或者說(shuō)確定下 nginx 的 Service 端口和地址。至于真正的 nginx 服務(wù),后面再確定。創(chuàng)建 Service 和 Endpoint 的順序是任意的,只是這里我們提出抽象,先約定 端口,再提供服務(wù),所以先創(chuàng)建 Service。
創(chuàng)建應(yīng)用
我們隨便找臺(tái) worker 或者 master 節(jié)點(diǎn),創(chuàng)建一個(gè) nginx 容器:
docker run -itd -p 80:80 nginx:latest
為什么不用 pod,直接創(chuàng)建容器?因?yàn)槲覀兲幱陂_(kāi)發(fā)階段,如果把 nginx 改成 mysql,我們要 Debug 呢?測(cè)試自己的數(shù)據(jù)庫(kù)呢?要模擬數(shù)據(jù)呢?我們?cè)谏a(chǎn)時(shí)再通過(guò) Deployment 創(chuàng)建應(yīng)用,但是此時(shí)我們可以使用自己的數(shù)據(jù)庫(kù)或者本地應(yīng)用。
官方文檔說(shuō):
希望在生產(chǎn)環(huán)境中使用外部的數(shù)據(jù)庫(kù)集群,但測(cè)試環(huán)境使用自己的數(shù)據(jù)庫(kù)。
希望服務(wù)指向另一個(gè) 名字空間(Namespace) 中或其它集群中的服務(wù)。
你正在將工作負(fù)載遷移到 Kubernetes。 在評(píng)估該方法時(shí),你僅在 Kubernetes 中運(yùn)行一部分后端。
總之,我們創(chuàng)建了 Service,可以提供了抽象,至于怎么提供這個(gè)服務(wù),我們可以使用 pod ,也可以直接使用命令執(zhí)行機(jī)器上的二進(jìn)制程序,也可以通過(guò) docker 提供。而且 mysql 可能是在外部服務(wù)提供的,或者 mysql 直接部署在宿主機(jī)上,而不使用容器和 pod,我們可以通過(guò) Endpoint 來(lái)跟蹤 mysql 服務(wù)的端口。
然后查詢這個(gè)容器的 ip,:
docker inspect {容器id} | grep IPAddress
筆者得到的是:"IPAddress": "172.17.0.2",可以試試 curl 172.17.0.2 ,看看是否能夠訪問(wèn) nginx,如果沒(méi)問(wèn)題我們來(lái)進(jìn)行下一步。
創(chuàng)建 Endpoint
創(chuàng)建一個(gè) endpoint.yaml 文件,內(nèi)容如下(注意替換ip為你容器訪問(wèn)ip):
apiVersion: v1kind: Endpointsmetadata:
name: nginxsubsets:
- addresses:
- ip: 172.17.0.2
ports:
- port: 80
然后應(yīng)用 yaml:
kubectl apply -f endpoint.yaml
查看 endpoint:
kubectl get endpoints# 不能填寫(xiě)成 endpoint
然后訪問(wèn) Service 的 ip:
curl 10.99.142.24:6666
也可以通過(guò)公網(wǎng)訪問(wèn)此 IP。
如果 Endpoint 需要跟蹤多個(gè) ip (多個(gè) pod 或者容器或者應(yīng)用),可以使用:
- addresses:
- ip: 172.17.0.2
- ip: 172.17.0.3
- ip: 172.17.0.4
“Service和Endpoint的原理和作用是什么”的內(nèi)容就介紹到這里了,感謝大家的閱讀。如果想了解更多行業(yè)相關(guān)的知識(shí)可以關(guān)注億速云網(wǎng)站,小編將為大家輸出更多高質(zhì)量的實(shí)用文章!
免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如果涉及侵權(quán)請(qǐng)聯(lián)系站長(zhǎng)郵箱:is@yisu.com進(jìn)行舉報(bào),并提供相關(guān)證據(jù),一經(jīng)查實(shí),將立刻刪除涉嫌侵權(quán)內(nèi)容。