Kubernetes Service 与 kube‑proxy 深度详解

Kubernetes Service 与 kube‑proxy 深度详解|五种 Service 类型、服务发现、会话保持、金丝雀发布、kube‑proxy 三种模式完整实验教程

摘要:Pod 生命周期是短暂的,重建、调度后 Pod‑IP 会发生变化,业务不能硬编码 PodIP 访问。Service 是 Kubernetes 集群核心网络抽象,提供固定虚拟 IP、负载均衡、服务发现。本文从实际痛点出发,完整讲解 VS‑Code 编写 K8s 资源、Service 五大类型、3 种服务发现方式、会话保持、基于副本的金丝雀灰度发布;深度拆解 kube‑proxy 的 iptables / IPVS / Userspace 三种工作模式,附带全套可复制 YAML、实验命令、原理图、排坑经验,适合云原生运维入门学习。

目录

  1. 前置:VS Code 编写 Kubernetes 资源清单
  2. 为什么需要 Service?真实业务痛点
  3. Service 核心概念与基础实操(ClusterIP)
  4. Kubernetes 三种服务发现机制
  5. Service 五大类型完整实验:ClusterIP / NodePort / LoadBalancer (MetalLB) / ExternalName / Headless 无头服务
  6. Service 会话保持 sessionAffinity
  7. 基于 Service+Deployment 实现金丝雀(灰度)发布
  8. kube‑proxy 底层深度剖析:iptables / IPVS / Userspace 模式
  9. 常见问题排坑总结
  10. 实验环境清理

1、前置:VS Code 编写 Kubernetes 资源清单

日常写 YAML 资源清单,推荐使用 VS Code,搭配两个官方扩展,实现语法校验、自动补全、集群资源可视化管理。

1.1 VS Code 两个核心扩展

  1. YAML by Red Hat(红帽 YAML 支持)

专门处理 YAML 语法,不是 K8s 专属,是底层依赖。

  • YAML 语法错误检测、Schema 校验(字段错误、缺少必填项标红)
  • 自动补全字段、枚举值,悬浮鼠标查看字段说明
  • 文件格式化、代码大纲、锚点& *支持
  • Helm 的!Ref !Sub自定义标签需要手动配置参数,否则报语法错误
  1. Kubernetes by Microsoft(微软 K8s 扩展)

K8s 运维工作台,会自动安装上面 YAML 扩展。

  • 侧边树视图:查看命名空间、Pod、Deployment、Service、Node,实时刷新
  • 右键直接操作资源:apply / delete / describe / 日志 / 进入pod终端 / 端口转发
  • Helm chart 脚手架、仓库管理
  • 自动拉取集群 CRD 的 OpenAPI Schema,实现自定义资源补全

⚠️注意:Kubernetes 扩展本身不做语法校验,只是提供 schema,真正校验、补全逻辑全部交给 YAML 扩展;CRD 补全需要 VS Code 能连通 K8s 集群。

1.2 VS Code 连接 K8s 集群完整步骤

  1. 下载 Windows 版kubectl.exe,放到$HOME\.kube\目录,把这个目录加入系统环境变量PATH。
  2. 将 K8s master 节点~/.kube/config集群认证配置文件拷贝到 Windows 本地路径:$HOME\.kube\config。
  3. 重启 VS Code,打开 Kubernetes 侧边栏,刷新,即可看到集群全部资源。

1.3 使用 VS Code 编写资源

  1. 新建本地文件夹存放 yaml 清单,用 VS Code 打开该文件夹。
  2. 新建.yaml文件,输入首字母例如p,编辑器弹出 Kubernetes 资源模板,选择Kubernetes Pod自动生成基础模板。
  3. 补全小技巧:输入字段后加上冒号:,触发自动提示。
  4. 写完 yaml,右键文件,选择Apply直接部署资源,不需要来回切换命令行终端。

示例自动生成 Pod 模板:

yaml 复制代码
apiVersion: v1
kind: Pod
metadata:
  name: myapp
  labels:
    app.kubernetes.io/name: myapp
spec:
  containers:
  - name: myapp
    image: <Image>
    resources:
      limits:
        memory: "128Mi"
        cpu: "500m"
    ports:
      - containerPort: <Port>

