侧边栏壁纸
博主头像
小周的知识站 博主等级

行动起来,活在当下

  • 累计撰写 80 篇文章
  • 累计创建 12 个标签
  • 累计收到 8 条评论

目 录CONTENT

文章目录
K8S

K8S Service四层负载均衡

Administrator
2024-07-17 / 0 评论 / 0 点赞 / 13 阅读 / 0 字

K8S Service 四层负载均衡

本章主要学习k8s的流量负载组件:Service与ingress,Service用于4层流量的负载,ingress用于7层流量负载。

1 Service介绍

Kubernetes集群中有三类网络,一类是真实存在的,如:Node节点网络、Pod网络,这两种网络均提供真实IP地址。

还有一类是虚拟的Service网络,提供虚拟cluster IP(VIP)地址,这个地址不会出现在接口上,仅会出现在Service当中。

在Kubernetes集群时,由于Pod经常处于用后即焚的状态,Pod经常被重新生成,因此Pod对应的IP地址也会经常变化,导致无法直接访问Pod提供的应用服务。

Kubernetes中使用了Service来解决这一问题,即在Pod前面使用Service对Pod进行代理,无论Pod怎样变化,只要有Label,就可以让Service能够联系上Pod,进而实现通过Service访问Pod目的。

2 Kube-proxy介绍

Service的本质就是一条代理规则,真正实现代理功能的其实是kube-proxy代理组件,集群的每个节点都运行着一个kube-proxy服务进程,当创建Service的时候,就等于创建了一条代理规则,而这条规则就是告诉kube-proxy 通过那种模式进行流量转发。

3 kube-proxy代理模式介绍

Kube-proxy三种代理模式:UserSpace模式、iptables模式、ipvs模式

4 UserSpace模式介绍

最原始的转发模式,用户通过clusterIP(VIP)访问需要经过kube-proxy进行代理转发,这种模式效率低,已经很少用。

UserSpace模式模式的实现原理图示如下:

5 iptables模式介绍

该模式下kube-proxy不承担四层负载均衡器的角色,kube-proxy 只是作为 controller(控制器)去创建iptables规则,然后用户的请求直接通过iptables转发规则被转发到后端的每个Pod中(真正实现流量转发的是内核的 netfilter模块,基于内核进行流量转发本身效率就高,而且对比与userspace还少了一个kube-proxy转发的环节)。

iptables 模式的实现原理图示如下:

iptables模式不能提供灵活的负载均衡策略,只是随机的将流量转发到后端的Pod,当后端Pod不可用时也无法进行健康检查。

6 ipvs模式介绍

ipvs(Virtual Server)与iptables类似,都是基于 netfilter 进行流量转发,kube-proxy也不承担四层负载均衡器的角色,只创建ipvs规则,但是ipvs在转发时支持的负载均衡算法非常的灵活,例如:轮询、加权轮询、基于端口转发、最小负载、最少连接等,ipvs 支持服务器健康检查和连接重试等功能。

ipvs 模式的实现原理图示如下:

想要使用ipvs转发模式需要安装ipvs内核模块,否则会降级为iptables模式

查看ipvs模块(本实验环境在第二章集群环境部署时已经安装)
[root@master01 ~]# lsmod | grep -e ip_vs -e nf_conntrack_ipv4
nf_conntrack_ipv4
nf_defrag_ipv4 
ip_vs_sh
ip_vs_wrr
ip_vs_rr 
ip_vs
nf_conntrack
libcrc32c 


开启ipvs,编辑kube-proxy文件
[root@master01 ~]# kubectl edit cm kube-proxy -n kube-system
mode: "ipvs"   #修改为ipvs模式
#提示:cm(ConfigMap)在K8s中属于配置资源



删除当前正在使用的kube-proxy的pod(按照标签删除)
[root@master01 ~]# kubectl get pod --show-labels -n kube-system | grep kube-proxy*

[root@master01 ~]# kubectl delete pod -l k8s-app=kube-proxy -n kube-system



查看kube-proxy的pod是否被重建
[root@master ~]# kubectl get po -n kube-system



查看ipvs功能是否开启
[root@master01 ~]# ipvsadm -Ln    

