首页 > 其他分享 >kubernetes Headless Services

kubernetes Headless Services

时间:2023-06-21 16:13:06浏览次数:50  
标签:demoapp kubernetes Service headless demo svc Headless DNS Services

Headless Services介绍

有时不需要或不想要负载均衡,以及单独的 Service IP。 遇到这种情况,可以通过显式指定 Cluster IP(spec.clusterIP)的值为 "None" 来创建 Headless Service。

你可以使用一个Headless Service 与其他服务发现机制进行接口,而不必与 Kubernetes 的实现捆绑在一起。

Headless Service 不会获得 Cluster IP,kube-proxy 不会处理这类服务, 而且平台也不会为它们提供负载均衡或路由。 DNS 如何实现自动配置,依赖于 Service 是否定义了标签选择器。

应用场景

StatefulSet控制器对象是Headless Service资源的一个典型应用场景。

有标签选择器的服务

对定义了标签选择器的Headless Service,Kubernetes 控制平面在 Kubernetes API 中创建 EndpointSlice 对象, 并且修改 DNS 配置返回 A 或 AAAA 条记录(IPv4 或 IPv6 地址),这些记录直接指向 Service 的后端 Pod 集合。

无标签选择器的服务

对没有定义标签选择器的Headless Service,控制平面不会创建 EndpointSlice 对象。 然而 DNS 系统会查找和配置以下之一:
对于 type: ExternalName 服务,查找和配置其 CNAME 记录
对所有其他类型的服务,针对 Service 的就绪端点的所有 IP 地址,查找和配置 DNS A / AAAA 条记录
  对于 IPv4 端点,DNS 系统创建 A 条记录。
  对于 IPv6 端点,DNS 系统创建 AAAA 条记录

ExternalName Service

ExternalName Service是一种特殊类型的Service资源,它不需要使用标签选择器关联任何Pod对象,也无须定义任何端口或EndpointSlice,但必须要使用spec.externalName属性定义一个CNAME记录,用于返回真正提供服务的服务名称的别名。ClusterDNS会为这种类型的Service资源自动生成<service>.<ns>.svc.<zone>. <ttl> IN CNAME <extname>.格式的DNS资源记录。
ExternalName用于通过DNS别名将外部服务发布到Kubernetes集群上,这类的DNS别名同本地服务的DNS名称具有相同的形式。因而Pod对象可像发现和访问集群内部服务一样来访问这些发布到集群之上的外部服务,这样隐藏了服务的位置信息,使得各工作负载能够以相同的方式调用本地和外部服务。等到了能够或者需要把该外部服务引入到Kubernetes集群上之时,管理员只需要修改相应ExternalName Service对象的类型为集群本地服务即可。

externalname-svc.yaml

apiVersion: v1
kind: Namespace
metadata:
    name: headless-demo

---
kind: Service
apiVersion: v1
metadata:
  name: externalname-web-svc
  namespace: headless-demo
spec:
  type: ExternalName
  externalName: www.baidu.com
  ports:
  - protocol: TCP
    port: 80
    targetPort: 80
    nodePort: 0
  selector: {}

查看svc资源

# kubectl get svc -n headless-demo
NAME                   TYPE           CLUSTER-IP   EXTERNAL-IP     PORT(S)   AGE
externalname-web-svc   ExternalName   <none>       www.baidu.com   80/TCP    6m21s

查看svc

# kubectl describe svc externalname-web-svc -n headless-demo
Name:              externalname-web-svc
Namespace:         headless-demo
Labels:            <none>
Annotations:       <none>
Selector:          <none>
Type:              ExternalName
IP Families:       <none>
IP:                
IPs:               <none>
External Name:     www.baidu.com
Port:              <unset>  80/TCP
TargetPort:        80/TCP
Endpoints:         <none>
Session Affinity:  None
Events:            <none>

登录client

