網(wǎng)站首頁 編程語言 正文
Srevice
Service 是將運(yùn)行在一組 Pods 上的應(yīng)用程序公開為網(wǎng)絡(luò)服務(wù)的抽象方法。如果我們使用 Deployment 部署 pod,則可以以 Deployment 為對象創(chuàng)建 Service。
在 K8S 中,每個 Pod 都有其自己唯一的 ip 地址,而 Service 可以為多個 Pod(一組)提供相同的 DNS 名,并且可以在他們直接進(jìn)行負(fù)載均衡。
假如有一組 nginx pod,如果 nginx 動態(tài)伸縮改變或因?yàn)槟承┰?ip/端口發(fā)生改變,那么其 ip 和 端口都不是固定的,而且我們很難確定它新擴(kuò)容的 pod 的地址是什么,又萬一 pod 被刪除,ip 不再可用。
又假如一組 pod 稱為前端,如 web 服務(wù),另一組 pod 稱為后端,例如 mysql。那么 前端 如何查找并跟蹤要連接的 ip 地址,以便前端可以使用工作負(fù)載的后端部分?
這真是 Service 要解決的問題。Kubernetes Service 定義了一種抽象:邏輯上的一組 Pod,一種可以訪問它們的策略 —— 通常稱為微服務(wù)。當(dāng)使用 Service 為一組 pod (Deployment 的方式創(chuàng)建的)創(chuàng)建服務(wù)時,無論我們創(chuàng)建了多少個 pod 副本,這些 pod 怎么變化,前端不需要關(guān)心它們調(diào)用了哪個后端副本,而且不需要知道后端 pod 的狀態(tài)也不需要跟蹤 pod。Service 把前后端的這種關(guān)聯(lián)抽象化,把它們解耦了。
Service 的創(chuàng)建及現(xiàn)象
現(xiàn)在按照下面的命令快速創(chuàng)建 pod,pod 將會在各個節(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
也就是說外部訪問端口是 30424。
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE kubernetes ClusterIP 10.96.0.1 <none> 443/TCP 3d6h nginx LoadBalancer 10.101.132.236 <pending> 80:30424/TCP 39s
這時,我們可以通過公網(wǎng)和端口訪問這個 Service。
我們可以查看此 Service 的 yaml 文件:
kubectl get service nginx -o yaml
apiVersion: v1 kind: Service metadata: creationTimestamp: "2021-04-23T07:40:35Z" labels: app: nginx name: nginx namespace: default resourceVersion: "369738" uid: 8dc49805-2fc8-4407-adc0-8e31dc24fa79 spec: 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: LoadBalancer status: loadBalancer: {}
有了標(biāo)準(zhǔn)的 yaml 文件模板,我們可以很方便地修改并定制一個 Service。
我們查看通過 Deployment 創(chuàng)建的 pod:
kubectl get pods -o wide
NAME IP NODE NOMINATED NODE READINESS GATES nginx-55649fd747-9fzlr 192.168.56.56 instance-2 <none> <none> nginx-55649fd747-ckhrw 192.168.56.57 instance-2 <none> <none> nginx-55649fd747-ldzkf 192.168.23.138 instance-1 <none> <none>
注:pod 在哪個節(jié)點(diǎn)中運(yùn)行,我們是不一樣的。
當(dāng)我們通過外部網(wǎng)絡(luò)訪問時,Service 會自動提供其中一個 pod 給我們,但是這個過程較為復(fù)雜,我們這里先將表面現(xiàn)象。
------------ | | --- 公網(wǎng)ip --> | pod1 | | pod2 | | pod3 | ------------
然后我們通過命令查看 iptables 配置:
iptables-save
然后查找 random 關(guān)鍵字:
你可以看到有三個?default/nginx
, 第一個 pod 被訪問的機(jī)會都是?0.33333...
,然后 2/3 的概率中,2/3 的 0.5 的概率選擇第二個 pod,剩下的 1/3 概率選擇第三個 pod。
如果要訪問 pod,可以以任意部署了 nginx pod 的節(jié)點(diǎn)的 ip 進(jìn)行訪問。由于 master 不能部署 pod,所以不能通過 master 的 ip 進(jìn)行訪問。
當(dāng)然,它并不是直接都是?0.33333..
?這樣的,iptables 的規(guī)則有點(diǎn)復(fù)雜,這里難以講清楚,我們只需要知道 外網(wǎng)能夠訪問 Service,而 Service 通過 iptable 為我們轉(zhuǎn)發(fā)流量。即使 Deployment 部署的 pod 不在同一個節(jié)點(diǎn)上, k8s 的 dns 服務(wù)等會正確處理的,我們不需要手動配置這些網(wǎng)絡(luò)。
Service 定義
在上一小節(jié)中,介紹了 Service 的創(chuàng)建方法(kubectl expose ...
),也介紹了其依賴的 iptables,這里將繼續(xù)學(xué)習(xí) Service 的定義方法。
因?yàn)橹拔覀兪峭ㄟ^ Deployment 進(jìn)行操作,直接為一個 deployment 中的 pod (副本)統(tǒng)一映射。當(dāng)然我們也可以為不同的 pod 進(jìn)行網(wǎng)絡(luò)映射。
apiVersion: v1 kind: Service metadata: name: my-service spec: selector: app: MyApp ports: - protocol: TCP port: 6666 targetPort: 80
這里我們使用了?selector
?選擇器,一般 pod 的 Label 都會有?app
,表示此 pod 的名稱(一般是鏡像名稱)。port、targetPort 分別是 pod 端口、提供給外界訪問的端口。
當(dāng)我們不通過 Deployment 或者 job 等對象處理 pod 時,可以通過?selector
?來選擇合適的 pod。
Service 能夠?qū)⒁粋€接收 容器或者 pod 的端口?targetPort
?映射到任意的 port 端口,port 是外部可以訪問的端口。 如果使用?kubectl expose
?去映射端口,會默認(rèn)隨機(jī)提供一個?30xxx
?端口。而使用 yaml ,默認(rèn)情況下,targetPort
?將被設(shè)置為與?port
?字段相同的值。
Endpoint slices
”端點(diǎn)切片(Endpoint Slices)?提供了一種簡單的方法來跟蹤 Kubernetes 集群中的網(wǎng)絡(luò)端點(diǎn) (network endpoints)。它們?yōu)?Endpoints 提供了一種可伸縮和可拓展的替代方案。“
在 Kubernetes 中,EndpointSlice
?包含對一組網(wǎng)絡(luò)端點(diǎn)的引用。 指定選擇器后控制面會自動為設(shè)置了 選擇算符 的 Kubernetes 服務(wù)創(chuàng)建 Endpoint。
也就是說創(chuàng)建 Service(帶選擇運(yùn)算符) 會自動創(chuàng)建 Endpiont。
我們查看默認(rèn)命名空間的 endpoint:
kubectl get endpoints
NAME ENDPOINTS AGE kubernetes 10.170.0.2:6443 3d7h nginx 192.168.56.24:80,192.168.56.25:80,192.168.56.26:80 59m
這些都是 pod 的 ip 和端口,也就是說,通過 Endpoint 我們跟蹤 Kubernetes 集群中的網(wǎng)絡(luò)端點(diǎn) (network endpoints)變得更加任意。不過這樣解釋是很難明白的,筆者翻了很多次資料,一點(diǎn)點(diǎn)試錯才搞懂。接下來我們一步步來上手操作,然后一點(diǎn)點(diǎn)理解這些操作的含義。
創(chuàng)建 Endpoint、Service
接下來我們手動創(chuàng)建 Service 和 Endpoint 和 ,需要先創(chuàng)建 Service ,再創(chuàng)建 Endpoint (這兩者創(chuàng)建順序可以隨意)。
Service
我們先刪除之前創(chuàng)建的 service。
kubectl delete service nginx
編寫 service.yaml 文件內(nèi)容如下如下:
apiVersion: v1 kind: Service metadata: name: nginx spec: ports: - protocol: TCP port: 6666 targetPort: 80
應(yīng)用這個 Service:
kubectl apply -f service.yaml
查看 service :
kubectl get services
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE kubernetes ClusterIP 10.96.0.1 <none> 443/TCP 3d12h nginx ClusterIP 10.98.113.242 <none> 6666/TCP 6s
由于此 Service 沒有映射任何 pod 等,因此沒有任何用處,但是此時已經(jīng)可以給開發(fā)人員一個交待了,或者說確定下 nginx 的 Service 端口和地址。至于真正的 nginx 服務(wù),后面再確定。創(chuàng)建 Service 和 Endpoint 的順序是任意的,只是這里我們提出抽象,先約定 端口,再提供服務(wù),所以先創(chuàng)建 Service。
創(chuàng)建應(yīng)用
我們隨便找臺 worker 或者 master 節(jié)點(diǎn),創(chuàng)建一個 nginx 容器:
docker run -itd -p 80:80 nginx:latest
為什么不用 pod,直接創(chuàng)建容器?因?yàn)槲覀兲幱陂_發(fā)階段,如果把 nginx 改成 mysql,我們要 Debug 呢?測試自己的數(shù)據(jù)庫呢?要模擬數(shù)據(jù)呢?我們在生產(chǎn)時再通過 Deployment 創(chuàng)建應(yīng)用,但是此時我們可以使用自己的數(shù)據(jù)庫或者本地應(yīng)用。
官方文檔說:
- 希望在生產(chǎn)環(huán)境中使用外部的數(shù)據(jù)庫集群,但測試環(huán)境使用自己的數(shù)據(jù)庫。
- 希望服務(wù)指向另一個 名字空間(Namespace) 中或其它集群中的服務(wù)。
- 你正在將工作負(fù)載遷移到 Kubernetes。 在評估該方法時,你僅在 Kubernetes 中運(yùn)行一部分后端。
總之,我們創(chuàng)建了 Service,可以提供了抽象,至于怎么提供這個服務(wù),我們可以使用 pod ,也可以直接使用命令執(zhí)行機(jī)器上的二進(jìn)制程序,也可以通過 docker 提供。而且 mysql 可能是在外部服務(wù)提供的,或者 mysql 直接部署在宿主機(jī)上,而不使用容器和 pod,我們可以通過 Endpoint 來跟蹤 mysql 服務(wù)的端口。
然后查詢這個容器的 ip,:
docker inspect {容器id} | grep IPAddress
筆者得到的是:"IPAddress": "172.17.0.2"
,可以試試?curl 172.17.0.2
?,看看是否能夠訪問 nginx,如果沒問題我們來進(jìn)行下一步。
創(chuàng)建 Endpoint
創(chuàng)建一個 endpoint.yaml 文件,內(nèi)容如下(注意替換ip為你容器訪問ip):
apiVersion: v1 kind: Endpoints metadata: name: nginx subsets: - addresses: - ip: 172.17.0.2 ports: - port: 80
然后應(yīng)用 yaml:
kubectl apply -f endpoint.yaml
查看 endpoint:
kubectl get endpoints # 不能填寫成 endpoint
然后訪問 Service 的 ip:
curl 10.99.142.242:6666
也可以通過公網(wǎng)訪問此 IP。
如果 Endpoint 需要跟蹤多個 ip (多個 pod 或者容器或者應(yīng)用),可以使用:
- addresses: - ip: 172.17.0.2 - ip: 172.17.0.3 - ip: 172.17.0.4 ... ...
原文鏈接:https://www.cnblogs.com/whuanle/p/14695815.html
相關(guān)推薦
- 2022-06-25 C++鏈表類的封裝詳情介紹_C 語言
- 2022-05-10 axios方式發(fā)送ajax,語法類似,但更簡單
- 2022-05-06 C語言中#define定義的標(biāo)識符和宏實(shí)例代碼_C 語言
- 2022-06-28 python神經(jīng)網(wǎng)絡(luò)tfrecords文件的寫入讀取及內(nèi)容解析_python
- 2022-09-17 python?Pandas之DataFrame索引及選取數(shù)據(jù)_python
- 2022-05-11 springboot 忽略接收請求中的參數(shù)
- 2022-04-30 詳解Matlab如何繪制小提琴圖_C 語言
- 2023-01-02 Kotlin?RadioGroup與ViewPager實(shí)現(xiàn)底層分頁按鈕方法_Android
- 最近更新
-
- window11 系統(tǒng)安裝 yarn
- 超詳細(xì)win安裝深度學(xué)習(xí)環(huán)境2025年最新版(
- Linux 中運(yùn)行的top命令 怎么退出?
- MySQL 中decimal 的用法? 存儲小
- get 、set 、toString 方法的使
- @Resource和 @Autowired注解
- Java基礎(chǔ)操作-- 運(yùn)算符,流程控制 Flo
- 1. Int 和Integer 的區(qū)別,Jav
- spring @retryable不生效的一種
- Spring Security之認(rèn)證信息的處理
- Spring Security之認(rèn)證過濾器
- Spring Security概述快速入門
- Spring Security之配置體系
- 【SpringBoot】SpringCache
- Spring Security之基于方法配置權(quán)
- redisson分布式鎖中waittime的設(shè)
- maven:解決release錯誤:Artif
- restTemplate使用總結(jié)
- Spring Security之安全異常處理
- MybatisPlus優(yōu)雅實(shí)現(xiàn)加密?
- Spring ioc容器與Bean的生命周期。
- 【探索SpringCloud】服務(wù)發(fā)現(xiàn)-Nac
- Spring Security之基于HttpR
- Redis 底層數(shù)據(jù)結(jié)構(gòu)-簡單動態(tài)字符串(SD
- arthas操作spring被代理目標(biāo)對象命令
- Spring中的單例模式應(yīng)用詳解
- 聊聊消息隊列,發(fā)送消息的4種方式
- bootspring第三方資源配置管理
- GIT同步修改后的遠(yuǎn)程分支