成人免费xxxxx在线视频软件_久久精品久久久_亚洲国产精品久久久_天天色天天色_亚洲人成一区_欧美一级欧美三级在线观看

萬字解讀云原生時代,如何從 0 到 1 構建 K8s 容器平臺的 LB(Nginx)負載均衡體系

云計算 云原生
云原生時代,基于 Kubernetes 的容器編排方案是當下最優選擇,各個中型、大型互聯網公司全都擁抱 Kubernetes,沒有其他方案可以與 Kubernetes 匹敵。

云原生時代,基于 Kubernetes 的容器編排方案是當下最優選擇,各個中型、大型互聯網公司全都擁抱 Kubernetes,沒有其他方案可以與 Kubernetes 匹敵。

所有業務(尤其是高并發業務)的訪問必然要通過負載均衡 LB 代理層,服務端高并發系統離不開負載均衡,大中型公司下,負載均衡代理層都是有專人進行獨立開發和建設的,云原生 Kubernetes 容器平臺下的 LB 代理層,同樣需要有專人來負責建設和維護。那么 Kubernetes 容器平臺基礎下的的 LB(Nginx) 負載均衡代理層要怎么建設?和非容器平臺下的 LB 建設有什么異同?建設的核心要點和當下最優的方案是什么?相信看完本文,都會對 Kubernetes 容器平臺的 LB(Nginx)負載均衡了然于心,并且可以快速深入建設 Kubernetes LB(Nginx)負載均衡體系。還可以了解到,一個中大型公司,是如何從 0 到 1 來構建大規模 Kubernetes 容器平臺的 LB(Nginx)負載均衡體系的一些非常寶貴的實戰經驗。

適應人群 :Kubernetes 開發者、LB 開發者、Kubernetes 基礎運維人員、LB(Nginx)從業者、容器平臺開發 or 架構設計人員。

一、容器 LB 建設的背景

PS:如果對 Kubernetes 基本概念還不熟,那么需要先理解一下 Kubernetes,本文是針對對 Kubernetes 基本概念有一定理解的基礎上來進行分析和設計。

1.初識負載均衡(LB)

負載均衡(Load Balancer,簡稱 LB)是指把客戶端訪問的流量通過負載均衡器,然后根據指定的一些負載均衡策略進行轉發,最終可以均勻的分攤到后端上游服務器上,然后上游服務器進行響應后再返回數據給客戶端。負載均衡的最常見應用是充當反向代理,通過負載均衡,可以大大的提高服務的響應速度、提高并發請求、提高穩定性(防止單點故障)。

  • 負載均衡的基本實現方案,從業界來看,一般分為軟件和硬件兩大類,軟件負載均衡又可以分層如4層、7層負載均衡,如下:
  • 硬件負載均衡
  • 如 F5,性能好,但是貴。一般的互聯網公司都沒有采集硬件負載均衡
  • 軟件負載均衡
  • 目前這兩個都可以實現 4 層,但是更多的還是使用 Nginx 的 7 層功能。
  • 4 層:典型的如 LVS
  • 7 層:典型的如 Nginx、HAProxy

2.容器化下 LB 的異同點

在物理機時代,還沒有容器化之前,典型的負載均衡的建設方案就是搭建一套 Nginx 集群,提供 7 層的代理;搭建一套 LVS 集群,提供 4 層代理方案。并且同時,一般 7 層之上,都有一個 4 層代理,流量的基本流向就是 client -> LVS(4 層) -> Nginx(7層) -> server 。

在物理機這個時代,運維人員對 Nginx 的 upstream 的配置,基本都是手動添加修改各個 server,然后推送配置上線應用。傳統的物理機時代的維護方式,是基于后端 server 的 IP 基本是固定的,比如,你上線一個 WebServer 的服務,要部署到哪些機器上,這個是事先確定好的了,IP 會固定不變,不管你怎么升級,服務都還是固定在這些機器上,因此這個時代這樣的維護方式,并沒有太多問題,大家以往也都維護的挺和諧。

在容器化時代,基于 Kubernetes 的容器化平臺下,LB 的建設有哪些差異呢?主要分為兩大塊:

? 后端服務的 IP,會由于集群的調度,IP 是可變的,每當你部署、升級等操作的時候,IP 都會改變,那么這個時候,我們顯然不能夠再繼續采用原有寫死 IP 的方式來進行 7 層代理的維護了。由于服務 IP 的不確定性,我們必須要改變姿勢,不能由人為填充 Nginx 的 upstream 的 server ip 的方式,只能通過動態的獲取和變更,這個就需要 LB 能夠主動發現后端服務并且動態更新

? Kubernetes 的容器化平臺下,集群內部的網絡是虛擬的,虛擬網絡的 IP 在集群外部是無法訪問的,因此還需要解決好容器集群內外的網絡互通問題。

二、容器 LB 負載均衡怎么建設

1.Kubernetes 的負載均衡

Kubernetes 本身有內置一個集群內部的負載均衡方案,叫 kube-proxy,但是這個只能內部訪問,并且功能稍顯不足;而實際上,我們的容器平臺,必須要提供集群外部訪問的功能,因為你的用戶(客戶端)都是在集群外部。

Kubernetes 負載均衡相關的方案,包括:

  • 集群內部負載均衡【內置】

Pod IP 在集群內部都是互通的,因此集群內部無需考慮網絡互通問題

每個 Node 節點上的 kube-proxy,就是集群內置的內部負載均衡的解決方案;但是只限于集群內部,并且功能有限

  • 集群外部負載均衡【額外添加】

社區提供的 nginx-ingress-controller 方案可以滿足需求

云廠商的 Cloud provider 也可以滿足需求

參考 nginx-ingress-controller 的模式,自建 LB 方案

由此可見,如果是在自己 IDC 內部建設容器 LB 方案,那么只能采用自建方案 或者基于 nginx-ingress-controller 方案來建設;如果是上云的話,那么可以自建,也可以直接采用云廠商的方案。

下面所有的介紹,都是基于自建方案來設計,在 IDC 內部,我們要怎么從 0 到 1 來建設 K8s 容器的 LB 體系。

2.業務需求

業務功能需求就在于,業務(開發)使用容器 LB 體系的時候,他們會需要哪些需求,包括怎么使用、需要哪些功能、需要哪些策略,作為容器 LB 建設的開發人員,我們需要能夠站在業務方的角度去考慮,如下圖所示,有這些業務需求:

圖片

詳細說明如下:

  • 體驗需求

LB 分組:這個業務非常核心,需要獨立的 LB 集群,也就是 LB 代理層需要分組

域名解析線路:如果是多集群、多 IDC,那么服務暴露的域名,要怎么解析,是全 IDC 都解析,還是只解析到某一個集群

7 層代理的一些高級配置,如 uri 的 rewrite 規則、自定義一些特殊配置

大部分用戶:業務要暴露自己的服務只需要足夠簡單的配置和理解,他們不需要也不想關注服務暴露的細節,要的就是一個結果,我的服務部署了,我要暴露出去給 client 端調用

小眾用戶:業務非常核心,有各種不確定因素存在,業務開發人員需要關注細節

  • 負載均衡代理層的常規功能需求

要能夠統計 SLA ,包括 QPS、慢請求、錯誤數 等

要能夠針對異常進行告警

要能夠支持常見的負載均衡算法,如輪詢、最小連接、hash 等

負載均衡代理層要能夠支持超時、重試等基本功能

負載均衡代理層還必須要能夠支持對后端服務的健康檢查

基本的服務暴露:支持 4 層、7 層的代理方案,支持 7 層的 HTTP、HTTPS,也支持基本的 PATH 路由

域名:服務暴露的時候,每個服務肯定需要有自己的域名,那么這個域名需要能夠支持默認按照一定規則生成,還需要能夠支持自定義域名;具體怎么選擇就看業務自己的需求

內外網的需求:有些業務是直接給 APP 調用的,那么必然需要暴露到外網;而有些業務只是需要集群內部訪問,那么就暴露到內網即可;

upstream 上游(后端)服務的基本策略

監控和統計

  • 負載均衡代理層的高級策略需求

限流策略:高可用服務必須要有的功能,通過 LB 代理層進行限流,防止流量太大從而導致后端過載引發整體故障

熔斷保護機制:當服務發現異常,并且通過限流還不能解決的時候,需要能夠直接熔斷,也就是直接斷開請求,防止影響到其他業務

灰度放量:當業務新上線一個功能(版本迭代)的時候,首先需要進行灰度放量,然后觀察,看是否滿足預期,如果滿足預期則繼續灰度放量;如果有異常則需要馬上回滾