2、为什么需要 Service?真实业务痛点

Pod 是短暂生命周期资源 ,Deployment 扩缩容、滚动更新、节点故障都会删除重建 Pod,Pod 的 IP 地址会随之改变。

示例 1:直接访问 PodIP 的问题

Pod 重建 IP 就变,客户端无法写死 PodIP 访问业务。集群外部网络默认也不能直接访问 PodIP。

yaml 复制代码
kubectl run web --image=hub.laoma.cloud/library/httpd --image-pull-policy=IfNotPresent -o yaml --dry-run=client > pod-web.yml
kubectl apply -f pod-web.yml
kubectl get pod -o wide
# 拿到PodIP,集群外部无法直接curl访问,pod删除重建IP发生变化

示例 2:hostPort 端口绑定坑

hostPort 会把容器端口直接绑定宿主机端口,同一个宿主机同一个端口只能被一个进程占用。

yaml 复制代码
ports:
- containerPort: 80
  hostPort: 8080

当 Deployment 副本数大于 1,多个 Pod 调度到同一节点,会出现 Pod Pending,事件提示:didn't have free ports for the requested pod ports,节点没有空闲端口。

✨痛点总结

  1. Pod IP 动态变化,客户端不能硬编码 PodIP;
  2. hostPort 端口冲突,无法单机多副本;
  3. 多副本业务缺少内置负载均衡;
  4. Pod 故障重建,前端访问地址需要不断修改。

👉 Service 就是用来解决上面全部问题的核心资源。

Service 核心定义

Service 将一组 Pod 封装成一个网络服务。Service 拥有固定不变 Cluster‑IP,实现负载均衡、服务发现。

  1. Service 通过selector标签选择器筛选后端 Pod,自动维护 Endpoints(端点列表,保存所有后端 PodIP + 端口);
  2. Pod 新建、删除、重建,Endpoints 会自动更新,Service IP 永远不会改变;
  3. 底层由每个节点上的kube‑proxy组件实现流量转发;
  4. 业务客户端只访问 Service,完全不需要感知后端 Pod 变化。

实验准备命名空间

yaml 复制代码
kubectl create ns services
kubectl config set-context --current --namespace services

3、Service 基础实操:ClusterIP(默认类型)

先创建 3 副本 httpd Deployment 作为后端业务

yaml 复制代码
kubectl create deployment web --image=hub.laoma.cloud/library/httpd:2.4.58 --replicas=3
kubectl get pods --show-labels

创建 ClusterIP Service,--tcp=Service端口:Pod容器端口

yaml 复制代码
kubectl create service clusterip web --tcp=8080:80
kubectl get svc

输出示例

yaml 复制代码
NAME   TYPE        CLUSTER-IP      EXTERNAL-IP   PORT(S)    AGE
web    ClusterIP   10.103.19.150   <none>        8080/TCP   6m

查看 Service 详情,重点看Selector、Endpoints

yaml 复制代码
kubectl describe service web
  • Selector: app=web:标签选择器,匹配哪些 Pod 作为后端;
  • Endpoints:所有匹配标签 Pod 的PodIP:容器端口集合,真实后端地址。

访问测试

yaml 复制代码
curl 10.103.19.150:8080

验证 Service 四大核心能力

1)负载均衡能力

修改每个 Pod 主页为 Pod 名称,循环访问 Service 观察流量分发

yaml 复制代码
for pod in $(kubectl get pods -o name | awk -F/  '{print $2}')
do
  kubectl exec -it $pod -- bash -c "echo \$pod > htdocs/index.html"
done
# 循环60次访问service
for i in {1..60};do curl -s 10.103.19.150:8080;done|sort |uniq -c

现象:请求均衡分发到各个后端 Pod。

2)自动发现新增 Pod

新建一个拥有相同标签app=web的 Pod,会自动加入 Service 后端列表

yaml 复制代码
kubectl run web --image=hub.laoma.cloud/library/httpd --labels=app=web
for i in {1..60};do curl -s 10.103.19.150:8080;done|sort |uniq -c

