与集群外部服务映射

将Service与集群外部服务映射,即用于令集群内部的资源,如Pod,可以借助Service对象访问外部的服务。

共有两种实现方式:

  1. 外部服务只提供IP地址,则使用Endpoint资源匹配外部服务的IP地址和端口信息,再交由Service对象;

  2. 外部服务提供了完全限定域名(FQDN),则使用spec.type=ExternalName的Service

Endpoint映射外部服务

Service介绍一节中,提到过在Service与Pod之间,有一层Endpoint来负责选择将流量转发至哪些Pod,而默认情况下,Endpoint是由Service的标签选择器负责创建的,它会自动为标签匹配的Pod创建Endpoint资源,并将所有的这些Pod的IP地址和端口信息都记录其中。

因此,若想通过Endpoint实现与外部服务的映射,仅需如下两步即可:

  1. 将Service对象的spec.selector置为空,令该Service对象不会自动创建Endpoint;

  2. 创建与Service对象同名的Endpoint对象,并且将外部服务的IP地址和端口记录其中;

在下图中,集群内部的Pod可以通过访问Service(ClusterIP: 10.108.226.39:80)直接与4个被映射的外部服务进行通信:

使用Endpoint映射外部服务架构

创建无标签选择器的Service

创建的Service的spec.selector为空,令其不会自动创建Endpoint对象。最简单的配置文件案例格式如下,该Service对象的名字为external-service:

apiVersion: v1
kind: Service
metadata:
  name: external-service
spec:
  ports:
  - port: 80

创建Endpoint对象

创建的Endpoint对象需要与Service对象同名,并将外部服务的IP地址和端口记录其中。配置文件案例格式如下,该Endpoint对象与Service对象同名,均为external-service:

apiVersion: v1
kind: Endpoints
metadata:
  name: external-service
subsets:    # 包含了相关的外部服务的IP地址和端口信息
  - addresses:
    - ip: 11.11.11.11
    - ip: 22.22.22.22
    ports:
    - port: 8000
    - port: 8001

Tips: 上面这种配置文件的含义是,可以访问的地址集为:11.11.11.11:8000, 11.11.11.11:8001, 22.22.22.22:8000, 22.22.22.22:8001

ExternalName类型的Service映射外部服务

通过使用spec.type=ExternalName类型的Service对象,可以省去手动创建Endpoint对象的过程,这种Service对象不具备ClusterIP不创建Endpoint资源对象。相当于为服务创建了CNAME记录,在DNS级别进行重定向,将访问服务的FQDN转换为外部服务的FQDN。

使用这种方式的前提是,外部服务有自己的FQDN,spec.externalName中即使填写IP地址,也会被Kubernetes识别为FQDN去进行解析。

如下图,在名为default的命名空间中有如下资源,因此Pod可以通过访问external-service.default.svc.cluster.local(甚至是external-service,至于为什么可以参考Pod发现Service章节中的通过FQDN发现Service)来与someapi.somecompany.com进行通信:

ExternalName类型的Service映射外部服务架构

给出下面这个案例,Service名为external-service:

apiVersion: v1
kind: Service
metadata: 
  name: external-service
spec:
  type: ExternalName    # 修改类型为ExternalName,用来将连接重定向至外部的dns域名
  externalName: someapi.somecompany.com    # 外部的域名
  ports:
  - port: 80

Last updated

Was this helpful?