3.運維需求

我們建設的容器 LB 方案,最終是要交付給運維同學去使用的,運維必須要把控好整個公司的流量入口,LB 就是整個公司的流量入口;而且一般業務同學也沒有權限去操作 LB 相關的配置。那么,站在運維的角度來看,容器 LB 需要提供哪些功能呢?如下圖所示,有這些運維需求:

圖片

詳細說明如下:

  • 負載均衡器的相關管理

負載均衡器的自動化腳本部署,因為運維需要部署負載均衡器,那么怎么樣能夠實現更為智能的自動化腳本部署,而不是零散的各個命令去操作呢?這塊依賴于我們提供的一些操作步驟和子命令,然后結合 ansible 來封裝實現

負載均衡器的擴縮容,部署完了之后,后續還可能有擴縮容需求,比如國慶期間、春節期間、大促期間,這是需要提前擴容的,那么怎么能夠快速擴縮容?怎么更自動化?這塊同樣也是需要結合 ansible 來封裝實現

負載均衡器的分組,對運維而言,穩定性是首要的,那么線上的業務,有重要的服務,也有非重要的服務,一般而言,對重要核心的服務、流量非常大的服務,都需要單獨的分組,用來進行物理上的隔離和管控

  • 權限管控和審計

權限,一般而言,公司建設 Kubernetes 容器平臺,都會有一套管理平臺系統,所有人都是通過管理平臺來操作,包括運維和開發。如部署業務服務、上下線、LB 的操作和管理等等。那么既然是這樣,那么必須要控制好權限,不同角色有不同的操作權限,避免所有人都能夠操作負載均衡的相關配置,只有管理員 或者 運維人員才能夠操作

審計,線上的所有變更,都需要有審計,方便回溯問題

  • 業務服務的配置操作

Nginx 負載均衡的基本配置檢測,要能夠通過管理平臺來實現,包括基本檢測和異常檢測,檢測通過才能執行變更

Nginx 負載均衡配置的灰度和回滾機制,灰度是說變更之前,需要先灰度 1 個 Nginx 節點,確保這次變更沒有問題之后,才能全量變更;回滾是說如果灰度出現問題,那么需要能夠快速回滾到上一個版本

Nginx 負載均衡配置的基本查看、搜索;可以全局管理所有配置;可以搜索關鍵字來快速定位配置

  • 穩定性的相關操作(流控)

業務限流,當業務流量過大之后,根據實際情況進行限流,避免打滿后端服務

灰度放量,業務更新之前需要一個灰度逐步放量的過程

  • LB 系統和域名管理系統打通

中大型公司而言,都會有內部的域名管理系統,每個服務都會有一個對外暴露的域名來訪問,那么域名管理系統必須要和 LB 系統打通并且聯動起來,形成一個完整的操作鏈。這就需要用戶暴露一個服務的時候,并不用事先申請域名,直接在 LB 系統這里進行申請即可。

4.基本方案和基本原則

Kubernetes 下,后端服務都是 Pod 的形態,Pod 要能夠實現對外的負載均衡,就必須要成為 nginx 的 upstream。而 Pod 的 IP 是隨時都可能變化的,為此,就需要一個 Nginx-Controller 來動態發現 Pod,然后渲染為 nginx 的 upstream;Nginx-Controller 就是一個 Nginx 再加上一個 Controller(發現 Pod 并渲染為 upstream)。

所以,就需要我們能夠自研一個 Nginx-Controller 組件來實現了,那么這個 Nginx-Controller 有些什么要求 ?

A,集群內外的網絡要能互通

基本要求就是:

  • 集群內,Nginx-Controller 要能夠將流量分發給 Pod

需要將 Nginx-Controller 納入到 Kubernetes 的節點中,也就是部署 Nginx-Controller 的機器必須是 Kubernetes 的 Node 節點

  • 集群外,外網的請求要能夠轉發到 Nginx-Controller 中

這就需要部署 Nginx-Controller 的機器能夠和外部互通,一個最簡單的方式就是,Nginx-Controller 采用二進制部署,使用 Node 主機的網絡,這樣就可以了

因為 Node IP 是互通的,只有 Pod IP 不互通

B,動態發現 Pod 并且渲染為 nginx 配置