3)Pod 重建,Service 自动更新 Endpoints

重启 Deployment,所有 Pod 全部重建,Service 自动同步后端端点,访问不受影响

yaml 复制代码
kubectl rollout restart deployment web
for i in {1..60};do curl -s 10.103.19.150:8080;done|sort |uniq -c

4)Deployment selector 和 Service selector 互相独立

Deployment 的 selector 用于管理 Pod;Service selector 只用来挑选后端 Pod,两者标签可以完全不一样,互不绑定。

示例:deployment 匹配app1:web1,service 匹配app2:web2,只要 Pod 同时具备这两个标签就可以作为后端。

⚠️重要知识点:ClusterIP ping 不通是正常现象!

ClusterIP 是内核 iptables/ipvs 虚拟出来的 IP,只处理 Service 定义的 TCP/UDP 业务端口,不处理 ICMP 协议(ping)。

现象:ping ClusterIP 没有回应,但是 curl 访问业务端口正常,属于预期行为,不是故障。

yaml 方式创建 Service

从命令行导出 yaml 模板

yaml 复制代码
kubectl delete svc web
kubectl create service clusterip web --tcp=8080:80 -o yaml --dry-run=client > svc-web.yml

svc‑web.yml

yaml 复制代码
apiVersion: v1
kind: Service
metadata:
  labels:
    app: web
  name: web
spec:
  ports:
  - name: 8080-80
    port: 8080        # Service(ClusterIP)监听端口
    protocol: TCP
    targetPort: 80    # 后端Pod容器端口
  selector:
    app: web          # 标签选择器,筛选后端Pod
  type: ClusterIP

字段说明

  • port:Service 自身端口(ClusterIP 端口)
  • targetPort:Pod 容器里面业务监听端口
  • selector:标签筛选后端 Pod
  • type:服务类型,默认ClusterIP

4、K8s 三种服务发现方式

服务发现:集群内部 Pod 如何找到 Service 访问后端业务。一共 3 种方式。

方式 1:直接写 ClusterIP 访问

直接写死 Service 的 ClusterIP 地址访问。 ✅优点:简单;❌缺点:ClusterIP 是集群动态分配,IP 发生变化业务就要改配置,生产环境不推荐。

实验示例:mysql + wordpress

yaml 复制代码
# 创建mysql pod
kubectl run mysql --image=hub.laoma.cloud/library/mysql \
--image-pull-policy=IfNotPresent \
--env=MYSQL_ROOT_PASSWORD=redhat \
--env=MYSQL_USER=tom \
--env=MYSQL_PASSWORD=redhat \
--env=MYSQL_DATABASE=blog \
--dry-run=client -o yaml > pod-mysql.yaml
kubectl apply -f pod-mysql.yaml
kubectl expose pod mysql --port=3306 --target-port=3306
# 使用service ip访问数据库
mysql -u tom -predhat -h 10.111.69.45 --ssl-mode=DISABLED  -e 'show databases;'

方式 2:环境变量方式发现 Service

⚠️硬性前提:必须先创建 Service,再启动 Pod! Pod 启动的时候,会把当前命名空间已经存在的 Service 注入环境变量;如果 Pod 先启动,后续新建 Service,不会自动注入到已经运行的 Pod。

yaml 复制代码
kubectl run test --rm -it --image=hub.laoma.cloud/library/busybox sh
env|grep MYSQL

输出示例

yaml 复制代码
MYSQL_SERVICE_HOST=10.111.69.45
MYSQL_SERVICE_PORT=3306

业务程序读取MYSQL_SERVICE_HOST拿到服务地址。 ❌缺点:依赖启动顺序;跨命名空间 Pod 拿不到对方 Service 环境变量,生产很少使用。

方式 3:DNS 域名访问(生产首选)

K8s 集群默认部署 CoreDNS,提供集群内部 DNS 解析。 完整 DNS 域名格式: 服务名.命名空间.svc.cluster.local

  • 同一个命名空间可以简写,直接写 Service 名字即可。

查看 coredns 组件

yaml 复制代码
kubectl get deployments.apps -n kube-system |grep coredns
# kube‑dns serviceIP固定:10.96.0.10
kubectl get svc kube-dns -n kube-system

