K8s之负载均衡

👨‍🎓博主简介

🏅CSDN博客专家

🏅云计算领域优质创作者

🏅华为云开发者社区专家博主

🏅阿里云开发者社区专家博主

💊交流社区: 运维交流社区 欢迎大家的加入!

🐋 希望大家多多支持,我们一起进步!😄

🎉如果文章对你有帮助的话,欢迎 点赞 👍🏻 评论 💬 收藏 ⭐️ 加关注+💗


文章目录

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

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

1.1 编写yaml文件

  • vi nginx-daemonset.yaml
yaml 复制代码
apiVersion: v1
kind: Namespace
metadata: 
  name: nginx
---
apiVersion: apps/v1
kind: DaemonSet
metadata:
  name: nginx-daemonset
  namespace: nginx
  labels:
    app: nginx
spec:
  selector:
    matchLabels:
      app: nginx
  template:
    metadata:
      labels:
        app: nginx
    spec:
      tolerations:           # ← 添加容忍度,如果不添加,则不会再有污点的节点上部署
        - key: node-role.kubernetes.io/master
          effect: NoSchedule
          operator: Exists
        - key: node-role.kubernetes.io/control-plane
          effect: NoSchedule
          operator: Exists
      containers:
      - name: nginx
        image: nginx:1.24.0
        ports:
        - containerPort: 80
        resources:         
          requests:
            cpu: "100m"
            memory: "128Mi"
          limits:
            cpu: "500m"
            memory: "256Mi"

1.2 创建并部署nginx服务

bash 复制代码
# 创建并部署nginx服务
kubectl apply -f nginx-daemonset.yaml

# 查看部署的服务状态
kubectl get ds -n nginx
kubectl get pods -n nginx -o wide

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

1.3 修改nginx默认内容

修改nginx默认内容,便于区分是否进行负载;

给三个 nginx pod中的index.html添加内容,内容例如为:This is k8s-master ,内容需要和对应的节点相同,便于区分;

  • 修改nginx podindex.html内容
bash 复制代码
kubectl exec -n nginx nginx-daemonset-sgpzz -- sh -c 'echo "This is k8s-master" > /usr/share/nginx/html/index.html'
kubectl exec -n nginx nginx-daemonset-5chs6 -- sh -c 'echo "This is k8s-node1" > /usr/share/nginx/html/index.html'
kubectl exec -n nginx nginx-daemonset-j46k4 -- sh -c 'echo "This is k8s-node2" > /usr/share/nginx/html/index.html'
  • 查看并确认修改成功
bash 复制代码
[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
yaml 复制代码
apiVersion: v1
kind: Service
metadata:
  name: nginx-service
  namespace: nginx
spec:
  type: ClusterIP
  ports:
    - protocol: TCP
      port: 80
      targetPort: 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
bash 复制代码
# 创建并运行svc
kubectl apply -f nginx-svc.yaml
# 检查svc运行是否正常
kubectl get svc -n nginx
  • 使用dns域名svc ip进行测试

注意:

使用的ClusterIP模式,仅支持k8s集群內部访问;

使用dns访问需提前安装CoreDNS,如果没有安装,可参考:K8S 部署 CoreDNS 之 DNS 域名获取

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

bash 复制代码
kubectl get endpoints -n nginx nginx-service

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

bash 复制代码
# svc ip方式
kubectl exec -n nginx nginx-daemonset-5chs6 -- sh -c 'curl -s http://10.0.0.6'

# 域名方式
kubectl exec -n nginx nginx-daemonset-5chs6 -- sh -c 'curl -s http://nginx-service.nginx.svc.cluster.local'

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

bash 复制代码
# svc ip方式
for i in {1..10}; do
  kubectl exec -n nginx nginx-daemonset-5chs6 -- sh -c 'curl -s http://10.0.0.6'
done

# 域名方式
for i in {1..10}; do
  kubectl exec -n nginx nginx-daemonset-5chs6 -- sh -c 'curl -s http://nginx-service.nginx.svc.cluster.local'
done

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

2.2 NodePort 方式进行负载

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

  • 创建svc,vim nginx-svc.yaml
yaml 复制代码
apiVersion: v1
kind: Service
metadata:
  name: nginx-service
  namespace: nginx
spec:
  type: NodePort
  ports:
    - protocol: TCP
      port: 80
      targetPort: 80
      # 端口需在30000-32767
      nodePort: 30800
  selector:
    app: nginx              # 匹配 DaemonSet 的 Pod 标签
  externalTrafficPolicy: Cluster
  # Cluster: 全集群负载均衡(可能跨节点转发)
  # Local: 仅转发到本节点 Pod(性能更好,但可能不均)

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

  • 创建并运行svc
bash 复制代码
# 创建并运行svc
kubectl apply -f nginx-svc.yaml
# 检查svc运行是否正常
kubectl get svc -n nginx
  • 访问ip端口进行测试(页面或服务器访问测试都行)
bash 复制代码
for i in {1..10}; do
  kubectl exec -n nginx 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
bash 复制代码
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   # 指向你的后端 Service
            port:
              number: 80		# Service 的端口

3.2 编写 nginx svc

  • vi nginx-svc.yaml
bash 复制代码
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

bash 复制代码
kubectl apply -f nginx-ingress.yaml
kubectl apply -f nginx-svc.yaml

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

bash 复制代码
# 查看nginx daemonset状态
kubectl get ds -n nginx
# 查看nginx pod的状态
kubectl get pods -n nginx 
# 查看nginx service的状态
kubectl get svc -n nginx

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 脚本测试负载
bash 复制代码
# 本机测试
for i in {1..10};do curl 127.0.0.1:32465; done

# 集群任意IP访问测试
for i in {1..10};do curl 172.16.11.230:32465; done

# 集群任意IP访问测试 - https
for i in {1..10};do curl -k https://172.16.11.230:32483; done

四、LoadBalancer + 云厂商 LB

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

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

方式 访问范围 端口范围 适用场景 是否需Controller
ClusterIP 集群内部 任意 服务间调用
NodePort 外部访问 30000-32767 测试/小规模暴露
Ingress 外部访问 80/443(通过Controller) 生产环境、域名路由 是(需部署)
相关推荐
学困昇1 小时前
彻底搞懂 Linux 基础 IO:文件描述符、重定向、dup2、缓冲区一次讲透!
linux·运维·服务器·开发语言·c++
xmlhcxr1 小时前
从 0 到 1 落地企业级 DevOps CI/CD 流水线:基于 GitLab+Jenkins+Harbor 的完整实践
运维·docker·gitlab·jenkins·harbor·devops
赋创小助手1 小时前
PCIe 8.0 要来了:1TB/s 带宽背后,AI 算力服务器正在进入“高速互联时代”
运维·服务器·人工智能
xiaoye-duck2 小时前
《Linux系统编程》Linux指令 (三):从零开始理解Linux基础指令
linux
好赞科技2 小时前
深度对比2026年三款小程序商城精选推荐榜单,解决您的电商选择难题
大数据·运维·人工智能
hecgaoyuan2 小时前
解决使用Nvidia Jetson Nano嵌入式系统远程桌面不能操作的问题
linux
贝锐2 小时前
贝锐向日葵:商用安卓设备大规模远程运维体系搭建指南
运维·远程控制
yyuuuzz2 小时前
国际云服务商运维常见问题梳理
运维·服务器·网络·github·aws
米高梅狮子2 小时前
11.Quota and Limits、健康检查和认证与授权
云原生·容器·架构·kubernetes·自动化