Kubernetes Pod
是平凡的,由Deployment
等控制器管理的Pod
对象都是有生命周期的,它们会被建立,也会意外挂掉。虽然它们能够由控制器自动重建或者滚动更新,可是重建或更新以后的Pod
对象的IP地址等都会发生新的变化。这样就会致使一个问题,若是一组Pod
(称为backend
)为其它Pod
(称为frontend
)提供服务,那么那些frontend
该如何发现,并链接到这组Pod
中的哪些backend
呢? 这时候就用到了:Service
html
示例说明为何要使用Servicenode
以下图所示,当Nginx Pod
做为客户端访问Tomcat Pod
中的应用时,IP
的变更或应用规模的缩减会致使客户端访问错误。而Pod
规模的扩容又会使得客户端没法有效的使用新增的Pod
对象,从而影响达成规模扩展之目的。为此,Kubernetes
特意设计了Service
资源来解决此类问题。nginx
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
一个
Service
对象就是工做节点上的一些iptables
或ipvs
规则,用于将到达Service
对象IP
地址的流量调度转发至相应的Endpoints
对象指定的IP
地址和端口之上。kube-proxy
组件经过API Server
持续监控着各Service
及其关联的Pod
对象,并将其建立或变更实时反映到当前工做节点上的iptables
规则或ipvs
规则上。vim
ipvs
是借助于Netfilter
实现的网络请求报文调度框架,支持rr
、wrr
、lc
、wlc
、sh
、sed
和nq
等十余种调度算法,用户空间的命令行工具是ipvsadm
,用于管理工做与ipvs
之上的调度规则。后端
Service IP
事实上是用于生成iptables
或ipvs
规则时使用的IP
地址,仅用于实现Kubernetes
集群网络的内部通讯,而且可以将规则中定义的转发服务的请求做为目标地址予以相应,这也是将其称为虚拟IP
的缘由之一。api
kube-proxy
将请求代理至相应端点的方式有三种:userspace(用户空间)、iptables和ipvs。服务器
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
版本前是默认的转发策略。
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
模式则能够。
kube-proxy
跟踪API Server
上Service
的Endpoints
对象的变更,据此来调用netlink
接口建立ipvs
规则,并确保与API Server
中的变更保持同步,其请求流量的调度功能由ipvs
实现,其他的功能由iptables
实现。ipvs
支持众多调度算法,如rr
、lc
、dh
、sh
、sed
和nq
等。
建立
Service
对象的经常使用方法有两种,一是直接使用命令“kubectl expose”
命令,二是使用资源清单配置文件。定义Service
资源清单文件时,spec
的两个较为经常使用的内嵌字段分别是selector
和port
,分别用于定义使用的标签选择器和要暴露的端口。
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
资源支持Session affinity
(粘性会话或会话粘性)机制,可以未来自同一个客户端的请求始终转发至同一个后端的Pod
对象。这意味着会影响调度算法的流量分发功能,进而下降其负载均衡的效果。因此,当客户端访问pod
中的应用程序时,若是有基于客户端身份保存某些私有信息,并基于这些私有信息追踪用户的活动等一类的需求时,就能够启用session affinity
机制。
Session affinity
的效果仅在一段时间期限内生效,默认值为10800
秒,超出此时长以后,客户端的再次访问会被调度算法从新调度。Service
资源的Session affinity
机制仅能基于客户端的IP
地址识别客户端身份,把经由同一个NAT
服务器进行源地址转换的全部客户端识别为同一个客户端,便致使调度效果不佳,因此,这种方法并不经常使用。
Service
资源经过service.spec.sessionAffinity
和service.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
的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
存在。
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
即节点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
的方式实现了从集群外部端口进行访问,实践中并不建议自定义使用的节点端口,由于容易产生冲突。建议让其自动生成便可。
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
对象建立一条记录。
配置
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
工做特性可知,它记录于ClusterDNS
的A
记录的相关解析结果是后端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 ......