Service资源管理

目录

1.为什么需要Service资源:

2、  Service

2.1  Service资源概述

2.2    虚拟IP和服务代理

2.3    Service资源的基础应用

2.4   创建Service资源

2.5   向Service对象请求服务

2.6  Service类型

2.6.1    NodePort类型的Service资源

2.6.2    LoadBalancer类型的Service资源

2.6.3   ExternalName Service

2.7   Headless类型的Service资源  (无头service)

2.7.1  创建 Headless Service资源


1.为什么需要Service资源:

  • Pod对象得动态性会给客户端带来困扰
  1. pod资源对象存在生命周期且不可重现,必要时仅能创建一个新的替代者;
  2. pod对象在其控制器进行应用规模伸缩时,同一应用程序的Pod对象会增加或减少;
  • Service资源为动态管理的Pod对象添加一个有着固定访问入口的抽象层
  1. Service通过标签选择器关联至拥有相关标签的Pod对象;
  2. 客户端向Service进行请求,而非目标Pod对象

2、  Service

运行于 Pod 中的部分容器化应用是向客户端提供服务的守护进程,例如, nginx tomcat etcd 等,它们受控于控制器资源对象,存在生命 周期,在自愿或非自愿中断后只能被重构的新 Pod 对象所取代,属于非 可再生类的组件。于是,在动态、弹性的管理模型下, Service 资源用于 为此类 Pod 对象提供一个固定、统一的访问接口及负载均衡的能力,并 支持借助于新一代 DNS 系统的服务发现功能,解决客户端发现并访问容 器化应用的难题。
 
然而, Service Pod 对象的 IP 地址都仅在 Kubernetes 集群内可达,它们无法接入集群外部的访问流量。解决此类问题的办法中,除了在单一 节点上做端口暴露( hostPort )及让 Pod 资源共享使用工作节点的网络名 称空间( hostNetwork )之外,更推荐用户使用的是 NodePort LoadBalancer 类型的 Service 资源,或者是有着七层负载均衡能力的 Ingress 资源。
 
 

2.1  Service资源概述

Deployment 等控制器管理的 Pod 对象中断后会由新建的资源对象所取代,而扩缩容后的应用则会带来 Pod 对象群体的变动,随之变化的 还有 Pod IP 地址访问接口等,这也是编排系统之上的应用程序必然要 面临的问题。例如,当图 6-1 中的 Nginx Pod 作为客户端访问 tomcat Pod 的应用时, IP 的变动或应用规模的缩减会导致客户端访问错误,而 Pod 规模的扩容又会使得客户端无法有效地使用新增的 Pod 对象,从而影响 达成规模扩展之目的。为此, Kubernetes 特地设计了 Service 资源来解决 此类问题。

Service 资源基于标签选择器将一组 Pod 定义成一个逻辑组合,并通过自己的 IP 地址和端口调度代理请求至组内的 Pod 对象之上,如图 6-2 示,它向客户端隐藏了真实的、处理用户请求的 Pod 资源,使得客户端 的请求看上去就像是由 Service 直接处理并进行响应的一样。
 
 
Service 对象的 IP 地址也称为 Cluster IP ,它位于为 Kubernetes 集群配置指定专用 IP 地址的范围之内,而且是一种虚拟 IP 地址,它在 Service 象创建后即保持不变,并且能够被同一集群中的 Pod 资源所访问。 Service 端口用于接收客户端请求并将其转发至其后端的 Pod 中应用的相 应端口之上,因此,这种代理机制也称为 端口代理 port proxy )或四 层代理,它工作于 TCP/IP 协议栈的传输层。
 
通过其标签选择器匹配到的后端 Pod 资源不止一个时, Service 资源能够以负载均衡的方式进行流量调度,实现了请求流量的分发机制。 Service Pod 对象之间的关联关系通过标签选择器以松耦合的方式建 立,它可以先于 Pod 对象创建而不会发生错误,于是,创建 Service Pod 资源的任务可由不同的用户分别完成,例如,服务架构的设计和创建由 运维工程师进行,而填充其实现的 Pod 资源的任务则可交由开发者进 行。 Service 、控制器与 Pod 之间的关系如图 6-3 所示。
 
