Kubernetes-6.服務、負載均衡、聯網(2)Service

壓死稻草的第一隻駱駝發表於2020-10-30
  1. Service?將執行在同一組Pods上的應用程式公開為網路服務的抽象方法。Kubernetes為Pods提供了Ip地址,併為一組Pod提供了相同的DNS,他們之間可以實現負載均衡。
  2. 為何要使用Service?使用Deployment,Pod能被動態建立/銷燬,為了跟蹤提供功能的Pod而使用Service。
  3. Kubernetes Service定義了一種抽象:邏輯上的一組Pod和一種可以訪問他們策略——微服務。這一組Pod能夠被Service訪問,通常是通過選擇算符實現。
    以上內容,舉例:考慮一個圖片處理後端,他執行了三個副本,副本之間可以呼喚,前端不需要關心呼叫了哪個後端副本,但形成一組的後端程式的Pod是可能發生變成的,Service的定義的抽象解耦了前端(Client)和後端(Pods)的管理。
  4. Service在Kubernetes中本質是REST物件,(Representational State Transfer,表述性狀態傳遞),基於POST方式,請求API server建立例項。
    Service配置例子:
在這裡插入程式碼片apiVersion: v1
kind: Service			//表明這是一個Service
metadata:	
  name: my-service		//Service物件名
spec:
  selector:
    app: MyApp			//標籤為MyApp的**Pod**
  ports:
    - protocol: TCP
      port: 80			//TCP協議使用的埠
      targetPort: 9376  //Pod暴露的埠
  1. 若服務沒有選擇算符(Selector),則不會自動建立Endpoint物件。可以手動新增Endpoint物件,將服務手動對映到執行該服務的ip地址和埠
apiVersion: v1
kind: Endpoints
metadata:
  name: my-service
subsets:
  - addresses:
      - ip: 192.0.2.42
    ports:
      - port: 9376
  1. kubernetes叢集的每個節點都執行了kube-proxy提供了**VIP (virtual IP)**的形式,而不是ExternalName。

  2. 代理模式:
    ①userspace代理模式
    在這裡插入圖片描述
    ②iptables代理模式
    在這裡插入圖片描述
    ③IPVS(IP Virtual Server)
    在這裡插入圖片描述

  3. 多埠Service,定義時需要提供所有的埠名乘避免歧義。

apiVersion: v1
kind: Service
metadata:
  name: my-service
spec:
  selector:
    app: MyApp
  ports:
    - name: http
      protocol: TCP
      port: 80
      targetPort: 9376
    - name: https
      protocol: TCP
      port: 443
      targetPort: 9377
  1. 服務發現:
    ①環境變數
    Pod執行在Node上,kubernetes為活躍的Service新增一組環境變數
    一個名稱為 “redis-master” 的 Service 暴露了 TCP 埠 6379, 同時給它分配了 Cluster IP 地址 10.0.0.11,這個 Service 生成了如下環境變數:
REDIS_MASTER_SERVICE_HOST=10.0.0.11
REDIS_MASTER_SERVICE_PORT=6379
REDIS_MASTER_PORT=tcp://10.0.0.11:6379
REDIS_MASTER_PORT_6379_TCP=tcp://10.0.0.11:6379
REDIS_MASTER_PORT_6379_TCP_PROTO=tcp
REDIS_MASTER_PORT_6379_TCP_PORT=6379
REDIS_MASTER_PORT_6379_TCP_ADDR=10.0.0.11