待Service资源externalname-web-svc创建完成后,各Pod对象即可通过短格式或FQDN格式的Service名称访问相应的服务。DNS会把该名称以CNAME格式解析为.spec.externalName字段中的名称,而后通过DNS服务将其解析为相应主机的IP地址。我们可通过此前Pod对象client-pod对该名称进行解析测试。
# kubectl run client --image=uhub.service.ucloud.cn/xk-base/admin-box -it --rm --restart=Never  -n headless-demo --command -- /bin/sh
root@client #

名称解析

未指定解析类型的,nslookup命令会对解析得到的CNAME结果自动进行更进一步的解析。例如下面命令中,请求解析externalname-web-svc.headless-demo.svc.wgs.local名称得到CNAME格式的结果www.baidu.com将被进一步解析为A记录格式的结果。
root@client # nslookup externalname-web-svc
Server:		10.100.0.2
Address:	10.100.0.2#53

externalname-web-svc.headless-demo.svc.wgs.local	canonical name = www.baidu.com.
www.baidu.com	canonical name = www.a.shifen.com.
Name:	www.a.shifen.com
Address: 110.242.68.4
Name:	www.a.shifen.com
Address: 110.242.68.3

Headless Service

除了为每个Service资源对象在创建时自动指派一个遵循<service>.<ns>.svc.<zone>格式的DNS名称,ClusterDNS还会为Headless Service中的每个端点指派一个遵循<hostname>.<service>.<ns>.svc.<zone>格式的DNS名称,因此,每个Headless Service资源对象的名称都会由ClusterDNS自动生成以下几种类型的资源记录。
根据端点IP地址的类型,在Service名称上为每个IPv4地址的端点生成A记录,为IPv6地址的端点生成AAAA记录。
  <service>.<ns>.svc.<zone>. <ttl> IN A <endpoint-ip>
  <service>.<ns>.svc.<zone>. <ttl> IN AAAA <endpoint-ip>
根据端点IP地址的类型,在端点自身的hostname名称上为每个IPv4地址的端点生成A记录,为IPv6地址的端点生成AAAA记录。
  <hostname>.<service>.<ns>.svc.<zone>. <ttl> IN A <endpoint-ip>
  <hostname>.<service>.<ns>.svc.<zone>. <ttl> IN AAAA <endpoint-ip>
为每个定义了名称的端口生成一个SRV记录,未命名的端口号则不具有该记录。
_<port>._<proto>.<service>.<ns>.svc.<zone>. <ttl> IN SRV <weight> <priority> <portnumber> <service>.<ns>.svc.<zone>.
对于每个给定的每个端点的主机名称的A记录(例如a.b.c.d)或AAAA记录(例如a1a2a3a4:b1b2b3b4:c1c2c3c4:d1d2d3d4:e1e2e3e4:f1f2f3f4:g1g2g3g4:h1h2h3h4),都要生成PTR记录,它们各自的格式如下所示。
  <d>.<c>.<b>.<a>.in-addr.arpa. <ttl> IN PTR <hostname>.<service>.<ns>.svc.<zone>.
  h4.h3.h2.h1.g4.g3.g2.g1.f4.f3.f2.f1.e4.e3.e2.e1.d4.d3.d2.d1.c4.c3.c2.c1.b4.b3.b2.b1.a4.a3.a2.a1.ip6.arpa <ttl> IN PTR <hostname>.<service>.<ns>.svc.<zone>

demoapp-headless-svc.yaml

apiVersion: v1
kind: Namespace
metadata:
    name: demo-headless
---
kind: Service
apiVersion: v1
metadata:
  name: demoapp-headless-svc
  namespace: demo-headless
spec:
  clusterIP: None
  selector:
    app: demoapp
  ports:
  - port: 80
    targetPort: 80
    name: http

depoly-demoapp-v10.yaml

apiVersion: apps/v1
kind: Deployment
metadata:
  labels:
    app: demoappv10
    version: v1.0
  name: demoappv10
  namespace: demo-headless