Service 资源会通过 API Server 持续监视着( watch )标签选择器匹配到的后端 Pod 对象,并实时跟踪各对象的变动,例如, IP 地址变动、对 象增加或减少等。不过,需要特别说明的是, Service 并不直接链接至 Pod 对象,它们之间还有一个中间层 —Endpoints 资源对象,它是一个由 IP 地址和端口组成的列表,这些 IP 地址和端口则来自于由 Service 的标签 选择器匹配到的 Pod 资源。这也是很多场景中会使用 “Service 的后端端 Endpoints )这一术语的原因。默认情况下,创建 Service 资源对象 时,其关联的 Endpoints 对象会自动创建。
 

2.2    虚拟IP和服务代理

简单来讲,一个 Service 对象就是工作节点上的一些 iptables ipvs 规则,用于将到达 Service 对象 IP 地址的流量调度转发至相应的 Endpoints 象指向的 IP 地址和端口之上。工作于每个工作节点的 kube-proxy 组件通 API Server 持续监控着各 Service 及与其关联的 Pod 对象,并将其创建或 变动实时反映至当前工作节点上相应的 iptables ipvs 规则上。客户端、 Service 及其 Pod 对象的关系如图 6-4 所示。

提示 Netfilter Linux 内核中用于管理网络报文的框架,它具有网络地址转换( NAT )、报文改动和报文过滤等防火墙功能,用户 借助于用户空间的 iptables 等工具可按需自由定制规则使用其各项功能。 ipvs 是借助于 Netfilter 实现的网络请求报文调度框架,支持 rr wrr lc wlc sh sed nq 等十余种调度算法,用户空间的命令行工具是 ipvsadm ,用于管理工作于 ipvs 之上的调度规则。
 
Service IP 事实上是用于生成 iptables ipvs 规则时使用的 IP 地址,它仅用于实现 Kubernetes 集群网络的内部通信,并且仅能够将规则中定义 的转发服务的请求作为目标地址予以响应,这也是它被称为虚拟 IP 的原 因之一。 kube-proxy 将请求代理至相应端点的方式有三种: userspace (用户空间)、 iptables ipvs
 
1.userspace 代理模型
此处的 userspace 是指 Linux 操作系统的用户空间。这种模型中,kube-proxy 负责跟踪 API Server Service Endpoints 对象的变动(创建或 移除),并据此调整 Service 资源的定义。对于每个 Service 对象,它会随 机打开一个本地端口(运行于用户空间的 kube-proxy 进程负责监听), 任何到达此代理端口的连接请求都将被代理至当前 Service 资源后端的各 Pod 对象上,至于会挑中哪个 Pod 对象则取决于当前 Service 资源的调度方 式,默认的调度算法是轮询( round-robin ),其工作逻辑如图 6-5 所示。 另外,此类的 Service 对象还会创建 iptables 规则以捕获任何到达 ClusterIP 和端口的流量。在 Kubernetes 1.1 版本之前, userspace 是默认的代理模 型。
 
这种代理模型中,请求流量到达内核空间后经由套接字送往用户空间的 kube-proxy ,而后再由它送回内核空间,并调度至后端 Pod 。这种方 式中,请求在内核空间和用户空间来回转发必然会导致效率不高。
 
 
2.iptables 代理模型

同前一种代理模型类似,iptables代理模型中,kube-proxy负责跟踪API ServerServiceEndpoints对象的变动(创建或移除),并据此做 Service资源定义的变动。同时,对于每个Service,它都会创建iptables 规则直接捕获到达ClusterIPPort的流量,并将其重定向至当前Service的后端,如图6-6所示。对于每个Endpoints对象,Service资源会为其创iptables规则并关联至挑选的后端Pod资源,默认算法是随机调度 random)。iptables代理模式由Kubernetes 1.1版本引入,并自1.2版开始成为默认的类型。

 

