Service四层代理详解

目录

1.Service类型

1.1 ExternalName

1.2 ClusterIP

1.3 NodePort

1.4 LoadBalancer

nodeport案例

        映射外部服务案例


        Service是一个固定接入层,客户端可以通过访问 Service ip和端口访问到Service所关联的后端Pod。Service 工作依赖于在Kubernetes集群之上部署的一个附件,就是Kubernetes的Dns,服务(不同Kubernetes版本的Dns默认使用的也是不一样的,1.11之前的版本使用的是KubeDNS,较新的版本使用的是Coredns),Service的名称解析是依赖于Coredns.附件的,因此在部署完K8S之后需要部署Dns附件,Kubernetes,要想给客户端提供网络功能,需要依赖第三方的网络插件(Flannel,Calico等)。 ​ 每个K8S节点上都有一个组件叫做Kube-proxy,Kube-proxy需要跟Master之上的ApiServer交互,随时连接到ApiServer获取任何一个与Service资源相关的资源变动状态,这种是通过Kubernetes.中固有的一种请求方法 Watch(监视)来实现的,一旦有Service资源的内容发生变动(如创建,删除),Kube-proxy都会将它转化成当前节点之上的能够实现Service资源调度,把我们请求调度到后端特定的pod资源之上的规则,这个规则可能是lptables,也可能是ipvs,取决于Service 的部署实现方式。


K8S在创建Service时,会根据标签选择器(Label Selector)来查找对应的Pod,据此创建与Service同名的endpoint对象,当Pod地址发生变化时,Endpoint也会随之发生变化,Service接收前端Client请求的时候,就会通过Endpoint,找到转发到哪个Pod进行访问的地址(至于转发到哪个节点的Pod,由负载均衡Kube-proxy决定)。

总结:

1、Service通过 Label Selector查找指定的Pod

2、Service通过endpoint来获取Pod地址列表;

3、Service通过CoreDNS实现名称解析;

4、Service通过 Kube-Proxy实现Pod 的代理;

5、Kube-Proxy通过IPVS或者iptables实现负载均衡


1.Service类型

有四种类型: ClusterIP ,NodePort ,ExternalName , LoadBalancer

1.1 ExternalName

适用于k8s集群内部容器访问外部资源,它没有selector,也没有定义任何的端口和Endpoint。

Service定义的是将Prod名称空间中的my-service服务映射到my.database.example.com

apiVersion: v1
kind: Service
metadata:
  name: my-service
  namespace: prod
spec:
  type: ExternalName
  externalName: my.database.example.com

当查询主机 my-service.prod.svc.cluster.local时﹐群集DNS 将返回值为 ​ my.database.example.com 的CNAME记录。

Service的 FQDN是:<service_name>.<namespace>.suc.cluster.local

1.2 ClusterIP

通过K8S集群内部IР暴露服务,通过该类型服务只能够集群内通信,这也是默认的ServiceType。

1.3 NodePort

通过每个Node节点上的IP和静态端口暴露K8S集群内部的服务。通过请求<NodelP>:<NodePort>可以把请求代理到内部的Pod。

访问流程:Client --> NodelP:NodePort --> Service lp:ServicePort --> PodlP:ContainerPort。

1.4、LoadBalancer

使用云提供商的负载均衡器(阿里云SLB/腾讯云ELB),可以向外部暴露服务。外部的负载均衡器可以路由到NodePort服务和ClusterlP服务。

elinks --dump 172.16.104.18

Service可以对外提供统一固定的ip地址,并将请求重定向至集群中的pod。其中“将请求重定向至集群中的pod”就是通过endpoint 与selector协同工作实现。selector是用于选择pod,由selector选择出来的pod的 ip.地址和端口号,将会被记录在endpoint中。 endpoint 便记录了所有pod 的ip.地址和端口号。当一个请求访问到service的ip.地址时,就会从endpoint中选择出一个ip地址和端口号,然后将请求重定向至pod中。具体把请求代理到哪个pod,需要的就是kube-proxy的轮询实现的。service不会直接到pod,service是直接到endpoint资源,就是地址加端口,再由endpoint再关联到pod。 service只要创建完成,我们就可以直接解析它的服务名,每一个服务创建完成后都会在集群dns.中动态添加一个资源记录,添加完成后我们就可以解析了,资源记录格式是:sVC_NAME.NS_NAME.DOMAIN.LTD. 服务名.命名空间.域名后缀

nodeport案例

apiVersion: v1
kind: Service
metadata:
  name: dream-svc
  labels:
    run: dream-deployment
spec:
  type: NodePort
  ports:
  - port: 80
    protocol: TCP
    targetPort: 80
  selector:
    run: dream-deployment


服务请求走向:Client node ip:30380 -service ip:80 -> pod ip:container port
            Client >192.168.200.111:30380 →10.102.109.111:80 ->pod ip:80

Externalname案例:

vim client.yaml

apiVersion: apps/v1
kind: Deployment
metadata:
  name: client
spec:
  replicas: 3
  selector:
    matchLabels:
      app: busybox
  template:
    metadata:
      labels:
        app: busybox
    spec:
      containers:
      - name: busybox
        image: busybox:latest
        imagePullPolicy: IfNotPresent
        command: ["/bin/sh","-c","sleep 36000"]







vim clint-server.yaml

apiVersion: v1
kind: Service
metadata:
  name: clint-service
spec:
  type: ExternalName
  externalName: nginx-dreamsrv.nginx-namedr.svc.cluster.local
  ports:
  - name: http
    port: 80
    targetPort: 80


kubectl create ns nginx-namedr




vim nginx-1212.yaml     

apiVersion: apps/v1
kind: Deployment
metadata:
  name: nginx-1212
  namespace: nginx-namedr
spec:
  replicas: 3
  selector:
    matchLabels:
      app: nginx
  template:
    metadata:
      labels:
        app: nginx
    spec:
      containers:
      - name: nginx
        image: nginx:1.21.5
        imagePullPolicy: IfNotPresent
        
        
        
        
vim nginx-1212-service.yaml     

apiVersion: v1           
kind: Service
metadata:
  name: nginx-dreamsrv
  namespace: nginx-namedr
spec:
  selector:
    app: nginx
  ports:
  - name: hhtp
    protocol: TCP
    port: 80
    targetPort: 80
               

这样配置 client里的pod 可以通过externalname这个类型进行访问到nginx-1212的pod

externalName: nginx-dreamsrv.nginx-namedr.svc.cluster.local svc.cluster.local这个格式是固定不变的

并且pod nginx-1212的service的名字是nginx-dreamsrv nginx-1212的namespace是nginx-namedr

映射外部服务案例

k8s集群引用外部的mariadb 数据库

在node1上安装mariadb数据库

在master上写service和endpoint两条yaml

apiVersion: v1
kind: Service
metadata:
  name: mysql
spec:
  type: ClusterIP
  ports:
  - port: 3306



apiVersion: v1
kind: Endpoints
metadata:
  name: mysql
subsets:
- addresses:
  - ip: 192.168.120.102
  ports:
  - port: 3306

然后在node1 节点登陆mysql mysql -uroot -h 10.97.56.178 这个ip地址用的是service里面的

然后给master授权给权限: grant all on . to root@'192.168.120.10_' identified by '123456'; flush privillges;

然后再master节点进入 mysql -uroot -p123456 -h 10.97.56.178

然后把service的类型改为nodeport

apiVersion: v1
kind: Service
metadata:
  name: mysql
spec:
  type: NodePort
  ports:
  - port: 3306
    nodePort: 30388

然后就可以再windos的mysql数据库通过连接30388端口

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

你可知这世上再难遇我

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值