1. 程式人生 > 其它 >Kubernetes學習記錄(六):深入理解service和Ingress

Kubernetes學習記錄(六):深入理解service和Ingress

1. service

  • 防止pod失聯(服務發現)
  • 定義一組pod的訪問規則(負載均衡)

 

服務發現

假設現在是一個deployment控制器,一般為了保證高可用都會至少部署三個副本,而且三個pod都有獨立的ip地址

當一個pod掛掉之後,deployment會立刻拉取一個新的pod,但是新pod的ip地址明顯是和掛掉的那個pod不一樣

這時候service就發揮了作用,前端和後端pod不需要通過ip地址來直接通訊,而是經由service來做一個統一的管理操作

 

負載均衡

當我有多個副本時,客戶端傳送的請求需要具體轉發到哪個pod上,這就是負載均衡

 

1.1 Pod和Service的關係

  • pod與service通過label-selector關聯
  • 通過service實現pod的負載均衡(TCP/UDP四層,只負責IP資料包轉發

Service看起來就像是為Pod提供了一個網路代理的功能

 

1.2 Service常用型別

  • ClusterIP:預設設定,叢集內部使用
  • NodePort:對外暴露應用
  • LoadBalancer:對外暴露應用,適用於公有云

比如在一個客戶端-後端-資料庫的業務架構中,客戶端-後端、後端-資料庫之間的通訊就要選擇ClusterIP,因為這些都不需要暴露

而使用者和客戶端之間就需要使用NodePort,即我們要把客戶端的服務暴露出去

 

1.2.1 ClusterIP

分配一個穩定的IP地址,即VIP,只能在叢集內部訪問,同一個namesapce內的pod

最典型的ClusterIP就是k8s叢集服務的service,我們可以通過下面的指令檢視所有的svc

kubectl get svc

 

這個虛擬IP可以在任意一個節點、任意一個pod內訪問

 

1.2.2 NodePort

提供一個埠,供外部訪問,但其存在一個問題就是可以通過所有的<NodeIP+port>的形式來訪問

 

對外暴露的埠號從30000起,預設是叢集隨機分配的

也可以通過spec.ports.nodePort欄位來指定一個暴露埠,但注意可能會存在端口占用情況

這個暴露的埠在每個節點都會監聽,不論這個節點有沒有提供服務的pod

 

外界訪問任意一個node都可以獲取服務,通過 <NodeIP:NodePort> 的形式,然後統一由service來做負載均衡

 

比如在下面這個svc列表中,web是作為NodePort型別的,可以看到它在 PORT(S)這一項是有兩個埠號

左側是叢集內部訪問的,也就是一種ClusterIP

右邊是通過節點IP地址暴露出去的一個埠號

 

一般來講,生產環境中所有的node都部署在內網,即使暴露了埠,在公網上也無法訪問

這時候一般會有以下解決方案:

  • 找一臺有公網IP的伺服器,使用nginx反向代理到node
  • 使用外部負載均衡器,比如nginx、LVS、HAProxy做負載均衡,將流量轉發到node

 

1.2.3 LoadBalancer

與NodePort類似,在每個節點上啟用一個埠來暴露服務

除此之外,k8s還會請求底層雲平臺上的負載均衡器,將每個Node <NodeIP:NodePort> 作為後端新增進去

使用者通過訪問公有云上的負載均衡器來訪問node 

 

1.3 Service代理模式

1.3.1 Iptables

iptables是Service的預設模式

iptables能做什麼?

  • 阻斷IP通訊
  • 埠對映NAT
  • 跟蹤包的狀態
  • 資料包的修改

 

kube-proxy元件預設實現iptables,具體來講就是實現資料包在node之間的轉發

將service相關規則來落地實現

如果使用NodePort的訪問規則的話,我們在外部訪問任意節點IP+暴露埠,採取輪詢機制找到一個提供服務的pod

NodePort:192.167.11.89:30008

     -> KUBE-SVC-XXXXXX (負載均衡) --probalility  0.3333333

     -> KUBE-SEP-YYYYYYY

     -> -j DNAT --to-destination 10.244.2.2:80 (提供服務的Pod)

 

iptables的特點:

  • 靈活,功能強大
  • 規則遍歷匹配和更新,呈線性時延

 

1.3.2 IPVS

 

LVS就是基於ipvs模組實現的四層負載均衡器

ipvs特點:

  • 工作在核心態,有更好的效能
  • 排程演算法豐富:rr、wrr、lc、wlc、ip hash ...

 

2. Ingress

為什麼需要Ingress?

首先來看一下NodePort存在的問題:

  • 一個埠只能一個服務來使用,因為在所有的Node上都暴露了這個埠
  • 只支援四層的負載均衡

 

2.1 Ingress和Pod的關係

  • 通過Service完成關聯
  • 通過Ingress Controller實現Pod的負載均衡,支援TCP/UDP四層和HTTP七層

 

2.2 部署Ingress Controller

Ingress Controller有很多實現,官方維護的是nginx控制器,其他的主流控制器也有Traefik和Istio

官方提供了很多第三方控制器的專案地址:Ingress 控制器 | Kubernetes

我們使用官方的nginx控制器,下載好yaml之後需要修改映象源為國內映象源,修改hostNetwork: true

wget https://raw.githubusercontent.com/kubernetes/ingress-nginx/controller-v1.1.2/deploy/static/provider/cloud/deploy.yaml > ic.yaml

 

根據這個YAML檔案建立兩個pod,其實是和節點數有關,這是以DaemonSet方式部署的

 

2.3 設定Ingress規則

對於下面這個ingress規則,首先需要指定kind為ingress

最重要的就是service欄位,指明暴露的服務名稱和埠

同時通過域名繫結服務,如果測試的話需要修改本機hosts來訪問

2.4 Ingress根據URL路由到多個服務

比如在下面的示例中,Ingress管理了兩個service

使用者可以通過域名的方式來訪問這兩個service,其中/foo和/bar就負責路由的轉發

這個Ingress規則的YAML檔案如下所示:

 

Ingress規則中有兩個後端service,路由路徑分別為/foo和/bar

當我們訪問foo.bar.com/foo時,ingress就會幫我路由到service1,訪問foo.bar.com/bar時,ingress會路由到service2

其中的pathType: Prefix是字首匹配,也就是說只要是以 "/foo" 開頭的URL都會被路由到service1

匹配規則可見:Ingress | Kubernetes

 

2.5 Ingress Controller高可用方案

其中叢集模式更為常見,可以在公網節點上部署一個負載均衡器,比如nginx,把流量轉發給Ingress Controller

 

參考:

Ingress | Kubernetes

Installation Guide - NGINX Ingress Controller (kubernetes.github.io)

Ingress 控制器 | Kubernetes