spec:
  replicas: 3
  selector:
    matchLabels:
      app: demoapp
  strategy: {}
  template:
    metadata:
      creationTimestamp: null
      labels:
        app: demoapp
        version: v1.0
    spec:
      containers:
      - image: ikubernetes/demoapp:v1.0
        imagePullPolicy: IfNotPresent
        name: demoapp
        env:
        - name: PORT
          value: "80"
        resources: {}

创建资源

# kubectl apply -f demoapp-headless-svc.yaml -f depoly-demoapp-v10.yaml
namespace/demo-headless created
service/demoapp-headless-svc created
deployment.apps/demoappv10 created

查看svc资源

# kubectl get svc -n demo-headless -o wide
NAME                   TYPE        CLUSTER-IP   EXTERNAL-IP   PORT(S)   AGE   SELECTOR
demoapp-headless-svc   ClusterIP   None         <none>        80/TCP    40s   app=demoapp

查看pod资源 

# kubectl get pod -n demo-headless -o wide
NAME                         READY   STATUS    RESTARTS   AGE     IP               NODE              NOMINATED NODE   READINESS GATES
demoappv10-597c58f6b-9dfhq   1/1     Running   0          5m20s   172.20.154.241   192.168.174.106   <none>           <none>
demoappv10-597c58f6b-lskz4   1/1     Running   0          5m20s   172.20.89.154    192.168.174.108   <none>           <none>
demoappv10-597c58f6b-rqcqx   1/1     Running   0          5m20s   172.20.44.225    192.168.174.107   <none>           <none>

查看svc信息

我们从其资源详细描述中可以看出,demoapp-headless-svc没有ClusterIP,但因标签选择器能够匹配到Pod资源,因此它拥有端点记录。
# kubectl describe svc demoapp-headless-svc -n demo-headless
Name:              demoapp-headless-svc
Namespace:         demo-headless
Labels:            <none>
Annotations:       <none>
Selector:          app=demoapp
Type:              ClusterIP
IP Family Policy:  SingleStack
IP Families:       IPv4
IP:                None
IPs:               None
Port:              http  80/TCP
TargetPort:        80/TCP
Endpoints:         172.20.154.241:80,172.20.44.225:80,172.20.89.154:80
Session Affinity:  None
Events:            <none>

查看解析

# kubectl run client --image=uhub.service.ucloud.cn/xk-base/admin-box -it --rm --restart=Never  -n demo-headless --command -- /bin/sh
# nslookup demoapp-headless-svc
Server:		10.100.0.2
Address:	10.100.0.2#53

Name:	demoapp-headless-svc.demo-headless.svc.wgs.local
Address: 172.20.89.154
Name:	demoapp-headless-svc.demo-headless.svc.wgs.local
Address: 172.20.154.241
Name:	demoapp-headless-svc.demo-headless.svc.wgs.local
Address: 172.20.44.225
其解析结果正是Headless Service通过标签选择器关联到的所有Pod资源的IP地址。于是,客户端向此Service对象发起的请求将直接接入Pod资源中的应用之上,而不再由Service资源进行代理转发,它每次接入的Pod资源是由DNS服务器接收到查询请求时以轮询方式返回的IP地址。

方向解析

另一方面,每个IP地址的反向解析记录(PTR)对应的FQDN名称是相应端点所在主机的主机名称。对于Kubernetes上的容器来说,其所在主机的主机名是指Pod对象上的主机名称,它由Pod资源的spec.hostname字段和spec.subdomain组合定义,格式为<hostname>.subdomain>.<service>.<ns>.svc.<zone>,其中的<subdomain>可省略。若此两者都未定义,则<hostname>值取自IP地址,IP地址a.b.c.d对应的主机名为a-b-c-d,如下面命令的解析结果所示。
# nslookup -query=PTR 172.20.89.154
Server:		10.100.0.2
Address:	10.100.0.2#53

154.89.20.172.in-addr.arpa	name = 172-20-89-154.demoapp-headless-svc.demo-headless.svc.wgs.local.

