K8S內(nèi)部pod之間相互調(diào)用案例以及詳解
服務(wù)發(fā)現(xiàn)簡(jiǎn)介:
1、service是用于K8S的服務(wù)發(fā)現(xiàn)的重要組件,pod作為運(yùn)行業(yè)務(wù)的承載方式,要想被客戶端訪問(wèn)或者集群內(nèi)部其它服務(wù)訪問(wèn),就需要提供一個(gè)訪問(wèn)入口;
2、傳統(tǒng)來(lái)說(shuō)ip+端口是普適的訪問(wèn)方式,但是pod是一種動(dòng)態(tài)的資源,它會(huì)因故障被重建或重啟,因而pod ip會(huì)發(fā)生變化,所以使用ip作為pod的訪問(wèn)入口并不合適;而K8S是通過(guò)service來(lái)充當(dāng)pod與訪問(wèn)端的中間代理,要訪問(wèn)pod首先訪問(wèn)pod對(duì)應(yīng)的service,再由service代理到對(duì)應(yīng)的pod
3、而pod采用了標(biāo)簽來(lái)代替ip作為唯一標(biāo)識(shí),以供service篩選。service對(duì)應(yīng)的也有標(biāo)簽選擇器用來(lái)篩選pod標(biāo)簽
4、 而service本身是ipvs規(guī)則,是由kube-porxy組件生成的,這個(gè)規(guī)則只要不刪除就會(huì)一直存在,但是刪除了service ip也會(huì)發(fā)生變化,這樣一來(lái)客戶端仍有無(wú)法訪問(wèn)到service ip的風(fēng)險(xiǎn)
5、因此K8S使用了DNS來(lái)記錄service ip和service域名的記錄,客戶端使用域名就可以通過(guò)DNS中拿到對(duì)應(yīng)的service ip了,而當(dāng)service ip發(fā)生變化時(shí),DNS也會(huì)動(dòng)態(tài)的即使跟新到記錄表中,這樣即使service ip發(fā)生改變,仍然可以通過(guò)service的域名拿到對(duì)應(yīng)的service ip,有了service ip就可以訪問(wèn)到Service 而后service代理到對(duì)應(yīng)的pod上
service類型:(主要用兩種)
1、clusterIP: 在K8S集群內(nèi)部通信使用,無(wú)法接入集群外部流量
2、NodePort: 可以接入集群外部流量,在每個(gè)node節(jié)點(diǎn)監(jiān)聽(tīng)一個(gè)和service定義的相同的端口,用于客戶端的訪問(wèn),把請(qǐng)求轉(zhuǎn)發(fā)到對(duì)應(yīng)的service,然后service再轉(zhuǎn)發(fā)給pod; 用于將K8S服務(wù)暴露給K8S以外的客戶端訪問(wèn)
注:serviceIP=clusterIP
NodePort 訪問(wèn)流程如下:
客戶端client ------->node_IP+端口------->cluster_IP+端口-------->pod_IP+端口
上面的訪問(wèn)流程可以看出NodePort類型還是需要借助clusterIP才能把集群外的訪問(wèn)引入到集群內(nèi)
3、何為無(wú)頭服務(wù)?
service的不同模式都是在上一種模式的基礎(chǔ)上增強(qiáng)版,nodePort就是在clusterIP的基礎(chǔ)上新增了功能,并不是一種新的功能模式,因?yàn)閚odePort模式下客戶端訪問(wèn)過(guò)程中還是要經(jīng)過(guò)clusterIP的,這意味著clusterIP是service最基本要件,但也可以把這個(gè)clusterIP移除掉,而一旦No cluster,就稱為無(wú)頭服務(wù)了,無(wú)頭服務(wù)的主要作用在于可以把服務(wù)名稱(service_name)直接解析到后端的podIP;而本來(lái)只能解析到serviceIP
NodePort 示例:
部署nginx和tomcat這兩個(gè)前后端服務(wù)pod,通過(guò)NodePort類型service 相互調(diào)用
一、部署nginx容器
1、編寫(xiě)yaml文件
root@k8s-deploy:~# vim nginx.yaml
kind: Deployment
apiVersion: apps/v1 #可查詢它的api版本 kubectl explain deployment.apiVersion
metadata: #定義pod元數(shù)據(jù)信息,可查詢它的下級(jí)子字段kubectl explain deployment.metadata
labels: #定義deployment控制器標(biāo)簽
app: nginx-deployment-label #標(biāo)簽名稱以鍵值形式定義,可以定義多個(gè),這里標(biāo)簽是app值為nginx-deployment-label
name: nginx-deployment #deployment資源的名字
namespace: myserver #deployment所屬的namespace,默認(rèn)是defaule
spec: #定義Deployment中容器的詳細(xì)信息,可通過(guò)kubectl explain deployment.spec查詢
replicas: 1 #定義創(chuàng)建出pod的副本數(shù),默認(rèn)值是1個(gè)pod
selector: #定義標(biāo)簽選擇器,它跟上面的Deployment標(biāo)簽不是一回事,它是找下面template中定義的labels標(biāo)簽
matchLabels: #定義匹配的標(biāo)簽,必須要設(shè)置
app: nginx-selector #匹配的目標(biāo)標(biāo)簽,控制器會(huì)拿這個(gè)標(biāo)簽匹配下面的pod
template: #定義模板,用來(lái)描述需要?jiǎng)?chuàng)建的pod作用
metadata: #定義模板元數(shù)據(jù)
labels: #這個(gè)labels會(huì)繼承給這個(gè)yaml文件Deployment控制器創(chuàng)建的所有pod
app: nginx-selector #這個(gè)labels的key是app,值是nginx-selector,它會(huì)繼承給下面的pod,和上面matchLabels.app: nginx-selector一樣
spec: #定義pod的詳細(xì)信息
containers: #定義pod中容器列表,可以定義多個(gè)pod
- name: nginx-container #容器名稱
image: nginx:1.20 #容器鏡像
imagePullPolicy: Always #鏡像拉取策略
ports: #定義容器端口列表
- containerPort: 80 #定義一個(gè)端口
protocol: TCP #定義協(xié)議
name: http #端口名稱
- containerPort: 443
protocol: TCP
name: https
env: #給容器傳遞環(huán)境變量
- name: "password" #變量名稱,必須引號(hào)引起來(lái)
value: "123" #上面變量的值
- name: "age"
value: "18"---
kind: Service
apiVersion: v1
metadata:
name: nginx-service
labels:
app: nginx-service-label #service資源的標(biāo)簽
namespace: myserver #所在的命名空間,與上面控制器必須在同一個(gè)命名空間
spec:
type: NodePort #service類型是NodePort
ports: #定義訪問(wèn)端口,一個(gè)service可以定義多個(gè)端口的映射關(guān)系
- name: http #定義協(xié)議名稱
port: 80 #定義service端口,它可以和pod,node端口都不同,它是K8S中一個(gè)獨(dú)立子網(wǎng)
protocol: TCP #定義類型
targetPort: 80 #目標(biāo)pod端口,當(dāng)訪問(wèn)宿主機(jī)30004端口時(shí)就會(huì)轉(zhuǎn)達(dá)到pod的80端口
nodePort: 30004 #手動(dòng)指定node節(jié)點(diǎn)暴露的端口,如果沒(méi)有指定端口,那service會(huì)隨機(jī)分配一個(gè)端口
- name: https
port: 443
protocol: TCP
targetPort: 443
nodePort: 30443
selector:
app: nginx-selector #這個(gè)標(biāo)簽就是上面pod的標(biāo)簽,service通過(guò)這個(gè)標(biāo)簽來(lái)匹配對(duì)應(yīng)的pod2、創(chuàng)建資源
創(chuàng)建資源 # kubectl apply -f nginx.yaml 查看nginx pod已經(jīng)啟動(dòng) root@k8s-deploy:~# kubectl get pod -A | grep nginx myserver nginx-deployment-766fc9dfdd-f488k 1/1 Running 0 8m11s 查看nginx-service已經(jīng)創(chuàng)建 root@k8s-deploy:~# kubectl get svc -A | grep nginx-service default nginx-service NodePort 10.100.57.113 <none> 80:30004/TCP,443:30443/TCP 2m11s
3、訪問(wèn)node節(jié)點(diǎn)的http協(xié)議的30004端口
因?yàn)閟ervice中定義了nodePort規(guī)則,因此要訪問(wèn)nginx容器的80端口,直接訪問(wèn)任意node節(jié)點(diǎn)的30004端口即可轉(zhuǎn)發(fā)到nginx容器的80端口