7 Service常用访问方式介绍

  • ClusterIP:默认访问方式,分配一个集群内部可以访问的虚拟IP(该方式只能用于集群内部访问,外部无法访问)

  • NodePort:在每个Node上分配一个端口作为外部访问入口,端口范围为30000-32767(该访问适用于外部访问)

  • LoadBalancer:通过在集群外部的公有云平台上,例如:阿里云、华为云、AWS等做一个负载均衡,通过外部负载均衡将流量转发到集群中。

    访问过程:用户----->域名----->云服务提供商提供LB负载均衡设备----->NodeIP:Port(service IP)----->Pod IP:端口

8 Service资源清单文件介绍

kubectl explain svc 查看service资源支持的属性

apiVersion: v1    	#版本
kind: Service     	#资源类型
metadata:         	#元数据
  name: 		   	#资源名称
  namespace: 	  	#所属名称空间
spec:             	#描述
  selector:       	#标签选择器,用于确定当前service代理哪些pod
    app:            #标签
  type:             	Service类型
  clusterIP:        	clusterIP访问方式
  ports:            	端口信息
    - protocol: TCP     端口协议
      port:         	访问Service使用的端口
      targetPort:   	pod中容器的端口
      nodePort:     	node端口(Service需要暴露给外部访问的节点端口,端口范围:30000-32767)

9 Cluster IP应用案例

案例:通过HPA创建3个Pod并设置标签为app=deploy-nginx(使用前面的hpa-deploy_nginx.yml创建即可)通过Service ClusterIP访问方式进行代理

ClusterIP:默认访问方式,由k8s自动分配的虚拟IP,只能在集群内部访问

[root@master01 ~]# vim hpa-deploy_nginx.yml
apiVersion: v1          
kind: Service
metadata:
  name: svc-nginx
  namespace: test

spec:
  type: ClusterIP        service默认访问方式
  ports:                 定义端口信息
  - port: 80             访问service使用的端口,可自定义
    targetPort: 80       pod中容器端口
  selector:              标签选择器(基于标签选择代理的Pod)
    app: deploy-nginx    标签(需要下方代理的Pod标签一致)

---
apiVersion: autoscaling/v1     #自动扩缩容版本
kind: HorizontalPodAutoscaler  #类型
metadata:
    name: hpa-nginx
    namespace: test
spec:
  minReplicas: 3             最小的pod数量
  maxReplicas: 10            #最大的pod数量
  targetCPUUtilizationPercentage: 6    cpu使用指标,表示60%
  scaleTargetRef:            #指定要控制的nginx信息
    apiVersion: apps/v1
    kind: Deployment         #deploy类型
    name: deploy-nginx       #deploy名称

---
apiVersion: apps/v1
kind: Deployment
metadata:
    name: deploy-nginx
    namespace: test

spec:
    replicas: 3                 创建pod的副本数量,默认为1
    selector:                   #标签选择器(基于选择器匹配Pod)
      matchLabels:              #标签类型
        app: deploy-nginx       #匹配pod的标签(表示deploy管理带有此标签的Pod)

    template:                   #pod的配置模板
      metadata:
        labels:
          app: deploy-nginx     pod的标签

      spec:
        containers:
        - name: nginx
          image: nginx:1.17.0   #指定镜像
          ports:                #定义端口
          - containerPort: 80   #端口
            protocol: TCP       #端口协议
          resources:            #资源限额
            limits:             #资源上限
              cpu: 600m         cpu 1核心的60%的资源



      
创建Pod
[root@master01 ~]# kubectl create -f hpa-deploy_nginx.yml



查看pod详细信息
[root@master01 ~]# kubectl get pod -n test
[root@master01 ~]# kubectl get pod -n test -o wide



为了更好的验证用户请求被分配到哪个pod中,修改3个Pod中nginx默认首页为具体的Pod IP地址
[root@master01 ~]# kubectl exec -it deployment-6696798b78-6zl8p -n test /bin/bash

[root@master01 ~]# echo "10.244.1.44" > /usr/share/nginx/html/index.html



访问3个pod测试
[root@master01 ~]# curl http://10.244.1.44
10.244.1.44
[root@master01 ~]# curl http://10.244.2.24
10.244.2.24
[root@master01 ~]# curl http://10.244.1.45
10.244.1.45