测试 DNS 解析

yaml 复制代码
kubectl run busybox --rm -it --image=hub.laoma.cloud/library/busybox /bin/sh
# 完整域名访问
wget mysql.services.svc.cluster.local:3306
# 同命名空间简写,直接写service名字
wget mysql:3306

Pod 内部/etc/resolv.conf的 nameserver 指向10.96.0.10,也就是 coredns 的 serviceIP。

✅生产最佳实践:业务配置全部写 Service 域名,不写 IP,不需要关心 ClusterIP 变化。 wordpress 连接数据库直接配置环境变量:WORDPRESS_DB_HOST=mysql。


5、Service 五大类型详解

Service 类型 核心作用 访问范围
ClusterIP(默认) 分配集群内部虚拟 IP 仅集群内部 Pod 访问
NodePort 每个节点打开统一宿主机端口 集群内外都可访问
LoadBalancer 分配独立外部 VIP,需要 MetalLB 外部客户端访问
ExternalName DNS CNAME 代理外部域名 集群内访问外部域名
Headless 无头服务 不分配 ClusterIP,DNS 直接返回 PodIP 多用于 StatefulSet 有状态应用

5.1 ClusterIP

默认类型,分配集群内部网段虚拟 IP;NodePort、LoadBalancer 底层都依赖 ClusterIP。 设置clusterIP: None就是无头 Headless Service。

5.2 NodePort

  • 集群每个节点都会监听同一个 NodePort 端口 ,端口默认范围:30000‑32767;
  • 外部客户端访问 任意节点IP:NodePort端口;
  • 创建 NodePort Service 会自动生成对应的 ClusterIP。
yaml 复制代码
apiVersion: v1
kind: Service
metadata:
  labels:
    app: web
  name: web
spec:
  ports:
  - port: 8080
    nodePort: 30080  # 手动指定,不指定自动随机分配
    protocol: TCP
    targetPort: 80
  selector:
    app: web
  type: NodePort

端口区分:

  • nodePort:宿主机节点监听端口;
  • port:ClusterIP 服务端口;
  • targetPort:Pod 容器业务端口。

访问示例:curl http://节点IP:30080

5.3 LoadBalancer

原生 K8s 本身没有实现外部负载均衡;裸金属物理机集群需要部署 MetalLB 组件,分配外部局域网 VIP。

MetalLB 完整部署

yaml 复制代码
wget https://laoma.cloud/class/course-materials/softwares/stage03/metallb-0.14.8.tar.gz
tar -xf metallb-0.14.8.tar.gz
sed -i 's/quay.io/hub.laoma.cloud/g' metallb-0.14.8/config/manifests/metallb-native.yaml
kubectl apply -f metallb-0.14.8/config/manifests/metallb-native.yaml
# 等待所有pod就绪
kubectl get all -n metallb-system

配置 IP 地址池(给 LoadBalancer 分配的外部 IP 段) ippool.yaml

yaml 复制代码
apiVersion: metallb.io/v1beta1
kind: IPAddressPool
metadata:
  name: first-pool
  namespace: metallb-system
spec:
  addresses:
  - 10.1.8.40-10.1.8.80

L2.yaml 二层宣告配置

yaml 复制代码
apiVersion: metallb.io/v1beta1
kind: L2Advertisement
metadata:
  name: example
  namespace: metallb-system
kubectl apply -f ippool.yaml
kubectl apply -f L2.yaml

创建 LoadBalancer Service

yaml 复制代码
apiVersion: v1
kind: Service
metadata:
  labels:
    app: web
  name: web
spec:
  ports:
  - port: 80
    targetPort: 80
  selector:
    app: web
  type: LoadBalancer

创建后EXTERNAL‑IP字段会分配来自 IPAddressPool 的外部 IP,客户端直接访问这个 VIP。

📝流量路径:客户端 → MetalLB ARP 宣告 VIP → 节点 kube‑proxy → Service → 后端 Pod MetalLB 只负责 ARP 宣告占用 IP,流量转发全部依靠 kube‑proxy。

5.4 ExternalName