二、部署tomcat服務(wù)
1、編寫(xiě)yaml文件
root@k8s-deploy:~# vim tomcat.yaml
kind: Deployment
apiVersion: apps/v1
metadata:
name: tomcat-deployment
namespace: myserver
labels:
app: tomcat-deployment-label
spec:
replicas: 1
selector:
matchLabels:
app: tomcat-selector
template:
metadata:
labels:
app: tomcat-selector
spec:
containers:
- name: tomcat-container
image: tomcat:7.0.109-jdk8-openjdk
imagePullPolicy: Always
ports:
- containerPort: 8080
protocol: TCP
name: http
env:
- name: "password"
value: "123"
- name: "age"
value: "18"
---
kind: Service
apiVersion: v1
metadata:
name: tomcat-serivce
namespace: myserver
labels:
app: tomcat-service-label
spec:
type: NodePort #service有四種類型,默認(rèn)是cluser ip
ports:
- name: http
port: 80
protocol: TCP
nodePort: 30005
targetPort: 8080
selector:
app: tomcat-selector2、創(chuàng)建資源
root@k8s-deploy:~# kubectl apply -f tomcat.yaml
3、訪問(wèn)tomcat
可以訪問(wèn)下node節(jié)點(diǎn)的30005端口,報(bào)404是因?yàn)檫€沒(méi)有頁(yè)面,下面進(jìn)入tomcat容器中手動(dòng)創(chuàng)建一個(gè)頁(yè)面
root@k8s-deploy:~# kubectl get pod -A | grep tomcat myserver tomcat-deployment-5576d59694-rv2sb 1/1 Running 0 7m16s 進(jìn)入容器 root@k8s-deploy:~# kubectl exec -it nginx-deployment-7d7bd78b5c-v9mjs bash -n myserver root@tomcat-deployment-5576d59694-rv2sb:/usr/local/tomcat# cd webapps root@tomcat-deployment-5576d59694-rv2sb:/usr/local/tomcat/webapps# mkdir myapp root@tomcat-deployment-5576d59694-rv2sb:/usr/local/tomcat/webapps# echo "myapp web magedu n70" > myapp/index.jsp
而后再來(lái)訪問(wèn)這個(gè)頁(yè)面就有內(nèi)容了,說(shuō)明現(xiàn)在tomcat服務(wù)是正常的

