自在学
分类课程智能体订阅
分类课程AI导师价格
课程进度
6 / 11
上一节Kubernetes Deployment下一节Kubernetes 的存储世界
自在学

© 2025 - 2026 自在学,保留所有权利。

公网安备湘公网安备43020302000292号 | 湘ICP备2025148919号-1

关于我们隐私政策使用条款

© 2025 自在学,保留所有权利。

公网安备湘公网安备43020302000292号湘ICP备2025148919号-1

编程KubernetesKubernetes Service

Kubernetes Service

在 Kubernetes 集群中,Pod 的生命周期是动态的,其 IP 地址也可能随时发生变化。为了确保客户端或其他应用能够稳定、可靠地访问后端服务,Kubernetes 引入了 Service(服务)这一重要组件。 Service 为一组可变的、同类型的 Pod 提供了一个持久且唯一的访问入口,屏蔽了背后 Pod 实例频繁变化所带来的复杂性。

Kubernetes Service


Service 的核心工作原理

理解 Service 的运作方式,需要关注其核心机制,包括标签选择器(Label Selector)与 Endpoints 机制等。

标签与选择器:Service 精确定位目标 Pod

Service 并不直接管理 Pod 实例,而是通过标签(Labels)与选择器(Label Selectors)来动态选定为其提供服务的 Pod。当我们为 Pod 指定如 app: web-frontend 或 env: production 等标签,并在 Service 配置中通过 selector 指定筛选规则后,所有满足相应标签的 Pod 都会自动受 Service 管控。

这种解耦模型保障了 Service 与 Pod 的松散连接——无论新增、删除还是变更标签,Pod 都会根据当前标签状态自动纳入或移出 Service 的管理范围。

如上图所示,Service 借助如 app=chicken 这样的选择器,将流量精准路由至所有标签匹配的目标 Pod,同时自动忽略标签不匹配的 Pod。

Endpoints 对象:维护实时后端 Pod 列表

对于每个 Service,Kubernetes 自动维护一个 Endpoints 对象,用以记录所有当前可被该 Service 路由的 Pod 的 IP 地址与端口。该对象随集群内 Pod 状态的变化而实时同步——只要满足选择条件的 Pod 健康可用,其信息即被自动添加至 Endpoints;相应地,失效或被删除的 Pod 会及时从列表中移除。

在流量转发过程中,Service 始终查询对应的 Endpoints 信息,动态选择健康的后端 Pod 处理客户端请求,这一机制确保了服务访问的高可用性与稳定性。


多种 Service 类型:灵活适配多样化场景需求

为满足各类应用场景中的访问需求,Kubernetes 提供了多种 Service 类型。每种类型均针对不同的网络暴露需求和部署环境进行优化,用户可根据实际场景灵活选用。

多种 Service 类型:灵活适配多样化场景需求

ClusterIP:集群内部流量的默认入口

ClusterIP 是 Kubernetes Service 的默认类型。该类型会为 Service 分配一个仅能被集群内部访问的虚拟 IP,所有集群内的 Pod、节点均可通过该 IP 地址进行通信,无法被集群外部直接访问。此类型广泛用于集群内部各服务间的互联。例如,Web 应用服务器通过 ClusterIP 访问后端数据库服务,实现微服务间安全、稳定的内部通信。

NodePort:节点级别端口暴露

NodePort 类型会在每个节点(Node)上开放一个同样的、预定的端口,并将流量转发至后端的 Service。通过访问集群内任意节点的 [节点IP]:[NodePort],外部客户端即可访问到服务。这一机制基于 ClusterIP 实现,并向外层拓展了访问范围。NodePort 适用于开发、测试等环境下的简易外部暴露,但在生产环境下需谨慎使用,因为其端口分配有限且占用全局资源。

尽管 NodePort 能够快速将服务暴露到外部,但在生产环境建议谨慎使用,避免端口资源冲突及安全隐患。

LoadBalancer:通过云服务商实现公网负载均衡

LoadBalancer 类型适用于需要直接暴露至公网的生产级服务。该类型在 NodePort 基础上,借助所使用的云服务平台(如 AWS、Azure、GCP)自动分配和配置外部负载均衡器。负载均衡器分配一个公网 IP,并将访问流量转发至所有后端节点上的 NodePort。该方式为服务引流提供了高可用、可扩展的流量入口,是云端场景下推荐的对外暴露方式。

ExternalName:外部服务的集群内部别名

ExternalName 类型并不直接将流量导向集群内部的 Pod,而是通过为 Service 配置 DNS CNAME,从而将服务名称映射为外部可访问的域名。当集群内部的服务访问此 Service 时,实际上将被自动重定向至指定的外部域名。这种用法对于集群内应用统一访问第三方托管服务(如外部数据库、API 接口)场景非常有价值。


创建你的第一个 Service

让我们来亲手创建一个 Service 吧!在 Kubernetes 中,我们强烈推荐使用声明式的 YAML 文件来定义和管理对象。

虽然可以使用 kubectl expose 这样的命令式操作来快速创建 Service,但这被认为是不好的实践。因为它会让你的操作脱离版本控制,导致配置文件和实际运行状态不一致,给未来的维护带来隐患。

声明式 YAML:更专业的方式

