53·网络进阶

Service 网络

kubernetesnetworkingservice

Service 网络

学习目标

  1. 理解 Service 的作用和类型
  2. 掌握 kube-proxy 的工作原理
  3. 了解 Service 发现和负载均衡机制

核心概念

一句话解释

Service 为一组 Pod 提供稳定的访问入口和负载均衡,解决 Pod IP 不稳定的问题。

为什么需要 Service

问题:Pod IP 不稳定

Pod A (10.1.1.2) → 重启 → Pod A (10.1.1.5)
Pod B (10.1.1.3) → 扩容 → Pod B (10.1.1.6)
                        → Pod C (10.1.1.7)

其他服务如何找到这些 Pod?

解决方案:Service

┌─────────────────────────────────────────┐
│              Service                     │
│         Name: my-service                 │
│         ClusterIP: 10.96.0.100          │
│         Port: 80                         │
└─────────────────────────────────────────┘
                    ↓
        ┌───────────┼───────────┐
        ↓           ↓           ↓
    ┌───────┐  ┌───────┐  ┌───────┐
    │ Pod A │  │ Pod B │  │ Pod C │
    │10.1.1.2│ │10.1.1.3│ │10.1.1.4│
    └───────┘  └───────┘  └───────┘

访问 Service 的 ClusterIP → 自动负载均衡到后端 Pod

Service 类型

类型说明使用场景
ClusterIP集群内部 IP(默认)Pod 间通信
NodePort在每个节点上开放端口开发测试
LoadBalancer云厂商负载均衡器生产环境
ExternalName映射到外部域名访问外部服务
ClusterIP(默认):
┌─────────────────────────────────────────┐
│              集群内部                     │
│  ┌─────────────────────────────────────┐│
│  │         Service                     ││
│  │      ClusterIP: 10.96.0.100        ││
│  └─────────────────────────────────────┘│
│         ↑ 集群内部可访问                  │
│         ↓ 外部无法访问                   │
└─────────────────────────────────────────┘

NodePort:
┌─────────────────────────────────────────┐
│              Node                       │
│  ┌─────────────────────────────────────┐│
│  │         Service                     ││
│  │      NodePort: 30080                ││
│  └─────────────────────────────────────┘│
│         ↑ 外部通过 NodeIP:30080 访问     │
└─────────────────────────────────────────┘

LoadBalancer:
┌─────────────────────────────────────────┐
│         云负载均衡器                      │
│           Public IP                      │
└─────────────────────────────────────────┘
                    ↓
    ┌───────────────┼───────────────┐
    ↓               ↓               ↓
┌───────┐      ┌───────┐      ┌───────┐
│ Node1 │      │ Node2 │      │ Node3 │
└───────┘      └───────┘      └───────┘

kube-proxy 工作原理

kube-proxy 监听 Service 和 Endpoints 变化:

1. 用户创建 Service
           ↓
2. kube-proxy 监听到变化
           ↓
3. 配置 iptables/IPVS 规则
           ↓
4. 流量按规则转发到 Pod

┌─────────────────────────────────────────────────────┐
│                     Node                            │
│  ┌─────────────────────────────────────────────────┐│
│  │  kube-proxy                                    ││
│  │       ↓ 配置规则                                ││
│  │  ┌─────────────────────────────────────────────┐││
│  │  │  iptables / IPVS                           │││
│  │  │  ClusterIP:10.96.0.100:80                  │││
│  │  │       → 10.1.1.2:80 (Pod A)               │││
│  │  │       → 10.1.1.3:80 (Pod B)               │││
│  │  │       → 10.1.1.4:80 (Pod C)               │││
│  │  └─────────────────────────────────────────────┘││
│  └─────────────────────────────────────────────────┘│
└─────────────────────────────────────────────────────┘

Service 发现

# 环境变量方式
apiVersion: v1
kind: Pod
metadata:
  name: my-pod