首先,我們需要能夠 watch 到 Pod、Service、 Endpoints 等資源的變化,這個就需要和 K8s API Server 交互,一般我們現在都是使用 Golang 語言來實現,因此可以基于官方的 client-go 來實現

在這,我們需要提供一套統一的模板配置,方便業務配置,然后自動渲染。因為 Nginx-Controller 要 watch 的業務服務資源是未知的,隨時可以增加或者刪除,那么最好能夠有一套模板機制來實現,對于 Golang,可以通過 Golang 的 template包來封裝模板的實現,結合模版和當前 Service、Endpoints 的情況,渲染成對應的 nginx 配置。比如:

upstream test-api {
{{ k8sBuildUpstream "default.test-back" "port=8080" "max_fails=3" "fail_timeout=3s" }}

會渲染成相應服務的節點列表和端口:

upstream test-api {
server 10.1.1.7:8080 max_fails=3 fail_timeout=3s;
server 10.1.1.9:8080 max_fails=3 fail_timeout=3s;
}

C,實現灰度、全量、回滾的機制

Nginx-Controller 雖然可以動態渲染 nginx 配置了,但是作為線上服務,必須需要有灰度、全量、回滾的機制。

因為我們的容器 LB 是需要分組的,每一組 LB 也都會有多個 nginx 節點,灰度就是指,我們的配置要發布,首先灰度一個節點,確保這個節點 OK 之后,再灰度到下一個 nginx 節點,或者可以全量到所有 nginx 節點。回滾則是指當我們灰度一個節點之后發現有問題,則回滾這個節點的配置。

怎么實現呢?可以通過兩個 configmap 來解決灰度和全量更新的問題,configmap-canary 這個作為灰度的 configmap,并且通過 annotation 來標記哪些是要灰度的 nginx 節點的 IP,這樣 nginx controller 如果識別到configmap-canary 里面的變化,則通過 annotation 的 IP 來判斷是否是本節點的,如果是本節點的則渲染配置并且 reload nginx,從而生效,如果不是本節點的,那么則丟棄。當要全量的時候,則:

  • 首先,將所有的全量節點追加到 configmap-canary 的annotation["ip"]字段中,nginx-controller 讀取該字段,匹配ip字段,匹配節點更新配置
  • 然后,如果確保已經全量成功,那么則先將 configmap-canary 的內容覆蓋到 configmap-release 中,然后再清空 configmap-canary 中的 IP 列表;這樣就可以完成整個灰度和全量的過程。

如果灰度的時候,發現異常了,需要回滾,那么直接清空 configmap-canary 中的 IP 列表;然后再回滾到上一個版本后,重新再走一遍發布流程來完成回滾操作

D,容器 LB 組件本身的管理和部署

上面說到容器 LB 組件本身(Nginx-Controller)需要二進制部署到 Node 主機上,那么要合理的管理這種二進制部署的需要一直運行的程序,一個較常見并且優雅的姿勢就是通過 systemd 來管理。示例配置如下:

[Unit]
Descriptinotallow=nginx-controller daemon
Documentatinotallow=/www/nginx-controller/bin/nginx-controller -h
After=nginx.service
Wants=nginx.service

[Service]
Type=simple
ExecStart=/www/nginx-controller/bin/nginx-controller --slow-start=true --is_dynamic=true ${OPTIONS}
ExecStop=/bin/kill -SIGTERM $MAINPID
ExecReload=/bin/kill -HUP $MAINPID
KillSignal=SIGQUIT
Restart=on-failure
RestartSec=3s

[Install]
WantedBy=multi-user.target

只要將這個配置放到 /usr/lib/systemd/system/ 中,systemd 就可以管理起來了。

E,各種統計和監控

Nginx-Controller 代理層所需的監控包括如下:

  • 進程的監控

進程是否存活、是否出現 panic 等

  • 日志監控

日志首先要采集,然后要對錯誤日志進行監控,可以使用 ELK

  • 基本指標監控

Nginx-Controller 的一些基本指標監控,可以使用 Prometheus

比如 reload 次數、更新次數、更新是否失敗 等。。。。

  • LB 所在主機的機器性能監控

CPU:idle、system、user 等指標

網卡軟中斷

網絡帶寬:流入和流出帶寬指標、網卡丟包指標

內存使用、swap 使用

磁盤 IO:讀、寫兩方面

剩余句柄數

  • LB 代理層的基本業務指標監控

SLA

錯誤統計

延遲統計

域名維度、path 維度等

三、容器 LB 體驗優化(LB 架構產品設計)

1.初期的架構圖

我們既然是從 0 到 1 來構建 K8s 的 負載均衡體系,那么初期必然是需要從物理機轉向容器,一般的選擇是為了能夠保證項目可以正常實施,容器 LB 這塊的抉擇,會結合著運維同學的一些習慣、可接受性以及更少的改動、更高的穩定性來做一些架構上的取舍。

沒有容器化之前,7 層代理的架構一般是 client -> CDN -> LVS -> 物理機 Nginx -> server ;

為了滿足上述訴求,在容器化之初,容器 LB 可能還不穩定,需要逐步導量過來,因此整體架構會是client -> CDN -> LVS -> 物理LB -> 容器LB(Nginx-Controller) -> POD ,如下:

圖片

LVS 和 Nginx 都需要做高可用,因此:

  • LVS 就是通過 keepalive 本身來做高可用,并且 LVS 需要配置萬兆網卡,因為所有流量都要經過 LVS。
  • Nginx 的高可用和高并發就是建立一組 Nginx(多個 Nginx 實例),然后掛到 LVS 下面做心跳檢測和流量分發

LVS 4 層代理可以對 Nginx 做檢測來保證高可用

LVS 4 層代理可以基于 4 層做流量分發到 Nginx 上

  • 容器 LB(Nginx-Controller) 和 Pod 的網絡需要能夠互通,因此 容器 LB 也需要建立在 Kubernetes 集群之內,在同一個網絡架構下

Kubernetes 容器平臺的網絡可以選擇 Calico

2.最優的架構圖

在項目中后期,容器 LB 傾向穩定之后,那么我們要考慮的就是性能問題、成本問題、體驗問題了,為此,架構需要逐步演進。

  • 首先,物理機 Nginx 的存在,會導致多了一層鏈路

增加響應耗時

增加配置管理的復雜度

增加問題排查的鏈路分析

增加機器成本

  • 其次,Nginx-Controller 這個方案,有更優的替代方案,那就是nginx-ingress-controller

整體的最優的架構流向就是: client -> CDN -> LVS -> Nginx-Ingress-Controller -> Pod

Nginx-Ingress-Controller 的具體介紹在后面章節進行分析。

3.體驗優化

優化 1:實現動態 upstream,減少 Nginx Reload 帶來的 502

為何需要支持動態 upstream 呢?這是因為,在 K8s 下,服務的 Pod IP 會經常改變,比如每次發布更新的時候 Pod IP 都會變化,這也就意味著,nginx 的 upstream 的 server 列表會經常改變,那么每次 IP 有變化的時候,nginx 都需要 reload 的話,那么在線上高并發、大流量的場景下,長連接的服務會經常在 nginx reload 的時候出現 502,這個是不能接受的,非常影響業務的 SLA

那么為何長連接的服務會經常在 nginx reload 的時候出現 502 呢?這個要重點分析下 nginx 在進行 reload 的時候,對于老連接是怎么處理的,一個確定的流程是:

  • 如果當前連接是空閑狀態,那么直接關閉
  • 如果當前連接還在等待 upstream response,那么會等待請求處理結束或者超時 (proxy_read_timeout),再關閉

這一過程對于短連接的請求,是挺合理的,表現也挺正常的。但是對于長連接場景,nginx 有些處理不好的地方。對于長連接請求,nginx 在處理完最后一個請求,返回 response 的時候,他依然是返回 Connection: keepalive 的 response header。這樣就會導致會有一個時間窗口差,在 nginx 對于這個連接進行 close 以及到 Linux 內核完整 close 這個連接,并且發出 FIN 到 client 這個時間段內,client 端如果是高并發的場景,那么由于是長連接,因此很也可能會繼續復用這個連接來發起新的請求給 Nginx,這樣 Nginx 機器所在的 Linux 內核看到對于一個已關閉的連接還有新的請求,那么就會直接返回 RST 包,從而導致了 client 的一些 502 的錯誤。

優化 2:實現 SlowStart 功能,減少 Pod 啟動初期的 SLA 性能下降

SlowStart 策略,指的是,在 Pod 初次啟動并且能夠對外提供服務之后,剛開始給一個緩沖時間,在這個緩沖時間內,先提供小流量的請求,進行有 weight 權重的 RR 算法,只允許非常小比例的流量;這個緩沖時間之后,再開始無權重的 RR 算法。

一般而言,Pod 的 Readiness 探針是可 worker 之后,就認為這個 Pod 可以開始對外提供服務了。但是針對某些 Java 服務,Readiness 探針 OK 后,還不能馬上提供大量服務,因為 Java 需要啟動 Java 虛擬機,初始化相關系統、組件;還有一些各種內存池、線程池 等初始化工作要做;而這些初始化工作在某些情況下可能需要一點耗時;或者某些情況下是有請求過來后才進行初始化,但是由于初始化需要時間,因此 Readiness 探針 OK 之后,還不能馬上提供大量服務,否則在啟動的時候就可能造成服務的些許不穩定,從而降低 SLA,給業務帶來影響。這個是我們實際 Java 項目所得出的結論,因為 jit 的影響,如果在低流量下完成 jit 編譯,這樣給一個緩沖時間,最終效果就是可以提高 SLA。目前這個功能其實是一個規避措施,按理來說需要業務方自己解決的,因為不同的業務方可能情況也有些區別。

具體怎么實現呢?這就要結合 Kubernetes 本身機制來綜合實現了。一般 Kubernetes 中服務的部署是通過 Deployment + Service 來部署一個服務;那么這樣的話,服務就可以支持 Deployment 的滾動更新的特性,通過配置MaxSurge(如 25%),MaxUnavailable(如 25%),minReadySeconds(如 30s),progressDeadlineSeconds(如 600s) 幾個參數來控制滾動策略,可以實現每次滾動升級過程中新舊一起加起來的總的 Pod 數會小于等于(1+MaxSurge)* desiredPods,而 available 可以的 Pod 節點數可以保證大于等于 MaxUnavailable * desiredPods,新增 Pod 節點 ready 后等待最少 minReadySeconds 后成 available,整個滾動流程超過 progressDeadlineSeconds 600s 停滯則認為失敗,回滾舊版本。

為此,SlowStart 的機制實現就可以利用這個特性了,如果開啟了 SlowStart 功能,那么就判斷 Pod 節點是否是本次更新新啟動的節點,如果是新啟動的的 Pod 節點則調整其 Pod 的 weight 成預設比例(一般是較小權重),當節點 ready 時間超過 MinReadySeconds 后 ,恢復 weight 成正常權重(默認:100) ,從而實現 SlowStart 慢啟動。這個機制的 SlowStart 功能實現的慢啟動針對的是整個業務的 Service 級別的。利用這個特性來判斷節點是否為新增節點,總結來看需要滿足的條件如下:

# 1. 節點在deployment發布周期內
LatestPod.ReadyStatus.LastTransitionTime + progressDeadlineSeconds > CurTime

# 2. 節點ready后未超過minReadySeconds窗口
CurPod.ReadyStatus.LastTransitionTime + minReadySeconds > CurTime

# 3. 當前節點初始化時間與最新節點初始化時間差值未超過minReadySeconds窗口,防止擴步長限流
CurPod.InitializedStatus.LastTransitionTime + minReadySeconds > LatestPod.InitializedStatus.LastTransitionTime

如果是新增節點的話,則設置其 weight 為 100 * slow-start-weight,并且設置 service 級別的觸發器,在LatestPod.ReadyStatus.LastTransitionTime + minReadySeconds + 10s - CurTime 時間后恢復為默認權重( weight=100)。

優化 3:LB 配置發布和運維域名管理系統打通,減少服務暴露的流程步驟

一般的互聯網公司,運維這邊都會有自己的域名管理系統,開發人員可以通過提單的方式,讓運維給自己的服務分配一個域名(內網、外網);然后開發人員拿到這個域名之后呢,再和自己的服務綁定,這個綁定的過程就是服務暴露的過程。服務暴露就是指在 LB 這邊建立對應的規則,然后讓就可以通過這個域名來訪問對應的服務了。

這個服務暴露的過程,首先需要人工提單,拿到域名后再進行手動配置,為此,如果公司有合適的機制和契機,那么應該需要將容器 LB 進行服務暴露的過程和域名管理系統打通,當業務需要進行服務暴露的時候,不再需要通過多個平臺的操作來完成,只需要在容器 LB 這邊的管理平臺中進行服務暴露,然后內部可以自動生成域名或者自定義域名,然后自動和域名管理系統打通,然后正式生效對外提供服務。

這樣的優化主要的目的就是為了提升用戶體驗,減少中間的人工操作環境,從而也可以進一步減少人力成本。

優化 4:移除物理機 Nginx,優化鏈路,降低成本

我們前面說到,在初期的時候,為了保證穩定和過渡,還是需要有物理機 Nginx 的存在,物理機 Nginx 的主要作用有兩方面:

  • 其一,可以通過物理機 Nginx 這一層來對容器 LB 的流量進行灰度放量,同時可以能及時回滾
  • 其二,整個公司的業務服務,會有很多依然部署在物理機上,初期只會有小部分服務會開始逐步往容器進行遷移,因此物理機 Nginx 還必須要保留

但是在項目中后期,容器 LB 會逐步趨于穩定,此時,就需要逐步移除物理機 Nginx,直接是 LVS 到容器 LB,但是移除物理機 Nginx 需要有大量的工作要去梳理,因為物理機 Nginx 的配置是手動配置的,可能有很多差異化、特性化的配置。

優化 5:采用 nginx-ingress-controller 方案,減少 nginx 配置的干預,一步到位

前面說到 nginx-ingress-controller 可以作為最優方案來替代 Nginx-Controller, nginx-ingress-controller 產生的主要目的就在于能夠將 Kubernetes 中的 Service 所代理的 Pod 服務暴露在 Kubernetes 集群之外,這樣就能夠打通集群內外的訪問問題,通過 ingress 可以直接進行七層的負載均衡,并且可以對外訪問,同時減少了一些復雜的配置。

因此,請求流程 client -> LVS VIP -> ingress-controller -> 業務 POD

具體的 nginx-ingress-controller 方案參看下面最后的說明。

四、容器 LB 開發設計的核心考量點

容器 LB 開發設計的核心考量點有如下:

圖片

詳細說明如下:

1.支持動態 upstream 的實現【非常重要】

K8s 容器平臺下,業務服務的 Pod 的是動態變化的,比如再每次重新部署、滾動升級、被驅逐重建等情況之后, Pod 的 IP 都是會發生改變。每次 Pod IP 改變,那么就意味著 Nginx 的 upstream 發生了變化,如果沒有實現動態 upstream,那么將會導致每次 Pod IP 變化,Nginx 都需要進行異常 Reload 操作。在線上大規模集群下,如果業務的 QPS 請求很高,Nginx 頻繁 Reload 會導致 client 端的長連接請求在 Nginx Reload 的時候出現 502,這樣將降低業務的 SLA,故而無法提供高可靠的服務保障。

故而,只要我們實現了動態 upstream,比如基于 lua 模塊的實現,那么不管后端 Pod IP 如何變化,Nginx 后端 upstream 的 IP 將會通過 lua 共享內存傳遞并進行負載均衡,因此 Nginx 將不會進行 Reload,從而會大大提高 SLA 服務質量。

2.支持后端 pod 的健康檢查

Pod 本身,K8s 的 kubelet 會做健康檢查,那么容器 LB 層面為何還需要對 Pod(業務服務)做健康檢查呢?

  • kubelet 本身可能會出現故障導致不能及時摘除異常的 Pod,因此我們不能完全信任 kubelet
  • 如果 Node 節點出現異常,那么 kubelet 把 pod 標記不可用,基本需要幾十秒,也就是影響幾十秒之后才能檢測到

3.SlowStart 策略

Nginx 的商業版本有支持 slow_start 功能,使用如下:

upstream backend {
server backend1.example.com slow_start=30s;
server backend2.example.com;
}

SlowStart 策略是指配置了 SlowStart 策略的 server,在 SlowStart 時間范圍內,先給一定量的流量(比如 0% - 1%),在過了 SlowStart 時間之后,再恢復 100% 的流量。

這樣,在 SlowStart 時間范圍內,這個 server 就可以在低流量下處理一些服務內部初期的一些事情,比如 Java 服務,可以在低流量下完成 jit 編譯、完成 Java 虛擬機初始化等,這樣,當過了 SlowStart 時間之后,等一切就緒在恢復 100% 的流量,可以保證服務可以對外提供更好的質量。

當前,這個是商業版本的實現,開源版本無法使用,因此就需要我們自己實現,在 K8s 下,容器 LB 的 SlowStart 功能的具體實現可以參考文章前面的說明。

4.巡檢模塊

巡檢模塊不僅僅是針對容器 LB,可以是針對所有容器基礎模塊,這個的目的就在于,人為模擬一些實際情況,通過巡檢,把容器 LB 的各個環節都定期檢測一遍。這個在上線初期尤為重要。

巡檢模塊的實現至少包括如下:

  • 解耦待巡檢服務(利于增加不同的巡檢模塊)
  • 多久檢測一次(間隔、重試)
  • 檢測的異常定義(比如 latency、error 等)
  • 出現異常的處理機制(比如告警、輸出日志等)

通過巡檢模塊,可以有如下優勢:

  • 首先可以保證容器 LB 出現問題能夠及時發現,因為是自定義任務來檢測容器 LB 的各個環節,因此大概率可以先于業務本身發現。巡檢模塊出現問題之后,需要及時告警給相關人員進行處理
  • 然后因為巡檢了容器 LB 的各個環節,因此如果巡檢模塊沒有出現問題,那么容器 LB 的整體就基本是正常的,這個對于維護人員的信心度可以大大增強。

5.Nginx SLA 統計模塊

業界用的多是 tengine 的 ngx_http_reqstat_module,如果想要更優化,可以在此基礎上進行擴展,增加如下這些功能:

  • 慢請求統計
  • 支持 http 自定義錯誤碼(如 6xx 7xx) 等的統計
  • 自定義 http status 的統計
  • 支持以 upstream 為維度來統計

6.性能壓測和優化

容器 LB 必須要進行大量壓測和優化,以求達到最優的性能,提供最穩定的服務。

本文轉載自微信公眾號「 后端系統和架構」,作者「AllenWu」,可以通過以下二維碼關注。

轉載本文請聯系「 后端系統和架構」公眾號。

責任編輯:武曉燕 來源: 后端系統和架構
相關推薦

2025-05-26 10:00:00

TkinterGUIPython

2021-10-18 11:58:56

負載均衡虛擬機

2022-07-18 18:48:32

Kubernetes云原生

2024-08-30 10:29:21

2025-03-05 08:33:56

2021-04-25 10:26:58

云計算云原生

2024-11-27 16:37:57

2021-07-14 18:21:38

負載均衡K8SgRPC

2025-01-03 08:08:56

2024-07-15 07:55:00

2024-09-26 09:50:07

2022-08-21 07:25:09

Flink云原生K8S

2021-08-09 11:43:02

容器云原生安全

2023-03-06 11:35:55

經營分析體系

2023-08-28 16:08:12

2022-04-07 10:17:18

云原生服務器優化

2022-07-13 11:17:00

大數據規劃

2022-01-02 08:42:50

架構部署容器

2018-02-01 10:31:12

Nginx負載均衡軟件
點贊
收藏

51CTO技術棧公眾號

主站蜘蛛池模板: 久久精品网 | 天天射天天操天天干 | 欧美日批 | 精品一区二区三区在线观看 | 亚洲 欧美 综合 | 日韩av福利在线观看 | 亚洲视频在线看 | 久久狠狠| 日本一区二区三区视频在线 | 黄色在线免费观看 | 成人精品啪啪欧美成 | 国产黄a一级 | 我我色综合 | 日韩精品一区二区三区在线 | 久久久久久免费看 | 在线免费观看成人 | 国产精品国产三级国产aⅴ中文 | 国产a级黄色录像 | 狠狠操电影 | 秋霞国产 | 久久精品网 | 国产网站在线播放 | 一区二区三区四区免费在线观看 | 第一区在线观看免费国语入口 | 亚洲精品一区二区三区 | 欧美黄色片在线观看 | 香蕉视频一区二区 | 看片地址 | 国产精品免费小视频 | 国产精品不卡一区 | 久久精品视频在线播放 | 日韩在线一区二区三区 | 免费a网 | 国产永久免费 | 成人乱人乱一区二区三区软件 | 欧美一级黄 | 久久国产精品-久久精品 | 亚洲国产成人在线观看 | 羞羞视频网页 | 久久大香 | 欧美精 |