更新时间:2025-11-04 GMT+08:00
分享

服务概述

在Kubernetes中,服务(Service)用于将运行在一组Pod上的应用程序公开为网络服务。它不仅为这些Pod提供了一个统一的DNS名称,还实现了Pod之间的负载均衡。本文将为您介绍Kubernetes Service的基本概念以及不同类型Service的对比介绍。

基本概念

Service的类型

您可以在集群中创建指定类型的Service,不同类型Service的描述及适用场景如下:

Service类型

描述

适用场景

计费说明

集群内访问(ClusterIP)

ClusterIP是默认的服务类型,从集群的服务网段中分配一个仅在集群内部可访问的虚拟IP。

如果只需要在集群内部进行服务间的通信,而不需要将服务暴露给集群外部,可以使用ClusterIP类型的服务。

例如,集群中部署的前端应用Pod需要访问同一集群中部署的后端数据库,此时后端数据库可以配置为ClusterIP类型,以确保仅在集群内部可访问。

创建该类型的Service不涉及计费

节点访问(NodePort)

NodePort会在集群中的每个节点上开放一个端口,从而允许从集群外部通过 <NodeIP>:<NodePort> 来访问服务。

在业务需要临时或低流量访问的场景中,您可以通过NodePort类型服务暴露节点端口进行访问。

例如,在测试环境中,当您部署和调试一个Web应用服务时,可以使用NodePort类型。

创建该类型的Service不涉及计费。

若需要通过公网访问NodePort服务,您可以为节点绑定EIP。关于EIP的计费说明,请参见EIP费用组成

负载均衡(LoadBalancer)

LoadBalancer类型在NodePort的基础上添加了外部负载均衡器,支持将外部流量向集群内的多个Pod进行分发。Service会自动分配一个外部IP地址,允许客户端通过该IP访问服务。该类型服务不仅支持在OSI模型的第四层(传输层)处理TCP和UDP流量,还能扩展至第七层(应用层),支持HTTP和HTTPS流量的管理。

在云上提供应用访问时,若需提供一个稳定且易于管理的对外访问入口,可以使用LoadBalancer类型的服务。

例如生产环境中需从互联网访问的公共服务,这些服务需承受大量外部流量并确保高可用性,如Web应用和API服务等。

涉及负载均衡实例的费用,计费详情请参见ELB计费模式

DNAT网关(DNAT)

DNAT类型的服务可以为集群内的所有节点提供网络地址转换服务,使多个节点可以共享使用弹性IP。

在业务需要通过公网进行临时或低流量访问的场景中,您可以通过DNAT类型服务进行访问。DNAT类型与节点访问类型相比增强了可靠性,弹性IP无需与单个节点绑定,任何节点状态的异常不影响其访问。

涉及NAT网关的费用,计费详情请参见NAT网关计费模式

涉及EIP的费用,计费详情请参见EIP费用组成

Headless Service

Headless Service不会分配ClusterIP。当访问后端Pod时,服务的DNS查询会直接返回Pod的IP地址列表,客户端可以直接与特定的Pod进行通信。

应用需要直接与后端的具体Pod进行通信,而不是通过代理或负载均衡器。

例如,当您部署有状态应用(如ClickHouse数据库服务)时,可以使用Headless Service,使应用Pod直接访问每个ClickHouse Pod,并且能够均衡地读取数据或针对性地写入数据,从而提升数据处理效率。

创建该类型的Service不涉及计费

集群内无法访问Service的说明

当Service设置了服务亲和为节点级别,即externalTrafficPolicy取值为Local时,在使用中可能会碰到从集群内部(节点上或容器中)访问不通的情况,回显类似如下内容:
upstream connect error or disconnect/reset before headers. reset reason: connection failure
或:
curl: (7) Failed to connect to 192.168.10.36 port 900: Connection refused

在集群中访问ELB地址时出现无法访问的场景较为常见,这是由于Kubernetes在创建Service时,kube-proxy会把ELB的访问地址作为外部IP(即External-IP,如下方回显所示)添加到iptables或IPVS中。如果客户端从集群内部发起访问ELB地址的请求,该地址会被认为是服务的外部IP,被kube-proxy直接转发,而不再经过集群外部的ELB。