三、使用nginx代理tomcat服務(wù)
這個(gè)tomcat端口其實(shí)不是必須要暴露的,測(cè)試完后,我這里再把它注釋掉,去掉之后就沒(méi)有nodeport了,就是僅在K8S內(nèi)部的一個(gè)cluser ip了 ,僅能在K8S內(nèi)部訪問(wèn),下面用nginx代理tomcat服務(wù),實(shí)現(xiàn)在K8S內(nèi)部?jī)蓚€(gè)服務(wù)之間通過(guò)service相互轉(zhuǎn)發(fā)
1、注釋

2、 注釋后再執(zhí)行下apply,可以看見(jiàn)tomcat-deployment是不變的,tomcat-serivce配置了

3、 查看tomcat service的名稱,下面配置nginx代理tomcat文件要用

4、修改nginx容器的配置文件
下面用nginx作為代理訪問(wèn)tomcat,進(jìn)入nginx容器中進(jìn)行配置
root@k8s-deploy:~# kubectl get pod -A | grep nginx myserver nginx-deployment-766fc9dfdd-f488k 1/1 Running 0 8m11s 進(jìn)入nginx容器 root@k8s-deploy:~# kubectl exec -it nginx-deployment-766fc9dfdd-f488k bash -n myserver root@nginx-deployment-766fc9dfdd-f488k:/etc/nginx# vim conf.d/default.conf
修改nginx容器的配置文件/etc/nginx/conf.d/default.conf (這是在nginx容器里配置的,配置如下圖),添加完配置后nginx -s reload重置下再curl訪問(wèn)

全路徑訪問(wèn)如下:

這里cluster.local是當(dāng)時(shí)創(chuàng)建集群時(shí)候在hosts文件里定義的
可以看下當(dāng)時(shí)定義的K8S集群域名

四、測(cè)試
訪問(wèn)nginx的30004端口,就可以代理到tomcat服務(wù)了

