【k8s】什么是Service

在 Kubernetes(K8s)中,Service(服务) 是一个非常核心、关键的抽象概念。它的主要作用是:

为一组 Pod 提供稳定的网络访问入口(IP + Port),实现服务发现和负载均衡。


为什么需要 Service?

在 Kubernetes 中:

  • Pod 是临时的、动态的 —— 它们随时可能被调度、重启、扩缩容,IP 会变
  • 如果其他应用或用户直接访问 Pod IP,一旦 Pod 重建,连接就会失败
  • 我们需要一个稳定的访问端点(Service),无论后端 Pod 如何变化

Service 的核心功能为:

功能说明
服务发现通过 Service 名称(在集群内 DNS 可解析)访问后端应用
负载均衡自动将请求分发到后端多个 Pod 实例
解耦访问与实现用户访问 Service,无需关心后端是哪些 Pod、IP 是多少
支持多种暴露方式可在集群内访问、节点上暴露、或对外暴露公网访问

Service 如何工作?

  1. 创建一个 Service,并指定“选择器(selector)”来匹配一组 Pod(如 app: my-app
  2. Kubernetes 为 Service 分配一个集群内唯一的虚拟 IP(ClusterIP)
  3. kube-proxy 组件在每个节点上设置 iptables/IPVS 规则,实现流量转发和负载均衡
  4. 当请求发送到 Service 的 IP:Port,流量会被自动转发到后端健康的 Pod

Service 的 4 种类型

1️⃣ ClusterIP(默认)

  • 只在集群内部可访问
  • 为 Service 分配一个集群内虚拟 IP
  • 适用于微服务之间互相调用
1
2
3
4
5
6
7
spec:
  type: ClusterIP
  ports:
    - port: 80
      targetPort: 8080
  selector:
    app: my-app

2️⃣ NodePort

  • 每个节点上开放一个端口(默认 30000-32767)
  • 外部用户可通过 http://<NodeIP>:<NodePort> 访问服务
  • 适合开发、测试或没有 LoadBalancer 的环境
1
2
3
4
5
6
7
8
spec:
  type: NodePort
  ports:
    - port: 80
      targetPort: 8080
      nodePort: 30007  # 可选,不填则自动分配
  selector:
    app: my-app

3️⃣ LoadBalancer

  • 适用于云平台(AWS、GCP、Azure、阿里云等)
  • 云平台会自动创建一个外部负载均衡器,并分配公网 IP
  • 用户通过公网 IP 访问服务
  • 最适合生产环境对外暴露服务
1
2
3
4
5
6
7
spec:
  type: LoadBalancer
  ports:
    - port: 80
      targetPort: 8080
  selector:
    app: my-app

在 Minikube 或本地环境,可以使用 minikube service <service-name> 来模拟 LoadBalancer。

4️⃣ ExternalName

  • 不指向 Pod,而是通过 CNAME 指向一个外部域名
  • 用于将集群内服务名称映射到外部服务(如数据库、第三方 API)
1
2
3
spec:
  type: ExternalName
  externalName: my.database.example.com

举个例子

假设部署了一个 Web 应用:

1
kubectl create deployment my-nginx --image=nginx

默认它没有对外暴露,只能通过 kubectl port-forward 临时访问。

创建一个 Service 让它可被访问:

1
kubectl expose deployment my-nginx --port=80 --target-port=8080 --type=NodePort

或写 YAML:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
apiVersion: v1
kind: Service
metadata:
  name: my-nginx-service
spec:
  type: NodePort
  ports:
    - port: 80        # Service 暴露的端口
      targetPort: 80  # Pod 容器监听的端口(nginx 默认 80)
  selector:
    app: my-nginx     # 匹配 Deployment 的 label

然后:

1
2
3
4
kubectl get svc
# 输出示例:
# NAME               TYPE       CLUSTER-IP      EXTERNAL-IP   PORT(S)        AGE
# my-nginx-service   NodePort   10.96.123.123   <none>        80:30007/TCP   10s

访问 http://<你的节点IP>:30007 就能看到 Nginx 页面

Service 与 DNS

Kubernetes 集群内置 CoreDNS,Service 会自动注册 DNS 记录:

  • 在集群内,你可以通过 <service-name>.<namespace>.svc.cluster.local 访问服务
  • 同命名空间下,直接用 <service-name> 即可

例如:

1
2
# 在集群内 Pod 中执行:
curl http://my-nginx-service

Service 与 Deployment/Pod 的关系

1
2
3
用户 → Service (稳定入口) → 负载均衡 → 多个 Pod(动态、IP 会变)
                      由 Deployment 管理
  • Deployment 管理 Pod 生命周期(滚动更新、扩缩容)
  • Service 管理网络访问(服务发现 + 负载均衡)
  • 二者配合,实现高可用、弹性、稳定的应用架构
Licensed under CC BY-NC-SA 4.0
使用 Hugo 构建
主题 StackJimmy 设计