摘要:慶幸,引入了這個(gè)抽象的概念。會(huì)虛擬出一個(gè),并在它銷毀之前保持該地址保持不變。通過(guò)對(duì)它的訪問(wèn),以代理的方式負(fù)載到對(duì)應(yīng)的上,同時(shí)生命周期的變換,也會(huì)及時(shí)反應(yīng)在代理上。該與同名,它所暴露的地址信息正是對(duì)應(yīng)的地址。由此猜測(cè)是維護(hù)了與的映射關(guān)系。
帶著問(wèn)題學(xué) Kubernetes 抽象對(duì)象 Service
摘要:本文屬于原創(chuàng),歡迎轉(zhuǎn)載,轉(zhuǎn)載請(qǐng)保留出處:https://github.com/jasonGeng88/blog
文章一:帶著問(wèn)題學(xué) Kubernetes 架構(gòu)
文章二:帶著問(wèn)題學(xué) Kubernetes 基本單元 Pod
當(dāng)前環(huán)境Mac OS 10.11.x
kubectl == v1.6.4
minikube == v0.19.1
docker == 1.11.1
知識(shí)點(diǎn)Service 的 Selector 與 Label 匹配機(jī)制
Service 與 Pods 的地址映射關(guān)系
kube-proxy 的 iptables 代理機(jī)制
Service 的服務(wù)發(fā)現(xiàn)機(jī)制
Service 的服務(wù)暴露方式
前言上一篇講述了 Pod 的相關(guān)內(nèi)容,了解了 Pod 的定義、生命周期以及通信機(jī)制等。正如上文說(shuō)的,Pod 是存在生命周期的,它的崩潰、更新都是以創(chuàng)建新 Pod 替換原有的 Pod 的方式進(jìn)行的,所以通過(guò)固定 Pod 地址的訪問(wèn)變得不太可行。我們需要通過(guò)一種上層調(diào)用的方式,來(lái)解決底層 Pod 的動(dòng)態(tài)變化的場(chǎng)景。
慶幸,K8S 引入了 Service 這個(gè)抽象的概念。Service 會(huì)創(chuàng)建一個(gè)虛擬的服務(wù),由它來(lái)整合集群內(nèi)的 Pod。Service 會(huì)虛擬出一個(gè) VIP,并在它銷毀之前保持該 VIP 地址保持不變。通過(guò)對(duì)它的訪問(wèn),以代理的方式負(fù)載到對(duì)應(yīng)的 Pod 上,同時(shí) Pod 生命周期的變換,也會(huì)及時(shí)反應(yīng)在代理上。
下面我們幾種常見(jiàn)的場(chǎng)景,來(lái)具體看看 Service 是如何工作的。
環(huán)境準(zhǔn)備 演示鏡像鏡像名:jasonn/php-echoserver
作用:打印當(dāng)前容器的 IP
K8S Pod 創(chuàng)建文件名:deploy-echoserver.yml (這里以 Deployment 的方式來(lái)創(chuàng)建與管理 Pod)
文件內(nèi)容:
apiVersion: apps/v1beta1 kind: Deployment metadata: # Deployment 實(shí)例名稱 name: echoserver spec: # 設(shè)置 Pod 個(gè)數(shù) replicas: 2 template: metadata: # 設(shè)置 Pod 標(biāo)簽 labels: app: echoserver spec: # 運(yùn)行 docker 鏡像 containers: - name: echoserver image: jasonn/php-echoserver
啟動(dòng)命令:
kubectl create -f deploy-echoserver.yml
至此,準(zhǔn)備工作全部完成。短暫的等待后,Pod 創(chuàng)建成功,并且也由 deployment 管理著。
查看 deployment 啟動(dòng)情況:
對(duì) Pod 的訪問(wèn)情況如下(通過(guò)kubectl describe pods獲取 Pod 的 IP 地址):
問(wèn)題 場(chǎng)景1:現(xiàn)在 K8S 上運(yùn)行著2個(gè) Pod。我們希望通過(guò)上述所說(shuō)的 Service 來(lái)整合這兩個(gè) Pod 的訪問(wèn),完成對(duì)它們的統(tǒng)一訪問(wèn),而不用向具體的 Pod 發(fā)出請(qǐng)求。 Q1: Service 如何對(duì) Pod 進(jìn)行整合這里所說(shuō)的 Pod 默認(rèn)都是帶有標(biāo)簽(label)的,我們之前創(chuàng)建的兩個(gè) Pod 所賦予的標(biāo)簽是 app: echoserver,所以我們?cè)趧?chuàng)建 Service 時(shí),就要通過(guò)選擇器(selector)來(lái)獲取符合條件的 Pod 進(jìn)行整合。
Service 創(chuàng)建腳本內(nèi)容如下(service-echoserver.yml):
apiVersion: v1 kind: Service metadata: # Service 實(shí)例名稱 name: svc-echoserver spec: ports: - protocol: TCP # Service 端口地址 port: 8080 # Pod 端口地址 targetPort: 80 selector: # 匹配符合標(biāo)簽條件的 Pod app: echoserver
創(chuàng)建 Service 命令:
kubectl create -f service-echoserver.yml
由此,我們創(chuàng)建好了一個(gè) Service,同時(shí)也生成了一個(gè)對(duì)應(yīng)的 VIP。
查看 Serivce 創(chuàng)建情況:
下面,我們來(lái)驗(yàn)證下是否如之前所說(shuō),對(duì) VIP 的訪問(wèn)能訪問(wèn)到 Pod 的內(nèi)容。
我們發(fā)現(xiàn)不僅能成功訪問(wèn),而且還提供了負(fù)載均衡的功能。后面會(huì)講負(fù)載是怎么實(shí)現(xiàn)的
PS: 標(biāo)簽篩選查找范圍僅在同個(gè)命名空間(namespace)內(nèi)。
這里引出了另一個(gè)概念 Endpoints。我們先來(lái)看看它的一個(gè)具體情況。
發(fā)現(xiàn)在 Service 創(chuàng)建的同時(shí),還生成了一個(gè) Endpoints。 該 Endpoints 與 Service 同名,它所暴露的地址信息正是對(duì)應(yīng) Pod 的地址。由此猜測(cè)是 Endpoints 維護(hù)了 Service 與 Pod 的映射關(guān)系。
為了驗(yàn)證我們的猜測(cè),我們手動(dòng)刪除 Endpoints,發(fā)現(xiàn)之前能成功訪問(wèn)到 Pod 的 VIP,現(xiàn)在已經(jīng)已經(jīng)訪問(wèn)不到了。
我們?cè)谑謩?dòng)把 Endpoints 創(chuàng)建回來(lái),創(chuàng)建腳本如下(endpoint-echoserver.yml):
apiVersion: v1 kind: Endpoints metadata: # Endpoints 實(shí)例的名稱 name: svc-echoserver subsets: - addresses: - ip: 172.17.0.5 - ip: 172.17.0.6 ports: - port: 80
創(chuàng)建命令:
kubectl create -f endpoint-echoserver.yml
注意:Endpoints 與 Service 的綁定關(guān)系通過(guò)名稱來(lái)關(guān)聯(lián)的,所以這兩者的名稱(name)一定要一致。
如果創(chuàng)建失敗,出現(xiàn)的錯(cuò)誤信息是“...endpoints "svc-echoserver" already exists”,說(shuō)明 Service 已經(jīng)更新了 Endpoints。這里就說(shuō)到了 Service 會(huì)定期去檢查 Pod 的狀態(tài),并且將結(jié)果更新到 Endpoints 上。
VIP 再次訪問(wèn)時(shí)又能成功訪問(wèn)到,如圖:
現(xiàn)在我們已經(jīng)能輕松的解決場(chǎng)景2的問(wèn)題了,在創(chuàng)建 Service 時(shí),只要不設(shè)置 Selector 屬性,那么將不會(huì)自動(dòng)創(chuàng)建 Endpoints,這是我們可以根據(jù)需求手動(dòng)的創(chuàng)建指定地址(address)的 Endpoints,來(lái)解決標(biāo)簽無(wú)法實(shí)現(xiàn)的整合。
我們現(xiàn)在要做的呢,是將 VIP 請(qǐng)求給轉(zhuǎn)發(fā)到對(duì)應(yīng)的 Pod 上。而實(shí)現(xiàn)此的正是 iptables。
了解 iptables 的同學(xué)都知道四表五鏈的概念,而做端口地址轉(zhuǎn)發(fā)的呢,主要是在 nat 表中實(shí)現(xiàn)。我們下面看一下一個(gè) VIP 請(qǐng)求在 nat 表中是如何一步步被轉(zhuǎn)發(fā)到 Pod 上的。
根據(jù) iptables 的機(jī)制,請(qǐng)求是先到 nat 表的 PREROUTING 鏈(chain)上的,它的規(guī)則如下:
從圖中發(fā)現(xiàn),請(qǐng)求首先經(jīng)過(guò) KUBE-SERVICE 鏈,其次再到 DOCKER 鏈上的。
我們看一下 KUBE-SERVICE 的情況:
我們發(fā)現(xiàn) KUBE-SERVICE 中包含了一系列 Service 的規(guī)則。根據(jù)我們請(qǐng)求的 VIP 的目的地址,對(duì)應(yīng)到了下一個(gè)名叫 KUBE-SVC-PRQ3AXYQLQGIVVIU 的 Service 鏈上。
KUBE-SVC-PRQ3AXYQLQGIVVIU 規(guī)則如下:
從規(guī)則的名字上可以看出,該條 Service 鏈上記錄的是2個(gè) Endpoints 鏈,具體的選擇是通過(guò) 50% 的隨機(jī)性的進(jìn)行決定(這也是它的一個(gè)負(fù)載規(guī)則)。
我們來(lái)看第一個(gè)名叫 KUBE-SEP-JSFY3ZFM2EVD64VQ 的 Endpoints 鏈的情況:
從圖中,我們已經(jīng)很清晰的看到了它轉(zhuǎn)發(fā)到 Pod 的具體規(guī)則。
下面以一張簡(jiǎn)單的流程圖,看一下請(qǐng)求的轉(zhuǎn)發(fā)情況:
關(guān)于 DOCKER 鏈的跟蹤,方法是差不多的,請(qǐng)求 從 nat 表結(jié)束后,在到 filter 表中,這里就不加以說(shuō)明了。
而這些規(guī)則的實(shí)現(xiàn)正是由 Service、Endpoints 來(lái)完成的。我們?cè)趧?chuàng)建、更新、以及其自身的檢測(cè)機(jī)制,都會(huì)對(duì)這些規(guī)則進(jìn)行更新。
對(duì)于服務(wù)與服務(wù)間的調(diào)用,實(shí)際上就是 Pod 對(duì) Servie 的調(diào)用。而 Pod 是如何發(fā)現(xiàn) Service 的,這里可選擇的方式有2種。
我們通過(guò)啟動(dòng)一個(gè)名為 busybox 的 Pod 來(lái)觀察這兩種方式:
kubectl run -i --tty busybox --image=busybox --restart=Never -- sh
環(huán)境變量:
在 Pod 中,集群中的 Service 會(huì)以環(huán)境變量的方式賦值在容器中,我們可以通過(guò) {SERVICE_NAME}_SERVICE_HOST 和 {SERVICE_NAME}_SERVICE_PORT 進(jìn)行獲取(對(duì)于有多個(gè) Port 的,可以通過(guò)帶指定 PORT 名稱的變量獲得。)。
busybox 中 環(huán)境變量如下:
查看訪問(wèn)情況:
dns 解析:
第二種方式是通過(guò) kube-dns 對(duì) Service 進(jìn)行域名解析,同樣能達(dá)到服務(wù)發(fā)現(xiàn)的目的。
查看 DNS 域名解析配置:
通過(guò) nslookup 查詢 dns 記錄:
查看訪問(wèn)結(jié)果:
在 Service 的配置文件中,屬性spec.type就是用來(lái)設(shè)置服務(wù)暴露的方式,它提供的三種方式如下:
ClusterIP: 提供一個(gè)集群內(nèi)部的虛擬IP以供Pod訪問(wèn)(默認(rèn)類型,我們上述使用的正是這種方式)。
NodePort: 在每個(gè)Node上打開(kāi)一個(gè)端口以供外部訪問(wèn)。
LoadBalancer: 通過(guò)外部的負(fù)載均衡器來(lái)訪問(wèn)(一般需要云提供商提供 LB 支持)。
我們這里簡(jiǎn)單起見(jiàn),還是通過(guò) NodePort 方式進(jìn)行。
修改 Service 配置文件,并重新啟動(dòng):
apiVersion: v1 kind: Service metadata: # Service 實(shí)例名稱 name: svc-echoserver spec: ports: - protocol: TCP # Service 端口地址 port: 8080 # Pod 端口地址 targetPort: 80 selector: # 匹配符合標(biāo)簽條件的 Pod app: echoserver type: NodePort
注意:這里如果要以kubecrl replace -f service-echoserver.yml方式進(jìn)行平滑更新,配置中需添加spec.clusterIP屬性,值為當(dāng)前 Service 的 VIP,否則更新會(huì)失敗。這也符合了一開(kāi)始說(shuō)的 Service 在它終止之前,VIP 是不會(huì)改變的。
查看 Service 更新情況:
外部訪問(wèn)(該 Node 地址是:192.168.64.6):
總結(jié)文本從 Service 的標(biāo)簽與選擇器開(kāi)始,講了 Service 整合 Pod 的過(guò)程,引出了 Service, Endpoints, Pods 三者的關(guān)系情況。隨后又通過(guò) iptables 詳細(xì)展開(kāi)了 kube-proxy 的代理機(jī)制。最后,以 Service 的集群內(nèi)與集群外的訪問(wèn)設(shè)置,講述了 Service 的服務(wù)發(fā)現(xiàn)與服務(wù)暴露機(jī)制。
關(guān)于 Service 的有遺漏重要的知識(shí)點(diǎn),或者有講的不對(duì)的地方,也歡迎提出和指正!最后,希望本篇對(duì)你學(xué)習(xí) K8S 有所幫助~
文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請(qǐng)注明本文地址:http://systransis.cn/yun/26991.html
摘要:慶幸,引入了這個(gè)抽象的概念。會(huì)虛擬出一個(gè),并在它銷毀之前保持該地址保持不變。通過(guò)對(duì)它的訪問(wèn),以代理的方式負(fù)載到對(duì)應(yīng)的上,同時(shí)生命周期的變換,也會(huì)及時(shí)反應(yīng)在代理上。該與同名,它所暴露的地址信息正是對(duì)應(yīng)的地址。由此猜測(cè)是維護(hù)了與的映射關(guān)系。 帶著問(wèn)題學(xué) Kubernetes 抽象對(duì)象 Service 摘要:本文屬于原創(chuàng),歡迎轉(zhuǎn)載,轉(zhuǎn)載請(qǐng)保留出處:https://github.com/jas...
摘要:又因?yàn)槭枪雀璩銎返模蕾嚵撕芏喙雀枳约旱溺R像,所以對(duì)于國(guó)內(nèi)的同學(xué)環(huán)境搭建的難度又增加了一層。 帶著問(wèn)題學(xué) Kubernetes 架構(gòu) 摘要:本文屬于原創(chuàng),歡迎轉(zhuǎn)載,轉(zhuǎn)載請(qǐng)保留出處:https://github.com/jasonGeng88/blog 打開(kāi)這篇文章的同學(xué),想必對(duì) docker 都不會(huì)陌生。docker 是一種虛擬容器技術(shù),它上手比較簡(jiǎn)單,只需在宿主機(jī)上起一個(gè) docke...
摘要:又因?yàn)槭枪雀璩銎返?,依賴了很多谷歌自己的鏡像,所以對(duì)于國(guó)內(nèi)的同學(xué)環(huán)境搭建的難度又增加了一層。 帶著問(wèn)題學(xué) Kubernetes 架構(gòu) 摘要:本文屬于原創(chuàng),歡迎轉(zhuǎn)載,轉(zhuǎn)載請(qǐng)保留出處:https://github.com/jasonGeng88/blog 打開(kāi)這篇文章的同學(xué),想必對(duì) docker 都不會(huì)陌生。docker 是一種虛擬容器技術(shù),它上手比較簡(jiǎn)單,只需在宿主機(jī)上起一個(gè) docke...
摘要:后面會(huì)涉及以配置文件進(jìn)行部署。的調(diào)度完成,被分配到指定上。這是的一種最終狀態(tài)。圖相較而言,除了提供的基本功能,還支持聲明式的更新和回滾。共享數(shù)據(jù)存儲(chǔ)的問(wèn)題主要分為數(shù)據(jù)臨時(shí)存儲(chǔ)與持久性存儲(chǔ)。 帶著問(wèn)題學(xué) Kubernetes 基本單元 Pod 摘要:本文屬于原創(chuàng),歡迎轉(zhuǎn)載,轉(zhuǎn)載請(qǐng)保留出處:https://github.com/jasonGeng88/blog 文章一:帶著問(wèn)題學(xué) Kube...
摘要:后面會(huì)涉及以配置文件進(jìn)行部署。的調(diào)度完成,被分配到指定上。這是的一種最終狀態(tài)。圖相較而言,除了提供的基本功能,還支持聲明式的更新和回滾。共享數(shù)據(jù)存儲(chǔ)的問(wèn)題主要分為數(shù)據(jù)臨時(shí)存儲(chǔ)與持久性存儲(chǔ)。 帶著問(wèn)題學(xué) Kubernetes 基本單元 Pod 摘要:本文屬于原創(chuàng),歡迎轉(zhuǎn)載,轉(zhuǎn)載請(qǐng)保留出處:https://github.com/jasonGeng88/blog 文章一:帶著問(wèn)題學(xué) Kube...
閱讀 1945·2021-10-11 10:59
閱讀 1050·2021-09-07 09:59
閱讀 2246·2021-08-27 16:17
閱讀 2802·2019-08-30 15:54
閱讀 2287·2019-08-30 12:58
閱讀 1791·2019-08-30 12:53
閱讀 1482·2019-08-28 18:13
閱讀 743·2019-08-26 13:35