可以看下nginx的日志,每當(dāng)請(qǐng)求/myapp/index.jsp文件就由nginx通過(guò)tomcat service轉(zhuǎn)發(fā)給tomcat service后面的pod了
root@k8s-deploy:~# kubectl logs -f nginx-deployment-766fc9dfdd-nq4ck -n myserver 10.200.166.128 - - [18/Nov/2022:07:50:45 +0000] "GET /myapp/ HTTP/1.1" 200 21 "-" "Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:106.0) Gecko/20100101 Firefox/106.0" "-" 10.200.166.128 - - [18/Nov/2022:07:50:53 +0000] "GET /myapp/index.jsp HTTP/1.1" 200 21 "-" "Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:106.0) Gecko/20100101 Firefox/106.0" "-" 10.200.166.128 - - [18/Nov/2022:07:52:09 +0000] "GET /myapp/index.jsp HTTP/1.1" 200 21 "-" "Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:106.0) Gecko/20100101 Firefox/106.0" "-" 10.200.166.128 - - [18/Nov/2022:07:52:10 +0000] "GET /myapp/index.jsp HTTP/1.1" 200 21 "-" "Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:106.0) Gecko/20100101 Firefox/106.0" "-"
注意:
上面使用curl訪問(wèn)的是tomcat-service,是因?yàn)閚ginx和tomcat都在同一個(gè)namesapce中,所以可以之間訪問(wèn)名稱簡(jiǎn)寫(xiě)
如果不在一個(gè)namespace中需要名字全稱,如果不在一個(gè)namespace就需要把nginx容器里的配置文件修改 ,其中80端口可以不寫(xiě),因?yàn)檫@里調(diào)用的是service,而tomcat service的端口定義的就是80

因?yàn)樵趖omcat.yaml文件中定義的service 端口是80,所以在nignx配置文件中調(diào)用這個(gè)端口,這個(gè)80端口會(huì)轉(zhuǎn)給pod的8080端口
總結(jié):
客戶端訪問(wèn)node節(jié)點(diǎn)的30004端口,而后轉(zhuǎn)發(fā)到nginx-service, 如果nginx-pod是多副本的,再由nginx-service根據(jù)算法轉(zhuǎn)發(fā)給某個(gè)nginx-pod; 然后nginx-pod把請(qǐng)求轉(zhuǎn)發(fā)給tomcat-service,最后再由tomcat-service根據(jù)算法轉(zhuǎn)發(fā)給tomcat-pod進(jìn)行處理

總結(jié)
到此這篇關(guān)于K8S內(nèi)部pod之間相互調(diào)用案例的文章就介紹到這了,更多相關(guān)K8S內(nèi)部pod相互調(diào)用內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
k8s:pod has unbound PersistentVolumeClaims問(wèn)題及
部署redis-ha時(shí),Pod因PVC未綁定報(bào)錯(cuò),原因在于value.yaml中storageClassName為空,且未啟用DefaultDefaultStorageClass,解決方法是手動(dòng)指定PVC的StorageClassName為現(xiàn)有存儲(chǔ)類,確保PV分配成功2025-07-07
ES業(yè)務(wù)數(shù)據(jù)遷移遇到的精度問(wèn)題BUG
這篇文章主要為大家介紹了ES業(yè)務(wù)數(shù)據(jù)遷移遇到的BUG精度問(wèn)題,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2022-06-06
K8s Token過(guò)期問(wèn)題及解決(Kubeadm)
本文介紹了Kubernetes中Token的生成、管理和使用方法,包括生成默認(rèn)24小時(shí)Token和永久有效Token,以及查看、刪除Token和獲取CA證書(shū)Hash值,此外,還提供了Node節(jié)點(diǎn)加入K8s集群的完整命令2026-01-01
K8S加入新的node節(jié)點(diǎn)實(shí)現(xiàn)方式
文章主要介紹了基于kubeadm安裝的k8s集群加入新的節(jié)點(diǎn)的過(guò)程,包括初始化節(jié)點(diǎn)、安裝Docker和相關(guān)組件、配置鏡像下載加速器、添加軟件源、安裝組件、上傳和解壓鏡像、加入新的節(jié)點(diǎn)并查看節(jié)點(diǎn)狀態(tài)等步驟2026-04-04
Centos?8.2?升級(jí)內(nèi)核通過(guò)elrepo源的方法
這篇文章主要介紹了Centos?8.2?升級(jí)內(nèi)核通過(guò)elrepo源,本文給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2022-10-10

