This repository has been archived on 2026-05-24. You can view files and clone it. You cannot open issues or pull requests or push a commit.
Files
all-in-kingsoft/hhs/MS/05-部署运维/02-Kubernetes/03-网络与服务发现.md
T
2026-05-18 00:17:59 +08:00

4.7 KiB
Raw Blame History

tags, create time
tags create time
kubernetes
service
ingress
networking
service-discovery
2026-05-18 00:30

K8s 网络与服务发现 — Service 与 Ingress

概述

Kubernetes 的网络模型解决了容器 IP 频繁变动的问题。Service 提供稳定的服务发现入口,Ingress 提供L7 HTTP 路由能力。本文将梳理核心概念、典型模式和常见问题。

Service 类型

类型 特点 使用场景
ClusterIP 集群内 IP,外部不可访问 默认,内部服务间调用
NodePort 在每个 Node 上开端口 调试、临时访问
LoadBalancer 云厂商分配公网 IP 对外暴露的服务
ExternalName CNAME 到外部域名 对接外部系统

ClusterIP Service — 服务发现的载体

apiVersion: v1
kind: Service
metadata:
  name: order-service
spec:
  selector:
    app: order                          # 匹配带此 label 的 Pod
  ports:
    - port: 80                          # Service 端口(对外暴露)
      targetPort: 8080                  # 容器实际监听端口
      protocol: TCP
  type: ClusterIP

调用方只需 http://order-service:80,K8s 通过 iptables/IPVS 自动实现负载均衡。

[!question] Service 是怎么做到负载均衡的?

每个 Node 上的 kube-proxy 会监控 Service 的变动,自动生成 iptables 规则或 IPVS 虚拟服务器配置。当请求发往 ClusterIP 时,内核将其 DNAT 到后端 Pod IP 之一,负载均衡算法默认是 round-robin。K8s 1.14+ 推荐使用 IPVS 模式(kube-proxy --proxy-mode=ipvs),性能更高且支持更多算法。

Ingress — HTTP/HTTPS 路由

apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: main-ingress
  annotations:
    nginx.ingress.kubernetes.io/rewrite-target: /
spec:
  rules:
  - host: api.example.com
    http:
      paths:
      - path: /orders
        pathType: Prefix
        backend:
          service:
            name: order-service
            port:
              number: 80
      - path: /users
        pathType: Prefix
        backend:
          service:
            name: user-service
            port:
              number: 80

[!info] Ingress Controller 是什么?

Ingress 只是一个 API 对象,真正的 HTTP 路由由 Ingress Controller(如 NGINX、Traefik、Envoy)执行。安装后会在集群中运行一个 LoadBalancer 类型的 Pod 集群,监听 Ingress 资源变化并生成对应配置。

常见 Ingress Annotation(NGINX 为例)

Annotation 用途 示例值
rewrite-target URL 重写 /
ssl-redirect 强制 HTTPS "true"
rate-limit 限流 100
whitelist-source-range IP 白名单 10.0.0.0/8
client-max-body-size 上传文件大小限制 50m

Headless Service — 无头服务

Headless Service (ClusterIP: None) 不分配虚拟 IP,而是返回所有匹配 Pod 的真实 IP。这是 StatefulSet 的灵魂搭档:

apiVersion: v1
kind: Service
metadata:
  name: mysql-headless
spec:
  clusterIP: None                # 关键:不分配 ClusterIP
  selector:
    app: mysql
  ports:
  - port: 3306

通过 DNS 可以直接访问单个 Pod:

  • mysql-cluster-0.mysql-headless.production.svc.cluster.local:3306
  • mysql-cluster-1.mysql-headless.production.svc.cluster.local:3306

K8s 网络模型总结

flowchart LR
    EXT["外部流量"] --> INGRESS["Ingress Controller"]
    
    INGRESS --> SVC_A["order-service:80"]
    INGRESS --> SVC_B["user-service:80"]
    
    SVC_A --> Pod1["order-pod-1\n10.244.1.5:8080"]
    SVC_A --> Pod2["order-pod-2\n10.244.2.3:8080"]
    
    SVC_B --> Pod3["user-pod-1\n10.244.1.8:3000"]
    
    Pod1 -->|DNS解析| COREDNS["CoreDNS<br/>svc.cluster.local"]
    
    style EXT fill:#e3f2fd
    style INGRESS fill:#fff3e0
    style SVC_A fill:#e8f5e9
    style SVC_B fill:#fce4ec

[!tip] 调试技巧:Service 不通怎么办?

  1. kubectl get svc <name> 确认 Service 存在且有 ClusterIP
  2. kubectl get endpoints <name> 检查 Endpoint 列表是否为空
  3. Endpoint 为空 → 检查 selector 标签是否匹配 Pod
  4. Endpoint 有值但 curl 不通 → 进入 Pod curl <ClusterIP>:<port> 验证
  5. ClusterIP 通但外部不通 → 检查 Ingress / LoadBalancer 配置

关联笔记