跨集群流量調度實現 Kubernetes 集群金絲雀升級

有了多集群服務和跨集群的流量調度之后,使用 Kubernetes 的方式會發生很大的變化。流量的管理不再限制單一集群內,而是橫向跨越了多個集群。最重要的是這一切“靜悄悄地”發生,對應用來說毫無感知。

就拿 Kubernetes 版本升級來說吧。記得曾經經歷過集群的原地升級:團隊的幾個人經過多次、多個環境的演練,還要在凌晨的時候進行生產環境的升級。幸好最后是有驚無險,整個過程的體驗就像是下圖一樣:為飛行中的飛機換引擎。

8aaa2f35120bd8473ec10e8abf733239.png
圖片來自網絡

解決了跨集群的流量調度之后,一切就會變得簡單:只需重新建個集群,慢慢將應用遷移到新的集群,讓乘客來個“空中轉機”。

方案

與之前所做的示例類似,整個方案的核心仍然是跨集群的服務調用:服務可以像使用本地 Service 一樣使用多集群 Service。

67c57988438e5704c04ef46f5bd49a6f.gif

Kubernetes 集群金絲雀升級

升級過程中,創建新版本的 Kubernetes 集群,其他的中間件復用現有的,這樣少了數據同步等問題。剩下的便是,調整 CD的流程將服務“同時部署到新的集群”。然后再通過?全局流量策略?慢慢放少部分流量到新的集群中進行測試,邊測試邊調整流量。兩個集群的服務也可保持一段時間觀察穩定性,然后再慢慢減少原集群的實例直至所有實例下線。

接下來,我們使用進行下示例演示。

演示

環境準備

如上面的圖展示的那樣,我們先創建兩個集群:control-plane1-23?和?1-25。集群?1-23?就是我們現有的集群,1-25?就是最新版本的集群。

集群對外訪問地址api-server 對外端口LB 對外端口描述
control-planeHOST_IP(192.168.1.110)6444N/A控制平面集群
1-23HOST_IP(192.168.1.110)644581應用集群
1-25HOST_IP(192.168.1.110)644682應用集群

環境搭建

獲取主機 IP 地址備用,192.168.1.110?是我本機的地址。

export?HOST_IP=192.168.1.110

搭建集群

使用 k3d 來創建這 3 個 集群。

API_PORT=6444?#6445?6446
PORT=80?#81?82
for?CLUSTER_NAME?in?control-plane?1-23?1-25
dok3d?cluster?create?${CLUSTER_NAME}?\--image?docker.io/rancher/k3s:v1.23.8-k3s2?\--api-port?"${HOST_IP}:${API_PORT}"?\--port?"${API_PORT}:6443@server:0"?\--port?"${PORT}:80@server:0"?\--servers-memory?4g?\--k3s-arg?"--disable=traefik@server:0"?\--timeout?120s?\--wait((API_PORT=API_PORT+1))((PORT=PORT+1))
done

安裝 FSM

在 3 個集群中安裝 FSM。

helm?repo?update
export?FSM_NAMESPACE=flomesh
exportFSM_VERSION=0.2.0-alpha.9
for?CLUSTER_NAME?in?control-plane?1-23?1-25
do?kubectx?k3d-${CLUSTER_NAME}sleep?1helm?install?--namespace?${FSM_NAMESPACE}?--create-namespace?--version=${FSM_VERSION}?--set?fsm.logLevel=5?fsm?fsm/fsmsleep?1kubectl?wait?--for=condition=ready?pod?--all?-n?$FSM_NAMESPACE?--timeout=120s
done

加入集群組

將集群?1-23?和?1-25?納入集群?control-plane?的管理。不管是新集群還是舊集群,如果要進行跨集群的服務調用,都是要加入集群組的。

export?HOST_IP=192.168.1.110
kubectx?k3d-control-plane
sleep?1
PORT=81
for?CLUSTER_NAME?in?1-23?1-25
dokubectl?apply?-f?-?<<EOF
apiVersion:?flomesh.io/v1alpha1
kind:?Cluster
metadata:name:?${CLUSTER_NAME}
spec:gatewayHost:?${HOST_IP}gatewayPort:?${PORT}kubeconfig:?|+
`k3d?kubeconfig?get?${CLUSTER_NAME}?|?sed?'s|^|????|g'?|?sed?"s|0.0.0.0|$HOST_IP|g"`
EOF
((PORT=PORT+1))
done

