1、概述

  在《Kubernetes Headless服务》这篇博文中对Kubenertes Service资源类型进行了概述并详细介绍了Headless服务,通过这篇博文我们可以知道Service一般分为3种类型:ClusterIP、NodePort、LoadBalancer,唯独对 ExternalName 置若罔闻,本文将详细介绍Kubernetes ExternalName类型的服务。

  ExternalName Service是Kubernetes中一个特殊的service类型,它不需要指定selector去选择哪些pods实例提供服务,而是使用DNS CNAME机制把服务请求透明地重定向到指定的DNS名称,无论该名称指向的是外部服务还是集群内的其他服务,例如第三方 API 服务、外部数据库,或跨命名空间的内部服务。在配置上,只需将 Service 的 type 设置为 ExternalName 并指定 externalName 字段即可。ExternalName Service 简化了对不同 DNS名称资源的访问配置,使得服务依赖的地址变化对集群内的应用透明,但不提供负载均衡和服务发现功能。

2、工作机制

  • 当访问 ExternalName Service 时,Kubernetes 的 DNS 解析返回一个 CNAME 记录。
  • 这个 CNAME 记录将请求重定向到指定的 DNS 名称,从而实现服务的透明重定向。

知识普及:DNS  CName(CanonicalName)记录,简称CNAME记录。也叫别名级联,如同给人起的外号一样,小名一样,如你的名字:叫张小明,你家人叫你小明,也是指的是你。

  CNAME也被称为规范名字。CNAME记录允许您将多个名字映射到同一台计算机。 通常用于同时提供WWW和MAIL服务的计算机。例如,有一台计算机名为“host.pt6.cn”(A记录)。 它同时提供WWW和MAIL服务,为了便于用户访问服务。可以为该计算机设置两个cname别名(CNAME):WWW和MAIL。 这两个别名的全称就是“ www.pt6.cn”和“mail.pt6.cn” 。实际上他们都指向“host.pt6.cn”。 同样的方法可以用于当您拥有多个域名需要指向同一服务器IP,此时您就可以将一个域名做A记录DNS解析指向服务器IP然后将其他的域名做cname记录别名到之前做A记录的域名上,那么当您的服务器IP地址变更时您就可以不必麻烦的一个一个域名更改指向了,只需要更改做A记录DNS解析的那个域名,而其他做cname别名DNS解析的那些域名的指向也将自动更改到新的IP地址上了。

3、配置

通过 spec.type 字段设置为 ExternalName,并在 spec.externalName 字段中指定目标 DNS 名称。

apiVersion: v1
kind: Service
metadata:
  name: my-service
  namespace: default
spec:
  type: ExternalName
  externalName: my.external.service.com

在这个示例中,my-service 是一个 ExternalName Service,它将请求重定向到 my.external.service.com。

4、示例

编辑external_name.yaml文件如下:

apiVersion: v1
kind: Namespace
metadata:
  name: dev

---

apiVersion: v1
kind: Service
metadata:
  name: search
  namespace: dev
spec:
  type: ExternalName
  externalName: www.baidu.com

使用如下命令创建资源:

[root@master service]# kubectl apply -f external_name.yaml
namespace/dev created
service/search created

查看资源如下:

[root@master service]# kubectl get service -n dev
NAME     TYPE           CLUSTER-IP   EXTERNAL-IP     PORT(S)   AGE
search   ExternalName   <none>       www.baidu.com   <none>    11s

此时,在集群内部的pod中就可以通过 search.dev.svc.cluster.local 访问www.baidu.com了,下面验证一下,首先登录一个pod查看 /etc/resolve.conf:

[root@master service]# kubectl exec -it pod/pc-deployment-6gdc5bf56c-9bg6w -n dev /bin/bash
kubectl exec [POD] [COMMAND] is DEPRECATED and will be removed in a future version. Use kubectl exec [POD] -- [COMMAND] instead.
root@pc-deployment-5ffc5bf56c-9bg6w:/#
root@pc-deployment-5ffc5bf56c-9bg6w:/# cat /etc/resolv.conf
nameserver 10.96.0.10
search dev.svc.cluster.local svc.cluster.local cluster.local
options ndots:5

然后使用dig命令验证:

[root@master service]# dig @10.96.0.10 search.dev.svc.cluster.local

; <<>> DiG 9.11.4-P2-RedHat-9.11.4-26.P2.el7_9.9 <<>> @10.96.0.10 search.dev.svc.cluster.local
; (1 server found)
;; global options: +cmd
;; Got answer:
;; WARNING: .local is reserved for Multicast DNS
;; You are currently testing what happens when an mDNS query is leaked to DNS
;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 62861
;; flags: qr aa rd; QUERY: 1, ANSWER: 4, AUTHORITY: 0, ADDITIONAL: 1
;; WARNING: recursion requested but not available

;; OPT PSEUDOSECTION:
; EDNS: version: 0, flags:; udp: 4096
;; QUESTION SECTION:
;search.dev.svc.cluster.local.  IN      A

;; ANSWER SECTION:
search.dev.svc.cluster.local. 30 IN     CNAME   www.baidu.com.
www.baidu.com.          30      IN      CNAME   www.a.shifen.com.
www.a.shifen.com.       30      IN      A       110.242.68.3
www.a.shifen.com.       30      IN      A       110.242.68.4

;; Query time: 5 msec
;; SERVER: 10.96.0.10#53(10.96.0.10)
;; WHEN: Wed Apr 06 23:48:14 CST 2022
;; MSG SIZE  rcvd: 219

5、使用场景 

  • 外部资源访问: 将集群内服务请求重定向到外部资源,例如第三方 API 服务、外部数据库等。
  • 内部资源访问: 在多集群或多命名空间环境中,将服务请求重定向到不同命名空间或不同集群内的服务。
  • 服务迁移与重构: 在服务迁移过程中,临时将请求重定向到新的服务地址,确保服务的连续性和透明性。

6、总结

  ExternalName Service 是 Kubernetes 中一种灵活的服务类型,通过 DNS CNAME 机制将请求重定向到指定的 DNS 名称。它适用于需要透明地访问外部或内部 DNS 资源的场景,简化了服务访问配置,使得服务依赖的地址变化对应用透明。