《Kubernetes知识篇:kubernetes四层负载均衡service》



一、四层负载均衡Service概述

1.1、为什么要有Service?

在kubernetes中,pod是有生命周期的,如果pod重启ip地址有可能会发生变化,如果客户端服务中定义的是pod的ip地址的话,那么该pod的ip地址发生变化后客户端服务会找不到之前定义的ip地址从而发生报错。 为了解决这个问题,在kubernetes中定义了service资源对象。Service 定义了一个服务访问的入口,客户端通过这个入口即可访问服务背后的应用集群实例,service是一组Pod的逻辑集合,这一组Pod能够被Service访问到,通常是通过Label Selector(标签选择器)实现的
在这里插入图片描述
总结:
1、pod ip经常发生变化,service是pod的代理,客户端访问,只需要访问service,service就会把请求代理到后端Pod。
2、pod ip在k8s集群之外是无法访问,所以需要创建service,这个service可以在k8s集群外访问的。


1.2、Service是什么?

在Kubernetes平台上,Pod是有生命周期,为了可以给客户端一个固定的访问端点,因此需要在客户端和Pod之间添加一个中间层,这个中间层称之为Service。

在Kubernetes中,每个节点都安装了kube-proxy,kube-proxy通过kubernetes中固有的watch请求方法持续监听apiserver。一旦有service资源发生变动(增删改查)kube-proxy可以及时转化为能够调度到后端Pod节点上的规则,这个规则可以是iptables也可以是ipvs,取决于service实现方式。


1.3、Service实现原理

k8s在创建Service时,会根据标签选择器selector(lable selector)来查找Pod,据此创建与Service同名的endpoint对象,当Pod地址发生变化时,endpoint也会随之发生变化,service接收前端client请求的时候,就会通过endpoint,找到转发到那个Pod进行访问的地址。至于转发到哪个节点的Pod,由kube-proxy负载均衡来决定。如下图所示:
在这里插入图片描述
总结:
在这里插入图片描述
1、endpoint是k8s集群中的一个资源对象,存储在etcd中,用来记录一个service对应的所有pod的访问地址。
2、只有当service配置selector(选择器),endpoint controller才会自动创建对应的endpoint对象,否则,不会生成endpoint对象。
3、在k8s集群中创建kubernetes的service,就会生成一个同名的endpoint对象,endpoint就是service关联的Pod的ip地址和端口。
4、访问Service的请求,不论是Cluster IP+TargetPort的方式;还是用Node节点IP+NodePort的方式,都被Node节点的Iptables规则重定向到Kube-proxy监听Service服务代理端口。kube-proxy接收到Service的访问请求后,根据负载策略,转发到后端的Pod。


1.4、kube-proxy三种运行模式

kube-proxy三种运行模式


二、kubernets中三类IP地址

2.1、Node Network(节点网络)

Node Network(节点网络):物理节点或者虚拟节点的网络,如ens33接口上的网路地址。

ens33: flags=4163<UP,BROADCAST,RUNNING,MULTICAST>  mtu 1500
        inet 192.168.1.16  netmask 255.255.255.0  broadcast 192.168.1.255
        inet6 fe80::556d:553b:fe97:ab7b  prefixlen 64  scopeid 0x20<link>
        ether 00:0c:29:43:a9:f0  txqueuelen 1000  (Ethernet)
        RX packets 14026340  bytes 3605525779 (3.3 GiB)
        RX errors 0  dropped 246096  overruns 0  frame 0
        TX packets 4652141  bytes 663629292 (632.8 MiB)
        TX errors 0  dropped 0 overruns 0  carrier 0  collisions 0

2.2、Pod network(pod 网络)

Pod network(pod 网络):创建的Pod具有的IP地址。

[root@k8s-client-17 state]# kubectl get pods -o wide
NAME                                      READY   STATUS    RESTARTS   AGE    IP              NODE            NOMINATED NODE   READINESS GATES
sts-nginx-0                               1/1     Running   0          2d4h   10.244.27.43    k8s-worker-21   <none>           <none>
sts-nginx-1                               1/1     Running   0          2d4h   10.244.115.60   k8s-worker-16   <none>           <none>
sts-nginx-2                               1/1     Running   0          2d4h   10.244.27.44    k8s-worker-21   <none>           <none>

