K8s之负载均衡
2026/7/26 11:34:42 网站建设 项目流程

👨‍🎓博主简介

🏅CSDN博客专家
🏅云计算领域优质创作者
🏅华为云开发者社区专家博主
🏅阿里云开发者社区专家博主
💊交流社区:运维交流社区 欢迎大家的加入!
🐋 希望大家多多支持,我们一起进步!😄
🎉如果文章对你有帮助的话,欢迎 点赞 👍🏻 评论 💬 收藏 ⭐️ 加关注+💗


文章目录

    • 一、使用DaemontSet方式部署 nginx服务 - 用于测试
      • 1.1 编写yaml文件
      • 1.2 创建并部署nginx服务
      • 1.3 修改nginx默认内容
    • 二、按 Service 方式进行负载
      • 2.1 ClusterIP 方式进行负载
      • 2.2 NodePort 方式进行负载
        • 2.2.1 externalTrafficPolicy 对比
    • 三、按 Ingress 方式进行负载
      • 3.1 编写 Ingress 规则
      • 3.2 编写 nginx svc
      • 3.3 创建 Ingress 规则和 svc
      • 3.4 检查 pod 和 svc是否创建成功
      • 3.5 检验是否负载成功
        • 3.5.1 页面访问
        • 3.5.2 脚本测试负载
    • 四、LoadBalancer + 云厂商 LB
    • 五、三种负载均衡方式的对比总结表

一、使用DaemontSet方式部署 nginx服务 - 用于测试

1.1 编写yaml文件

  • vi nginx-daemonset.yaml
apiVersion:v1kind:Namespacemetadata:name:nginx---apiVersion:apps/v1kind:DaemonSetmetadata:name:nginx-daemonsetnamespace:nginxlabels:app:nginxspec:selector:matchLabels:app:nginxtemplate:metadata:labels:app:nginxspec:tolerations:# ← 添加容忍度,如果不添加,则不会再有污点的节点上部署-key:node-role.kubernetes.io/mastereffect:NoScheduleoperator:Exists-key:node-role.kubernetes.io/control-planeeffect:NoScheduleoperator:Existscontainers:-name:nginximage:nginx:1.24.0ports:-containerPort:80resources:requests:cpu:"100m"memory:"128Mi"limits:cpu:"500m"memory:"256Mi"

1.2 创建并部署nginx服务

# 创建并部署nginx服务kubectl apply-fnginx-daemonset.yaml# 查看部署的服务状态kubectl get ds-nnginx kubectl get pods-nnginx-owide

主要检查pod的运行状态和node节点就行,每个节点跑一个nginx pod

1.3 修改nginx默认内容

修改nginx默认内容,便于区分是否进行负载;
给三个nginx pod中的index.html添加内容,内容例如为:This is k8s-master,内容需要和对应的节点相同,便于区分;

  • 修改nginx podindex.html内容
kubectlexec-nnginx nginx-daemonset-sgpzz --sh-c'echo "This is k8s-master" > /usr/share/nginx/html/index.html'kubectlexec-nnginx nginx-daemonset-5chs6 --sh-c'echo "This is k8s-node1" > /usr/share/nginx/html/index.html'kubectlexec-nnginx nginx-daemonset-j46k4 --sh-c'echo "This is k8s-node2" > /usr/share/nginx/html/index.html'
  • 查看并确认修改成功
[root@k8s-master ~]# kubectl exec -n nginx nginx-daemonset-j46k4 -- sh -c 'cat /usr/share/nginx/html/index.html'This is k8s-node2[root@k8s-master ~]# kubectl exec -n nginx nginx-daemonset-5chs6 -- sh -c 'cat /usr/share/nginx/html/index.html'This is k8s-node1[root@k8s-master ~]# kubectl exec -n nginx nginx-daemonset-sgpzz -- sh -c 'cat /usr/share/nginx/html/index.html'This is k8s-master

二、按 Service 方式进行负载

2.1 ClusterIP 方式进行负载

适用场景

  • 集群内部服务互相调用
  • 不需要外部直接访问
  • 创建svc,vim nginx-svc.yaml
apiVersion:v1kind:Servicemetadata:name:nginx-servicenamespace:nginxspec:type:ClusterIPports:-protocol:TCPport:80targetPort:80# 需和daemonset/deployment/StatefulSet写的一致selector:app:nginx# 负载均衡策略:None=轮询,ClientIP=会话保持sessionAffinity:None# 内部负载均衡由 kube-proxy 实现(iptables/ipvs 随机分发)

默认不写sessionAffinity: None,也会进行轮询,因为ClusterIP方式默认自带的就是None轮询;如果是使用会话保持,这个是需要加此配置的:sessionAffinity: ClientIP

⚠:如果pod服务指定了hostNetwork: true,需要加上dnsPolicy: ClusterFirstWithHostNet,否则无法解析集群 DNS,那么根据域名就找不到此服务进行负载;

  • 创建并运行svc
# 创建并运行svckubectl apply-fnginx-svc.yaml# 检查svc运行是否正常kubectl get svc-nnginx

  • 使用dns域名svc ip进行测试

注意:
使用的ClusterIP模式,仅支持k8s集群內部访问;
使用dns访问需提前安装CoreDNS,如果没有安装,可参考:K8S 部署 CoreDNS 之 DNS 域名获取

