Kubernetes(通常简写为K8s)中的Service是一种核心资源对象,它用于将一组Pod(容器组)抽象为一个单一的服务,使得这些Pod能够对外提供稳定的服务入口。
一、作用
- 提供稳定的网络终点:Service为Pod提供了一个稳定的IP地址和DNS名称,无论Pod如何变化(例如被删除、重新调度等),Service的IP地址和DNS名称都不会改变,确保了服务的稳定性。
- 实现负载均衡:Service内部实现了负载均衡机制,它可以将进入的请求均匀地分配给后端的Pod副本,提高了系统的可扩展性和可靠性。
- 实现故障隔离:当某个Pod发生故障时,Service会自动将该Pod从服务池中剔除,保证请求不会被故障的Pod处理,从而实现了故障隔离。
- 实现服务发现:Service允许前端的应用程序通过Label Selector来找到提供特定服务的Pod,从而实现了服务的自动发现。
二、类型
Kubernetes支持以下几种类型的Service:
- ClusterIP:这是最常见的Service类型,也是默认类型。它为Service在集群内部提供一个固定的虚拟IP(ClusterIP),只有集群内部的客户端可以访问此服务。ClusterIP Service适用于内部服务通信,对外部不可见。
- NodePort:这种类型的Service允许将服务公开到集群节点上的某个端口上(NodePort),从而可以从集群外部访问服务。它会在每个节点上监听相同的端口,并将流量转发到Service中的Pod。NodePort Service适用于需要从集群外部访问服务的情况,通常用于测试和开发环境。
- LoadBalancer:在NodePort的基础上,LoadBalancer类型的Service通过云服务提供商(如AWS、GCP、Azure)的负载均衡器来公开服务,可以将流量分布到多个节点上的Pod。这允许外部流量访问服务,同时实现负载均衡。LoadBalancer Service适用于需要在云环境中公开服务,并且需要负载均衡的情况,常用于生产环境。
- ExternalName:这种类型的Service将Kubernetes Service映射到外部服务的DNS名称,不通过kube-proxy进行代理。它通常用于将现有的外部服务映射到Kubernetes内部服务,实现平滑迁移。
- Headless Service:Headless Service不分配ClusterIP,而是为每个选择的Pod创建DNS记录。这意味着每个Pod都有其独立的DNS记录,通常用于服务发现或需要直接访问每个Pod的场景,如数据库复制等。
三、类型详解
1、ClusterIP
ClusterIP 是 Service 类型的一种,它是默认的服务类型。当创建一个类型为 ClusterIP 的 Service 时,Kubernetes 会为该 Service 分配一个集群内部的虚拟IP地址(Cluster IP),这个地址仅在集群内部可见和可访问。这个地址的分配和管理是由 Kubernetes 集群中的 kube-proxy 组件和底层的网络插件(如 Calico、Flannel、Weave 等)共同完成的。
(1)特点
- 内部访问:ClusterIP Service 主要用于集群内部的Pod之间的相互通信。外部网络无法直接访问通过 ClusterIP 暴露的服务,除非通过其他方式(如 NodePort、LoadBalancer 或 Ingress)将服务暴露到集群外部。
- 虚拟IP:每个 ClusterIP Service 都会获得一个虚拟IP地址,这个地址在集群内部是唯一的,并且会根据集群的网络配置和大小来分配。Pod 可以使用 Service 的 ClusterIP 地址和端口来访问背后的后端Pod集合。
- 负载均衡:Service 的 ClusterIP 地址实际上是一个逻辑上的IP,而不是直接绑定到某个物理或虚拟网络接口上的。当集群内部的Pod通过 ClusterIP 访问 Service 时,kube-proxy 会将请求转发到 Service 后面的一个或多个 Pod 上,从而实现负载均衡。具体的负载均衡算法(如轮询、最少连接等)取决于 kube-proxy 的配置和使用的网络插件。
- DNS 支持:Kubernetes 的 DNS 系统(CoreDNS 或 kube-dns)会为每个 Service 创建一个 DNS 记录,这样 Pod 就可以通过 Service 的名称(而不是 IP 地址)来访问它。这使得服务发现变得更加简单和可靠。
- Service 的定义:在定义 ClusterIP Service 时,需要指定 Service 的名称、Selector(用于选择一组Pod)、端口信息(包括服务的端口和Pod上对应的端口)等。Selector 是一个标签选择器,用于指定哪些Pod应该被包括在这个Service中。
(2)示例
apiVersion: v1
kind: Service
metadata:
name: my-service
spec:
selector:
app: my-app
ports:
- protocol: TCP
port: 80 # Service端口
targetPort: