Kubernetes--Service 是如何工作的?

Service 理論

之前我們提到 Pod 是 Kubernetes 用來部署的最小的原子單元,並且 Pod is mortal Pod 終有一死。
當 kubernetes 執行擴展,自恢復操作時,原來的 Pod 就會死掉,被新的 Pod 代替。那麼原有 Pod 對應的 IP 就將不再工作。
這就導致了單獨 Pod 的 IP 是不穩定的,是不能夠依賴的。Kubernetes Service 能夠擁有穩定的 IP 地址,DNS 名字和端口。

Kubernetes Service 和 Pods 關聯起來,併爲這些 Pod 提供路由服務。如下圖所示。

通過在 Pod 前面部署的 Service, Pods 可以自由的擴展,更新,回滾而不會影響到整個服務,這些也是 Kubernetes 的精髓。
那麼有一個問題,當一個 Pod 死掉,新的 Pod 加入的時候 Service 是如何發現 Pods 的呢?

Service 是如何發現 Pods 的呢?

同 Deployments 管理 Pods 的理論一樣,Service 也是通過標籤選擇器來管理 Pods 的,並且是一個松耦合的標籤選擇器。
Pods 必須擁有 Service 定義的所有標籤,但是 Pods 可以擁有 Service 沒定義的額外標籤。
比如下面 3 種情況的前兩種情況是可以管理 Pod 的,但是最後一種確實不可以管理到 Pod 的。

第一種情況完全匹配:

第二種情況:Pods 可以擁有額外的標籤

第三種情況:Pods 少了一個標籤,匹配失敗

Service 通過標籤選擇器會創建一個叫 Endpoints 的 object,這個 Endpoints 會負責維護一個匹配的 Pods 列表。當 Service 把流量發送到 Pods 時就會查詢這個 Endpoints
Endopoints 永遠維護着最新的 PodService 通過標籤選擇器會創建一個叫 Endpoints 的 object,這個 Endpoints 會負責維護一個匹配的 Pods 列表。

如何在 cluster 內部訪問 service 服務?

Kubernetes Service 包含了多種類型,默認的類型是 ClusterIP Service。ClusterIP Service 擁有穩定的 IP 地址的端口。ClusterIP Service 會把 Service 名字註冊到 Cluster 內部的 DNS Service。
而 cluster 中的所有 Pod 都能夠知道 DNS Service(這個是在創建 Pod 時寫進去的),即默認能夠解析 Service。

如何在 Cluster 外部訪問 Service 服務?

Kubernetes Service 通過另一個類型叫 NodePort Service 來支持從 cluster 外部訪問 service。NodePort Service 是基於 ClusterIP Service,並且包含一個額外的端口叫 NodePort。
NodePort Service 包含 4 個屬性。

Name: magic-sandbox
ClusterIP: 172.12.5.17
port: 8080
NodePort: 30050

除了 NodePort 類型,Kubernetes 還支持 LoadBalancer 和 ExternalName 類型。LoadBalancer 是基於 NodePort Service 的,允許通過雲服務廠商的 load balancer 來訪問 Pods。

不同於前 3 種 Service 類型,ExternalName Service 則是把流量路由到 Kubernetes cluster 之外的一種類型。

Kubernetes 如何實現 Service 發現?

Kubernetes 支持兩種方式實現 Service 發現, 基於 DNS Service 和基於環境變量。基於 DNS 實現的方式,kubernetes dns service 會持續檢測 API Server,並自動把新創建的 Service 註冊到 DNS 中。而基於環境變量的實現方式只能在創建 Pod 時把 Kubernetes Service 相關的信息寫到 Pod 中,這導致的一個最大的問題是 Pod 無法發現在 Pod 創建後創建的 Service。所以目前基於 DNS 的 Service 發現是主流。

實際定義一個 Service

下面我們來看一個實際的 Service 的 manifest 定義
hello-svc.yml

apiVersion: v1
kind: Service
metadata:
  name: hello-svc
spec:
  type: NodePort
  ports:
  - port: 8080
    nodePort: 30001
    targetPort: 8080
    protocal: TCP
  selector:
    app: hello-world

port 指示這個叫 hello-svc 的 Service 對 cluster 內部請求監測 8080,NodePort 指示對外部請求監測 30001,targetPort 指示 Service 把請求發送到 Pod 的 8080 端口(即 application service 監聽端口)。

本文由 Readfog 進行 AMP 轉碼,版權歸原作者所有。
來源https://mp.weixin.qq.com/s/xtO3bxIk8O_eAhShlSxVcw