不做流量代理,只做 DNS CNAME 记录。集群内部解析 Service 域名,直接 CNAME 跳转到外部域名。

yaml 复制代码
apiVersion: v1
kind: Service
metadata:
  name: www
spec:
  type: ExternalName
  externalName: www.laoma.cloud

集群内访问www.services.svc.cluster.local,DNS 直接返回 CNAME 记录指向www.laoma.cloud。

5.5 Headless 无头服务

设置clusterIP: None,不分配 ClusterIP 虚拟 IP,kube‑proxy 不会处理这个 Service。 DNS 解析 Service 名称,直接返回全部后端 Pod 的 IP 地址列表。

典型用途:StatefulSet 有状态应用(Redis 集群、Mysql 主从),给每个 Pod 提供稳定 DNS 域名。

yaml 复制代码
apiVersion: v1
kind: Service
metadata:
  name: web-headless
spec:
  clusterIP: None
  selector:
    app: web
  ports:
  - port: 80
    targetPort: 80

两种模式

  1. 带 selector:DNS 直接返回后端 PodIP;
  2. 不带 selector:手动自定义 Endpoints。

6、Service 会话保持 sessionAffinity(会话亲和)

默认 Service 是轮询随机分发请求;开启会话保持,同一个客户端 IP 的请求,始终转发到同一个后端 Pod。

适用场景:web 登录会话、WebSocket 长连接、游戏服务。

关键字段

  • sessionAffinity: ClientIP:开启基于客户端 IP 会话保持;
  • sessionAffinityConfig.clientIP.timeoutSeconds:会话超时时间,默认 10800 秒(3 小时)。

实操演示

yaml 复制代码
kubectl create deployment web --image=hub.laoma.cloud/library/httpd --replicas=2
kubectl expose deployment web --port 80
# 修改pod主页内容为pod名称
for pod in $(kubectl get pods -o name | awk -F/  '{print $2}'); do
  kubectl exec -it $pod -- bash -c "echo \$pod > htdocs/index.html"
done
# 未开启会话保持,流量随机分散
for i in {1..20};do curl -s $(kubectl get svc web -o jsonpath='{.spec.clusterIP}');done|sort |uniq -c

开启会话保持

yaml 复制代码
kubectl patch svc web -p '{"spec":{"sessionAffinity":"ClientIP"}}'
# 再次访问,全部请求落到同一个Pod
for i in {1..20};do curl -s $(kubectl get svc web -o jsonpath='{.spec.clusterIP}');done|sort |uniq -c

底层原理

  • iptables 模式:依靠 iptables 概率标记实现;
  • IPVS 模式:kube‑proxy 自动切换sh源地址哈希调度算法,实现会话粘性。

7、基于 Service 实现金丝雀发布(灰度发布)

金丝雀发布:少量流量导入新版本应用,验证新版本稳定性,没问题再逐步把全部流量切到新版本。

实现原理:

  1. 一套 Service,selector 匹配新旧两套 Deployment 的公共标签;
  2. 通过调整新旧 Deployment 副本数量,控制流量权重比例;
  3. 少量副本运行新版本接收一小部分流量,观察业务是否异常。

⚠️局限:这种方式只能按副本比例切流量;不能按照请求头、用户 ID 精准切流量,精细化灰度需要 Ingress 网关。

完整实验步骤

  1. 创建 ConfigMap 保存两个版本网页
yaml 复制代码
mkdir web
echo hello nginx 1.28 > web/index28.html
echo hello nginx 1.29 > web/index29.html
kubectl create configmap web --from-file=./web
  1. 稳定版本 Deployment(1.28,track: stable) webapp‑1.28.yaml
yaml 复制代码
apiVersion: apps/v1
kind: Deployment
metadata:
  labels:
    app: web
  name: web-28
spec:
  replicas: 10
  selector:
    matchLabels:
      app: web
      tier: frontend
      track: stable
  template:
    metadata:
      labels:
        app: web
        tier: frontend
        track: stable
    spec:
      containers:
      - image: hub.laoma.cloud/library/nginx:1.28
        name: nginx
        imagePullPolicy: IfNotPresent
        ports:
        - containerPort: 80
        volumeMounts:
        - name: webcontent
          mountPath: "/usr/share/nginx/html"
      volumes:
      - name: webcontent
        configMap:
          name: web
          items:
            - key: index28.html
              path: index.html