安裝服務網格

下載 osm CLI

system=$(uname?-s?|?tr?[:upper:]?[:lower:])
arch=$(dpkg?--print-architecture)
release=v1.3.0-beta.1
curl?-L?https://github.com/flomesh-io/osm-edge/releases/download/$release/osm-edge-$release-$system-$arch.tar.gz?|?tar?-vxzf?-
./${system}-${arch}/osm?version
cp?./${system}-${arch}/osm?/usr/local/bin/

將服務網格 osm-edge 安裝到集群?1-23?和?1-25。控制平面不處理應用流量,無需安裝。

export?OSM_NAMESPACE=osm-system
export?OSM_MESH_NAME=osm
for?CLUSTER_NAME?in?1-23?1-25
dokubectx?k3d-${CLUSTER_NAME}DNS_SVC_IP="$(kubectl?get?svc?-n?kube-system?-l?k8s-app=kube-dns?-o?jsonpath='{.items[0].spec.clusterIP}')"
osm?install?\--mesh-name?"$OSM_MESH_NAME"?\--osm-namespace?"$OSM_NAMESPACE"?\--set=osm.certificateProvider.kind=tresor?\--set=osm.image.pullPolicy=Always?\--set=osm.sidecarLogLevel=error?\--set=osm.controllerLogLevel=warn?\--timeout=900s?\--set=osm.localDNSProxy.enable=true?\--set=osm.localDNSProxy.primaryUpstreamDNSServerIPAddr="${DNS_SVC_IP}"
done

部署實例應用

在集群?1-23?的?httpbin?命名空間(由網格管理,會注入 sidecar)下,部署?httpbin?應用。這里的?httpbin?應用由?Pipy[1]?實現,會返回當前的集群名,并提示被網格管理。

NAMESPACE=httpbin
CLUSTER_NAME="1-23"kubectx?k3d-${CLUSTER_NAME}
kubectl?create?namespace?${NAMESPACE}
osm?namespace?add?${NAMESPACE}
kubectl?apply?-n?${NAMESPACE}?-f?-?<<EOF
apiVersion:?apps/v1
kind:?Deployment
metadata:name:?httpbinlabels:app:?pipy
spec:replicas:?1selector:matchLabels:app:?pipytemplate:metadata:labels:app:?pipyspec:containers:-?name:?pipyimage:?flomesh/pipy:latestports:-?containerPort:?8080command:-?pipy-?-e-?|pipy().listen(8080).serveHTTP(new?Message('Hi,?I?am?from?${CLUSTER_NAME}?and?controlled?by?mesh!\n'))
---
apiVersion:?v1
kind:?Service
metadata:name:?httpbin
spec:ports:-?port:?8080targetPort:?8080protocol:?TCPselector:app:?pipy
EOFsleep?3
kubectl?wait?--for=condition=ready?pod?-n?${NAMESPACE}?--all?--timeout=60s

在命名空間?curl?下部署?curl?應用,這個命名空間也是被網格管理的,注入的 sidecar 會完全流量的跨集群調度。

export?NAMESPACE=curl
kubectx?k3d-1-23
kubectl?create?namespace?${NAMESPACE}
osm?namespace?add?${NAMESPACE}
kubectl?apply?-n?${NAMESPACE}?-f?-?<<EOF
apiVersion:?v1
kind:?ServiceAccount
metadata:name:?curl
---
apiVersion:?v1
kind:?Service
metadata:name:?curllabels:app:?curlservice:?curl
spec:ports:-?name:?httpport:?80selector:app:?curl
---
apiVersion:?apps/v1
kind:?Deployment
metadata:name:?curl
spec:replicas:?1selector:matchLabels:app:?curltemplate:metadata:labels:app:?curlspec:serviceAccountName:?curlcontainers:-?image:?curlimages/curlimagePullPolicy:?IfNotPresentname:?curlcommand:?["sleep",?"365d"]
EOFsleep?3
kubectl?wait?--for=condition=ready?pod?-n?${NAMESPACE}?--all?--timeout=60s

測試

在集群?1-23?中的?curl?向?httpbin?發送請求。

kubectx?k3d-1-23
curl_client="$(kubectl?get?pod?-n?curl?-l?app=curl?-o?jsonpath='{.items[0].metadata.name}')"kubectl?exec?"${curl_client}"?-n?curl?-c?curl?--?curl?-s?http://httpbin.httpbin:8080/

看到下面的輸出,說明服務正常。

Hi,?I?am?from?1-23?and?controlled?by?mesh!

導出服務

服務的導出就是向集群組注冊服務,執行下面的命令將集群?1-23?中的服務?httpbin?注冊到集群組。注意,該命令是在集群?1-23?中執行的。

export?NAMESPACE_MESH=httpbin
CLUSTER_NAME="1-23"
kubectx?k3d-${CLUSTER_NAME}
kubectl?apply?-f?-?<<EOF
apiVersion:?flomesh.io/v1alpha1
kind:?ServiceExport
metadata:namespace:?${NAMESPACE_MESH}name:?httpbin
spec:serviceAccountName:?"*"rules:-?portNumber:?8080path:?"/${CLUSTER_NAME}/httpbin-mesh"pathType:?Prefix
EOF
sleep?1

此時,我們的系統如下圖所示。

4181e4bdc31d82bddf4fad601946fcf3.jpeg
集群升級.002

升級遷移

新集群中部署應用

有了新版本的集群之后,我們慢慢向新集群遷移服務。在集群?1-25?中部署?httpbin?服務。

NAMESPACE=httpbin
CLUSTER_NAME="1-25"kubectx?k3d-${CLUSTER_NAME}
kubectl?create?namespace?${NAMESPACE}
osm?namespace?add?${NAMESPACE}
kubectl?apply?-n?${NAMESPACE}?-f?-?<<EOF
apiVersion:?apps/v1
kind:?Deployment
metadata:name:?httpbinlabels:app:?pipy
spec:replicas:?1selector:matchLabels:app:?pipytemplate:metadata:labels:app:?pipyspec:containers:-?name:?pipyimage:?flomesh/pipy:latestports:-?containerPort:?8080command:-?pipy-?-e-?|pipy().listen(8080).serveHTTP(new?Message('Hi,?I?am?from?${CLUSTER_NAME}?and?controlled?by?mesh!\n'))
---
apiVersion:?v1
kind:?Service
metadata:name:?httpbin
spec:ports:-?port:?8080targetPort:?8080protocol:?TCPselector:app:?pipy
---
apiVersion:?v1
kind:?Service
metadata:name:?httpbin-${CLUSTER_NAME}
spec:ports:-?port:?8080targetPort:?8080protocol:?TCPselector:app:?pipy
EOFsleep?3
kubectl?wait?--for=condition=ready?pod?-n?${NAMESPACE}?--all?--timeout=60s

導出服務

向集群組注冊集群?1-25?的服務?httpbin

export?NAMESPACE_MESH=httpbin
CLUSTER_NAME="1-25"
kubectx?k3d-${CLUSTER_NAME}
kubectl?apply?-f?-?<<EOF
apiVersion:?flomesh.io/v1alpha1
kind:?ServiceExport
metadata:namespace:?${NAMESPACE_MESH}name:?httpbin
spec:serviceAccountName:?"*"rules:-?portNumber:?8080path:?"/${CLUSTER_NAME}/httpbin-mesh"pathType:?Prefix
EOF
sleep?1

回到集群?1-23,查看?ServiceImports?httpbin,可以看到已經發現了集群?1-25?注冊的服務。

kubectl?get?serviceimports?httpbin?-n?httpbin?-o?jsonpath='{.spec}'?|?jq
{"ports":?[{"endpoints":?[{"clusterKey":?"default/default/default/1-25","target":?{"host":?"192.168.1.110","ip":?"192.168.1.110","path":?"/1-25/httpbin-mesh","port":?82}}],"port":?8080,"protocol":?"TCP"}],"serviceAccountName":?"*","type":?"ClusterSetIP"
}

但此時在?curl發送請求,并不會收到集群?1-25?中的響應。還記得?上篇?中提到過,默認的全局流量策略是?Locality,因此集群外的節點并不會參與請求的處理。

Hi,?I?am?from?1-23?and?controlled?by?mesh!
Hi,?I?am?from?1-23?and?controlled?by?mesh!
Hi,?I?am?from?1-23?and?controlled?by?mesh!

我們創建一個?ActiveActive?的全局流量策略。注意,這里設置?targets?的時候我們加上了代表權重的字段?weight?將其設置為 10,表示將 1/11 的流量導入集群?1-25?中,記住本集群的權重總是 100

kubectx?k3d-1-23
kubectl?apply?-n?httpbin?-f??-?<<EOF
apiVersion:?flomesh.io/v1alpha1
kind:?GlobalTrafficPolicy
metadata:name:?httpbin
spec:lbType:?ActiveActivetargets:-?clusterKey:?default/default/default/1-25weight:?10
EOF

這次我們請求 20 次,結果也正如我們所期望的,只有 1-2 次請求進入集群?1-25

for?i?in?{1..20};?do?kubectl?exec?"${curl_client}"?-n?curl?-c?curl?--?curl?-s?http://httpbin.httpbin:8080/?;?done
Hi,?I?am?from?1-23?and?controlled?by?mesh!
Hi,?I?am?from?1-23?and?controlled?by?mesh!
Hi,?I?am?from?1-25?and?controlled?by?mesh!
Hi,?I?am?from?1-23?and?controlled?by?mesh!
Hi,?I?am?from?1-23?and?controlled?by?mesh!
Hi,?I?am?from?1-23?and?controlled?by?mesh!
Hi,?I?am?from?1-23?and?controlled?by?mesh!
Hi,?I?am?from?1-23?and?controlled?by?mesh!
Hi,?I?am?from?1-23?and?controlled?by?mesh!
Hi,?I?am?from?1-23?and?controlled?by?mesh!
Hi,?I?am?from?1-23?and?controlled?by?mesh!
Hi,?I?am?from?1-23?and?controlled?by?mesh!
Hi,?I?am?from?1-23?and?controlled?by?mesh!
Hi,?I?am?from?1-25?and?controlled?by?mesh!
Hi,?I?am?from?1-23?and?controlled?by?mesh!
Hi,?I?am?from?1-23?and?controlled?by?mesh!
Hi,?I?am?from?1-23?and?controlled?by?mesh!
Hi,?I?am?from?1-23?and?controlled?by?mesh!
Hi,?I?am?from?1-23?and?controlled?by?mesh!
Hi,?I?am?from?1-23?and?controlled?by?mesh!

我們將集群?1-25?的權重設置為?900,因此會有 90% 的流量進入集群?1-25

kubectx?k3d-1-23
kubectl?apply?-n?httpbin?-f??-?<<EOF
apiVersion:?flomesh.io/v1alpha1
kind:?GlobalTrafficPolicy
metadata:name:?httpbin
spec:lbType:?ActiveActivetargets:-?clusterKey:?default/default/default/1-25weight:?900
EOF

然后請求 10 次,會看到 9 次的請求都進入到集群?1-25,也就是 90% 的流量分流到了其他集群。

for?i?in?{1..10};?do?kubectl?exec?"${curl_client}"?-n?curl?-c?curl?--?curl?-s?http://httpbin.httpbin:8080/?;?done
Hi,?I?am?from?1-25?and?controlled?by?mesh!
Hi,?I?am?from?1-23?and?controlled?by?mesh!
Hi,?I?am?from?1-25?and?controlled?by?mesh!
Hi,?I?am?from?1-25?and?controlled?by?mesh!
Hi,?I?am?from?1-25?and?controlled?by?mesh!
Hi,?I?am?from?1-25?and?controlled?by?mesh!
Hi,?I?am?from?1-25?and?controlled?by?mesh!
Hi,?I?am?from?1-25?and?controlled?by?mesh!
Hi,?I?am?from?1-25?and?controlled?by?mesh!
Hi,?I?am?from?1-25?and?controlled?by?mesh!

接著就是停止集群?1-23?中的實例,使所有流量都分流到外集群。

kubectl?scale?deploy?httpbin?-n?httpbin?--replicas?0

最后的工作就是慢慢得將?curl?服務也遷移到新的集群中,進而是所有的服務都遷移完成之后,下線舊的集群。

總結

自維護的 Kubernetes 集群升級不是一件容易的事情,原地升級風險高,尤其是升級控制面。不管是藍綠還是金絲雀升級,都面臨著流量跨集群的問題:流量除了從入口進入還會有其他的途徑,比如消息系統,定時任務等等。

解決了流量的跨集群調度問題后,這些問題都迎刃而解。剩下的問題就是如何讓遷移做到自動化、可控的遷移了。

引用鏈接

[1]?Pipy:?https://flomesh.io/pipy

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/news/280495.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/280495.shtml
英文地址,請注明出處:http://en.pswp.cn/news/280495.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

usr/bin/expect方式免密碼登錄和發送文件腳本

2019獨角獸企業重金招聘Python工程師標準>>> ssh 登錄 #!/usr/bin/expect set timeout 20 if { [llength $argv] < 3} { puts "Usage:" puts "remote_host password cmd" exit 1 } set remote_host [lindex $argv 0] set passwor…

8-[多線程] 進程池線程池

1、為甚需要進程池&#xff0c;線程池 介紹官網&#xff1a;https://docs.python.org/dev/library/concurrent.futures.htmlconcurrent.futures模塊提供了高度封裝的異步調用接口 ThreadPoolExecutor&#xff1a;線程池&#xff0c;提供異步調用 ProcessPoolExecutor: 進程池&a…

python 圖像識別pytesseract快速設置

一、安裝Tesseract 以window安裝為例&#xff0c;參考&#xff1a;https://segmentfault.com/a/1190000014086067 note&#xff1a; 使用虛擬環境需要&#xff1a; 在 python 環境&#xff08;或虛擬環境&#xff09; \Lib\site-packages\pytesseract 目錄下找到 pytessera…

香港連續25年被評為全球最自由經濟體

中新社香港1月25日電 美國智庫傳統基金會25日在華盛頓發表2019年《經濟自由度指數》報告&#xff0c;香港今年再次成為唯一一個總分超過90分的經濟體&#xff0c;已連續25年被評價為全球最自由經濟體。 報告顯示&#xff0c;香港今年的總分為90.2分&#xff08;100分為滿分&…

mac 下安裝jenkins

2019獨角獸企業重金招聘Python工程師標準>>> 平臺搭建 Jenkins安裝和啟動 官網&#xff1a;https://jenkins.io/index.html 下載&#xff1a;http://mirrors.jenkins-ci.org/war/latest/jenkins.war 安裝&#xff1a; 依賴于Java環境&#xff0c;首先安裝和配置Java…

safari 獲取視頻流_如何在Safari中將RSS feed和社交媒體合并為一個流

safari 獲取視頻流Safari allows you to subscribe to RSS feeds and add your social media accounts so you can view them right in the browser, in one universal feed, without the need of any add-on applications or extensions. Safari允許您訂閱RSS feed并添加您的社…

pytesseract:opencv預處理圖片

一、目的 原始圖片用pytesseract識別文字&#xff0c;精準度往往沒達到預期。使用opencv處理后&#xff0c;提高識別精準度。處理方法有 a.圖片轉成白底黑字。 b.截取圖片某固定區域。這個很重要&#xff0c;因為圖片包含圖標或其他形狀圖形&#xff0c;辨識導致錯亂的。 二…

編譯安裝Centos7.2+Apache2.4.25+PHP7.2.10+Mysql5.6.16

一、編譯部署Apache2.4.251、環境準備#設置或停止防火墻&#xff1a; [rootlocalhost ~]# systemctl stop firewalld.service [rootlocalhost ~]# systemctl disable firewalld.service#關閉selinux&#xff1a; 臨時關閉&#xff1a; [rootlocalhost ~]# setenforce 0永久關閉…

SDNU 1217 CD收藏——并查集

Description lmh平常愛聽歌&#xff0c;所以買了很多的CD來收藏&#xff0c;但是因為平常整理不當&#xff0c;所以忘記了這些CD的歌手是誰。現在他想知道他到底收藏了多少位歌手的專輯&#xff0c;于是他想了一個辦法&#xff0c;同時拿出兩個CD來聽&#xff0c;可以分辨出來是…

國際知名計算機視覺和機器學習軟件開源平臺OpenCV正式支持龍架構

前言介紹近期&#xff0c;OpenCV開源社區正式合入了對龍架構&#xff08;LoongArch?&#xff09;支持的代碼&#xff0c;基于龍架構自主指令系統&#xff0c;優化后的OpenCV性能顯著提升。OpenCV是一款跨平臺的計算機視覺和機器學習軟件平臺&#xff0c;在計算機視覺領域廣泛使…

優化器--牛頓法總結

---這里記錄下一些關于牛頓法來作為優化器的個人筆記 &#xff1a;&#xff09; 關于牛頓法&#xff0c;先不說其中的概念&#xff0c;來簡單看一個例子&#xff1f; 不用計算器&#xff0c;如何手動開一個值的平方根&#xff0c;比如計算{sqrt(a) | a4 } &#xff1f; 不用程序…

在命令提示符輸出c語言代碼_您可以在Windows命令提示符中更改輸出緩沖區的大小嗎?...

在命令提示符輸出c語言代碼If you are someone who loves using the Windows Command Prompt, you may have found yourself curious as to why the screen output buffer has such a ‘large’ default size. Can you change it to a smaller (or even larger) size? Today’…

django23:BS4/kindeditor上傳圖片

BS4 Beautiful Soup&#xff0c;Beautiful Soup 是一個可以從HTML或XML文件中提取數據的Python庫.它能夠通過你喜歡的轉換器實現慣用的文檔導航,查找,修改文檔的方式。 安裝 pip3 install beautifulsoup4 使用 from bs4 import BeautifulSoup#html_doc為網頁內容 soup Be…

設計模式——————觀察者模式

工廠模式分為簡單工廠&#xff0c;工廠和抽象工廠&#xff0c;三種工廠的實現是越來越復雜的。 觀察者模式 本質上就是一種訂閱/發布的模型&#xff0c;從邏輯上來說就是一對多的依賴關系。 什么意思呢&#xff1f;好比是一群守衛盯著一個囚犯&#xff0c;只要囚犯一有異動&…

SNMP簡介

SNMP簡介介紹SNMP的定義、目的、版本演進以及受益。 定義簡單網絡管理協議SNMP&#xff08;Simple Network Management Protocol&#xff09;是廣泛應用于TCP/IP網絡的網絡管理標準協議。SNMP提供了一種通過運行網絡管理軟件的中心計算機&#xff08;即網絡管理工作站&#xff…

詳解vue生命周期及每個階段適合進行的操作

VUE生命周期的四個階段 create 創建 -------- 創建vue實例并初始化mount 掛載 -------- 把vue實例和視圖進行關聯update 更新 ------- 監聽數據與視圖的變化destroy銷毀 ------- 銷毀實例生命周期 --- 鉤子函數 vue為上面的4個大的階段提供了一個可編程的接口&#xff0c;我們可…

.Net 7 新編譯器 ILC 簡析

楔子&#xff1a;這個新編譯器的全稱是ILCompiler。是之前CoreRT項目合并過來的&#xff0c;在.Net 7成熟&#xff0c;并且可以產業化應用。本質&#xff1a;ILC編譯器的本質除了構建CLR的所擁有的主要功能&#xff0c;還包含了對LLVM這種意圖取代GCC編譯器的操作&#xff0c;對…

mac 防止 下載 睡眠_如何暫時防止Mac進入睡眠狀態

mac 防止 下載 睡眠Let’s say you start a big download, then go to bed. When you wake up, you realize your Mac went to sleep before finishing its job. Isn’t there some way to stop this? 假設您開始進行大量下載&#xff0c;然后上床睡覺。 當您醒來時&#xff0…

ubuntu安裝chrome driver

首先下載Chrome Driver&#xff08;Firefox Driver的安裝與該步驟相同&#xff09; 鏈接&#xff1a; http://chromedriver.storage.googleapis.com/index.html 接下來在控制臺&#xff08;terminal&#xff09;上操作一下紅色字體的指令&#xff1a; Install Unzipsudo apt-ge…