K8S内部pod之间相互调用案例以及详解
作者:大洋百度
服务发现简介:
1、service是用于K8S的服务发现的重要组件,pod作为运行业务的承载方式,要想被客户端访问或者集群内部其它服务访问,就需要提供一个访问入口;
2、传统来说ip+端口是普适的访问方式,但是pod是一种动态的资源,它会因故障被重建或重启,因而pod ip会发生变化,所以使用ip作为pod的访问入口并不合适;而K8S是通过service来充当pod与访问端的中间代理,要访问pod首先访问pod对应的service,再由service代理到对应的pod
3、而pod采用了标签来代替ip作为唯一标识,以供service筛选。service对应的也有标签选择器用来筛选pod标签
4、 而service本身是ipvs规则,是由kube-porxy组件生成的,这个规则只要不删除就会一直存在,但是删除了service ip也会发生变化,这样一来客户端仍有无法访问到service ip的风险
5、因此K8S使用了DNS来记录service ip和service域名的记录,客户端使用域名就可以通过DNS中拿到对应的service ip了,而当service ip发生变化时,DNS也会动态的即使跟新到记录表中,这样即使service ip发生改变,仍然可以通过service的域名拿到对应的service ip,有了service ip就可以访问到Service 而后service代理到对应的pod上
service类型:(主要用两种)
1、clusterIP: 在K8S集群内部通信使用,无法接入集群外部流量
2、NodePort: 可以接入集群外部流量,在每个node节点监听一个和service定义的相同的端口,用于客户端的访问,把请求转发到对应的service,然后service再转发给pod; 用于将K8S服务暴露给K8S以外的客户端访问
注:serviceIP=clusterIP
NodePort 访问流程如下:
客户端client ------->node_IP+端口------->cluster_IP+端口-------->pod_IP+端口
上面的访问流程可以看出NodePort类型还是需要借助clusterIP才能把集群外的访问引入到集群内
3、何为无头服务?
service的不同模式都是在上一种模式的基础上增强版,nodePort就是在clusterIP的基础上新增了功能,并不是一种新的功能模式,因为nodePort模式下客户端访问过程中还是要经过clusterIP的,这意味着clusterIP是service最基本要件,但也可以把这个clusterIP移除掉,而一旦No cluster,就称为无头服务了,无头服务的主要作用在于可以把服务名称(service_name)直接解析到后端的podIP;而本来只能解析到serviceIP
NodePort 示例:
部署nginx和tomcat这两个前后端服务pod,通过NodePort类型service 相互调用
一、部署nginx容器
1、编写yaml文件
root@k8s-deploy:~# vim nginx.yaml kind: Deployment apiVersion: apps/v1 #可查询它的api版本 kubectl explain deployment.apiVersion metadata: #定义pod元数据信息,可查询它的下级子字段kubectl explain deployment.metadata labels: #定义deployment控制器标签 app: nginx-deployment-label #标签名称以键值形式定义,可以定义多个,这里标签是app值为nginx-deployment-label name: nginx-deployment #deployment资源的名字 namespace: myserver #deployment所属的namespace,默认是defaule spec: #定义Deployment中容器的详细信息,可通过kubectl explain deployment.spec查询 replicas: 1 #定义创建出pod的副本数,默认值是1个pod selector: #定义标签选择器,它跟上面的Deployment标签不是一回事,它是找下面template中定义的labels标签 matchLabels: #定义匹配的标签,必须要设置 app: nginx-selector #匹配的目标标签,控制器会拿这个标签匹配下面的pod template: #定义模板,用来描述需要创建的pod作用 metadata: #定义模板元数据 labels: #这个labels会继承给这个yaml文件Deployment控制器创建的所有pod app: nginx-selector #这个labels的key是app,值是nginx-selector,它会继承给下面的pod,和上面matchLabels.app: nginx-selector一样 spec: #定义pod的详细信息 containers: #定义pod中容器列表,可以定义多个pod - name: nginx-container #容器名称 image: nginx:1.20 #容器镜像 imagePullPolicy: Always #镜像拉取策略 ports: #定义容器端口列表 - containerPort: 80 #定义一个端口 protocol: TCP #定义协议 name: http #端口名称 - containerPort: 443 protocol: TCP name: https env: #给容器传递环境变量 - name: "password" #变量名称,必须引号引起来 value: "123" #上面变量的值 - name: "age" value: "18"--- kind: Service apiVersion: v1 metadata: name: nginx-service labels: app: nginx-service-label #service资源的标签 namespace: myserver #所在的命名空间,与上面控制器必须在同一个命名空间 spec: type: NodePort #service类型是NodePort ports: #定义访问端口,一个service可以定义多个端口的映射关系 - name: http #定义协议名称 port: 80 #定义service端口,它可以和pod,node端口都不同,它是K8S中一个独立子网 protocol: TCP #定义类型 targetPort: 80 #目标pod端口,当访问宿主机30004端口时就会转达到pod的80端口 nodePort: 30004 #手动指定node节点暴露的端口,如果没有指定端口,那service会随机分配一个端口 - name: https port: 443 protocol: TCP targetPort: 443 nodePort: 30443 selector: app: nginx-selector #这个标签就是上面pod的标签,service通过这个标签来匹配对应的pod
2、创建资源
创建资源 # kubectl apply -f nginx.yaml 查看nginx pod已经启动 root@k8s-deploy:~# kubectl get pod -A | grep nginx myserver nginx-deployment-766fc9dfdd-f488k 1/1 Running 0 8m11s 查看nginx-service已经创建 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、访问node节点的http协议的30004端口
因为service中定义了nodePort规则,因此要访问nginx容器的80端口,直接访问任意node节点的30004端口即可转发到nginx容器的80端口
二、部署tomcat服务
1、编写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有四种类型,默认是cluser ip ports: - name: http port: 80 protocol: TCP nodePort: 30005 targetPort: 8080 selector: app: tomcat-selector
2、创建资源
root@k8s-deploy:~# kubectl apply -f tomcat.yaml
3、访问tomcat
可以访问下node节点的30005端口,报404是因为还没有页面,下面进入tomcat容器中手动创建一个页面
root@k8s-deploy:~# kubectl get pod -A | grep tomcat myserver tomcat-deployment-5576d59694-rv2sb 1/1 Running 0 7m16s 进入容器 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
而后再来访问这个页面就有内容了,说明现在tomcat服务是正常的
三、使用nginx代理tomcat服务
这个tomcat端口其实不是必须要暴露的,测试完后,我这里再把它注释掉,去掉之后就没有nodeport了,就是仅在K8S内部的一个cluser ip了 ,仅能在K8S内部访问,下面用nginx代理tomcat服务,实现在K8S内部两个服务之间通过service相互转发
1、注释
2、 注释后再执行下apply,可以看见tomcat-deployment是不变的,tomcat-serivce配置了
3、 查看tomcat service的名称,下面配置nginx代理tomcat文件要用
4、修改nginx容器的配置文件
下面用nginx作为代理访问tomcat,进入nginx容器中进行配置
root@k8s-deploy:~# kubectl get pod -A | grep nginx myserver nginx-deployment-766fc9dfdd-f488k 1/1 Running 0 8m11s 进入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访问
全路径访问如下:
这里cluster.local是当时创建集群时候在hosts文件里定义的
可以看下当时定义的K8S集群域名
四、测试
访问nginx的30004端口,就可以代理到tomcat服务了
可以看下nginx的日志,每当请求/myapp/index.jsp文件就由nginx通过tomcat service转发给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访问的是tomcat-service,是因为nginx和tomcat都在同一个namesapce中,所以可以之间访问名称简写
如果不在一个namespace中需要名字全称,如果不在一个namespace就需要把nginx容器里的配置文件修改 ,其中80端口可以不写,因为这里调用的是service,而tomcat service的端口定义的就是80
因为在tomcat.yaml文件中定义的service 端口是80,所以在nignx配置文件中调用这个端口,这个80端口会转给pod的8080端口
总结:
客户端访问node节点的30004端口,而后转发到nginx-service, 如果nginx-pod是多副本的,再由nginx-service根据算法转发给某个nginx-pod; 然后nginx-pod把请求转发给tomcat-service,最后再由tomcat-service根据算法转发给tomcat-pod进行处理
总结
到此这篇关于K8S内部pod之间相互调用案例的文章就介绍到这了,更多相关K8S内部pod相互调用内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!