spec:
  containers:
  - name: app
    image: my-app
    env:
    - name: BACKEND_SERVICE_HOST
      value: "10.96.0.100"  # Service ClusterIP
    - name: BACKEND_SERVICE_PORT
      value: "80"
# DNS 方式(推荐)
apiVersion: v1
kind: Pod
metadata:
  name: my-pod
spec:
  containers:
  - name: app
    image: my-app
    env:
    - name: BACKEND_URL
      value: "http://my-service.default.svc.cluster.local"
DNS 解析规则:
┌─────────────────────────────────────────────────────┐
│  Service DNS 格式:                                  │
│  <service-name>.<namespace>.svc.cluster.local       │
│                                                      │
│  示例:                                              │
│  my-service → my-service.default.svc.cluster.local  │
│                                                      │
│  同 namespace 可以简化:                              │
│  my-service(省略后缀)                              │
└─────────────────────────────────────────────────────┘

Endpoints

# 查看 Service 的 Endpoints
kubectl get endpoints my-service

# 输出示例:
# NAME         ENDPOINTS                                AGE
# my-service   10.1.1.2:80,10.1.1.3:80,10.1.1.4:80    5m

# Endpoints 自动更新:
# - Pod 创建 → 添加到 Endpoints
# - Pod 删除 → 从 Endpoints 移除
# - Pod 就绪 → 添加到 Endpoints
# - Pod 未就绪 → 从 Endpoints 移除

实践练习

练习 1:创建 ClusterIP Service

# deployment.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
  name: nginx-deployment
spec:
  replicas: 3
  selector:
    matchLabels:
      app: nginx
  template:
    metadata:
      labels:
        app: nginx
    spec:
      containers:
      - name: nginx
        image: nginx
        ports:
        - containerPort: 80
---
# service.yaml
apiVersion: v1
kind: Service
metadata:
  name: nginx-service
spec:
  selector:
    app: nginx
  ports:
  - port: 80
    targetPort: 80
  type: ClusterIP
# 应用配置
kubectl apply -f deployment.yaml
kubectl apply -f service.yaml

# 查看 Service
kubectl get service nginx-service

# 查看 Endpoints
kubectl get endpoints nginx-service

# 测试访问
kubectl run test-pod --image=busybox --rm -it -- wget -qO- http://nginx-service

练习 2:创建 NodePort Service

# nodeport-service.yaml
apiVersion: v1
kind: Service
metadata:
  name: nginx-nodeport
spec:
  selector:
    app: nginx
  ports:
  - port: 80
    targetPort: 80
    nodePort: 30080
  type: NodePort
# 应用配置
kubectl apply -f nodeport-service.yaml

# 查看 Service
kubectl get service nginx-nodeport

# 通过 NodePort 访问
curl http://<node-ip>:30080

练习 3:Service 发现

# 创建测试 Pod
kubectl run test-pod --image=busybox --command -- sleep 3600

# 通过 DNS 名称访问 Service
kubectl exec test-pod -- nslookup nginx-service
kubectl exec test-pod -- wget -qO- http://nginx-service

# 查看完整的 DNS 名称
kubectl exec test-pod -- nslookup nginx-service.default.svc.cluster.local

常见误解

1. Service 是一个进程

错误理解:Service 是一个运行的进程
正确理解:Service 是 iptables/IPVS 规则,由 kube-proxy 配置

Service 没有自己的 Pod,只是转发规则

2. ClusterIP 可以从外部访问

错误理解:ClusterIP 可以从集群外部访问
正确理解:ClusterIP 只能在集群内部访问

外部访问需要 NodePort 或 LoadBalancer

小结

要点说明
Service为 Pod 提供稳定访问入口
类型ClusterIP、NodePort、LoadBalancer、ExternalName
kube-proxy配置 iptables/IPVS 规则实现转发
服务发现环境变量或 DNS(推荐)
Endpoints自动维护后端 Pod 列表

练习编辑器

bash
Loading...

继续学习

完成本课后,建议继续学习下一课「Ingress 简介」 以巩固所学知识。