②DNS
所有 Pod 都應該能夠通過其 DNS 名稱自動解析服務。Kubernetes DNS 伺服器是唯一一種能夠訪問ExternalName型別的Service方式。

  1. Headless Services (無頭服務) Cluster IP的值為“None”
    ①帶Selector
    Endpoint控制器在API內建立Endpoints記錄,修改DNS配置返回的A地址,通過這地址直達Service後端Pod。
    ②不帶Selector
    Endpoint控制器不會建立Endpoints記錄。DNS系統會查詢和配置。

  2. 釋出服務——服務型別
    ①ClusterIP(預設Service Type)
    通過叢集內部IP暴露服務,服務只能夠在叢集內可以訪問
    ②NodePort
    通過每個Node上的IP和靜態埠暴露服務。該型別服務會路由到ClusterIP Service(自動建立)上。通過**< Node IP >:< NodePort>** 指令,可以在叢集外部訪問NodePort服務
    ③LoadBalancer
    使用雲提供商(Cloud Provider)的負載均衡器,向外暴露服務。外部的負載均衡器可以路由到NodePort和ClusterIP。
    ④ExternalName
    通過返回CNAME和它的值,可以將服務對映到externalName欄位的內容。不需要建立任何型別代理。
    PS:CNAME 理解為別名,如下
    yy.com → http://www.xx.com → 111.111.111.111

  3. 虛擬IP實施(內部原理)
    ①避免衝突
    Kubernetes最主要的哲學之一,是使用者不應該暴露那些導致他們操作失敗、但又不是他們的錯誤的場景。對於Service資源的設計,這意味著如果使用者的選擇有可能與他人衝突,那就不要讓使用者自行選擇埠號。這是一個隔離性的失敗。
    為了使使用者能夠為他們的Service選擇一個埠號,我們必須確保不能有2個Service發生衝突。Kubernetes通過為每個Service分配他們自己的IP地址來實現。
    為了保證每個Service被分配到唯一的IP,需要一個內部的分配器能夠原子地更新etcd資料庫中的一個全域性分配對映表,這個更新操作要先於建立每一個Service。為了Service能夠獲取IP,這個對映表物件必須在註冊中心存在,否則建立Service將會失敗,知識一個IP不能被分配。
    在控制平面中,一個後臺Controller的職責是建立對映表(需要支援從使用了記憶體鎖的Kubernetes的舊版本遷移過來)。同時Kubernetes會通過控制器檢查不合理的分配(如管理員干預導致)以及清理已被分配但不再被任何Service使用的IP地址。
    ②Service IP 地址
    不像Pod的IP地址,Service IP地址實際路由到一個固定的目的地,Service的IP實際上不能通過單個主機進行應答。相反,我們使用iptables(Linux中資料包處理邏輯)來定義一個虛擬IP地址(VIP),它可以根據需求而透明地進行重定向。當客戶端連線到VIP時,他們的流量會自動地傳輸到一個合適的Endpoint。環境變數和DNS,實際上根據Service的VIP和埠進行填充。
    kube-proxy支援三種代理模式:userspace,iptables,IPVS。他們各自的操作略有不同。
    ③Userspace
    作為一個例子,考慮前面提到的圖片處理應用程式。當建立後端Service時,Kubernetes master(主節點) 指派一個虛擬IP地址,比如10.0.0.1.假設Service的埠是1234,該Service會被叢集中所有的kube-proxy例項觀察到。當代理看見一個新的Service,它會開啟一個新的埠,建立一個從該VIP重定向到新埠的iptables,並開始接受請求連線。當一個客戶端連線到一個VIP,iptables規則開始起作用,他會重定向該資料包到服務代理埠。服務代理選擇一個後端並將客戶端的流量代理到後端上。
    這意味著Service所有者能夠選擇任何他們想要使用的埠而不存在衝突的風險。客戶端可以簡單連線到一個IP和埠而不需要知道實際訪問了哪些Pod
    ④IPtables
    再次考慮前面提到的圖片處理應用程式。當建立後端Service時,Kubernetes控制皮膚會給它指派一個虛擬IP地址比如10.0.0.1,假設Service埠1234,該Service會被叢集中所有的kube-proxy例項觀察到。當代理看到一個新的Service,它會配置一系列的IPtables規則,從VIP重定向到每個Service規則。該特定於Service的規則連線到特定於Endpoint規則。基於Endpoint的規則會重定向刀後端Pod(目標地址轉譯)。
    當客戶端連線到一個VIP,iptable規則開始起作用。一個後端會被選擇(要麼根據SessionAffinity會話親和度,要麼隨機),資料包被重定向到這個後端。不像使用者空間帶理,資料包從來不拷貝到使用者空間,kubeproxy不是必須為了VIP工作而執行,而且客戶端IP是不可更改的。當流量打到Node的埠上或通過負載均衡器,會執行相同的基本流程,但是在哪些案例中客戶端IP是可以更改的。
    ⑤IPVS
    在大規模叢集(10000個服務)中,iptables操作會顯著降低速度。IPVS轉為負載平衡而設計,並基於核心內雜湊表。因此,您可以通過IPVS的kube-proxy在大量服務中實現效能一致性(O(1))。同時,基於IPVS的kube-proxy具有更復雜的負載平衡演算法(最小連線,區域性性,加權,永續性)

相關文章