前言

IPVS是什么

IPVS是LVS的负载均衡模块,亦基于netfilter,工作于TCP传输层(IP+端口)的负载均衡软件。

IPVS基本原理

IPVS会从TCP SYNC包开始为一个TCP连接所有的数据包建立状态跟踪机制,保证一个TCP连接中所有的数据包能到同一个后端。所以IPVS是基于TCP状态机进行控制管理,只感知TCP头而不对TCP的payload进行查看;因此,对IPVS后端服务器集群还有一个假定,那就是所有后端都具有同样的应用层的服务功能,但是由于IPVS可以给后端设定权重,所以每个后端的服务的能力可以不同。

一个合理的负载均衡软件,应该能够尽量提高服务接入能力(ReqPS, Request Per Second)而将服务处理能力(ResPS, Response Per second)通过合理分配后端来达到最佳。

根据处理请求和响应数据包的模式的不同,IPVS具有如下四种工作模式:

  • NAT模式
  • DR(Direct Routing)模式
  • TUN(IP Tunneling)模式
  • FULLNAT模式

而根据响应数据包返回路径的不同,可以分为如下两种模式:

  • 双臂模式:请求、转发和返回在同一路径上,client和IPVS director、IPVS director和后端real server都是由请求和返回两个路径连接。
  • 三角模式:请求、转发和返回三个路径连接client、IPVS director和后端real server成为一个三角形。

IPVS可以解决什么问题

  • 使用IPVS做集群内服务的负载均衡可以解决iptables带来的性能问题。IPVS专门用于负载均衡,并使用更高效的数据结构(散列表)
  • 允许几乎无限的规模扩张。
  • 支持服务器健康检查和连接重试】
  • 动态修改ipset的集合

设置ipvs模式

kubeadm安装的默认不是IPVS
要设置成ipvs模式需要满足:

  • k8s版本 >= v1.11
  • 安装ipset, ipvsadm安装ipset, ipvsadm
yum install ipset ipvsadm -y

确保 ipvs已经加载内核模块, ip_vs、ip_vs_rr、ip_vs_wrr、ip_vs_sh、nf_conntrack_ipv4。
如果这些内核模块不加载,当kube-proxy启动后,会退回到iptables模式。
检查是否已经加载

 lsmod | grep -e ip_vs -e nf_conntrack_ipv4

image.png

开启IPVS

修改ConfigMap的kube-system/kube-proxy中的模式为ipvs

 kubectl edit cm kube-proxy -n kube-system

# 找到mode 参数
# 修改为 mode: "ipvs"

重启kube-proxy

kubectl get pod -n kube-system | grep kube-proxy | awk '{system("kubectl delete pod "$1" -n kube-system")}'

查看路由

[root@master-01 ~]# ipvsadm -ln
IP Virtual Server version 1.2.1 (size=4096)
Prot LocalAddress:Port Scheduler Flags
  -> RemoteAddress:Port           Forward Weight ActiveConn InActConn
TCP  192.168.238.130:30005 rr
  -> 10.244.190.3:8443            Masq    1      0          0
TCP  192.168.238.130:32567 rr
  -> 10.244.184.5:80              Masq    1      0          0
TCP  10.1.0.1:443 rr
  -> 192.168.238.130:6443         Masq    1      0          0
TCP  10.1.0.10:53 rr
  -> 10.244.184.72:53             Masq    1      0          0
  -> 10.244.184.73:53             Masq    1      0          0
TCP  10.1.0.10:9153 rr
  -> 10.244.184.72:9153           Masq    1      0          0
  -> 10.244.184.73:9153           Masq    1      0          0
TCP  10.1.36.56:8000 rr
  -> 10.244.184.4:8000            Masq    1      0          0
TCP  10.1.44.121:443 rr
  -> 10.244.190.3:8443            Masq    1      0          0
TCP  10.1.217.99:443 rr
  -> 192.168.238.133:4443         Masq    1      1          0
TCP  10.1.229.170:80 rr
  -> 10.244.184.5:80              Masq    1      0          0
TCP  10.244.184.64:30005 rr
  -> 10.244.190.3:8443            Masq    1      0          0
TCP  10.244.184.64:32567 rr
  -> 10.244.184.5:80              Masq    1      0          0
TCP  127.0.0.1:30005 rr
  -> 10.244.190.3:8443            Masq    1      0          0
TCP  127.0.0.1:32567 rr
  -> 10.244.184.5:80              Masq    1      0          0
TCP  172.17.0.1:30005 rr
  -> 10.244.190.3:8443            Masq    1      0          0
TCP  172.17.0.1:32567 rr
  -> 10.244.184.5:80              Masq    1      0          0
UDP  10.1.0.10:53 rr
  -> 10.244.184.72:53             Masq    1      0          0
  -> 10.244.184.73:53             Masq    1      0          0

服务验证

安装NGINX集群

创建kubectl apply -f nginx-deployment.yaml

vim nginx-deployment.yaml
# 插入一下内容
apiVersion: apps/v1
kind: Deployment
metadata:
  name: nginx-deployment
  labels:
    app: nginx
spec:
  # 创建2个nginx容器
  replicas: 2
  selector:
    matchLabels:
      app: nginx
  template:
    metadata:
      labels:
        app: nginx
    spec:
      containers:
      - name: nginx
        image: nginx:1.14.2
        ports:
        - containerPort: 80

查看kubectl get pods
kubectl get deployment,下面是我已经部署好的 nginx 容器实例
image.png

开放端口

 kubectl expose deployment nginx-deployment --port=80 --type=LoadBalancer

image.png
测试Nginx副本
image.png