跳转至

K8s Service 与 Ingress

一句话概述:Service 是 K8s 中将一组 Pod 暴露为网络服务的抽象(内部负载均衡),Ingress 是 HTTP 层的反向代理入口(对外暴露),两者配合让外界能访问集群内的应用。

核心知识点

概念白话解释
ClusterIP集群内部 IP = 只能在集群内部访问(默认类型)
NodePort节点端口 = 在每个节点上开一个端口对外暴露
LoadBalancer负载均衡器 = 云厂商提供的外部负载均衡(如 AWS ELB)
Ingress入口 = HTTP/HTTPS 层的路由规则(域名→服务)
Ingress Controller入口控制器 = 真正执行路由规则的组件(如 Nginx)
Endpoint端点 = Service 后面真正的 Pod IP 列表

基本使用

1. Service 类型

# === ClusterIP(集群内部访问) ===
apiVersion: v1
kind: Service
metadata:
  name: api-service
spec:
  type: ClusterIP  # 默认类型
  selector:
    app: api  # 选择带 app=api 标签的 Pod
  ports:
    - port: 80  # Service 端口
      targetPort: 8080  # Pod 端口
      protocol: TCP

# 集群内用 api-service:80 或 api-service.default.svc.cluster.local:80 访问
# === NodePort(节点端口暴露) ===
apiVersion: v1
kind: Service
metadata:
  name: web-nodeport
spec:
  type: NodePort
  selector:
    app: web
  ports:
    - port: 80  # Service 端口
      targetPort: 8080  # Pod 端口
      nodePort: 30080  # 节点端口(30000-32767)

# 用 <节点IP>:30080 从外部访问
# === LoadBalancer(云端负载均衡) ===
apiVersion: v1
kind: Service
metadata:
  name: web-lb
spec:
  type: LoadBalancer
  selector:
    app: web
  ports:
    - port: 80
      targetPort: 8080

# 云厂商自动分配外部 IP

2. Ingress

# ingress.yaml
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: my-ingress
  annotations:
    nginx.ingress.kubernetes.io/rewrite-target: /  # URL 重写
spec:
  ingressClassName: nginx  # 使用 nginx Ingress Controller
  rules:
    - host: api.example.com  # 域名
      http:
        paths:
          - path: /  # 路径
            pathType: Prefix  # 前缀匹配
            backend:
              service:
                name: api-service  # 转发到哪个 Service
                port:
                  number: 80  # Service 端口
    - host: web.example.com  # 另一个域名
      http:
        paths:
          - path: /
            pathType: Prefix
            backend:
              service:
                name: web-service
                port:
                  number: 80

  tls:  # HTTPS 配置
    - hosts:
        - api.example.com
        - web.example.com
      secretName: tls-secret  # TLS 证书 Secret
# 安装 Nginx Ingress Controller
kubectl apply -f https://raw.githubusercontent.com/kubernetes/ingress-nginx/controller-v1.10.0/deploy/static/provider/cloud/deploy.yaml

kubectl apply -f ingress.yaml  # 创建 Ingress
kubectl get ingress  # 查看 Ingress
kubectl describe ingress my-ingress  # 查看详情

3. 路径分发

spec:
  rules:
    - host: app.example.com
      http:
        paths:
          - path: /api  # /api 开头的请求
            pathType: Prefix
            backend:
              service:
                name: api-service  # 转发到 API 服务
                port: { number: 80 }
          - path: /  # 其他请求
            pathType: Prefix
            backend:
              service:
                name: web-service  # 转发到 Web 服务
                port: { number: 80 }

高级用法

ExternalName(外部服务代理)

apiVersion: v1
kind: Service
metadata:
  name: external-db
spec:
  type: ExternalName
  externalName: db.example.com  # 集群内用 external-db 访问外部数据库

Headless Service(直接返回 Pod IP)

spec:
  clusterIP: None  # 不分配 ClusterIP
  selector:
    app: db
# DNS 查询返回所有 Pod 的 IP,用于 StatefulSet

常见报错

报错信息原因解决方法
no endpoints availableService 没有匹配到任何 Pod检查 selector 标签是否匹配
connection refusedPod 端口不对检查 targetPort 是否与容器 EXPOSE 一致
503 Service Unavailable后端 Pod 不健康检查 Pod 的就绪探针
404 Not Found on Ingress路径不匹配检查 path 和 pathType
Ingress 无外部 IPIngress Controller 未安装安装 nginx-ingress-controller

速查表

# === Service ===
kubectl get svc                    # 列出 Service
kubectl describe svc <name>       # 查看详情
kubectl get endpoints <name>      # 查看端点(实际 Pod IP)
kubectl expose deploy <n> --port=80 --type=NodePort  # 快速创建 Service

# === Ingress ===
kubectl get ingress               # 列出 Ingress
kubectl describe ingress <name>   # 查看详情

# === Service 类型选择 ===
# ClusterIP  → 集群内部通信(默认)
# NodePort   → 开发/测试对外暴露
# LoadBalancer → 生产环境对外暴露
# ExternalName → 代理外部服务
# Headless   → StatefulSet/直接 Pod 发现

参考:K8s Service 文档 | Ingress 文档 | 更新于 2026 年