# kubectl get svc nginx
NAME    TYPE           CLUSTER-IP      EXTERNAL-IP                   PORT(S)        AGE
nginx   LoadBalancer   10.247.76.156   123.**.**.**,192.168.0.133   80:32146/TCP   37s
当externalTrafficPolicy的取值为Local时,在不同容器网络模型和服务转发模式下访问不通的场景如下:
  • 多实例的工作负载需要保证所有实例均可正常访问,否则可能出现概率性访问不通的情况。
  • CCE Turbo集群(云原生2.0网络模型)中,仅当Service的后端对接使用主机网络(HostNetwork)的Pod时,亲和级别支持配置为节点级别。
  • 表格中仅列举了可能存在访问不通的场景,其他不在表格中的场景即表示可以正常访问。

服务端发布服务类型

访问类型

客户端请求发起位置

容器隧道集群(IPVS)

VPC集群(IPVS)

容器隧道集群(IPTABLES)

VPC集群(IPTABLES)

节点访问类型Service

公网/私网

与服务Pod同节点

访问服务端所在节点IP+NodePort — 正常访问

访问非服务端所在节点IP+NodePort — 无法访问

访问服务端所在节点IP+NodePort — 正常访问

访问非服务端所在节点IP+NodePort — 无法访问

访问服务端所在节点IP+NodePort — 正常访问

访问非服务端所在节点IP+NodePort — 无法访问

访问服务端所在节点IP+NodePort — 正常访问

访问非服务端所在节点IP+NodePort — 无法访问

与服务Pod不同节点

访问服务端所在节点IP+NodePort — 正常访问

访问非服务端所在节点IP+NodePort — 无法访问

访问服务端所在节点IP+NodePort — 正常访问

访问客户端所在节点私网IP+NodePort — 正常访问

访问其他节点IP+NodePort ——无法访问

正常访问

正常访问

与服务Pod同节点的其他容器

访问服务端所在节点IP+NodePort — 正常访问

访问非服务端所在节点IP+NodePort — 无法访问

访问服务端所在节点公网IP+NodePort — 正常访问

访问服务端所在节点私网IP+NodePort — 无法访问

访问非服务端所在节点IP+NodePort — 无法访问

访问服务端所在节点IP+NodePort — 正常访问

访问非服务端所在节点IP+NodePort — 无法访问

访问服务端所在节点公网IP+NodePort — 正常访问

访问服务端所在节点私网IP+NodePort — 无法访问

访问非服务端所在节点IP+NodePort — 无法访问

与服务Pod不同节点的其他容器

访问服务端所在节点IP+NodePort — 正常访问

访问客户端所在节点私网IP+NodePort — 正常访问

访问其他节点IP+NodePort ——无法访问

访问服务端所在节点IP+NodePort — 正常访问

访问客户端所在节点私网IP+NodePort — 正常访问

访问其他节点IP+NodePort ——无法访问

访问服务端所在节点IP+NodePort — 正常访问

访问非服务端所在节点IP+NodePort — 无法访问

访问服务端所在节点IP+NodePort — 正常访问

访问非服务端所在节点IP+NodePort — 无法访问

独享型负载均衡类型Service

私网

与服务Pod同节点

无法访问

无法访问

无法访问

无法访问

与服务Pod同节点的其他容器

无法访问

无法访问

无法访问

无法访问

NGINX Ingress控制器插件对接独享型ELB(Local)

私网

与cceaddon-nginx-ingress-controller Pod同节点

无法访问

无法访问

无法访问

无法访问

与cceaddon-nginx-ingress-controller Pod同节点的其他容器

无法访问

无法访问

无法访问

无法访问

解决这个问题通常有如下办法:

  • 推荐)在集群内部访问使用Service的ClusterIP或服务域名访问。
  • 将Service的externalTrafficPolicy设置为Cluster,即集群级别服务亲和。不过需要注意这会影响源地址保持。

    假设Service名称为my-service,命名空间为default,则对应的kubectl命令示例如下:

    kubectl patch service my-service -n default --type='merge' -p '{"spec":{"externalTrafficPolicy":"Cluster"}}'
  • 使用Service的pass-through特性,使用ELB地址访问时绕过kube-proxy,先访问ELB,经过ELB再访问到负载。具体请参见LoadBalancer类型Service使用pass-through能力
    • 在CCE Standard集群中,当使用独享型负载均衡配置pass-through后,从工作负载Pod所在节点或同节点的其他容器中访问ELB的私网IP地址,会出现无法访问的问题。
    • 1.15及以下老版本集群暂不支持该能力。
    • IPVS网络模式下,对接同一个ELB的Service需保持pass-through设置情况一致。
    • 使用节点级别(Local)的服务亲和的场景下,会自动设置kubernetes.io/elb.pass-through为onlyLocal,开启pass-through能力。

相关文档

相关文档