(七)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 ......
相關文章
相關標籤/搜索