在创建Service资源时,集群中每个节点上的kube-proxy都会收到通 知并将其定义为当前节点上的iptables规则,用于转发工作接口接收到的与此Service资源的ClusterIP和端口的相关流量。客户端发来的请求被相 关的iptables规则进行调度和目标地址转换(DNAT)后再转发至集群内 Pod象之上。

相对于用户空间模型来说,iptables模型无须将流量在用户空间和内核空间来回切换,因而更加高效和可靠。不过,其缺点是iptables代理模 型不会在被挑中的后端Pod资源无响应时自动进行重定向,而userspace 模型则可以

 

3.ipvs 代理模型
 

Kubernetes1.9-alpha版本起引入了ipvs代理模型,且自1.11版本起成为默认设置。此种模型中,kube-proxy跟踪API ServerServiceEndpoints对象的变动,据此来调用netlink接口创建ipvs规则,并确保与API Server中的变动保持同步,如图6-7所示。它与iptables规则的不同之处仅在于其请求流量的调度功能由ipvs实现,余下的其他功能仍由iptables完成。

 

类似于iptables模型,ipvs构建于netfilter的钩子函数之上,但它使用hash表作为底层数据结构并工作于内核空间,因此具有流量转发速度快、规则同步性能好的特性。另外,ipvs支持众多调度算法,例如rrlcdhshsednq等。

 

2.3    Service资源的基础应用

Service 资源本身并不提供任何服务,真正处理并响应客户端请求的是后端的 Pod 资源,这些 Pod 资源通常由 各类控制器对象 所创建和管理,因此 Service 资源通常要与控制器资源(最为常用的控制 器之一是 Deployment )协同使用以完成应用的创建和对外发布。
 

2.4   创建Service资源

创建 Service 对象的常用方法有两种:一是直接使用 “kubectl expose” 命令,这在前面 已经介绍过其使用方式;另一个是使用 资源配置文件,它与此前使用资源清单文件配置其他资源的方法类似。 定义 Service 资源对象时, spec 的两个较为常用的内嵌字段分别为 selector ports ,分别用于定义使用的标签选择器和要暴露的端口。下面的配置 清单是一个 Service 资源示例:

[root@master chapter6]# vim myapp-svc.yaml

kind: Service
apiVersion: v1
metadata:
  name: myapp-svc
spec:
  selector:
    app: myapp
  ports:
  - protocol: TCP
    port: 80
    targetPort: 80

Service 资源 myapp-svc 通过标签选择器关联至标签为 “app=myapp” 的各 Pod 对象,它会自动创建名为 myapp-svc Endpoints 资源对象,并自动 配置一个 ClusterIP ,暴露的端口由 port 字段进行指定,后端各 Pod 对象的 端口则由 targetPort 给出,也可以使用同 port 字段的默认值。 myapp-svc 建完成后,使用下面的命令即能获取相关的信息输出以了解资源的状 态:
 

[root@master chapter6]# kubectl apply -f myapp-svc.yaml
service/myapp-svc created

[root@master chapter6]# kubectl get svc myapp-svc
NAME        TYPE        CLUSTER-IP      EXTERNAL-IP   PORT(S)   AGE
myapp-svc   ClusterIP   10.107.27.178   <none>        80/TCP    39s

[root@master chapter6]# curl 10.107.27.178
Hello MyApp | Version: v3 | <a href="hostname.html">Pod Name</a>

上面命令中的结果显示, myapp-svc 的类型为默认的 ClusterIP ,其使用的地址自动配置为10.107.27.178 。此类型的 Service 对象仅能通过此 IP 地址接受来自于集群内的客户端 Pod 中的请求。若集群上存在标签 “app=myapp” Pod 资源,则它们会被关联和创建,作为此 Service 对象 的后端 Endpoint 对象,并负责接收相应的请求流量。类似下面的命令可 用于获取 Endpoint 资源的端点列表,其相关的端点是由 Deployment 控制器创建的 Pod 对象的套接字信息组成的:

