(七)Kubernetes Service资源

Service概述

为何要使用Service

Kubernetes Pod是平凡的,由Deployment等控制器管理的Pod对象都是有生命周期的,它们会被建立,也会意外挂掉。虽然它们能够由控制器自动重建或者滚动更新,可是重建或更新以后的Pod对象的IP地址等都会发生新的变化。这样就会致使一个问题,若是一组Pod(称为backend)为其它Pod(称为 frontend)提供服务,那么那些frontend该如何发现,并链接到这组Pod中的哪些backend呢? 这时候就用到了:Servicehtml

示例说明为何要使用Servicenode

以下图所示,当Nginx Pod做为客户端访问Tomcat Pod中的应用时,IP的变更或应用规模的缩减会致使客户端访问错误。而Pod规模的扩容又会使得客户端没法有效的使用新增的Pod对象,从而影响达成规模扩展之目的。为此,Kubernetes特意设计了Service资源来解决此类问题。nginx

Service实现原理

Service资源基于标签选择器将一组Pod定义成一个逻辑组合,并经过本身的IP地址和端口调度代理请求至组内的Pod对象之上,以下图所示,它向客户端隐藏了真实的、处理用户请求的Pod资源,使得客户端的请求看上去就像是由Service直接处理并响应同样。redis

Service对象的IP地址也称为Cluster IP,它位于Kubernetes集群配置指定专用IP地址的范围以内,是一种虚拟IP地址,它在Service对象建立后既保持不变,而且可以被同一集群中的Pod资源所访问。Service端口用于接收客户端请求并将其转发至其后端的Pod中的相应端口之上,所以,这种代理机构也称为“端口代理”(port proxy)或四层代理,工做于TCP/IP协议栈的传输层。算法

Service资源会经过API Server持续监视着(watch)标签选择器匹配到的后端Pod对象,并实时跟踪各对象的变更,例如,IP地址变更、对象增长或减小等。Service并不直接连接至Pod对象,它们之间还有一个中间层——Endpoints资源对象,它是一个由IP地址和端口组成的列表,这些IP地址和端口则来自由Service的标签选择器匹配到的Pod资源。当建立service对象时,其关联的Endpoints对象会自动建立。apache

虚拟IP和服务代理

一个Service对象就是工做节点上的一些iptablesipvs规则,用于将到达Service对象IP地址的流量调度转发至相应的Endpoints对象指定的IP地址和端口之上。kube-proxy组件经过API Server持续监控着各Service及其关联的Pod对象,并将其建立或变更实时反映到当前工做节点上的iptables规则或ipvs规则上。vim

ipvs是借助于Netfilter实现的网络请求报文调度框架,支持rrwrrlcwlcshsednq等十余种调度算法,用户空间的命令行工具是ipvsadm,用于管理工做与ipvs之上的调度规则。后端

Service IP事实上是用于生成iptablesipvs规则时使用的IP地址,仅用于实现Kubernetes集群网络的内部通讯,而且可以将规则中定义的转发服务的请求做为目标地址予以相应,这也是将其称为虚拟IP的缘由之一。api

kube-proxy将请求代理至相应端点的方式有三种:userspace(用户空间)iptablesipvs服务器

userspace代理模式

userspaceLinux操做系统的用户空间。这种模式下,kube-proxy负责跟踪API ServerServiceEndpoints对象的变更(建立或移除),并据此调整Service资源的定义。对于每一个Service对象,它会随机打开一个本地端口(运行于用户控件的kube-proxy进程负责监听),任何到达此端口的链接请求都将代理至当前Service资源后端的各Pod对象上,至于会挑选中哪一个Pod对象则取决于当前Service资源的调度方式(经过ServiceSessionAffinity来肯定),默认的调度算法是轮循(round-robin)。

其代理的过程是:请求到达service后,其被转发至内核空间,经由套接字送往用户空间的kube-proxy,然后再由它送回内核空间,并调度至后端Pod。其传输效率过低,在1.1版本前是默认的转发策略。

iptables代理模式

iptables代理模式中,kube-proxy负责跟踪API ServerServiceEndpoints对象的变更(建立或移除),并据此做出Service资源定义的变更。同时,对于每一个Service对象,它都会建立iptables规则直接捕获到达Cluster IP(虚拟IP)和Port的流量,并将其重定向至当前Service的后端。对于每一个Endpoints对象,Service资源会为其建立iptables规则并关联至挑选的后端Pod资源,默认的调度算法是随机调度(random)。实现基于客户端IP的会话亲和性(来自同一个用户的请求始终调度到后端固定的一个Pod),可将service.spec.sessionAffinity的值设置为“ClientIP”(默认值为“None”)。

其代理过程是:请求到达service后,其请求被相关service上的iptables规则进行调度和目标地址转换(DNAT)后再转发至集群内的Pod对象之上。

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

ipvs代理模式

kube-proxy跟踪API ServerServiceEndpoints对象的变更,据此来调用netlink接口建立ipvs规则,并确保与API Server中的变更保持同步,其请求流量的调度功能由ipvs实现,其他的功能由iptables实现。ipvs支持众多调度算法,如rrlcdhshsednq等。

Service资源的基础应用

建立Service对象的经常使用方法有两种,一是直接使用命令“kubectl expose”命令,二是使用资源清单配置文件。定义Service资源清单文件时,spec的两个较为经常使用的内嵌字段分别是selectorport,分别用于定义使用的标签选择器和要暴露的端口。

1、命令方式定义

1)首先建立一组pod资源

[root@k8s-master ~]# kubectl run nginx --image=nginx:1.12 --replicas=3 #建立pod资源指定副本数量为3个
[root@k8s-master ~]# kubectl get pods -o wide
NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES nginx-67685f79b5-688s7   1/1     Running   0          5s   10.244.2.61   k8s-node2   <none>           <none> nginx-67685f79b5-gpc2f   1/1     Running   0          5s   10.244.1.63   k8s-node1   <none>           <none> nginx-67685f79b5-grlrz   1/1     Running   0          5s   10.244.2.60   k8s-node2   <none>           <none> [root@k8s-master ~]# kubectl get deployment #查看deployment控制器资源
NAME    READY   UP-TO-DATE AVAILABLE AGE nginx 3/3     3            3           35s

2)为其建立对应的service资源

#下面这条命令表示为deployment控制器资源nginx建立一个service对象,并取名为nginx、端口为80、pod内暴露端口80、协议为TCP协议。
[root@k8s-master ~]# kubectl expose deployment nginx --name=nginx --port=80 --target-port=80 --protocol=TCP
service/nginx exposed [root@k8s-master ~]# kubectl get service #查看建立的service资源
NAME         TYPE        CLUSTER-IP       EXTERNAL-IP PORT(S) AGE kubernetes ClusterIP 10.96.0.1        <none>        443/TCP 27d nginx ClusterIP 10.104.116.156   <none>        80/TCP    9s

3)查看生成的endpoints对应关系

[root@k8s-master ~]# kubectl get endpoints
NAME ENDPOINTS AGE kubernetes 192.168.1.31:6443 27d nginx 10.244.1.63:80,10.244.2.60:80,10.244.2.61:80   29s

2、资源清单定义

1)编写资源清单文件(这里先定义一个Deployment控制器资源对象,而后定义Service进行关联)。注:同一个文件编写多个资源对象时,经过---进行分割。

[root@k8s-master ~]# vim manfests/service-demo.yaml
apiVersion: apps/v1 kind: Deployment metadata: name: service-deploy namespace: default spec: replicas: 3 selector: matchLabels: app: service-deploy-demo template: metadata: name: svc-deploy labels: app: service-deploy-demo spec: containers: - name: svc-pod image: ikubernetes/myapp:v1 imagePullPolicy: IfNotPresent ports: - name: http containerPort: 80

---
#定义service
apiVersion: v1 kind: Service metadata: name: service-demo    #service名称
spec: selector: #用于匹配后端的Pod资源对象,需和上面定义pod的标签一致
    app: service-deploy-demo ports: - port: 80    #service端口号
    targetPort: 80    #后端Pod端口号
    protocol: TCP    #使用的协议

2)建立并查看

[root@k8s-master ~]# kubectl apply -f manfests/service-demo.yaml #建立资源对象
deployment.apps/service-deploy created service/service-demo created [root@k8s-master ~]# kubectl get svc #查看service资源对象,"kubectl get svc"等于"kubectl get service"
NAME           TYPE        CLUSTER-IP       EXTERNAL-IP PORT(S) AGE kubernetes ClusterIP 10.96.0.1        <none>        443/TCP 27d nginx ClusterIP 10.104.116.156   <none>        80/TCP 80m service-demo   ClusterIP   10.98.31.157     <none>        80/TCP 7s [root@k8s-master ~]# kubectl get pods -o wide -l app=service-deploy-demo #查看pod资源对象
NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES service-deploy-66548cc57f-982cd   1/1     Running   0          15s   10.244.2.63   k8s-node2   <none>           <none> service-deploy-66548cc57f-blnvg   1/1     Running   0          15s   10.244.1.67   k8s-node1   <none>           <none> service-deploy-66548cc57f-vcmxb   1/1     Running   0          15s   10.244.2.62   k8s-node2   <none>           <none> [root@k8s-master ~]# kubectl get endpoints service-demo 查看生成的endpoints对应关系
NAME ENDPOINTS AGE service-demo   10.244.1.67:80,10.244.2.62:80,10.244.2.63:80   43s