2.3、Cluster Network

Cluster Network(集群地址,也称为service network):这个地址是虚拟的地址(virtual ip),没有配置在某个接口上,只是出现在service的规则当中。

#查看mpmt-calculate-svc服务cluster ip地址
[root@k8s-master-111 jms]# kubectl get svc
NAME                  TYPE        CLUSTER-IP      EXTERNAL-IP   PORT(S)          AGE
kubernetes            ClusterIP   10.96.0.1       <none>        443/TCP          323d
mpmt-calculate-svc    NodePort    10.96.155.70    <none>        8092:31092/TCP   9d

#通过ifconfig过滤10.96.155.70这个ip发现不存在
[root@k8s-worker-112 jms]# ifconfig | grep 10.96.155.70

#通过查看ipvs规则信息找到了10.96.155.70这个ip地址
[root@k8s-worker-112 jms]# ipvsadm -Ln --stats |grep -A 10 10.96.155.70
TCP  10.96.155.70:8092                   0        0        0        0        0
  -> 10.48.1.194:8092                    0        0        0        0        0
  -> 10.48.2.206:8092                    0        0        0        0        0

总结:Node Network配置在节点接口之上,pod网络地址是配置在pod资源之上的,因此这些地址都是配置在某些设备之上的,这些设备可能是硬件,也可能是软件模拟的。但是Cluster Network是虚拟的地址,没有配置在某个接口上,只是出现在service的规则当中。


三、Service四种类型

K8S官网:Service四种类型,如下图所示:
在这里插入图片描述


3.1、ExternalName

应用场景:跨名称空间访问
如下图所示lolaage名称空间下的主机上无法访问default名称空间里的pod服务,测试资源下载链接
在这里插入图片描述
需求:default名称空间下的客户端服务想要访问lolaage名称空间下的nginx-svc服务

#1、default名称空间下创建one-test-nginx服务
---
apiVersion: v1
kind: Service
metadata:
  name: one-test-nginx
  labels:
    app: one-test-nginx
  namespace: default
spec:
  selector:
    app: one-test-nginx
  type: ClusterIP
  ports:
  - port: 8088
    protocol: TCP
    targetPort: 80
---
apiVersion: apps/v1
kind: Deployment
metadata:
  name: one-test-nginx
spec:
  selector:
    matchLabels:
      app: one-test-nginx
  replicas: 1
  template:
    metadata:
      labels:
        app: one-test-nginx
    spec:
      containers:
      - name: nginx
        image: nginx
        imagePullPolicy: IfNotPresent
        ports:
        - containerPort: 80  #pod中的容器需要暴露的端口
---

#2、创建lolaage名称空间
kubectl create ns lolaage

#3、lolaage名称空间下创建two-test-nginx服务
---
apiVersion: v1
kind: Service
metadata:
  name: two-test-nginx
  namespace: lolaage
spec:
  type: ExternalName 
  externalName: one-test-nginx.default.svc.cluster.local #one-test-nginx服务的全限定域名,即FQDN域名
  ports:
  - port: 8088
    protocol: TCP
    targetPort: 80
---
apiVersion: apps/v1
kind: Deployment
metadata:
  name: two-test-nginx
  namespace: lolaage
spec:
  selector:
    matchLabels:
      app: two-test-nginx
  replicas: 1
  template:
    metadata:
      labels:
        app: two-test-nginx
    spec:
      containers:
      - name: nginx
        image: nginx
        imagePullPolicy: IfNotPresent
        ports:
        - containerPort: 80  #pod中的容器需要暴露的端口
---

service解析
service只要创建完成,我们就可以直接解析它的服务名,每一个服务创建完成后都会在集群dns中动态添加一个资源记录,添加完成后我们就可以解析了
资源记录格式是:
SVC_NAME.NS_NAME.DOMAIN.LTD.
服务名.命名空间.域名后缀
集群默认的域名后缀是svc.cluster.local.
就像我们上面创建的one-test-nginx这个服务,它的完整名称解析就是:one-test-nginx.default.svc.cluster.local