[root@master chapter6]# kubectl get endpoints myapp-svc
NAME        ENDPOINTS                                                 AGE
myapp-svc   10.244.1.19:80,10.244.1.6:80,10.244.2.23:80 + 1 more...   2m33s      # 10.244.1.19:80,10.244.1.6:80,10.244.2.23:80这三个地址分别指向了后端的三个pod可以通过下面的命令查看下pod的地址

[root@master chapter6]# kubectl get pods -o wide|grep myapp   
myapp-deploy-77dcc456d9-5hpg7   1/1     Running            0          47h     10.244.1.19   node1   <none>           <none>
myapp-deploy-77dcc456d9-lqzpt   1/1     Running            0          47h     10.244.2.23   node2   <none>           <none>
myapp-deploy-77dcc456d9-nprbj   1/1     Running            0          47h     10.244.2.24   node2   <none>           <none>

[root@master chapter6]# kubectl describe svc myapp  
Name:              myapp-svc
Namespace:         default
Labels:            <none>
Annotations:       <none>
Selector:          app=myapp
Type:              ClusterIP
IP:                10.107.27.178
Port:              <unset>  80/TCP
TargetPort:        80/TCP    #本地80端口
Endpoints:         10.244.1.19:80,10.244.1.6:80,10.244.2.23:80 + 1 more...    #创建svc时会默认去创建endpoints,而这里关联的则是endpoints的地址
Session Affinity:  None
Events:            <none>

提示 也可以不为 Service 资源指定 .spec.selector 属性值,其关 联的 Pod 资源可由用户手动创建 Endpoints 资源进行定义。
 
Service 对象创建完成后即可作为服务被各客户端访问,但要真正响应这些请求,还是要依赖于各后端的资源对象。
 
 

2.5   向Service对象请求服务

Service 资源的默认类型为 ClusterIP ,它仅能接收来自于集群中的Pod 对象中的客户端程序的访问请求。下面创建一个专用的 Pod 对象,利 用其交互式接口完成访问测试。为了简单起见,这里选择直接创建一个 临时使用的 Pod 对象作为交互式使用的客户端进行,它使用 CirrOS 像,默认的命令提示符为 “/#”

[root@master chapter6]#  kubectl run cirros-$RANDOM --rm -it --image=cirros -- sh
If you don't see a command prompt, try pressing enter.
/ #

提示 CirrOS 是设计用来进行云计算环境测试的 Linux 微型发行版,它拥有 HTTP 客户端工具 curl 等。
 
而后,在容器的交互式接口中使用 crul 命令对 myapp-svc 服务的ClusterIP 10.107.208.93 )和 Port 80/tcp )发起访问请求测试:

/ # curl http://10.107.27.178:80/
Hello MyApp | Version: v3 | <a href="hostname.html">Pod Name</a>

myapp 容器中的 “/hostname.html” 页面能够输出当前容器的主机名,可反复向 myapp-svc 的此 URL 路径发起多次请求以验证其调度的效果:

/ # for loop in 1 2 3 ; do curl http://10.107.27.178:80/hostname.html;done
myapp-deploy-77dcc456d9-5hpg7
myapp-deploy-77dcc456d9-nprbj
myapp-deploy-77dcc456d9-nprbj

当前 Kubernetes 集群的 Service 代理模式为 iptables ,它默认使用随机调度算法,因此 Service 会将客户端请求随机调度至与其关联的某个后端 Pod 资源上。命令取样次数越大,其调度效果也越接近于算法的目标效
 