参考文档

https://kubernetes.io/zh-cn/docs/concepts/services-networking/service/#headless-services

标签:demoapp,kubernetes,Service,headless,demo,svc,Headless,DNS,Services
From: https://www.cnblogs.com/wangguishe/p/17493975.html

相关文章

  • kubernetes 服务发现
    服务发现概述通常,稍有规模的系统架构需要抽象楚相当数量的服务,这些服务间可能存在复杂的依赖关系和通信模型,考虑到容器编排环境的动态特性,让客户端获知服务端的地址便成了难题之一。kubernetes系统上的Service为pod中的服务类应用提供了一个固定的访问入口,但pod客户端中的应用还......
  • kubernetes API概述·
    API对象组成部分Group+version+resource三个部分组成常见API(一)/api/--------"/api""/api/v1"常见API(二)/apis/--------"/apis/","/apis/admissionregistration.k8s.io","/apis/admissionregistration.k8s.io/v1","......
  • Kubernetes——构建平台工程的利器
    作者|LoftTeam翻译|Seal软件链接|https://loft.sh/blog/why-platform-engineering-teams-should-standardize-on-kubernetes/ 在当今快节奏、不断变化的技术环境中,平台工程团队一直面临着交付新的创新解决方案以满足不断变化的业务需求的压力。最大挑战之一则是管理支持这些......
  • 安装部署 Kubernetes 仪表板(Dashboard)
    简介Kubernetes仪表板(Dashboard)是基于网页的Kubernetes用户界面。你可以使用仪表板:展示了Kubernetes集群中的资源状态信息和所有报错信息。把容器应用部署到Kubernetes集群中。对容器应用排错。管理集群资源。获取运行在集群中的应用的概览信息。创建或者修改Kub......
  • Kubernetes哪一点最打动你?或者,它发布过的哪一项特性让你认为最厉害?
    kubernates打动我的地方应该是他解决了docker的一个痛点,各个docker之间的通信以及集成管理。因为这跟微服务很像,微服务之间也是需要通信和统一管理。知识总是相同的,在这里就体现出来了。用一个例子来演示会更加清晰......
  • kubernetes 生命周期问题分析
    1.Failed --pod里至少一个容器以非0code退出,说明应用有问题,需要debug应用容器2.pending--说明API对象已经被创建和保存在etcd数据库里,但是创建过程出了问题,可能是imagepull出问题,也可能是调度出了问题3.Unknow--说明pod的状态不能持续地被Kubelet发送给kubeapi,这很可能是......
  • kubernetes 资源请求和限制
    1.spec:containers:-name:exampleresources:requests:cpu:100mmemory:64Milimits:cpu:200mmemory:128Mi   例如,一个带有3个容器的pod,每个容器请求0......
  • kubernetes pvc pv 坑
    这里遇到一个问题,开始建立的pv死活claim为空,查看pv以及pvc的配置发现并没有任何名称上的关联,继续研究,发现纯粹是通过storage大小进行匹配的,之前因为照抄书本,一个是5G,一个是8G所以就无法匹配了,修改后成功。用一个例子来演示会更加清晰......
  • Kubernetes——存储
    目录Volume分类示例1:通过emptyDir共享数据示例2:使用HostPath挂载宿主机文件示例3:挂载NFS至容器PersistentVolume基于NFS的PV基于HostPath的PV基于CephRBD的PVPersistentVolumeClaim创建PVC使用PVC动态存储StorageClass定义StorageClass整合StorageClass和CephRBDCSI容器存储接口......
  • (转)kubernetes(k8s) yaml 文件详解2
    原文:https://juejin.cn/post/7202145223014252602#heading-0一、K8S支持的文件格式kubernetes支持YAML和JSON文件格式管理资源对象。JSON格式:主要用于api接口之间消息的传递YAML格式:用于配置和管理,YAML是一种简洁的非标记性语言,内容格式人性化,较易读1、yaml和json的主要区......