3)节点访问测试(这里使用建立一个新的pod资源模拟客户端进行访问)

Service资源的默认类型为ClusterIP,仅能接收kubernetes集群节点访问、或集群内部的pod对象中的客户端程序访问。

[root@k8s-master ~]# kubectl run busybox --image=busybox --rm -it -- /bin/sh #使用busybox建立一个临时pod客户端
/ # wget -O - -q http://10.98.31.157/ #访问上面建立的service对象的Cluster IP
Hello MyApp | Version: v1 | <a href="hostname.html">Pod Name</a>
/ # for i in 1 2 3 4; do wget -O - -q http://10.98.31.157/hostname.html; done #循环访问测试站点下的hostname.html页面,能够看出是轮循的分配给后端的pod资源。
service-deploy-66548cc57f-982cd service-deploy-66548cc57f-blnvg service-deploy-66548cc57f-982cd service-deploy-66548cc57f-982cd #说明:myapp容器中的“/hostname.html"页面可以输出当前容器的主机名。

Service会话粘性

Service资源支持Session affinity(粘性会话或会话粘性)机制,可以未来自同一个客户端的请求始终转发至同一个后端的Pod对象。这意味着会影响调度算法的流量分发功能,进而下降其负载均衡的效果。因此,当客户端访问pod中的应用程序时,若是有基于客户端身份保存某些私有信息,并基于这些私有信息追踪用户的活动等一类的需求时,就能够启用session affinity机制。

Session affinity的效果仅在一段时间期限内生效,默认值为10800秒,超出此时长以后,客户端的再次访问会被调度算法从新调度。Service资源的Session affinity机制仅能基于客户端的IP地址识别客户端身份,把经由同一个NAT服务器进行源地址转换的全部客户端识别为同一个客户端,便致使调度效果不佳,因此,这种方法并不经常使用。

Service资源经过service.spec.sessionAffinityservice.spec.sessionAffinityConfig两个字段配置粘性会话。sessionAffinity字段用于定义要使用的粘性会话的类型,仅支持使用“None”“ClientIp”两种属性值。

  • None:不使用sessionAffinity,默认值。

  • ClientIP:基于客户端IP地址识别客户端身份,把来自同一个源IP地址的请求始终调度至同一个Pod对象。

 示例

这里将上面建立的service-demo资源对象进行修改

[root@k8s-master ~]# vim manfests/service-demo.yaml
...... spec: selector: app: service-deploy-demo ports: - port: 80 targetPort: 80 protocol: TCP sessionAffinity: ClientIP #指定使用ClientIP
 sessionAffinityConfig: clientIP: timeoutSeconds: 10    #配置session超时时间,这里为了看效果设置的比较短
[root@k8s-master ~]# kubectl apply -f manfests/service-demo.yaml 
deployment.apps/service-deploy unchanged #一样使用pod客户端访问测试
/ # for i in 1 2 3 4; do wget -O - -q http://10.98.31.157/hostname.html; done
service-deploy-66548cc57f-blnvg service-deploy-66548cc57f-blnvg service-deploy-66548cc57f-blnvg service-deploy-66548cc57f-blnvg #等待10秒事后再次访问
/ # for i in 1 2 3 4; do wget -O - -q http://10.98.31.157/hostname.html; done
service-deploy-66548cc57f-vcmxb service-deploy-66548cc57f-vcmxb service-deploy-66548cc57f-vcmxb service-deploy-66548cc57f-vcmxb

Service类型