如下图所示,则表示在lolaage名称空间下可以访问default名称空间下的pod。
在这里插入图片描述
说明:externalName: one-test-nginx.default.svc.cluster.local定义了default名称空间下的one-test-nginx服务全限定域名,即FQDN,让使用者感觉就好像调用自己命名空间的服务一样。 如果测试的pod中没有curl命令也可以使用wget -q -O - one-test-nginx.default.svc.cluster.local命令进行测试。


3.2、ClusterIP

ClusterIP:暴露集群内部IP上的服务。选择此值将使服务只能从集群内部访问。这是默认的ServiceType。
示例如下:

---
apiVersion: v1
kind: Service
metadata:
  name: test-nginx
  labels:
    app: test-nginx
  namespace: default
spec:
  selector:
    app: test-nginx
  type: ClusterIP
  ports:
  - port: 8088
    protocol: TCP
    targetPort: 80
---
apiVersion: apps/v1
kind: Deployment
metadata:
  name: nginx
spec:
  selector:
    matchLabels:
      app: test-nginx
  replicas: 3
  template:
    metadata:
      labels:
        app: test-nginx
    spec:
      containers:
      - name: nginx
        image: nginx
        imagePullPolicy: IfNotPresent
        ports:
        - containerPort: 80  #pod中的容器需要暴露的端口
---

在集群内部(master节点和worker节点)可以通过service的cluster ip:port访问。
在这里插入图片描述
在集群外部(非master节点和非worker节点)不可以通过service的cluster ip:port访问。
在这里插入图片描述


3.3、NodePort

通过每个Node节点上的IP和静态端口暴露k8s集群内部的服务,请求访问:Client ==> NodeIP:NodePort ==> Service Ip:ServicePort ==> PodIP:ContainerPort

如果不记得k8s对外暴露端口范围,可参考如下命令:
在这里插入图片描述
示例如下::

---
apiVersion: v1
kind: Service
metadata:
  name: test-nginx
  labels:
    app: test-nginx
  namespace: default
spec:
  selector:
    app: test-nginx
  type: NodePort
  ports:
  - port: 8088
    protocol: TCP
    targetPort: 80
    nodePort: 33000
---
apiVersion: apps/v1
kind: Deployment
metadata:
  name: nginx
spec:
  selector:
    matchLabels:
      app: test-nginx
  replicas: 3
  template:
    metadata:
      labels:
        app: test-nginx
    spec:
      containers:
      - name: nginx
        image: nginx
        imagePullPolicy: IfNotPresent
        ports:
        - containerPort: 80  #pod中的容器需要暴露的端口
---

在集群内部(master节点和worker节点)可以通过service的cluster ip:port访问。
在这里插入图片描述
在集群外部(非master节点和非worker节点)可以通过每个Node节点上的IP和静态端口暴露k8s集群内部的服务。
在这里插入图片描述


3.4、LoadBalancer

使用云提供商的负载均衡器,可以向外部暴露服务。外部的负载均衡器可以路由到NodePort服务和ClusterIP 服务。


四、自定义endpoint实现映射外部服务

需求:kubernetes集群引用外部的Mysql数据库,如下图所示在kubernetes集群外主机上单独部署了一台mysql服务:
在这里插入图片描述
创建资源清单文件

---
apiVersion: v1
kind: Service
metadata:
  name: external-mysql
spec:
  type: ClusterIP
  ports:
  - port: 3306
---
apiVersion: v1
kind: Endpoints
metadata:
  name: external-mysql
subsets:
- addresses:
  - ip: 192.168.1.29
  ports:
  - port: 53000
---

如下图所示:
在这里插入图片描述
在kubernetes集群内主机上访问external-mysql服务的cluster ip和port,可以访问mysql,从而实现了将外部IP地址和服务引入到k8s集群内部,由service作为一个代理来达到能够访问外部服务的目的。
在这里插入图片描述


总结:整理不易,如果对你有帮助,可否点赞关注一下?

更多详细内容请参考:企业级K8s集群运维实战

  • 5
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

东城绝神

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

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

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

打赏作者

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

抵扣说明:

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

余额充值