K8s之负载均衡

发布时间:2026/7/26 11:34:57
K8s之负载均衡 ‍博主简介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 svc3.3 创建 Ingress 规则和 svc3.4 检查 pod 和 svc是否创建成功3.5 检验是否负载成功3.5.1 页面访问3.5.2 脚本测试负载四、LoadBalancer 云厂商 LB五、三种负载均衡方式的对比总结表一、使用DaemontSet方式部署 nginx服务 - 用于测试1.1 编写yaml文件vi nginx-daemonset.yamlapiVersion: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:100mmemory:128Milimits:cpu:500mmemory:256Mi1.2 创建并部署nginx服务# 创建并部署nginx服务kubectl apply-fnginx-daemonset.yaml# 查看部署的服务状态kubectl get ds-nnginx kubectl get pods-nnginx-owide主要检查pod的运行状态和node节点就行每个节点跑一个nginx pod1.3 修改nginx默认内容修改nginx默认内容便于区分是否进行负载给三个nginx pod中的index.html添加内容内容例如为This is k8s-master内容需要和对应的节点相同便于区分修改nginx pod中index.html内容kubectlexec-nnginx nginx-daemonset-sgpzz --sh-cecho This is k8s-master /usr/share/nginx/html/index.htmlkubectlexec-nnginx nginx-daemonset-5chs6 --sh-cecho This is k8s-node1 /usr/share/nginx/html/index.htmlkubectlexec-nnginx nginx-daemonset-j46k4 --sh-cecho This is k8s-node2 /usr/share/nginx/html/index.html查看并确认修改成功[rootk8s-master ~]# kubectl exec -n nginx nginx-daemonset-j46k4 -- sh -c cat /usr/share/nginx/html/index.htmlThis is k8s-node2[rootk8s-master ~]# kubectl exec -n nginx nginx-daemonset-5chs6 -- sh -c cat /usr/share/nginx/html/index.htmlThis is k8s-node1[rootk8s-master ~]# kubectl exec -n nginx nginx-daemonset-sgpzz -- sh -c cat /usr/share/nginx/html/index.htmlThis is k8s-master二、按 Service 方式进行负载2.1 ClusterIP 方式进行负载适用场景集群内部服务互相调用不需要外部直接访问创建svcvim nginx-svc.yamlapiVersion: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列表对比ENDPOINTS和pod 的ip是否一致如果少一个、多个或没有则是Service selector 标签不匹配或Pod未就绪问题kubectl get endpoints-nnginx nginx-service进入任意一个pod执行如下命令# svc ip方式kubectlexec-nnginx nginx-daemonset-5chs6 --sh-ccurl -s http://10.0.0.6# 域名方式kubectlexec-nnginx nginx-daemonset-5chs6 --sh-ccurl -s http://nginx-service.nginx.svc.cluster.local或可以使用脚本来循环跑一下看看走的哪个节点的nginx# svc ip方式foriin{1..10};dokubectlexec-nnginx nginx-daemonset-5chs6 --sh-ccurl -s http://10.0.0.6done# 域名方式foriin{1..10};dokubectlexec-nnginx nginx-daemonset-5chs6 --sh-ccurl -s http://nginx-service.nginx.svc.cluster.localdone这样就可以清晰的看到请求到哪个节点上了2.2 NodePort 方式进行负载适用场景 需要从集群外部访问创建svcvim nginx-svc.yamlapiVersion: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-ccurl -s 172.16.11.230:30800done这样就可以清晰的看到请求到哪个节点上了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.yamlapiVersion: 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 svcvi nginx-svc.yamlapiVersion: v1 kind: Service metadata: name: nginx-service# ← Ingress 里写的名字namespace: nginx# ← 必须和 Ingress 同一命名空间spec: selector: app: nginx# ← 匹配 Deployment 的 Pod 标签ports: - port:80# ← Ingress 里写的端口targetPort:80# ← 容器实际端口对应 containerPort3.3 创建 Ingress 规则和 svckubectl apply-fnginx-ingress.yaml kubectl apply-fnginx-svc.yaml3.4 检查 pod 和 svc是否创建成功# 查看nginx daemonset状态kubectl get ds-nnginx# 查看nginx pod的状态kubectl get pods-nnginx# 查看nginx service的状态kubectl get svc-nnginx3.5 检验是否负载成功3.5.1 页面访问使用节点任意IPingress-nginx-controller访问端口访问页面http://172.16.11.230:32465、https://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由于没有云服务器测试条件暂无法进行测试如果有测试过的可分享出来我将添加到其中同时也感谢您的支持五、三种负载均衡方式的对比总结表方式访问范围端口范围适用场景是否需ControllerClusterIP集群内部任意服务间调用否NodePort外部访问30000-32767测试/小规模暴露否Ingress外部访问80/443通过Controller生产环境、域名路由是需部署