ServiceIP地址只可以在集群内部可访问,对一些应用(如frontend)的某些部分,可能但愿经过外部(kubernetes集群外部)IP地址暴露Service,这时候就须要使用到NodePortkubernetes ServiceTypes支持四种类型:ClusterIPNodePortLoadBalancerExternalName,其默认是Cluster IP类型。

  • ClusterIP:经过集群内部IP地址暴露服务,此地址仅在集群内部可进行通行,没法被集群外部的客户端访问。

  • NodePort:经过每一个Node上的IP和静态端口(NodePort)暴露服务,会自动为Service分配集群IP地址,并将此做为NodePort的路有目标。经过请求<NodePort>:<NodePort> --> <ClusterIP>:<ClusterPort> --> <PodIP>:<ContainerPort>访问到一个NodePort服务。

  • LoadBalancer:构建在NodePort之上,并建立一个外部负载均衡器,路由到ClusterIP。所以LoadBalancer同样具备NodePortClusterIP

  • EXternalName:经过返回CNAME和它的值,能够将服务映射到externalName字段的内容。换言之,此种类型并不是定义由Kubernetes集群提供的服务,而是把集群外部的某服务以DNS CNAME记录的方式映射到集群内,从而让集群内的Pod资源可以访问外部的Service的一种实现方式。这种类型的Service没有ClusterIPNodePort,也没有标签选择器用于选择Pod资源,所以也不会有Endpoints存在。

ClusterIP类型的Service示例

1)编写配置清单文件(这里使用redis做为示例);先建立一个deployment,启动redis pod;再使用service绑定这个deployment下的pod资源。

[root@k8s-master ~]# vim manfests/redis-svc.yaml #编写yaml格式的清单文件
apiVersion: apps/v1 kind: Deployment metadata: name: redis-deploy namespace: default spec: replicas: 2 selector: matchLabels: app: redis template: metadata: labels: app: redis spec: containers: - name: redis-pod image: redis ports: - name: redis containerPort: 6379
--- apiVersion: v1 kind: Service metadata: name: redis-svc    #service对象名
spec: type: ClusterIP #这里指定使用ClusterIP,默认也是ClusterIP,这里无关紧要
 selector: app: redis #匹配上面定义的pod资源
 ports: - port: 6379    #service端口
    targetPort: 6379    #后端pod端口
    protocol: TCP    #协议
 [root@k8s-master ~]# kubectl apply -f manfests/redis-svc.yaml #建立资源对象
deployment.apps/redis-deploy created service/redis-svc created

2)查看建立的资源对象

[root@k8s-master ~]# kubectl get svc #查看service资源
NAME           TYPE        CLUSTER-IP       EXTERNAL-IP PORT(S) AGE kubernetes ClusterIP 10.96.0.1        <none>        443/TCP 27d nginx ClusterIP 10.104.116.156   <none>        80/TCP 17h redis-svc      ClusterIP   10.102.44.127    <none>        6379/TCP 8s service-demo   ClusterIP   10.98.31.157     <none>        80/TCP 16h [root@k8s-master ~]# kubectl get pods -l app=redis -o wide #查看标签app=redis的pod资源
NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES redis-deploy-6559cc4c4c-5v7kx   1/1     Running   0          33s   10.244.2.65   k8s-node2   <none>           <none> redis-deploy-6559cc4c4c-npdtf   1/1     Running   0          33s   10.244.1.69   k8s-node1   <none>           <none> [root@k8s-master ~]# kubectl describe svc redis-svc #查看redis-svc资源对象详细信息
Name:              redis-svc Namespace: default Labels: <none> Annotations: kubectl.kubernetes.io/last-applied-configuration: {"apiVersion":"v1","kind":"Service","metadata":{"annotations":{},"name":"redis-svc","namespace":"default"},"spec":{"ports":[{"port":6379,"...
Selector:          app=redis Type: ClusterIP IP: 10.102.44.127 Port: <unset>  6379/TCP TargetPort: 6379/TCP Endpoints: 10.244.1.69:6379,10.244.2.65:6379    #能够看出这里已经和上面的pod资源绑定
Session Affinity: None Events: <none>

3)集群内部进行测试

#(1)集群内部的节点上面测试
[root@k8s-master ~]# redis-cli -h 10.102.44.127
10.102.44.127:6379> ping PON #(2)在后端pod上面进行测试
[root@k8s-master ~]# kubectl exec redis-deploy-6559cc4c4c-5v7kx -it -- /bin/sh # redis-cli -h 10.102.44.127
10.102.44.127:6379> ping PONG

NodePort类型的Service示例

NodePort即节点Port,一般在安装部署Kubernetes集群系统时会预留一个端口范围用于NodePort,默认为30000~32767之间的端口。定义NodePort类型的Service资源时,须要使用.spec.type明确指定类型为NodePort

1)编写配置清单文件(这里使用nginx做为示例);先建立一个deployment,启动nginx pod;再使用service绑定这个deployment下的pod资源。

[root@k8s-master ~]# vim manfests/nginx-svc.yaml #编写yaml格式的清单文件
apiVersion: apps/v1 kind: Deployment metadata: name: nginx-deploy namespace: default spec: replicas: 2 selector: matchLabels: app: nginx template: metadata: labels: app: nginx spec: containers: - name: nginx-pod image: nginx:1.12 ports: - name: nginx containerPort: 6379
--- apiVersion: v1 kind: Service metadata: name: nginx-svc    #service对象名
spec: type: NodePort #这里指定使用ClusterIP,默认也是ClusterIP,这里无关紧要
 selector: app: nginx #匹配上面定义的pod资源
 ports: - port: 80    #service端口
    targetPort: 80    #后端pod端口
    nodePort: 30080    #节点端口
    protocol: TCP    #协议
 [root@k8s-master ~]# kubectl apply -f manfests/nginx-svc.yaml #建立资源对象
deployment.apps/nginx-deploy created service/nginx-svc created

2)查看建立的资源对象

[root@k8s-master ~]# kubectl get svc #查看service资源
NAME           TYPE        CLUSTER-IP      EXTERNAL-IP PORT(S) AGE kubernetes ClusterIP 10.96.0.1       <none>        443/TCP 27d nginx-svc      NodePort    10.105.21.137   <none>        80:30080/TCP 4s redis-svc      ClusterIP   10.102.44.127   <none>        6379/TCP 55m service-demo   ClusterIP   10.98.31.157    <none>        80/TCP 16h [root@k8s-master ~]# kubectl get pods -l app=nginx -o wide #查看标签app=nginx的pod资源
NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES nginx-deploy-b6f876447-nlv6h   1/1     Running   0          33s   10.244.1.71   k8s-node1   <none>           <none> nginx-deploy-b6f876447-xmn2t   1/1     Running   0          33s   10.244.2.66   k8s-node2   <none>           <none> [root@k8s-master ~]# kubectl describe svc nginx-svc #查看nginx-svc资源对象详细信息
Name:                     nginx-svc Namespace: default Labels: <none> Annotations: kubectl.kubernetes.io/last-applied-configuration: {"apiVersion":"v1","kind":"Service","metadata":{"annotations":{},"name":"nginx-svc","namespace":"default"},"spec":{"ports":[{"nodePort":30... Selector: app=nginx Type: NodePort IP: 10.105.21.137 Port: <unset>  80/TCP TargetPort: 80/TCP NodePort: <unset>  30080/TCP    #这里能够看到多了NodePort且端口为30080
Endpoints:                10.244.1.71:80,10.244.2.66:80 Session Affinity: None External Traffic Policy: Cluster Events: <none>

3)集群外部进行测试

[root@courtoap ~]# curl 192.168.1.31:30080 #访问集群master节点的30080端口
<!DOCTYPE html>
<html>
<head>
<title>Welcome to nginx!</title>
<style> body { width: 35em; margin: 0 auto; font-family: Tahoma, Verdana, Arial, sans-serif; } </style> [root@courtoap ~]# curl 192.168.1.32:30080 #访问集群node节点的30080端口
<!DOCTYPE html>
<html>
<head>
<title>Welcome to nginx!</title>
<style> body { width: 35em; margin: 0 auto; font-family: Tahoma, Verdana, Arial, sans-serif; } </style>

经过上面的测试能够看到经过NodePort的方式实现了从集群外部端口进行访问,实践中并不建议自定义使用的节点端口,由于容易产生冲突。建议让其自动生成便可。

Headless类型的Service资源

Service对象隐藏了各Pod资源,并负责将客户端请求流量调度至该组Pod对象之上,但也可能存在客户端直接访问Service资源后端的全部Pod资源,这时就应该向客户端暴露每一个Pod资源的IP地址,而不是中间层Service对象的ClusterIP,这种类型的Service资源便称为Headless Service(无头服务)。

Headless Service对象没有ClusterIP,所以便没有相关负载均衡或代理问题,其如何为此类Service配置IP地址,其取决于标签选择器的定义。

  • 具备标签选择器:端点控制器(Endpoints Controller)会在API中为其建立Endpoints记录,并将ClusterDNS服务中的A记录直接解析到此Service后端的各Pod对象的IP地址上。

  • 没有标签选择器:端点控制器(Endpoints Controller)不会再API中为其建立Endpoints记录,ClusterDNS的配置分为两种情形,对ExternalName类型的服务建立CNAME记录,对其余三种类型来讲,为那些与当前Service共享名称的全部Endpoints对象建立一条记录。

Headless类型的Service示例

配置Service资源配置清单时,只须要将ClusterIP字段的值设置为“None”即为其定义为Headless类型。

1)编写配置清单文件(这里使用apache做为示例);先建立一个deployment,启动apache pod;再使用service绑定这个deployment下的pod资源。

[root@k8s-master ~]# vim manfests/httpd-svc-headless.yaml
apiVersion: apps/v1 kind: Deployment metadata: name: httpd-deploy namespace: default spec: replicas: 3 selector: matchLabels: app: httpd template: metadata: labels: app: httpd spec: containers: - name: httpd-pod image: httpd ports: - name: httpd containerPort: 80
--- apiVersion: v1 kind: Service metadata: name: httpd-svc    #service对象名
spec: clusterIP: None #将ClusterIP字段设置为None即表示为headless类型的service资源对象
 selector: app: httpd #匹配上面定义的pod资源
 ports: - port: 80    #service端口
    targetPort: 80    #后端pod端口
    protocol: TCP    #协议
 [root@k8s-master ~]# kubectl apply -f manfests/httpd-svc-headless.yaml 
deployment.apps/httpd-deploy created service/httpd-svc created

2)查看建立的资源对象

[root@k8s-master ~]# kubectl get svc #查看service资源
NAME           TYPE        CLUSTER-IP      EXTERNAL-IP PORT(S) AGE httpd-svc      ClusterIP   None            <none>        80/TCP 4s kubernetes ClusterIP 10.96.0.1       <none>        443/TCP 27d nginx-svc      NodePort    10.105.21.137   <none>        80:30080/TCP 112m redis-svc      ClusterIP   10.102.44.127   <none>        6379/TCP 168m service-demo   ClusterIP   10.98.31.157    <none>        80/TCP 18h [root@k8s-master ~]# kubectl get pods -l app=httpd -o wide #查看标签app=httpd的pod资源
NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES httpd-deploy-5494485b74-4vx64   1/1     Running   0          27s   10.244.2.72   k8s-node2   <none>           <none> httpd-deploy-5494485b74-j6hwm   1/1     Running   0          27s   10.244.2.71   k8s-node2   <none>           <none> httpd-deploy-5494485b74-jn48q   1/1     Running   0          27s   10.244.1.74   k8s-node1   <none>           <none> [root@k8s-master ~]# kubectl describe svc/httpd-svc #查看httpd-svc资源对象详细信息
Name:              httpd-svc Namespace: default Labels: <none> Annotations: kubectl.kubernetes.io/last-applied-configuration: {"apiVersion":"v1","kind":"Service","metadata":{"annotations":{},"name":"httpd-svc","namespace":"default"},"spec":{"clusterIP":"None","por...
Selector:          app=httpd Type: ClusterIP IP: None Port: <unset>  80/TCP TargetPort: 80/TCP Endpoints: 10.244.1.74:80,10.244.2.71:80,10.244.2.72:80 Session Affinity: None Events: <none>

3)测试资源发现

Headless Service工做特性可知,它记录于ClusterDNSA记录的相关解析结果是后端Pod资源的IP地址。意味着客户端经过Service资源的名称发现的是各Pod资源。

#(1)经过建立一个专用的测试Pod资源对象,然后经过其交互式接口进行测试
[root@k8s-master ~]# kubectl run cirror-$RANDOM --rm -it --image=cirros -- /bin/sh
/ # nslookup httpd-svc
Server:    10.96.0.10 Address 1: 10.96.0.10 kube-dns.kube-system.svc.cluster.local Name: httpd-svc Address 1: 10.244.2.71 10-244-2-71.httpd-svc.default.svc.cluster.local Address 2: 10.244.1.74 10-244-1-74.httpd-svc.default.svc.cluster.local Address 3: 10.244.2.72 10-244-2-72.httpd-svc.default.svc.cluster.local #(2)直接在kubernetes集群上解析
[root@k8s-master ~]# dig -t A httpd-svc.default.svc.cluster.local. @10.96.0.10
...... ;; ANSWER SECTION: httpd-svc.default.svc.cluster.local. 26    IN A    10.244.2.72 httpd-svc.default.svc.cluster.local. 26    IN A    10.244.2.71 httpd-svc.default.svc.cluster.local. 26    IN A    10.244.1.74 ......
相关文章
相关标签/搜索