国产xxxx99真实实拍_久久不雅视频_高清韩国a级特黄毛片_嗯老师别我我受不了了小说

資訊專欄INFORMATION COLUMN

帶著問題學 Kubernetes 抽象對象 Service

baukh789 / 2440人閱讀

摘要:慶幸,引入了這個抽象的概念。會虛擬出一個,并在它銷毀之前保持該地址保持不變。通過對它的訪問,以代理的方式負載到對應的上,同時生命周期的變換,也會及時反應在代理上。該與同名,它所暴露的地址信息正是對應的地址。由此猜測是維護了與的映射關系。

帶著問題學 Kubernetes 抽象對象 Service

摘要:本文屬于原創,歡迎轉載,轉載請保留出處:https://github.com/jasonGeng88/blog

文章一:帶著問題學 Kubernetes 架構

文章二:帶著問題學 Kubernetes 基本單元 Pod

當前環境

Mac OS 10.11.x

kubectl == v1.6.4

minikube == v0.19.1

docker == 1.11.1

知識點

Service 的 Selector 與 Label 匹配機制

Service 與 Pods 的地址映射關系

kube-proxy 的 iptables 代理機制

Service 的服務發現機制

Service 的服務暴露方式

前言

上一篇講述了 Pod 的相關內容,了解了 Pod 的定義、生命周期以及通信機制等。正如上文說的,Pod 是存在生命周期的,它的崩潰、更新都是以創建新 Pod 替換原有的 Pod 的方式進行的,所以通過固定 Pod 地址的訪問變得不太可行。我們需要通過一種上層調用的方式,來解決底層 Pod 的動態變化的場景。

慶幸,K8S 引入了 Service 這個抽象的概念。Service 會創建一個虛擬的服務,由它來整合集群內的 Pod。Service 會虛擬出一個 VIP,并在它銷毀之前保持該 VIP 地址保持不變。通過對它的訪問,以代理的方式負載到對應的 Pod 上,同時 Pod 生命周期的變換,也會及時反應在代理上。

下面我們幾種常見的場景,來具體看看 Service 是如何工作的。

環境準備 演示鏡像

鏡像名:jasonn/php-echoserver

作用:打印當前容器的 IP

K8S Pod 創建