首先,我们需要创建一个 Deployment,这个对象将帮助我们在 Kubernetes 集群中部署和管理我们的应用程序。

yaml
# deploy.yml
apiVersion: apps/v1
kind: Deployment
metadata:
  name: web-deploy
spec:
  replicas: 3
  selector:
    matchLabels:
      app: hello-world
  template:
    metadata:
      labels:
        app: hello-world # 注意这里的标签,Service将通过它来找到Pod
    spec:
      containers:
      - name: hello-ctr
        image: nigelpoulton/k8sbook:latest
        ports:
        - containerPort: 8080

接下来,我们需要为刚才创建的 Deployment 配置一个 NodePort 类型的 Service。这个 Service 的作用是将外部的请求流量引导到集群内部的 Pod 上。 通过这种方式,我们可以在开发和测试环境中快速地将应用程序暴露给外部用户。具体来说,NodePort 会在每个节点上开放一个特定的端口,这样外部用户就可以通过节点的 IP 地址和这个端口来访问我们的应用程序。

yaml
# svc.yml
apiVersion: v1
kind: Service
metadata:
  name: hello-svc
spec:
  type: NodePort # 定义 Service 类型为 NodePort
  selector:
    app: hello-world # 选择所有带有 app=hello-world 标签的 Pod
  ports:
    - protocol: TCP
      port: 8080       # Service 在集群内部监听的端口 (ClusterIP 的端口)
      targetPort: 8080 # 流量要转发到 Pod 容器上的哪个端口
      nodePort: 30001  # 在每个节点上对外暴露的端口

现在我们需要使用 kubectl 命令来应用我们刚才编写的 YAML 配置文件。这个过程就像是给 Kubernetes 下达指令,让它根据我们的配置去创建和管理资源。 通过执行这些命令,Kubernetes 会在集群中创建相应的 Deployment 和 Service,从而实现应用程序的部署和对外暴露。

shell
$ kubectl apply -f deploy.yml
deployment.apps/web-deploy created
 
$ kubectl apply -f svc.yml
service/hello-svc created

现在,你可以通过 kubectl get svc 查看 Service 的状态:

shell
$ kubectl get svc hello-svc
NAME        TYPE       CLUSTER-IP      EXTERNAL-IP   PORT(S)          AGE
hello-svc   NodePort   10.108.144.24   <none>        8080:30001/TCP   1m

输出显示,我们的 Service hello-svc 已经成功创建,并且可以通过任意节点的 IP 地址加上 30001 端口从外部访问。


实现应用的平滑升级

Service 最强大的功能之一,就是能够与 Deployment 配合,实现应用的无缝升级(也称为蓝绿部署或金丝雀发布)。 想象一下,你的网站 v1 版本正在线上运行。现在你开发了 v2 版本,希望在不影响用户的情况下完成上线。

  1. 初始状态:Service 的选择器是 version: v1,所有流量都流向 v1 版本的 Pod。
  2. 部署新版:你将 v2 版本的 Pod(带有 version: v2 标签)部署到集群中。此时,因为标签不匹配,Service 不会把流量发给它们。
  3. 切换流量:当你确认 v2 版本工作正常后,只需修改 Service 的 YAML 文件,将选择器从 selector: { version: v1 } 改为 selector: { version: v2 },然后执行 kubectl apply -f svc.yml。

就在你应用修改的一瞬间,Kubernetes 就会更新 Service 的路由规则,所有新的用户请求都会被平滑地切换到 v2 版本的 Pod 上,整个过程用户毫无感知。如果 v2 版本出现问题,你只需用同样的方法把选择器改回 v1,就能立刻回滚。

这种简单而强大的机制,正是 Kubernetes 在保障应用高可用性和敏捷性方面的核心魅力所在。

清理实验环境

完成实验后,不要忘记删除我们刚刚创建的资源:

shell
$ kubectl delete -f deploy.yml
$ kubectl delete -f svc.yml

小结

在本部分,我们学习了 Kubernetes Service 如何为应用提供稳定可靠的网络。它通过固定的前端(IP、DNS)和动态的后端(通过标签选择的 Pods),优雅地解决了微服务架构中的服务发现和负载均衡难题。

  • Service 的核心工作原理
    • 标签与选择器:Service 精确定位目标 Pod
    • Endpoints 对象:维护实时后端 Pod 列表
  • 多种 Service 类型:灵活适配多样化场景需求
    • ClusterIP:集群内部流量的默认入口
    • NodePort:节点级别端口暴露
    • LoadBalancer:通过云服务商实现公网负载均衡
    • ExternalName:外部服务的集群内部别名
  • 创建你的第一个 Service
    • 声明式 YAML:更专业的方式
  • 实现应用的平滑升级
    • 清理实验环境
  • 小结

目录

  • Service 的核心工作原理
    • 标签与选择器:Service 精确定位目标 Pod
    • Endpoints 对象:维护实时后端 Pod 列表
  • 多种 Service 类型:灵活适配多样化场景需求
    • ClusterIP:集群内部流量的默认入口
    • NodePort:节点级别端口暴露
    • LoadBalancer:通过云服务商实现公网负载均衡
    • ExternalName:外部服务的集群内部别名
  • 创建你的第一个 Service
    • 声明式 YAML:更专业的方式
  • 实现应用的平滑升级
    • 清理实验环境
  • 小结