查看svc信息
[root@master01 ~]# kubectl  get svc -n test
[root@master ~]# kubectl describe svc -n test
Name:              service
Namespace:         dev
Labels:            <none>
Annotations:       <none>
Selector:          app=nginx-pod
Type:              ClusterIP
IP:                10.96.96.96
Port:              <unset>  80/TCP
TargetPort:        80/TCP
Endpoints:         10.244.1.44:80,10.244.1.45:80,10.244.2.24:80   代理的pod地址
Session Affinity:  None
Events:            <none>



查看ipvs的映射规则
[root@master01 ~]# ipvsadm -Ln
...
TCP  10.96.96.96:80 rr
  -> 10.244.1.44:80               Masq    1      0          0         
  -> 10.244.1.45:80               Masq    1      0          0         
  -> 10.244.2.24:80               Masq    1      0          0    
#rr为默认轮询策略:当service接收到请求后,会通过轮询算法将请求分配到对应的三个pod中



访问测试
[root@master01 ~]# while :
do
 	curl 10.96.96.96
    sleep 5
done

10.244.2.24
10.244.1.45
10.244.1.44
10.244.2.24
10.244.1.45
10.244.1.44



删除Pod
[root@master ~]# kubectl delete -f hpa-deploy_nginx.yml

总结:Cluster IP的访问方式只能用在集群内部主机之间访问,集群外部主机没办法访问。

10 NodePort 应用案例

在生产环境中,Service是需要暴露给外部访问的,那么就要用到NodePort类型的Service,NodePort的工作原理其实就是在Node节点上暴露一个端口,然后外部主机就可以通过节点IP+暴露端口来访问集群中的pod了

案例:将前边案例中的清单文件Cluster IP改为NodePort 类型,实现外部访问。

[root@master01 ~]# vim hpa-deploy_nginx.yml
apiVersion: v1
kind: Service
metadata:
  name: svc-nginx
  namespace: test

spec:
  type: NodePort         service类型
  ports:                 #定义端口信息
  - port: 80             #访问service使用的端口,可自定义
    targetPort: 80       #指定pod中容器端口
    nodePort: 30007      #自定义service端口
  selector:              #标签选择器(基于标签选择代理的Pod)
    app: deploy-nginx    #标签(需要与代理的Pod标签一致)

---
apiVersion: autoscaling/v1     #自动扩缩容版本
kind: HorizontalPodAutoscaler  #类型
metadata:
    name: hpa-nginx
    namespace: test
spec:
  minReplicas: 3             #最小的pod数量
  maxReplicas: 10            #最大的pod数量
  targetCPUUtilizationPercentage: 6    #cpu使用指标,表示60%
  scaleTargetRef:            #指定要控制的nginx信息
    apiVersion: apps/v1
    kind: Deployment         #deploy类型
    name: deploy-nginx       #deploy名称

---
apiVersion: apps/v1
kind: Deployment
metadata:
    name: deploy-nginx
    namespace: test

spec:
    replicas: 3
    selector:                   #标签选择器(基于选择器匹配Pod)
      matchLabels:              #标签类型
        app: deploy-nginx       #匹配pod的标签(表示deploy管理带有此标签的Pod)

    template:                   #pod的配置模板
      metadata:
        labels:
          app: deploy-nginx     #pod的标签

      spec:
        containers:
        - name: nginx
          image: nginx:1.17.0   #指定镜像
          ports:                #定义端口
          - containerPort: 80   #端口
            protocol: TCP       #端口协议
          resources:            #资源限额
            limits:             #资源上限
              cpu: 600m         #cpu 1核心的60%的资源



创建Pod
[root@master01 ~]# kubectl create -f hpa-deploy_nginx.yml



查看Pod信息
[root@master01 ~]# kubectl get pod -n test



查看Service信息
[root@master01 ~]# kubectl get svc -n test
NAME        TYPE       CLUSTER-IP       EXTERNAL-IP   PORT(S)        AGE
svc-nginx   NodePort   10.110.174.205   <none>        80:32388/TCP   13s
提示:
80     #Service端口
32388  #Service绑定的Node节点端口,这个端口是提供外部访问的



外部主机访问测试(通过宿主机主机IP加Node端口,访问集群中任何一台节点IP都可以)
http://192.168.0.13:32388



删除Pod
[root@master01 ~]# kubectl delete -f hpa-deploy_nginx.yml

0
K8S
  1. 支付宝打赏

    qrcode alipay
  2. 微信打赏

    qrcode weixin

评论区