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 ......