先查看后端Pod IP:Port列表,对比ENDPOINTSpod 的ip是否一致,如果少一个、多个或没有则是Service selector 标签不匹配,或Pod未就绪问题;

kubectl get endpoints-nnginx nginx-service

进入任意一个pod,执行如下命令:

# svc ip方式kubectlexec-nnginx nginx-daemonset-5chs6 --sh-c'curl -s http://10.0.0.6'# 域名方式kubectlexec-nnginx nginx-daemonset-5chs6 --sh-c'curl -s http://nginx-service.nginx.svc.cluster.local'

或可以使用脚本来循环跑一下,看看走的哪个节点的nginx

# svc ip方式foriin{1..10};dokubectlexec-nnginx nginx-daemonset-5chs6 --sh-c'curl -s http://10.0.0.6'done# 域名方式foriin{1..10};dokubectlexec-nnginx nginx-daemonset-5chs6 --sh-c'curl -s http://nginx-service.nginx.svc.cluster.local'done

这样就可以清晰的看到请求到哪个节点上了;

2.2 NodePort 方式进行负载

适用场景: 需要从集群外部访问

  • 创建svc,vim nginx-svc.yaml
apiVersion:v1kind:Servicemetadata:name:nginx-servicenamespace:nginxspec:type:NodePortports:-protocol:TCPport:80targetPort:80# 端口需在30000-32767nodePort:30800selector:app:nginx# 匹配 DaemonSet 的 Pod 标签externalTrafficPolicy:Cluster# Cluster: 全集群负载均衡(可能跨节点转发)# Local: 仅转发到本节点 Pod(性能更好,但可能不均)

默认不写externalTrafficPolicy: Cluster,也会进行轮询,因为NodePort方式默认自带的就是Cluster轮询;如果是使用本节点转发,这个是需要加此配置的:externalTrafficPolicy: Local

  • 创建并运行svc
# 创建并运行svckubectl apply-fnginx-svc.yaml# 检查svc运行是否正常kubectl get svc-nnginx

  • 访问ip端口进行测试(页面或服务器访问测试都行)
foriin{1..10};dokubectlexec-nnginx nginx-daemonset-lbx9p --sh-c'curl -s 172.16.11.230:30800'done

这样就可以清晰的看到请求到哪个节点上了;

2.2.1 externalTrafficPolicy 对比
策略流量分配源 IP 保留适用场景
Cluster全集群 Pod 均匀分配❌ SNAT 后丢失需要均匀负载均衡
Local仅本节点 Pod✅ 保留真实 IP需要获取客户端 IP,接收可能不均

三、按 Ingress 方式进行负载

前提:需部署Ingress Controller,如果没部署的,可参考:K8s 之 Ingress 及 Ingress Controller

适用场景:

  • 基于域名/路径路由
  • 需要 SSL 终止、限流、重写等高级功能

3.1 编写 Ingress 规则

  • vi nginx-ingress.yaml
apiVersion: networking.k8s.io/v1 kind: Ingress metadata: name: nginx namespace: nginx spec: ingressClassName: nginx# 对应你安装的 Controller# 比如现在安装的是nginx-ingress-controller,可以使用"kubectl get ingressclass"命令查看rules: - http: paths: - path: / pathType: Prefix backend: service: name: nginx-service# 指向你的后端 Serviceport: number:80# Service 的端口

3.2 编写 nginx svc

  • vi nginx-svc.yaml
apiVersion: v1 kind: Service metadata: name: nginx-service# ← Ingress 里写的名字namespace: nginx# ← 必须和 Ingress 同一命名空间spec: selector: app: nginx# ← 匹配 Deployment 的 Pod 标签ports: - port:80# ← Ingress 里写的端口targetPort:80# ← 容器实际端口(对应 containerPort)

3.3 创建 Ingress 规则和 svc

kubectl apply-fnginx-ingress.yaml kubectl apply-fnginx-svc.yaml

3.4 检查 pod 和 svc是否创建成功

# 查看nginx daemonset状态kubectl get ds-nnginx# 查看nginx pod的状态kubectl get pods-nnginx# 查看nginx service的状态kubectl get svc-nnginx

3.5 检验是否负载成功

3.5.1 页面访问

使用节点任意IP+ingress-nginx-controller访问端口访问页面:http://172.16.11.230:32465https://172.16.11.231:32483,可以访问到This is k8s-master这种就算成功,访问不止有This is k8s-master算是负载成功;

3.5.2 脚本测试负载
# 本机测试foriin{1..10};docurl127.0.0.1:32465;done# 集群任意IP访问测试foriin{1..10};docurl172.16.11.230:32465;done# 集群任意IP访问测试 - httpsforiin{1..10};docurl-khttps://172.16.11.230:32483;done

四、LoadBalancer + 云厂商 LB

由于没有云服务器测试条件,暂无法进行测试,如果有测试过的,可分享出来,我将添加到其中,同时也感谢您的支持!!!

五、三种负载均衡方式的对比总结表

方式访问范围端口范围适用场景是否需Controller
ClusterIP集群内部任意服务间调用
NodePort外部访问30000-32767测试/小规模暴露
Ingress外部访问80/443(通过Controller)生产环境、域名路由是(需部署)

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询