# k8s 使用 Service 暴露应用

# k8s Services 概述

(凡人皆有一死来描述 pod,没有比这跟准确的了)。事实上,Pod 是有生命周期的。当一个工作节点(Node)销毁时,节点上运行的 Pod 也会销毁,然后通过 ReplicationController 动态创建新的 Pods 来保持应用的运行。作为另一个例子,考虑一个图片处理 backend,它运行了 3 个副本,这些副本是可互换的 —— 前端不需要关心它们调用了哪个 backend 副本。也就是说,k8s 集群中的每个 Pod 都有一个独立的 IP 地址,甚至是同一个节点上的 Pod,因此需要有一种方式来自动协调各个 Pod 之间的变化,以便应用能够持续运行。

Enter Services。k8s 中的 Service 是一个抽象的概念,它定义了 Pod 的逻辑分组和一种可以访问它们的策略,这组 Pod 能被 Service 访问,使用 YAML (优先)或 JSON 来定义 Service,Service 所针对的一组 Pod 通常由LabelSelector实现(参见下文,为什么可能需要没有 selector 的 Service)。

可以通过 type 在 ServiceSpec 中指定一个需要的类型的 Service,Service 的四种 type:

  • ClusterIP(默认) - 在集群中内部 IP 上暴露服务。此类型使 Service 只能从群集中访问。
  • NodePort - 通过每个 Node 上的 IP 和静态端口(NodePort)暴露服务。NodePort 服务会路由到 ClusterIP 服务,这个 ClusterIP 服务会自动创建。通过请求 <NodeIP>:<NodePort>,可以从集群的外部访问一个 NodePort 服务。
  • LoadBalancer - 使用云提供商的负载均衡器(如果支持),可以向外部暴露服务。外部的负载均衡器可以路由到 NodePort 服务和 ClusterIP 服务。
  • ExternalName - 通过返回 CNAME 和它的值,可以将服务映射到 externalName 字段的内容,没有任何类型代理被创建。这种类型需要 v1.7 版本或更高版本kube-dnsc才支持。

更多不同类型 Service 的信息,请参考“Using Source IP”教程,Connecting Applications with Services。

使用ExternalName 类型可以实现一种情况,在创建 Service 涉及未定义selector的示例,创建的 Service selector不创建相应的 Endpoints 对象,可以通过手动将 Service 映射到特定 Endpoints。

k8s Service 是一个抽象层,它定义了一组逻辑的 Pods,借助 Service,应用可以方便的实现服务发现与负载均衡。

# Services 和 Labels

img

如上图,A 中 Service 路由一组 Pods 的流量。Service 允许 pod 在 k8s 中被销毁并复制 pod 而不影响应用。相关 Pod 之间的发现和路由(如应用中的前端和后端组件)由 k8s Services 处理。

Service 使用 label selectors 来匹配一组 Pod,允许对 k8s 中的对象进行逻辑运算,Label 以 key/value 键/值对附加到对象上。以多种方式使用:

  • 指定用于开发,测试和生产的对象
  • 嵌入版本 Label
  • 使用 Label 分类对象

你可以在使用 --exposekubectl 创建 Deployment 的同时创建 Service。

img

Label 可以在创建时或以后附加到对象上,可以随时修改。

Last Updated: 6/17/2023, 6:57:19 PM