文件名:deploy-echoserver.yml (這里以 Deployment 的方式來創建與管理 Pod

文件內容:

apiVersion: apps/v1beta1
kind: Deployment
metadata:
  # Deployment 實例名稱
  name: echoserver
spec:
  # 設置 Pod 個數
  replicas: 2
  template:
    metadata:
      # 設置 Pod 標簽
      labels:
        app: echoserver
    spec:
      # 運行 docker 鏡像
      containers:
      - name: echoserver 
        image: jasonn/php-echoserver

啟動命令:

kubectl create -f deploy-echoserver.yml

至此,準備工作全部完成。短暫的等待后,Pod 創建成功,并且也由 deployment 管理著。

查看 deployment 啟動情況:

對 Pod 的訪問情況如下(通過kubectl describe pods獲取 Pod 的 IP 地址):

問題 場景1:現在 K8S 上運行著2個 Pod。我們希望通過上述所說的 Service 來整合這兩個 Pod 的訪問,完成對它們的統一訪問,而不用向具體的 Pod 發出請求。 Q1: Service 如何對 Pod 進行整合

這里所說的 Pod 默認都是帶有標簽(label)的,我們之前創建的兩個 Pod 所賦予的標簽是 app: echoserver,所以我們在創建 Service 時,就要通過選擇器(selector)來獲取符合條件的 Pod 進行整合。

Service 創建腳本內容如下(service-echoserver.yml):

apiVersion: v1
kind: Service
metadata:
  # Service 實例名稱
  name: svc-echoserver
spec:
  ports:
    - protocol: TCP
      # Service 端口地址
      port: 8080
      # Pod 端口地址
      targetPort: 80
  selector:
    # 匹配符合標簽條件的 Pod
    app: echoserver

創建 Service 命令:

kubectl create -f service-echoserver.yml

由此,我們創建好了一個 Service,同時也生成了一個對應的 VIP。

查看 Serivce 創建情況:

下面,我們來驗證下是否如之前所說,對 VIP 的訪問能訪問到 Pod 的內容。

我們發現不僅能成功訪問,而且還提供了負載均衡的功能。后面會講負載是怎么實現的

PS: 標簽篩選查找范圍僅在同個命名空間(namespace)內。


場景2:了解了 Service 是通過 label & selecor 來進行整合 Pod 的。那如果 Pod 不存在標簽,又或者是在不同 Namespace 下,也可能是 K8S 集群外的一個服務。現實情況往往更加復雜,這樣的情況下,Service 又該如何整合。 Q2: Service 與 Pod 的地址映射關系由誰管理?

這里引出了另一個概念 Endpoints。我們先來看看它的一個具體情況。

發現在 Service 創建的同時,還生成了一個 Endpoints。 該 Endpoints 與 Service 同名,它所暴露的地址信息正是對應 Pod 的地址。由此猜測是 Endpoints 維護了 Service 與 Pod 的映射關系。

為了驗證我們的猜測,我們手動刪除 Endpoints,發現之前能成功訪問到 Pod 的 VIP,現在已經已經訪問不到了。

我們在手動把 Endpoints 創建回來,創建腳本如下(endpoint-echoserver.yml):

apiVersion: v1
kind: Endpoints
metadata:
  # Endpoints 實例的名稱
  name: svc-echoserver
subsets:
  - addresses:
    - ip: 172.17.0.5
    - ip: 172.17.0.6
    ports:
    - port: 80

創建命令:

kubectl create -f endpoint-echoserver.yml

注意:Endpoints 與 Service 的綁定關系通過名稱來關聯的,所以這兩者的名稱(name)一定要一致。

如果創建失敗,出現的錯誤信息是“...endpoints "svc-echoserver" already exists”,說明 Service 已經更新了 Endpoints。這里就說到了 Service 會定期去檢查 Pod 的狀態,并且將結果更新到 Endpoints 上。

VIP 再次訪問時又能成功訪問到,如圖:

現在我們已經能輕松的解決場景2的問題了,在創建 Service 時,只要不設置 Selector 屬性,那么將不會自動創建 Endpoints,這是我們可以根據需求手動的創建指定地址(address)的 Endpoints,來解決標簽無法實現的整合。


場景3:知道了 Service、Endpoints、Pod 的三者關系后,我們來具體看看所說的代理到底是如何實現的。從之前 K8S 的架構中,我們知道 Service 的代理是由 kube-proxy 實現的。而它的代理模式(Proxy mode)主要有兩種:userspace 與 iptables。自 K8S v1.2 開始,默認的代理模式就是 iptables,并且它的性能也是要高于 userspace 的,所以在這兒只討論 iptables 的實現。 Q3:kube-proxy 是如何使用 iptables 做到服務代理的(對于 iptables 不了解的同學可以直接跳過)?

我們現在要做的呢,是將 VIP 請求給轉發到對應的 Pod 上。而實現此的正是 iptables。

了解 iptables 的同學都知道四表五鏈的概念,而做端口地址轉發的呢,主要是在 nat 表中實現。我們下面看一下一個 VIP 請求在 nat 表中是如何一步步被轉發到 Pod 上的。

根據 iptables 的機制,請求是先到 nat 表的 PREROUTING 鏈(chain)上的,它的規則如下:

從圖中發現,請求首先經過 KUBE-SERVICE 鏈,其次再到 DOCKER 鏈上的。

我們看一下 KUBE-SERVICE 的情況:

我們發現 KUBE-SERVICE 中包含了一系列 Service 的規則。根據我們請求的 VIP 的目的地址,對應到了下一個名叫 KUBE-SVC-PRQ3AXYQLQGIVVIU 的 Service 鏈上。

KUBE-SVC-PRQ3AXYQLQGIVVIU 規則如下:

從規則的名字上可以看出,該條 Service 鏈上記錄的是2個 Endpoints 鏈,具體的選擇是通過 50% 的隨機性的進行決定(這也是它的一個負載規則)。

我們來看第一個名叫 KUBE-SEP-JSFY3ZFM2EVD64VQ 的 Endpoints 鏈的情況:

從圖中,我們已經很清晰的看到了它轉發到 Pod 的具體規則。

下面以一張簡單的流程圖,看一下請求的轉發情況:

關于 DOCKER 鏈的跟蹤,方法是差不多的,請求 從 nat 表結束后,在到 filter 表中,這里就不加以說明了。

而這些規則的實現正是由 Service、Endpoints 來完成的。我們在創建、更新、以及其自身的檢測機制,都會對這些規則進行更新。


場景4:Service 的創建、內部結構以及映射關系,我們都了解了。下面我們就要關心如何優雅的使用它,上面我們都是通過 Service 的 VIP 進行訪問的。這存在的問題是,如果有服務與服務之間的調用,難道我還要知道所調用服務的 VIP 不成,對于 VIP 的訪問能否更通用一些。 Q4:Service 的服務發現機制是怎樣的?

對于服務與服務間的調用,實際上就是 Pod 對 Servie 的調用。而 Pod 是如何發現 Service 的,這里可選擇的方式有2種。

我們通過啟動一個名為 busybox 的 Pod 來觀察這兩種方式:

kubectl run -i --tty busybox --image=busybox --restart=Never -- sh

環境變量:

在 Pod 中,集群中的 Service 會以環境變量的方式賦值在容器中,我們可以通過 {SERVICE_NAME}_SERVICE_HOST{SERVICE_NAME}_SERVICE_PORT 進行獲取(對于有多個 Port 的,可以通過帶指定 PORT 名稱的變量獲得。)。

busybox 中 環境變量如下:

查看訪問情況:

dns 解析:

第二種方式是通過 kube-dns 對 Service 進行域名解析,同樣能達到服務發現的目的。

查看 DNS 域名解析配置:

通過 nslookup 查詢 dns 記錄:

查看訪問結果:


場景5:集群間的服務調用解決了,可說到底還是通過的 VIP 進行的訪問。VIP 對于集群外的終端用戶,是無法訪問的。所以我們得通過服務暴露的方式,讓終端用戶能與集群內的服務進行通信。 Q5:Service 是如何對外暴露服務的?

在 Service 的配置文件中,屬性spec.type就是用來設置服務暴露的方式,它提供的三種方式如下:

ClusterIP: 提供一個集群內部的虛擬IP以供Pod訪問(默認類型,我們上述使用的正是這種方式)。

NodePort: 在每個Node上打開一個端口以供外部訪問。

LoadBalancer: 通過外部的負載均衡器來訪問(一般需要云提供商提供 LB 支持)。

我們這里簡單起見,還是通過 NodePort 方式進行。

修改 Service 配置文件,并重新啟動:

apiVersion: v1
kind: Service
metadata:
  # Service 實例名稱
  name: svc-echoserver
spec:
  ports:
    - protocol: TCP
      # Service 端口地址
      port: 8080
      # Pod 端口地址
      targetPort: 80
  selector:
    # 匹配符合標簽條件的 Pod
    app: echoserver
  type: NodePort

注意:這里如果要以kubecrl replace -f service-echoserver.yml方式進行平滑更新,配置中需添加spec.clusterIP屬性,值為當前 Service 的 VIP,否則更新會失敗。這也符合了一開始說的 Service 在它終止之前,VIP 是不會改變的。

查看 Service 更新情況:

外部訪問(該 Node 地址是:192.168.64.6):

總結

文本從 Service 的標簽與選擇器開始,講了 Service 整合 Pod 的過程,引出了 Service, Endpoints, Pods 三者的關系情況。隨后又通過 iptables 詳細展開了 kube-proxy 的代理機制。最后,以 Service 的集群內與集群外的訪問設置,講述了 Service 的服務發現與服務暴露機制。

關于 Service 的有遺漏重要的知識點,或者有講的不對的地方,也歡迎提出和指正!最后,希望本篇對你學習 K8S 有所幫助~

文章版權歸作者所有,未經允許請勿轉載,若此文章存在違規行為,您可以聯系管理員刪除。

轉載請注明本文地址:http://specialneedsforspecialkids.com/yun/32564.html

相關文章

  • 帶著問題 Kubernetes 抽象對象 Service

    摘要:慶幸,引入了這個抽象的概念。會虛擬出一個,并在它銷毀之前保持該地址保持不變。通過對它的訪問,以代理的方式負載到對應的上,同時生命周期的變換,也會及時反應在代理上。該與同名,它所暴露的地址信息正是對應的地址。由此猜測是維護了與的映射關系。 帶著問題學 Kubernetes 抽象對象 Service 摘要:本文屬于原創,歡迎轉載,轉載請保留出處:https://github.com/jas...

    opengps 評論0 收藏0
  • 帶著問題 Kubernetes 架構

    摘要:又因為是谷歌出品的,依賴了很多谷歌自己的鏡像,所以對于國內的同學環境搭建的難度又增加了一層。 帶著問題學 Kubernetes 架構 摘要:本文屬于原創,歡迎轉載,轉載請保留出處:https://github.com/jasonGeng88/blog 打開這篇文章的同學,想必對 docker 都不會陌生。docker 是一種虛擬容器技術,它上手比較簡單,只需在宿主機上起一個 docke...

    Allen 評論0 收藏0
  • 帶著問題 Kubernetes 架構

    摘要:又因為是谷歌出品的,依賴了很多谷歌自己的鏡像,所以對于國內的同學環境搭建的難度又增加了一層。 帶著問題學 Kubernetes 架構 摘要:本文屬于原創,歡迎轉載,轉載請保留出處:https://github.com/jasonGeng88/blog 打開這篇文章的同學,想必對 docker 都不會陌生。docker 是一種虛擬容器技術,它上手比較簡單,只需在宿主機上起一個 docke...

    CodeSheep 評論0 收藏0
  • 帶著問題 Kubernetes 基本單元 Pod

    摘要:后面會涉及以配置文件進行部署。的調度完成,被分配到指定上。這是的一種最終狀態。圖相較而言,除了提供的基本功能,還支持聲明式的更新和回滾。共享數據存儲的問題主要分為數據臨時存儲與持久性存儲。 帶著問題學 Kubernetes 基本單元 Pod 摘要:本文屬于原創,歡迎轉載,轉載請保留出處:https://github.com/jasonGeng88/blog 文章一:帶著問題學 Kube...

    pcChao 評論0 收藏0
  • 帶著問題 Kubernetes 基本單元 Pod

    摘要:后面會涉及以配置文件進行部署。的調度完成,被分配到指定上。這是的一種最終狀態。圖相較而言,除了提供的基本功能,還支持聲明式的更新和回滾。共享數據存儲的問題主要分為數據臨時存儲與持久性存儲。 帶著問題學 Kubernetes 基本單元 Pod 摘要:本文屬于原創,歡迎轉載,轉載請保留出處:https://github.com/jasonGeng88/blog 文章一:帶著問題學 Kube...

    frontoldman 評論0 收藏0

發表評論

0條評論

baukh789

|高級講師

TA的文章

閱讀更多
最新活動
閱讀需要支付1元查看
<