2.6  Service类型

  • KubernetesService共有四种类型:ClusterIPNodePort、LoadBalancerExternalName
  • ClusterIP:通过集群内部IP地址暴露服务,此地址仅在集群内部可达,而无法被集群外部的客户端访问,如图6-8所示。此为默认的Service类型。
  • NodePort:这种类型建立在ClusterIP类型之上,其在每个节点的IP地址的某静态端口(NodePort)暴露服务,因此,它依然会为Service配集群IP地址,并将此作为NodePort的路由目标。简单来说,NodePort类型就是在工作节点的IP地址上选择一个端口用于将集群外部的用户请求转发至目标ServiceClusterIPPort,因此,这种类型的Service既可ClusterIP一样受到集群内部客户端Pod的访问,也会受到集群外部客 户端通过套接字<NodeIP>: <NodePort>进行的请求。
 
  • LoadBalancer:这种类型建构在NodePort类型之上,其通过cloudprovider提供的负载均衡器将服务暴露到集群外部,因此LoadBalancer样具有NodePortClusterIP。简而言之,一个LoadBalancer类型的 Service会指向关联至Kubernetes集群外部的、切实存在的某个负载均衡 设备,该设备通过工作节点之上的NodePort向集群内部发送请求流量,如图6-9所示。例如Amazon云计算环境中的ELB实例即为此类的负载均 衡设备。此类型的优势在于,它能够把来自于集群外部客户端的请求调 度至所有节点(或部分节点)的NodePort之上,而不是依赖于客户端自 行决定连接至哪个节点,从而避免了因客户端指定的节点故障而导致的服务不可用。
  • ExternalName:其通过将Service映射至由externalName字段的内容指定的主机名来暴露服务,此主机名需要被DNS服务解析至CNAME型的记录。换言之,此种类型并非定义由Kubernetes集群提供的服务, 而是把集群外部的某服务以DNS CNAME记录的方式映射到集群内,从而让集群内的Pod资源能够访问外部的Service的一种实现方式,如图6-10所示。因此,这种类型的Service没有ClusterIPNodePort,也没有标签选择器用于选择Pod资源,因此也不会有Endpoints存在。

 

 
 
前面章节中创建的 myapp-svc 即为默认的 ClusterIP 类型 Service 资源,它仅能接收来自于集群中的 Pod 对象中的客户端程序的访问请求。如若 需要将 Service 资源发布至网络外部,应该将其配置为 NodePort LoadBalancer 类型,而若要把外部的服务发布于集群内容供 Pod 对象使 用,则需要定义一个 ExternalName 类型的 Service 资源。如若使用 kube- dns ,那么这种类型的实现将依赖于 1.7 及其以上版本的 Kubernetes 版本。
 

2.6.1    NodePort类型的Service资源

NodePort 即节点 Port ,通常在安装部署 Kubernetes 集群系统时会预留一个端口范围用于 NodePort ,默认为 30000 32767 之间的端口。与 ClusterIP 类型的可省略 .spec.type 属性所不同的是,定义 NodePort 类型的 Service 资源时,需要通过此属性明确指定其类型名称。例如,下面配置 清单中定义的 Service 资源对象 myapp-svc-nodeport ,它使用了 NodePort 型,且人为指定其节点端口为 32223

[root@master chapter6]# vim myapp-svc-nodeport.yaml

kind: Service
apiVersion: v1
metadata:
  name: myapp-svc-nodeport
spec:
  type: NodePort
  selector:
    app: myapp
  ports:
  - protocol: TCP
    port: 80
    targetPort: 80
    nodePort: 32223

[root@master chapter6]# kubectl apply -f myapp-svc-nodeport.yaml
service/myapp-svc-nodeport created

实践中,并不鼓励用户自定义使用的节点端口,除非事先能够明确知道它不会与某个现存的 Service 资源产生冲突。无论如何,只要没有特 别需求,留给系统自动配置总是较好的选择。使用创建命令创建上面的 Service 对象后即可了解其运行状态

[root@master chapter6]# kubectl get svc myapp-svc-nodeport
NAME                 TYPE       CLUSTER-IP      EXTERNAL-IP   PORT(S)        AGE
myapp-svc-nodeport   NodePort   10.96.205.132   <none>        80:32223/TCP   19s

