k8s跨服務(wù)調(diào)用入門到實(shí)戰(zhàn)示例詳解
背景
在做傳統(tǒng)業(yè)務(wù)開發(fā)的時(shí)候,當(dāng)我們的服務(wù)提供方有多個(gè)實(shí)例時(shí),往往我們需要將對方的服務(wù)列表保存在本地,然后采用一定的算法進(jìn)行調(diào)用;當(dāng)服務(wù)提供方的列表變化時(shí)還得及時(shí)通知調(diào)用方。
student: url: - 192.168.1.1:8081 - 192.168.1.2:8081
這樣自然是對雙方都帶來不少的負(fù)擔(dān),所以后續(xù)推出的服務(wù)調(diào)用框架都會想辦法解決這個(gè)問題。
以 spring cloud
為例:
服務(wù)提供方會向一個(gè)服務(wù)注冊中心注冊自己的服務(wù)(名稱、IP等信息),客戶端每次調(diào)用的時(shí)候會向服務(wù)注冊中心獲取一個(gè)節(jié)點(diǎn)信息,然后發(fā)起調(diào)用。
但當(dāng)我們切換到 k8s
后,這些基礎(chǔ)設(shè)施都交給了 k8s
處理了,所以 k8s
自然得有一個(gè)組件來解決服務(wù)注冊和調(diào)用的問題。
也就是我們今天重點(diǎn)介紹的 service
。
service
在介紹 service
之前我先調(diào)整了源碼:
func main() { http.HandleFunc("/ping", func(w http.ResponseWriter, r *http.Request) { name, _ := os.Hostname() log.Printf("%s ping", name) fmt.Fprint(w, "pong") }) http.HandleFunc("/service", func(w http.ResponseWriter, r *http.Request) { resp, err := http.Get("http://k8s-combat-service:8081/ping") if err != nil { log.Println(err) fmt.Fprint(w, err) return } fmt.Fprint(w, resp.Status) }) http.ListenAndServe(":8081", nil) }
新增了一個(gè) /service
的接口,這個(gè)接口會通過 service 的方式調(diào)用服務(wù)提供者的服務(wù),然后重新打包。
make docker
同時(shí)也新增了一個(gè) deployment-service.yaml
:
apiVersion: apps/v1 kind: Deployment metadata: labels: app: k8s-combat-service # 通過標(biāo)簽選擇關(guān)聯(lián) name: k8s-combat-service spec: replicas: 1 selector: matchLabels: app: k8s-combat-service template: metadata: labels: app: k8s-combat-service spec: containers: - name: k8s-combat-service image: crossoverjie/k8s-combat:v1 imagePullPolicy: Always resources: limits: cpu: "1" memory: 100Mi requests: cpu: "0.1" memory: 10Mi --- apiVersion: v1 kind: Service metadata: name: k8s-combat-service spec: selector: app: k8s-combat-service # 通過標(biāo)簽選擇關(guān)聯(lián) type: ClusterIP ports: - port: 8081 # 本 Service 的端口 targetPort: 8081 # 容器端口 name: app
使用相同的鏡像部署一個(gè)新的 deployment,名稱為 k8s-combat-service
,重點(diǎn)是新增了一個(gè)kind: Service
的對象。
這個(gè)就是用于聲明 service
的組件,在這個(gè)組件中也是使用 selector
標(biāo)簽和 deployment
進(jìn)行了關(guān)聯(lián)。
也就是說這個(gè) service
用于服務(wù)于名稱等于 k8s-combat-service
的 deployment
。
下面的兩個(gè)端口也很好理解,一個(gè)是代理的端口, 另一個(gè)是 service 自身提供出去的端口。
至于 type: ClusterIP
是用于聲明不同類型的 service
,除此之外的類型還有:
- NodePort
- LoadBalancer
- ExternalName等類型,默認(rèn)是
ClusterIP
,現(xiàn)在不用糾結(jié)這幾種類型的作用,后續(xù)我們在講到Ingress
的時(shí)候會具體介紹。
負(fù)載測試
我們先分別將這兩個(gè) deployment
部署好:
k apply -f deployment/deployment.yaml k apply -f deployment/deployment-service.yaml ? k get pod NAME READY STATUS RESTARTS AGE k8s-combat-7867bfb596-67p5m 1/1 Running 0 3h22m k8s-combat-service-5b77f59bf7-zpqwt 1/1 Running 0 3h22m
由于我新增了一個(gè) /service
的接口,用于在 k8s-combat
中通過 service
調(diào)用 k8s-combat-service
的接口。
resp, err := http.Get("http://k8s-combat-service:8081/ping")
其中 k8s-combat-service
服務(wù)的域名就是他的服務(wù)名稱。
如果是跨 namespace 調(diào)用時(shí),需要指定一個(gè)完整名稱,在后續(xù)的章節(jié)會演示。
我們整個(gè)的調(diào)用流程如下:
相信大家也看得出來相對于 spring cloud
這類微服務(wù)框架提供的客戶端負(fù)載方式,service
是一種服務(wù)端負(fù)載,有點(diǎn)類似于 Nginx
的反向代理。
為了更直觀的驗(yàn)證這個(gè)流程,此時(shí)我將 k8s-combat-service
的副本數(shù)增加到 2:
spec: replicas: 2
只需要再次執(zhí)行:
? k apply -f deployment/deployment-service.yaml deployment.apps/k8s-combat-service configured service/k8s-combat-service unchanged
不管我們對 deployment
的做了什么變更,都只需要 apply
這個(gè) yaml
文件即可, k8s 會自動將當(dāng)前的 deployment
調(diào)整為我們預(yù)期的狀態(tài)(比如這里的副本數(shù)量增加為 2);這也就是 k8s
中常說的聲明式 API。
可以看到此時(shí) k8s-combat-service
的副本數(shù)已經(jīng)變?yōu)閮蓚€(gè)了。
如果我們此時(shí)查看這個(gè) service
的描述時(shí):
? k describe svc k8s-combat-service |grep Endpoints Endpoints: 192.168.130.133:8081,192.168.130.29:8081
會發(fā)現(xiàn)它已經(jīng)代理了這兩個(gè) Pod
的 IP。
此時(shí)我進(jìn)入了 k8s-combat-7867bfb596-67p5m
的容器:
k exec -it k8s-combat-7867bfb596-67p5m bash curl http://127.0.0.1:8081/service
并執(zhí)行兩次 /service
接口,發(fā)現(xiàn)請求會輪訓(xùn)進(jìn)入 k8s-combat-service
的代理的 IP 中。
由于 k8s service
是基于 TCP/UDP
的四層負(fù)載,所以在 http1.1
中是可以做到請求級的負(fù)載均衡,但如果是類似于 gRPC
這類長鏈接就無法做到請求級的負(fù)載均衡。
換句話說 service
只支持連接級別的負(fù)載。
如果要支持 gRPC
,就得使用 Istio 這類服務(wù)網(wǎng)格,相關(guān)內(nèi)容會在后續(xù)章節(jié)詳解。
總結(jié)
總的來說 k8s service
提供了簡易的服務(wù)注冊發(fā)現(xiàn)和負(fù)載均衡功能,當(dāng)我們只提供 http 服務(wù)時(shí)是完全夠用的。
相關(guān)的源碼和 yaml 資源文件都存在這里:https://github.com/crossoverJie/k8s-combat
以上就是k8s跨服務(wù)調(diào)用入門到實(shí)戰(zhàn)示例詳解的詳細(xì)內(nèi)容,更多關(guān)于k8s跨服務(wù)調(diào)用的資料請關(guān)注腳本之家其它相關(guān)文章!
相關(guān)文章
安裝ingress-nginx遇到的一些坑實(shí)戰(zhàn)記錄
ingress是kubernetes集群對外暴露服務(wù)的一種方式,下面這篇文章主要給大家介紹了關(guān)于安裝ingress-nginx遇到的一些坑,文中通過實(shí)例代碼介紹的非常詳細(xì),需要的朋友可以參考下2022-09-09KVM虛擬化技術(shù)之virt-manager使用及KVM虛擬化平臺網(wǎng)絡(luò)模型介紹
這篇文章主要介紹了KVM虛擬化技術(shù)之virt-manager使用及KVM虛擬化平臺網(wǎng)絡(luò)模型介紹,需要的朋友可以參考下2016-10-10淺析k8s中各組件和kube?apiserver通信時(shí)的認(rèn)證和鑒權(quán)問題
這篇文章主要介紹了k8s中各組件和kube?apiserver通信時(shí)的認(rèn)證和鑒權(quán),本文使用的k8s集群是用kubekey搭建,命令是./kk create cluster --with-kubernetes v1.21.5 --with-kubesphere v3.2.1,需要的朋友可以參考下2022-06-06Rainbond云原生部署開源社區(qū)Discourse的配置過程
這篇文章主要為大家介紹了Rainbond云原生部署開源社區(qū)Discourse配置過程,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2022-04-04KubeSphere中部署Wiki系統(tǒng)wiki.js并啟用中文全文檢索
這篇文章主要為大家介紹了KubeSphere中部署Wiki系統(tǒng)wiki.js并啟用中文全文檢索實(shí)現(xiàn)過程,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2022-06-06kubernetes(k8s)安裝metrics-server實(shí)現(xiàn)資源使用情況監(jiān)控方式詳解
這篇文章主要介紹了kubernetes(k8s)安裝metrics-server實(shí)現(xiàn)資源使用情況監(jiān)控,包括Metrics?Server下載方式,?k8s集群安裝部署metrics的問題,本文給大家介紹的非常詳細(xì),需要的朋友可以參考下2022-04-04