溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊(cè)×
其他方式登錄
點(diǎn)擊 登錄注冊(cè) 即表示同意《億速云用戶服務(wù)條款》

Service和Endpoint的原理和作用是什么

發(fā)布時(shí)間:2021-07-05 16:41:38 來(lái)源:億速云 閱讀:1487 作者:chen 欄目:云計(jì)算

本篇內(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í)用文章!

向AI問(wèn)一下細(xì)節(jié)

免責(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)容。

AI