命令结果显示, NodePort 类型的 Service 资源依然会被配置ClusterIP ,事实上,它会作为节点从 NodePort 接入流量后转发的目标地 址,目标端口则是与 Service 资源对应的 spec.ports.port 属性中定义的端 口,如图 6-11 所示。
 
 
因此,对于集群外部的客户端来说,它们可经由任何一个节点的节点 IP 及端口访问 NodePort 类型的 Service 资源,而对于集群内的 Pod 客户 端来说,依然可以通过 ClusterIP 对其进行访问。
 
测试结果:
 

 

2.6.2    LoadBalancer类型的Service资源

NodePort 类型的 Service 资源虽然能够于集群外部访问得到,但外部客户端必须得事先得知 NodePort 和集群中至少一个节点的 IP 地址,且选 定的节点发生故障时,客户端还得自行选择请求访问其他的节点。另 外,集群节点很可能是某 IaaS 云环境中使用私有 IP 地址的 VM ,或者是 IDC 中使用私有地址的物理机,这类地址对互联网客户端不可达,因 此,一般还应该在集群之外创建一个具有公网 IP 地址的负载均衡器,由 它接入外部客户端的请求并调度至集群节点相应的 NodePort 之上。
 
IaaS 云计算环境通常提供了 LBaaS Load Balancer as a Service )服务,它允许租户动态地在自己的网络中创建一个负载均衡设备。那些部 署于此类环境之上的 Kubernetes 集群在创建 Service 资源时可以直接调用 此接口按需创建出一个软负载均衡器,而具有这种功能的 Service 资源即 LoadBalancer 类型。不过,如果 Kubernetes 部署于裸的物理服务器之 上,系统管理员也可以自行手动部署一个负载均衡器(推荐使用冗余配 置),并配置其将请求流量调度至各节点的 NodePort 之上即可。
 
下面是一个 LoadBalancer 类型的 Service 资源配置清单,若 Kubernetes系统满足其使用条件,即可自行进行应用测试。需要注意的是,有些环 境中可能还需要为 Service 资源的配置定义添加 Annotations ,必要时请自 行参考 Kubernetes 文档中的说明:

[root@master chapter6]# vim myapp-svc-lb.yaml

kind: Service
apiVersion: v1
metadata:
  name: myapp-svc-lb
spec:
  selector:
    app: myapp
  ports:
  - protocol: TCP
    port: 80
    targetPort: 80

进一步地,在 IaaS 环境支持手动指定 IP 地址时,用户还可以使用 .spec.loadBalancerIP 指定创建的负载均衡器使用的 IP地址,并可使 .spec.loadBalancerSourceRanges 指定负载均衡器允许的客户端来源的 地址范围。


2.6.3   ExternalName Service

ExternalName 类型的 Service 资源用于将集群外部的服务发布到集群中以供 Pod 中的应用程序访问,因此,它不需要使用标签选择器关联任 何的 Pod 对象,但必须要使用 spec.externalName 属性定义一个 CNAME 录用于返回外部真正提供服务的主机的别名,而后通过 CNAME 记录值 获取到相关主机的 IP 地址。
下面是一个 ExternalName 类型的 Service 资源示例,名为 external-redis-svc ,相应的 externalName “redis.ilinux.io”

[root@master chapter6]# vim external-redis.yaml

kind: Service
apiVersion: v1
metadata:
  name: external-www-svc
  namespace: default
spec:
  type: ExternalName
  externalName: www.kubernetes.io
  ports:
  - protocol: TCP
    port: 6379
    targetPort: 6379
    nodePort: 0
  selector: {}

[root@master chapter6]# kubectl apply -f external-redis.yaml
service/external-www-svc created

Service 资源 external-redis-svc 创建完成后,各 Pod 对象即可通过www.kubernetes.io 访问相应的服务。ClusterDNS 会将此名称以 CNAME 格式解析为 .spec.externalName 字段中的名称,而后通过 DNS 务将其解析为相应的主机的 IP 地址。例如,通过此前创建的交互 Pod 源客户端进行服务名称解析:

[root@master chapter6]# nslookup www.kubernetes.io
Server:        183.60.83.19
Address:    183.60.83.19#53

Non-authoritative answer:
www.kubernetes.io    canonical name = kubernetes.io.
Name:    kubernetes.io
Address: 147.75.40.148

由于 ExternalName 类型的 Service 资源实现于 DNS级别,客户端将直 接接入外部的服务而完全不需要服务代理,因此,它也无须配置 ClusterIP ,此种类型的服务也称为 Headless Service


2.7   Headless类型的Service资源  (无头service)

Service对象隐藏了各Pod资源,并负责将客户端的请求流量调度至该组Pod对象之上。不过,偶尔也会存在这样一类需求:客户端需要直 接访问Service资源后端的所有Pod资源,这时就应该向客户端暴露每个 Pod资源的IP地址,而不再是中间层Service对象的ClusterIP,这种类型 Service资源便称为Headless Service

Headless Service对象没有ClusterIP,于是kube-proxy便无须处理此 类请求,也就更没有了负载均衡或代理它的需要。在前端应用拥有自有 的其他服务发现机制时,Headless Service即可省去定义ClusterIP的需 求。至于如何为此类Service资源配置IP地址,则取决于它的标签选择器的定义。

  • 具有标签选择器:端点控制器(Endpoints Controller)会在API中为其创建Endpoints记录,并将ClusterDNS服务中的A记录直接解析到此 Service后端的各Pod对象的IP地址上。
  • 没有标签选择器:端点控制器(Endpoints Controller)不会在API中为其创建Endpoints记录,ClusterDNS的配置分为两种情形,对 ExternalName类型的服务创建CNAME记录,对其他三种类型来说,为 那些与当前Service共享名称的所有Endpoints对象创建一条记录。

2.7.1  创建 Headless Service资源

配置 Service 资源配置清单时,只需要将 ClusterIP 字段的值设置为 “None” 即可将其定义为 Headless 类型。下面是一个 Headless Service 源配置清单示例,它拥有标签选择器:

[root@master chapter6]# vim myapp-headless-svc.yaml

kind: Service
apiVersion: v1
metadata:
  name: myapp-headless-svc
spec:
  clusterIP: None
  selector:
    app: myapp
  ports:
  - port: 80
    targetPort: 80
    name: httpport

[root@master chapter6]# kubectl apply -f myapp-headless-svc.yaml
service/myapp-headless-svc created

 

 

使用资源创建命令 “kubectl create” “kubectl apply” 完成资源创建后,使用相关的查看命令获取 Service 资源的相关信息便可以看出,它没 ClusterIP ,不过,如果标签选择器能够匹配到相关的 Pod 资源,它便 拥有 Endpoints 记录,这些 Endpoints 对象会作为 DNS 资源记录名称 myapp- headless-svc 查询时的 A 记录解析结果:

[root@master chapter6]# kubectl get svc myapp-headless-svc
NAME                 TYPE        CLUSTER-IP   EXTERNAL-IP   PORT(S)   AGE
myapp-headless-svc   ClusterIP   None         <none>        80/TCP    45s

验证:随便连接一个容器内部  这里访问服务的名称是直接和pod通信的

[root@master chapter6]# kubectl exec -it myapp-pod -- /bin/sh
/ # cat /etc/resolv.conf
nameserver 10.96.0.10
search default.svc.cluster.local svc.cluster.local cluster.local
options ndots:5
/ # nslookup myapp-headless-svc
nslookup: can't resolve '(null)': Name does not resolve

Name:      myapp-headless-svc
Address 1: 10.244.1.6 myapp-pod
Address 2: 10.244.1.19 10-244-1-19.myapp-headless-svc.default.svc.cluster.local
Address 3: 10.244.2.23 10-244-2-23.myapp-headless-svc.default.svc.cluster.local
Address 4: 10.244.2.24 10-244-2-24.myapp-svc.default.svc.cluster.local
/ #

 

 
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值