1 Service 概述 1.1 为什么要使用Service
Kubernetes Pod是平凡的,由Deployment等控制器管理的Pod对象都是有生命周期的,它们会被创建,也会意外挂掉。虽然它们可以由控制器自动重建或者滚动更新,但是重建或更新之后的Pod对象的IP地址等都会发生新的变化。这样就会导致一个问题,如果一组Pod(称为backend)为其它Pod(称为 frontend)提供服务,那么那些frontend该如何发现,并连接到这组Pod中的哪些backend呢? 这时候就用到了:Service
示例说明为什么要使用Service
如下图所示,当Nginx Pod作为客户端访问Tomcat Pod中的应用时,IP的变动或应用规模的缩减会导致客户端访问错误。而Pod规模的扩容又会使得客户端无法有效的使用新增的Pod对象,从而影响达成规模扩展之目的。为此,Kubernetes特地设计了Service资源来解决此类问题。
1.2 Service实现原理 Service资源基于标签选择器将一组Pod定义成一个逻辑组合,并通过自己的IP地址和端口调度代理请求至组内的Pod对象之上,如下图所示,它向客户端隐藏了真实的、处理用户请求的Pod资源,使得客户端的请求看上去就像是由Service直接处理并响应一样。
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对象会自动创建。
1.3 虚拟IP和服务代理 一个Service对象就是工作节点上的一些iptables或ipvs规则,用于将到达Service对象IP地址的流量调度转发至相应的Endpoints对象指定的IP地址和端口之上。kube-proxy组件通过API Server持续监控着各Service及其关联的Pod对象,并将其创建或变动实时反映到当前工作节点上的iptables规则或ipvs规则上。
ipvs是借助于Netfilter实现的网络请求报文调度框架,支持rr、wrr、lc、wlc、sh、sed和nq等十余种调度算法,用户空间的命令行工具是ipvsadm,用于管理工作与ipvs之上的调度规则。
Service IP事实上是用于生成iptables或ipvs规则时使用的IP地址,仅用于实现Kubernetes集群网络的内部通信,并且能够将规则中定义的转发服务的请求作为目标地址予以相应,这也是将其称为虚拟IP的原因之一。
kube-proxy将请求代理至相应端点的方式有三种:userspace(用户空间) 、iptables 和ipvs 。
1.3.1 userspace代理模式 userspace是Linux操作系统的用户空间。这种模式下,kube-proxy负责跟踪API Server上Service和Endpoints对象的变动(创建或移除),并据此调整Service资源的定义。对于每个Service对象,它会随机打开一个本地端口(运行于用户控件的kube-proxy进程负责监听),任何到达此端口的连接请求都将代理至当前Service资源后端的各Pod对象上,至于会挑选中哪个Pod对象则取决于当前Service资源的调度方式(通过Service的SessionAffinity来确定),默认的调度算法是轮循(round-robin)。
其代理的过程是:请求到达service后,其被转发至内核空间,经由套接字送往用户空间的kube-proxy,而后再由它送回内核空间,并调度至后端Pod。其传输效率太低,在1.1版本前是默认的转发策略。
1.3.2 iptables代理模式 iptables代理模式中,kube-proxy负责跟踪API Server上Service和Endpoints对象的变动(创建或移除),并据此作出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模式则可以。
1.3.3 ipvs代理模式 kube-proxy跟踪API Server上Service的Endpoints对象的变动,据此来调用netlink接口创建ipvs规则,并确保与API Server中的变动保持同步,其请求流量的调度功能由ipvs实现,其余的功能由iptables实现。ipvs支持众多调度算法,如rr、lc、dh、sh、sed和nq等。
2 Service资源的基础应用 创建Service对象的常用方法有两种,一是直接使用命令“kubectl expose”命令,二是使用资源清单配置文件。定义Service资源清单文件时,spec的两个较为常用的内嵌字段分别是selector和port,分别用于定义使用的标签选择器和要暴露的端口。
一、命令方式定义
1)首先创建一组pod资源
1 2 3 4 5 6 7 8 9 [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资源
1 2 3 4 5 6 7 # 下面这条命令表示为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对应关系
1 2 3 4 [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
二、资源清单定义
1)编写资源清单文件(这里先定义一个Deployment控制器资源对象,然后定义Service进行关联)。注:同一个文件编写多个资源对象时,通过—进行分割。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 [root@k8s-master ~ ] 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 --- apiVersion: v1 kind: Service metadata: name: service-demo spec: selector: app: service-deploy-demo ports: - port: 80 targetPort: 80 protocol: TCP
2)创建并查看
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 [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对象中的客户端程序访问。
1 2 3 4 5 6 7 8 9 10 [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"页面能够输出当前容器的主机名。
2.1 Service会话粘性 Service资源支持Session affinity(粘性会话或会话粘性)机制,能够将来自同一个客户端的请求始终转发至同一个后端的Pod对象。这意味着会影响调度算法的流量分发功能,进而降低其负载均衡的效果。所以,当客户端访问pod中的应用程序时,如果有基于客户端身份保存某些私有信息,并基于这些私有信息追踪用户的活动等一类的需求时,就可以启用session affinity机制。
Session affinity的效果仅在一段时间期限内生效,默认值为10800秒,超出此时长之后,客户端的再次访问会被调度算法重新调度。Service资源的Session affinity机制仅能基于客户端的IP地址识别客户端身份,把经由同一个NAT服务器进行源地址转换的所有客户端识别为同一个客户端,便导致调度效果不佳,所以,这种方法并不常用。
Service资源通过service.spec.sessionAffinity和service.spec.sessionAffinityConfig两个字段配置粘性会话。sessionAffinity字段用于定义要使用的粘性会话的类型,仅支持使用“None”和“ClientIp”两种属性值。
示例
这里将上面创建的service-demo资源对象进行修改
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 [root@k8s-master ~ ] ...... spec: selector: app: service-deploy-demo ports: - port: 80 targetPort: 80 protocol: TCP sessionAffinity: ClientIP sessionAffinityConfig: clientIP: timeoutSeconds: 10 [root@k8s-master ~ ] deployment.apps/service-deploy unchanged / service-deploy-66548cc57f-blnvg service-deploy-66548cc57f-blnvg service-deploy-66548cc57f-blnvg service-deploy-66548cc57f-blnvg / service-deploy-66548cc57f-vcmxb service-deploy-66548cc57f-vcmxb service-deploy-66548cc57f-vcmxb service-deploy-66548cc57f-vcmxb
2.2 类型 1 Service`的`IP`地址只能够在集群内部可访问,对一些应用(如`frontend`)的某些部分,可能希望通过外部(`kubernetes`集群外部)`IP`地址暴露`Service`,这时候就需要使用到`NodePort`。`kubernetes
ServiceTypes支持四种类型:ClusterIP、NodePort、LoadBalancer、ExternalName,其默认是Cluster IP类型。
ClusterIP :通过集群内部IP地址暴露服务,此地址仅在集群内部可进行通行,无法被集群外部的客户端访问。
NodePort :通过每个Node上的IP和静态端口(NodePort)暴露服务,会自动为Service分配集群IP地址,并将此作为NodePort的路有目标。通过请求<NodePort>:<NodePort> --> <ClusterIP>:<ClusterPort> --> <PodIP>:<ContainerPort>访问到一个NodePort服务。
LoadBalancer :构建在NodePort之上,并创建一个外部负载均衡器,路由到ClusterIP。因此LoadBalancer一样具有NodePort和ClusterIP。
EXternalName :通过返回CNAME和它的值,可以将服务映射到externalName字段的内容。换言之,此种类型并非定义由Kubernetes集群提供的服务,而是把集群外部的某服务以DNS CNAME记录的方式映射到集群内,从而让集群内的Pod资源能够访问外部的Service的一种实现方式。这种类型的Service没有ClusterIP和NodePort,也没有标签选择器用于选择Pod资源,因此也不会有Endpoints存在。
2.2.1 ClusterIP类型的Service示例 1)编写配置清单文件(这里使用redis作为示例);先创建一个deployment,启动redis pod;再使用service绑定这个deployment下的pod资源。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 [root@k8s-master ~ ] 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 spec: type: ClusterIP selector: app: redis ports: - port: 6379 targetPort: 6379 protocol: TCP [root@k8s-master ~ ] deployment.apps/redis-deploy created service/redis-svc created
2)查看创建的资源对象
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 [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 2 3 4 5 6 7 8 9 10 # (1)集群内部的节点上面测试 [root@k8s-master ~]# redis-cli -h 10.102.44.127 10.102.44.127:6379> ping PONG # (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
2.2.2 NodePort类型的Service示例 NodePort即节点Port,通常在安装部署Kubernetes集群系统时会预留一个端口范围用于NodePort,默认为30000~32767之间的端口。定义NodePort类型的Service资源时,需要使用.spec.type明确指定类型为NodePort。
1)编写配置清单文件(这里使用nginx作为示例);先创建一个deployment,启动nginx pod;再使用service绑定这个deployment下的pod资源。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 [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)查看创建的资源对象
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 [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)集群外部进行测试
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 [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的方式实现了从集群外部端口进行访问,实践中并不建议自定义使用的节点端口,因为容易产生冲突。建议让其自动生成即可。
2.3 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对象创建一条记录。
2.3.1 Headless类型的Service示例 配置Service资源配置清单时,只需要将ClusterIP字段的值设置为“None”即为其定义为Headless类型。
1)编写配置清单文件(这里使用apache作为示例);先创建一个deployment,启动apache pod;再使用service绑定这个deployment下的pod资源。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 [root@k8s-master ~ ] 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 spec: clusterIP: None selector: app: httpd ports: - port: 80 targetPort: 80 protocol: TCP [root@k8s-master ~ ] deployment.apps/httpd-deploy created service/httpd-svc created
2)查看创建的资源对象
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 [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工作特性可知,它记录于ClusterDNS的A记录的相关解析结果是后端Pod资源的IP地址。意味着客户端通过Service资源的名称发现的是各Pod资源。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 # (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 ......