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

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM