Skip to content

Service 深度解析

Service 的作用

Pod 的 IP 是不稳定的(重建后变化),Service 提供稳定的访问入口:

  • 固定的 ClusterIP(虚拟 IP)
  • 固定的 DNS 名称
  • 自动负载均衡到后端 Pod

Service 类型详解

ClusterIP(默认)

yaml
apiVersion: v1
kind: Service
metadata:
  name: my-service
spec:
  type: ClusterIP
  selector:
    app: my-app
  ports:
  - name: http
    port: 80          # Service 端口
    targetPort: 8080  # Pod 端口(可以是端口名)
    protocol: TCP
  sessionAffinity: ClientIP  # 会话保持(同一客户端路由到同一 Pod)
  sessionAffinityConfig:
    clientIP:
      timeoutSeconds: 10800

NodePort

yaml
spec:
  type: NodePort
  ports:
  - port: 80
    targetPort: 8080
    nodePort: 30080    # 不指定则随机分配 30000-32767
  externalTrafficPolicy: Local  # Local | Cluster
  # Local:保留客户端源 IP,只转发到本节点的 Pod
  # Cluster:SNAT,可转发到任意节点的 Pod

LoadBalancer

yaml
spec:
  type: LoadBalancer
  loadBalancerIP: 1.2.3.4  # 指定外部 IP(云厂商支持)
  ports:
  - port: 443
    targetPort: 8443
  # 云厂商注解(以 AWS 为例)
  annotations:
    service.beta.kubernetes.io/aws-load-balancer-type: nlb
    service.beta.kubernetes.io/aws-load-balancer-cross-zone-load-balancing-enabled: "true"

Headless Service

yaml
spec:
  clusterIP: None  # 不分配 ClusterIP
  selector:
    app: my-app
  # DNS 直接返回所有 Pod IP(A 记录)
  # 用于 StatefulSet、服务发现

ExternalName

yaml
spec:
  type: ExternalName
  externalName: my-database.rds.amazonaws.com
  # DNS 返回 CNAME 记录,不做代理

Endpoints 与 EndpointSlice

bash
# 查看 Service 对应的 Endpoints
kubectl get endpoints my-service
kubectl describe endpoints my-service

# EndpointSlice(大规模集群推荐,每个 Slice 最多 100 个端点)
kubectl get endpointslices -l kubernetes.io/service-name=my-service

手动管理 Endpoints(无 selector)

yaml
# 用于代理集群外部服务
apiVersion: v1
kind: Service
metadata:
  name: external-db
spec:
  ports:
  - port: 5432
---
apiVersion: v1
kind: Endpoints
metadata:
  name: external-db
subsets:
- addresses:
  - ip: 192.168.100.10  # 外部数据库 IP
  ports:
  - port: 5432

多端口 Service

yaml
spec:
  ports:
  - name: http
    port: 80
    targetPort: 8080
  - name: https
    port: 443
    targetPort: 8443
  - name: metrics
    port: 9090
    targetPort: metrics  # 引用容器端口名

服务发现

bash
# 环境变量方式(自动注入,但只包含 Service 创建时已存在的)
# MY_SERVICE_SERVICE_HOST=10.96.100.1
# MY_SERVICE_SERVICE_PORT=80

# DNS 方式(推荐)
# 同命名空间:my-service
# 跨命名空间:my-service.other-namespace
# 完整 FQDN:my-service.default.svc.cluster.local

流量策略

yaml
spec:
  # 内部流量策略(Pod 到 Service)
  internalTrafficPolicy: Local  # Local | Cluster
  # Local:优先路由到同节点的 Pod(降低延迟)

  # 外部流量策略(NodePort/LoadBalancer)
  externalTrafficPolicy: Local  # 保留客户端源 IP

常用操作

bash
# 查看 Service
kubectl get svc
kubectl describe svc my-service

# 临时端口转发(调试用)
kubectl port-forward svc/my-service 8080:80

# 查看 Service 的 iptables 规则
iptables -t nat -L KUBE-SERVICES -n | grep my-service

本站内容由 褚成志 整理编写,仅供学习参考