利用 K8S 的反親和性構建高可用應用
K8S 支援多副本部署,但不代表應用的高可用,因為多個副本可能部署到同一個節點上。
早上發現應用的某一個功能有一半的請求失敗,排查之後發現,原來 容器服務中節點未設定反親和性,導致 Pod 部署到同一個節點中,影響 API 閘道器請求後端服務。
架構圖
先 review 以下架構圖
- Web 應用:Vue 框架,執行在 上
- 業務 API:Golang 框架,執行在 容器服務上,使用 NodePort 方式對外暴露服務
1. 問題
在頁面中使用頁面功能時,發現有一半的請求失敗,API 返回為空。
於是想到可能和 API 閘道器請求後端介面有關,下圖為 API 閘道器對應後端通道的配置,有 2 個節點。
檢視容器服務對應 Pod,發現兩個副本都執行在同一個節點上,問題找到了。
副本跑在同一個節點的原因:隨著叢集的變化,一開始部署在兩個節點上的 Pod, 因為其中一個節點的資源被佔滿, 導致 Pod 優先排程到另一個閒置的節點上。
2. 解決問題:設定反親和性
解決問題的思路是讓 Pod 不能排程在同一臺 伺服器上,需要打散排程到所有節點中。
ChatGPT 助手的 QA 詳見附錄,也可以檢視文字的幫助文件(是透過關鍵字
Anti-Affinity
檢索到的 )
容器服務雖然有
排程策略
功能,但無法滿足當前的場景, 於是編輯 Deployment 的 YAML 配置,在 Pod 上新增
spec.template.spec.topologySpreadConstraints
segment。
topologySpreadConstraints: - labelSelector: matchLabels: k8s-app: XXX qcloud-app: XXX maxSkew: 1 topologyKey: kubernetes.io/hostname whenUnsatisfiable: ScheduleAnyway
解讀:
maxSkew
設定為 1 表示允許的最大偏差為 1,即任一節點上的 Pod 數量不會比其他節點多 1 個以上。topologyKey
為"kubernetes.io/hostname"
,意味著在不同的節點上分佈 Pods。
部署後,Pod 分佈到多個節點上,問題解決。
3. 事後思考
- 開啟 API 閘道器的健康檢查,當 API 閘道器探測節點失效時從後端通道中剔除
- 瞭解 K8S 資源排程的基本概念
附錄:ChatGPT 助手
Q: TKE 如何設定讓 Deployment 的 2 個 Pod 分配到兩個節點上,目前 兩個 Pod 分配到同一個 節點中。
A(ChatGPT-4-turbo): TKE(Tencent Kubernetes Engine)是騰訊雲提供的託管 Kubernetes 服務。在 Kubernetes 中,如果希望讓 Deployment 的 Pods 分佈在不同的節點上,可以使用幾種策略,主要包括:
1. 親和性(Affinity)和反親和性(Anti-Affinity)規則:
使用 Pod 反親和性規則可以指定 Kubernetes 排程器不要將屬於同一 Deployment 的 Pods 排程到同一節點上。
例如,以下是一個 Deployment 配置的示例,它使用了 Pod 反親和性來確保 Pods 分散到不同的節點上:
apiVersion: apps/v1kind: Deploymentmetadata: name: my-deploymentspec: replicas: 2 selector: matchLabels: app: myapp template: metadata: labels: app: myapp spec: containers: - name: myapp-container image: myapp:1.0 affinity: podAntiAffinity: requiredDuringSchedulingIgnoredDuringExecution: - labelSelector: matchExpressions: - key: "app" operator: In values: - myapp topologyKey: "kubernetes.io/hostname"
在這個例子中,
requiredDuringSchedulingIgnoredDuringExecution
確保排程器在排程時遵循這些規則,而
topologyKey
設定為
"kubernetes.io/hostname"
表示 Pods 不能在擁有相同主機名的節點上執行。
2. 使用 Pod Topology Spread Constraints:
Pod Topology Spread Constraints 允許你更細粒度地控制 Pods 的分佈,這可以透過設定
maxSkew
、
topologyKey
和
whenUnsatisfiable
等引數來實現。
以下是一個使用 Pod Topology Spread Constraints 的 Deployment 示例:
apiVersion: apps/v1kind: Deploymentmetadata: name: my-deploymentspec: replicas: 2 selector: matchLabels: app: myapp template: metadata: labels: app: myapp spec: containers: - name: myapp-container image: myapp:1.0 topologySpreadConstraints: - maxSkew: 1 topologyKey: "kubernetes.io/hostname" whenUnsatisfiable: "ScheduleAnyway" labelSelector: matchLabels: app: myapp
在這個配置中,
maxSkew
設定為 1 表示允許的最大偏差為 1,即任一節點上的 Pod 數量不會比其他節點多 1 個以上。
topologyKey
同樣設定為
"kubernetes.io/hostname"
,意味著在不同的節點上分佈 Pods。
確保你的 Kubernetes 叢集有足夠的不同節點來支援這些分佈策略。如果叢集中只有一個可用節點,或者其他節點因為資源限制(如 CPU、記憶體不足)無法排程 Pods,那麼這些策略可能不會有效。
來自 “ ITPUB部落格 ” ,連結:https://blog.itpub.net/70030722/viewspace-3007532/,如需轉載,請註明出處,否則將追究法律責任。
相關文章
- 利用keepalived構建高可用MySQL-HAMySql
- 如何在阿里雲上構建高可用應用阿里
- 高可用架構之高可用的應用和服務架構
- 用 Hystrix 構建高可用服務架構架構
- 利用H5和ChromiumWebBrowser構建應用H5Web
- k8s高可用架構K8S架構
- 用於高可用性的Event Sourced 架構架構
- 構建高可用性、高效能和可擴充套件的Zabbix Server架構套件Server架構
- .1.7.2 應用程式高可用性與服務和FAN
- 利用Docker輕鬆實現雲原生應用-高可用架構設計Docker架構
- 構建ORACLE高可用環境Oracle
- OpenStack的高可用系統構建(1)
- OpenStack的高可用系統構建(2)
- 構建高效能和高彈性 WebSphere eXtreme Scale 應用程式的原則和最佳實踐WebREM
- Apache httpd和JBoss構建高可用叢集環境Apachehttpd
- 理解HDFS高可用性架構架構
- 構建高併發高可用的電商平臺架構實踐架構
- 如何利用容器與中介軟體實現微服務架構下的高可用性和彈性擴充套件微服務架構套件
- K8s 容器的定向排程與親和性K8S
- 反應性和非反應性程式碼的分離 - DZone
- 構建高併發&高可用&安全的IT系統-高併發部分
- 使用 WebSocket 構建實時性應用Web
- 利用Azure Functions和k8s構建Serverless計算平臺FunctionK8SServer
- 用Java構建反應式REST API - Kalpa SenanayakeJavaRESTAPINaN
- 搭建高可用k8sK8S
- 如何利用 Docker 環境加速 Android 應用的構建DockerAndroid
- 資深架構師談Redis高可用架構的應用及改進架構Redis
- 構建MHA實現MySQL高可用叢集架構MySql架構
- Mysql+Corosync+Pacemaker+DRBD構建高可用MMySqlROS
- 構建持續高可用系統的破局之道
- 華為雲FunctionGraph構建高可用系統的實踐Function
- MyCAT高可用方案和架構圖架構
- KubeSphere 最佳實戰:K8s 構建高可用、高效能 Redis 叢集實戰指南K8SRedis
- ELK架構下利用Kafka Group實現Logstash的高可用架構Kafka
- Activemq構建高併發、高可用的大規模訊息系統MQ
- 【陳吉平】《構建oracle高可用環境》前言Oracle
- 5、pgpool-II高可用性(一)資料庫的高可用性資料庫
- 使用 Yarn workspace,TypeScript,esbuild,React 和 Express 構建 K8S 雲原生應用(一)YarnTypeScriptUIReactExpressK8S