kubectl apply -f webapp-1.28.yaml
  1. Service,selector 匹配公共标签app: web,tier: frontend,同时匹配 stable 与 canary 的 Pod webapp‑svc.yaml
yaml 复制代码
apiVersion: v1
kind: Service
metadata:
  labels:
    app: web
  name: web
spec:
  ports:
  - port: 80
    protocol: TCP
    targetPort: 80
  selector:
    app: web
    tier: frontend
kubectl apply -f webapp-svc.yaml
  1. 金丝雀新版本 Deployment(1.29,track:canary) webapp‑1.29.yaml
yaml 复制代码
apiVersion: apps/v1
kind: Deployment
metadata:
  labels:
    app: web
  name: web-29
spec:
  replicas: 1
  selector:
    matchLabels:
      app: web
      tier: frontend
      track: canary
  template:
    metadata:
      labels:
        app: web
        tier: frontend
        track: canary
    spec:
      containers:
      - image: hub.laoma.cloud/library/nginx:1.29
        name: nginx
        imagePullPolicy: IfNotPresent
        ports:
        - containerPort: 80
        volumeMounts:
        - name: webcontent
          mountPath: "/usr/share/nginx/html"
      volumes:
      - name: webcontent
        configMap:
          name: web
          items:
            - key: index29.html
              path: index.html
kubectl apply -f webapp-1.29.yaml
  1. 调整副本数量,改变流量占比
yaml 复制代码
# 8个旧版本,2个新版本
kubectl scale deployment web-28 --replicas 8
kubectl scale deployment web-29 --replicas 2
# 压测观察流量分配
for i in {1..50}; do curl -s $(kubectl get svc web -o jsonpath='{.spec.clusterIP}'); done | sort -n|uniq -c

# 逐步迁移流量:6旧4新
kubectl scale deployment web-28 --replicas 6
kubectl scale deployment web-29 --replicas 4

8、kube‑proxy 深度剖析:Service 底层实现

kube‑proxy 运行在集群每一个节点上,以 DaemonSet 部署。 核心职责:监听 API‑Server 中 Service、Endpoint 资源变化,在宿主机内核生成转发规则,实现 Service 流量转发与负载均衡。

kube‑proxy 三种工作模式对比

模式 性能 适用场景 特点
iptables 中等,服务 > 1000 性能明显下降 小规模测试集群 依赖 netfilter iptables 规则;规则数量膨胀 CPU 飙升
IPVS 极高,支持上万服务规模 生产环境首选 内核哈希表 O (1) 查找;支持多种高级调度算法
Userspace 性能很差 已废弃(K8s1.25 + 移除) 用户态进程转发,不推荐使用

8.1 查看当前 kube‑proxy 运行模式

yaml 复制代码
# 查看configmap配置
kubectl get cm -n kube-system kube-proxy -o yaml|grep mode
# 查看pod日志确认真实运行模式
kubectl get pods -n kube-system -l k8s-app=kube-proxy -o name
kubectl logs -n kube-system kube-proxy-xxx |grep Using

输出Using iptables proxy代表 iptables 模式。

8.2 切换到 IPVS 模式

  1. 修改 kube‑proxy configmap
yaml 复制代码
kubectl edit configmap -n kube-system kube-proxy

修改配置

yaml 复制代码
mode: "ipvs"
  1. 滚动重启 kube‑proxy daemonset
yaml 复制代码
kubectl rollout restart daemonset -n kube-system kube-proxy
# 验证切换成功
kubectl logs -n kube-system kube-proxy-xxxx |grep Using
#输出 Using ipvs Proxier

IPVS 模式详解

IPVS 在内核维护哈希表,查找效率 O (1),不受服务数量影响。 支持调度算法:

  • rr:轮询(默认)
  • wrr:加权轮询(生产推荐)
  • lc:最少连接(长连接 WebSocket)
  • sh:源地址哈希(对应 service 的 ClientIP 会话保持)
  • sed:最短预期延迟
  • nq:最少队列

IPVS 完整参考配置

yaml 复制代码
apiVersion: kubeproxy.config.k8s.io/v1alpha1
kind: KubeProxyConfiguration
mode: ipvs
ipvs:
  scheduler: "wrr"
  tcpTimeout: 900
  tcpFinTimeout: 120
  udpTimeout: 300
  excludeCIDRs:
  - "127.0.0.1/32"
  strictARP: true

IPVS 实操验证

yaml 复制代码
# 创建3副本deployment
kubectl create deployment web --image=nginx --replicas=3
# 修改每个pod主页为pod名称
for pod in $( kubectl get pods -o custom-columns=NAME:.metadata.name --no-headers)
do
  kubectl exec $pod -- bash -c "echo \$pod > /usr/share/nginx/html/index.html"
done
kubectl expose deployment web --port=80
# 在节点执行ipvsadm查看虚拟服务与real‑server
ipvsadm -Lnt $(kubectl get svc web -o jsonpath='{.spec.clusterIP}'):80
# 循环访问,观察负载均衡分发
for i in {1..60}; do curl -s $(kubectl get svc web -o jsonpath='{.spec.clusterIP}'); done| sort | uniq -c

当 Service 开启sessionAffinity:ClientIP,IPVS 会自动切换sh源哈希算法实现会话粘性。

iptables 模式详解

kube‑proxy 动态生成大量 iptables nat 表规则链(KUBE‑SERVICES / KUBE‑SVC‑xxx / KUBE‑SEP‑xxx)。 缺点:每新增 Service/Endpoint 就新增多条 iptables 规则;上千服务时,逐条匹配规则 CPU 开销巨大。

查看 iptables 规则

yaml 复制代码
iptables-save > iptables.list
cat iptables.list | grep <你的service‑cluster‑ip>

完整链路:访问 ClusterIP → KUBE‑SERVICES 总链 → KUBE‑SVC‑xxx 服务专属链概率负载均衡 → KUBE‑SEP‑xxx 端点链 DNAT 转发到 PodIP。

Userspace 模式(废弃)

kube‑proxy 进程在用户态监听 Service 端口,接收流量再转发 Pod;性能很差,K8s1.25 版本彻底移除。


9、常见排坑总结

  1. Service 访问不通
  • 检查Endpoints是否存在;selector标签是否匹配 Pod;Pod 容器containerPort端口配置是否正确。
  1. ping ClusterIP 不通

正常现象,ClusterIP 虚拟 IP 不响应 ICMP ping,只处理 Service 定义 TCP/UDP 端口。

  1. 环境变量拿不到 Service 变量

必须先创建 Service,再启动 Pod!优先使用 DNS 域名访问。

  1. NodePort 访问失败

节点防火墙放行端口范围30000‑32767。

  1. kube‑proxy 切换 IPVS 不生效

确认节点已经加载 ipvs 内核模块,安装ipvsadm工具。

  1. 金丝雀发布流量不符合预期

Service selector 要同时匹配新旧 Deployment 的公共标签,只通过调整副本数改变流量权重。

10、实验环境清理

yaml 复制代码
kubectl delete ns services
相关推荐
傅科摆 _ py1 小时前
回溯力扣复习
算法·leetcode·职场和发展
wdfk_prog1 小时前
LWIP教程 40:从 `socket()` 到 `lwip_socket()`——DFS fd、SAL Socket 与 lwIP Backend
算法·深度优先
SatanII1 小时前
Kubernetes Ingress
kubernetes·ingress
中伟视界1 小时前
边缘端行为识别部署实战:AI算法分析盒子落地皮带场景
人工智能·算法
SatanII1 小时前
kubernetes service && proxy
云原生·容器·kubernetes
根目录下的猫1 小时前
ArkTS 代码中如何添加作者信息
linux·运维·ubuntu
落樱弥城1 小时前
FlashAttention 完全解析:从 Roofline 诊断到 CUDA 实现
人工智能·算法
艾伦_耶格宇2 小时前
【kubernetes - 1.28版本】-1 kubernetes基础
云原生·容器·kubernetes