日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

golang检查tcp是否可用_宕机处理:Kubernetes集群高可用实战总结

發(fā)布時(shí)間:2025/3/21 编程问答 35 豆豆
生活随笔 收集整理的這篇文章主要介紹了 golang检查tcp是否可用_宕机处理:Kubernetes集群高可用实战总结 小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

導(dǎo)語 |?在企業(yè)生產(chǎn)環(huán)境,Kubernetes高可用是一個(gè)必不可少的特性,其中最通用的場(chǎng)景就是如何在Kubernetes集群宕機(jī)一個(gè)節(jié)點(diǎn)的情況下保障服務(wù)依舊可用。本文對(duì)在該場(chǎng)景下實(shí)現(xiàn)集群和應(yīng)用高可用過程中遇到的各種問題進(jìn)行了梳理和總結(jié),希望與大家一同交流。文章作者,騰訊云架構(gòu)服務(wù)研發(fā)工程師。

一、整體架構(gòu)

1. control plane node管理節(jié)點(diǎn)采用 kubeadm 搭建的 3 節(jié)點(diǎn)標(biāo)準(zhǔn)高可用方案:Stacked etcd topology [1].該方案中,所有管理節(jié)點(diǎn)都部署 kube-apiserver,kube-controller-manager,kube-scheduler,以及 etcd 等組件。kube-apiserver 均與本地的 etcd 進(jìn)行通信,etcd 在三個(gè)節(jié)點(diǎn)間同步數(shù)據(jù)。而 kube-controller-manager 和 kube-scheduler 也只與本地的 kube-apiserver 進(jìn)行通信(或者通過 LB 訪問)。kube-apiserver 前面頂一個(gè) LB;work 節(jié)點(diǎn) kubelet 以及 kube-proxy 組件對(duì)接 LB 訪問 apiserver 。在這種架構(gòu)中,如果其中任意一個(gè) master 節(jié)點(diǎn)宕機(jī)了,由于 kube-controller-manager 以及 kube-scheduler 基于 Leader Election Mechanism?[2]實(shí)現(xiàn)了高可用,可以認(rèn)為管理集群不受影響,相關(guān)組件依舊正常運(yùn)行(在分布式鎖釋放后)。2. work node工作節(jié)點(diǎn)上部署應(yīng)用,應(yīng)用按照反親和[3]部署多個(gè)副本,使副本調(diào)度在不同的 work node 上,這樣如果其中一個(gè)副本所在的母機(jī)宕機(jī)了,理論上通過 Kubernetes service 可以把請(qǐng)求切換到另外副本上,使服務(wù)依舊可用。

二、網(wǎng)絡(luò)

針對(duì)上述架構(gòu),我們來分析一下實(shí)際環(huán)境中節(jié)點(diǎn)宕機(jī)對(duì)網(wǎng)絡(luò)層面帶來的影響。

1. service backend 剔除

正如上文所述,工作節(jié)點(diǎn)上應(yīng)用會(huì)按照反親和部署。這里我們討論最簡單的情況:例如一個(gè) nginx 服務(wù),部署了兩個(gè)副本,分別落在 work node1 和 work node2 上。集群中還部署了依賴 nginx 服務(wù)的應(yīng)用 A,如果某個(gè)時(shí)刻 work node1 宕機(jī)了,此時(shí)應(yīng)用 A 訪問 nginx service 會(huì)有問題嗎?這里的答案是:會(huì)有問題。因?yàn)?service 不會(huì)馬上剔除掉宕機(jī)上對(duì)應(yīng)的 nginx pod,同時(shí)由于 service 常用的 iptables 代理模式[4]?沒有實(shí)現(xiàn) retry with another backend [5]特性,所以在一段時(shí)間內(nèi)訪問會(huì)出現(xiàn)間歇性問題(如果請(qǐng)求輪詢到掛掉的 nginx pod 上),也就是說會(huì)存在一個(gè)訪問失敗間隔期(ipvs 模式具備健康檢查能力,能夠自動(dòng)從 ipvs 規(guī)則中及時(shí)剔除故障的 pod,具備更高的可用性)。這個(gè)間隔期取決于 service 對(duì)應(yīng)的 endpoint 什么時(shí)候踢掉宕機(jī)的 pod。之后,kube-proxy 會(huì) watch 到 endpoint 變化,更新對(duì)應(yīng)的 iptables 規(guī)則,使 service 訪問后端列表恢復(fù)正常,也就是踢掉該 pod 。要理解這個(gè)間隔,我們首先需要弄清楚 Kubernetes 節(jié)點(diǎn)心跳的概念:每個(gè) node 在 kube-node-lease namespace 下會(huì)對(duì)應(yīng)一個(gè) Lease object,kubelet 每隔 node-status-update-frequency 時(shí)間(默認(rèn)10s)會(huì)更新對(duì)應(yīng) node 的 Lease object 。node-controller 會(huì)每隔 node-monitor-period 時(shí)間(默認(rèn)5s )檢查 Lease object 是否更新,如果超過 node-monitor-grace-period 時(shí)間(默認(rèn)40s)沒有發(fā)生過更新,則認(rèn)為這個(gè) node 不健康,會(huì)更新 NodeStatus (ConditionUnknown)。如果這樣的狀態(tài)在這之后持續(xù)了一段時(shí)間(默認(rèn)5 mins),則會(huì)驅(qū)逐(evict)該 node 上的 pod 。對(duì)于母機(jī)宕機(jī)的場(chǎng)景,node controller 在 node-monitor-grace-period 時(shí)間段沒有觀察到心跳的情況下,會(huì)更新 NodeStatus (ConditionUnknown),之后 endpoint controller 會(huì)從 endpoint backend 中踢掉該母機(jī)上的所有 pod,最終服務(wù)訪問正常,請(qǐng)求不會(huì)落在掛掉的 pod 上。也就是說在母機(jī)宕機(jī)后,在 node-monitor-grace-period 間隔內(nèi)訪問 service 會(huì)有間歇性問題,我們可以通過調(diào)整相關(guān)參數(shù)來縮小這個(gè)窗口期,如下:(kubelet)node-status-update-frequency:default 10s(kube-controller-manager)node-monitor-period:default 5s(kube-controller-manager)node-monitor-grace-period:default 40s- Amount of time which we allow running Node to be unresponsive before marking it unhealthy. Must be N times more than kubelet's nodeStatusUpdateFrequency,?where?N?means?number?of?retries?allowed?for?kubelet?to?post?node?status.- Currently nodeStatusUpdateRetry is constantly set to 5 in kubelet.go

2. 連接復(fù)用

對(duì)于使用長連接訪問的應(yīng)用來說(默認(rèn)使用都是 tcp 長連接,無論 HTTP/2 還是 HTTP/1 ),在沒有設(shè)置合適請(qǐng)求 timeout 參數(shù)的情況下可能會(huì)出現(xiàn) 15mins 的超時(shí)問題,詳情見?Kubernetes Controller 高可用詭異的 15mins 超時(shí)[6]。通過對(duì)上述鏈接內(nèi)容的分析,我們可以知道是 TCP 的 ARQ 機(jī)制導(dǎo)致了 Controller 在母機(jī)宕機(jī)后 15mins 內(nèi)一直超時(shí)重試,超時(shí)重試失敗后,tcp socket 關(guān)閉,應(yīng)用重新創(chuàng)建連接。這個(gè)問題本質(zhì)上不是 Kubernetes 的問題,而是應(yīng)用在復(fù)用 tcp socket (長連接)時(shí)沒有考慮設(shè)置超時(shí),導(dǎo)致了母機(jī)宕機(jī)后,tcp socket 沒有及時(shí)關(guān)閉,服務(wù)依舊使用失效連接導(dǎo)致異常。要解決這個(gè)問題,可以從兩方面考慮:第一,應(yīng)用層使用超時(shí)設(shè)置或者健康檢查機(jī)制,從上層保障連接的健康狀態(tài),作用于該應(yīng)用。

第二,底層調(diào)整 TCP ARQ 設(shè)置(/proc/sys/net/ipv4/tcp_retries2),縮小超時(shí)重試周期,作用于整個(gè)集群。

由于應(yīng)用層的超時(shí)或者健康檢查機(jī)制無法使用統(tǒng)一的方案,這里只介紹如何采用系統(tǒng)配置的方式規(guī)避無效連接,如下:# 0.2+0.4+0.8+1.6+3.2+6.4+12.8+25.6+51.2+102.4 = 222.6s$ echo 9 > /proc/sys/net/ipv4/tcp_retries2另外對(duì)于推送類的服務(wù),比如 Watch,在母機(jī)宕機(jī)后,可以通過 tcp keepalive 機(jī)制來關(guān)閉無效連接。這也是上面測(cè)試 cluster-coredns-controller 時(shí)其中一個(gè)連接 5 分鐘(30+30*9=300s)斷開的原因:# 30 + 30*5 = 180s$ echo 30 > /proc/sys/net/ipv4/tcp_keepalive_time$ echo 30 > /proc/sys/net/ipv4/tcp_keepalive_intvl$ echo 5 > /proc/sys/net/ipv4/tcp_keepalive_probes注意:在Kubernetes環(huán)境中,容器不會(huì)直接繼承母機(jī)tcp keepalive的配置(可以直接繼承母機(jī)tcp超時(shí)重試的配置),因此必須通過一定方式進(jìn)行適配。這里介紹其中一種方式,添加initContainers使配置生效:- name: init-sysctl image: busybox command: - /bin/sh - -c - | sysctl -w net.ipv4.tcp_keepalive_time=30 sysctl -w net.ipv4.tcp_keepalive_intvl=30 sysctl -w net.ipv4.tcp_keepalive_probes=5 securityContext: privileged: true通過上述的 TCP keepalive 以及 TCP ARQ 配置,我們可以將無效連接斷開時(shí)間縮短到 4 分鐘以內(nèi),一定程度上解決了母機(jī)宕機(jī)導(dǎo)致的連接異常問題。不過最好的解決方案是在應(yīng)用層設(shè)置超時(shí)或者健康檢查機(jī)制及時(shí)關(guān)閉底層無效連接。

三、節(jié)點(diǎn)驅(qū)逐

對(duì)節(jié)點(diǎn)驅(qū)逐需要分應(yīng)用和存儲(chǔ)兩方面進(jìn)行分析:

1. 應(yīng)用相關(guān)

pod 驅(qū)逐可以使服務(wù)自動(dòng)恢復(fù)副本數(shù)量。如上所述,node controller 會(huì)在節(jié)點(diǎn)心跳超時(shí)之后一段時(shí)間(默認(rèn) 5 mins)驅(qū)逐該節(jié)點(diǎn)上的 pod,這個(gè)時(shí)間由如下參數(shù)決定:(kube-apiserver)default-not-ready-toleration-seconds:default?300(kube-apiserver)default-unreachable-toleration-seconds:default?300Kubernetes?automatically?adds?a?toleration?for?node.kubernetes.io/not-ready?and?node.kuber-netes.io/unreachable?with?toleration-Seconds=300,These?automatically-added?tolerations?mean?that?Pods?remain?bound?to?Nodes?for?5?minutes?after?one?of?these?problems?is?detected.摘自Kubernetes官方文獻(xiàn)

引用中涉及到兩個(gè)?tolerations [7]?:

  • node.kubernetes.io/not-ready: Node is not ready. This corresponds to the NodeCondition Ready being “False”;

  • node.kubernetes.io/unreachable: Node is unreachable from the node controller. This corresponds to the NodeCondition Ready being “Unknown”.

tolerations: - effect: NoExecute key: node.kubernetes.io/not-ready operator: Exists tolerationSeconds: 300 - effect: NoExecute key: node.kubernetes.io/unreachable operator: Exists tolerationSeconds: 300當(dāng)節(jié)點(diǎn)心跳超時(shí)( ConditionUnknown )之后,node controller 會(huì)給該 node 添加如下 taints :spec: ... taints: - effect: NoSchedule key: node.kubernetes.io/unreachable timeAdded: "2020-07-02T03:50:47Z" - effect: NoExecute key: node.kubernetes.io/unreachable timeAdded: "2020-07-02T03:50:53Z"由于 pod 對(duì) node.kubernetes.io/unreach-able:NoExecute taint 容忍時(shí)間為 300s,因此 node controller 會(huì)在 5 mins 之后驅(qū)逐該節(jié)點(diǎn)上的 pod 。這里面有比較特殊的情況,例如:statefulset,daemonset 以及 static pod。我們逐一說明:(1)statefulsetpod 刪除存在兩個(gè)階段,第一個(gè)階段是 controller-manager 設(shè)置 pod 的 spec.deletionTimestamp 字段為非 nil 值。第二個(gè)階段是 kubelet 完成實(shí)際的 pod 刪除操作( volume detach,container 刪除等)。當(dāng) node 宕機(jī)后,顯然 kubelet 無法完成第二階段的操作,因此 controller-manager 認(rèn)為 pod 并沒有被刪除掉,在這種情況下 statefulset 工作負(fù)載形式的 pod 不會(huì)產(chǎn)生新的替換 pod,并一直處于 “Terminating” 狀態(tài)[8]。Like a Deployment, a StatefulSet manages Pods?that are based on an identical containerspec. Unlike a Deployment, a StatefulSet main-tains a sticky identity for each of their Pods.?These pods are created from the same spec,?but are not interchangeable: each has a?persistent identifier...摘自Kubernetes官方文獻(xiàn)原因是 statefulset 為了保障 at most one semantics?[9],需要滿足對(duì)于指定 identity 同時(shí)只有一個(gè) pod 存在。在 node shoudown 后,雖然 pod 被驅(qū)逐了( “Terminating” ),但是由于 controller 無法判斷這個(gè) statefulset pod 是否還在運(yùn)行(因?yàn)椴]有徹底刪除),故不會(huì)產(chǎn)生替換容器,一定是要等到這個(gè)pod被完全刪除干凈( by kubelet [10]),才會(huì)產(chǎn)生替換容器。deployment 不需要滿足這個(gè)條件,所以在驅(qū)逐 pod 時(shí),controller 會(huì)馬上產(chǎn)生替換 pod,而不需要等待 kubelet 刪除 pod 。(2)daemonsetdaemonset 則更加特殊,默認(rèn)情況下 daemonset pod 會(huì)被設(shè)置多個(gè) tolerations,使其可以容忍節(jié)點(diǎn)幾乎所有異常的狀態(tài),所以不會(huì)出現(xiàn)驅(qū)逐的情況。這也很好理解,因?yàn)?daemonset 本來就是一個(gè)?node 部署一個(gè) pod,如下:tolerations: - effect: NoSchedule key: dns operator: Equal value: "false" - effect: NoExecute key: node.kubernetes.io/not-ready operator: Exists - effect: NoExecute key: node.kubernetes.io/unreachable operator: Exists - effect: NoSchedule key: node.kubernetes.io/disk-pressure operator: Exists - effect: NoSchedule key: node.kubernetes.io/memory-pressure operator: Exists - effect: NoSchedule key: node.kubernetes.io/pid-pressure operator: Exists - effect: NoSchedule key: node.kubernetes.io/unschedulable operator: Exists(3)static podstatic pod 類型類似 daemonset 會(huì)設(shè)置 tolerations 容忍節(jié)點(diǎn)異常狀態(tài),如下:tolerations: - effect: NoExecute operator: Exists因此在節(jié)點(diǎn)宕機(jī)后,static pod 也不會(huì)發(fā)生驅(qū)逐。

2. 存儲(chǔ)相關(guān)

當(dāng) pod 使用的 volume 只支持 RWO 讀寫模式時(shí),如果 pod 所在母機(jī)宕機(jī)了,并且隨后在其它母機(jī)上產(chǎn)生了替換副本,則該替換副本的創(chuàng)建會(huì)阻塞,如下所示:$ kubectl get pods -o widenginx-7b4d5d9fd-bmc8g 0/1 ContainerCreating 0 0s 10.0.0.1 nginx-7b4d5d9fd-nqgfz 1/1 Terminating 0 19m 192.28.1.165 10.0.0.2 $ kubectl describe pods/nginx-7b4d5d9fd-bmc8g[...truncate...]Events: Type Reason Age From Message ---- ------ ---- ---- ------- Normal Scheduled 3m5s default-scheduler Successfully assigned default/nginx-7b4d5d9fd-bmc8g to 10.0.0.1 Warning FailedAttachVolume 3m5s attachdetach-controller Multi-Attach error for volume "pvc-7f68c087-9e56-11ea-a2ef-5254002f7cc9" Volume is already used by pod(s) nginx-7b4d5d9fd-nqgfz??Warning??FailedMount?????????62s???kubelet,?10.0.0.1????????Unable?to?mount?volumes?for?pod?"nginx-7b4d5d9fd-bmc8g_default(bb5501ca-9fea-11ea-9730-5254002f7cc9)":?timeout?expired?waiting?for?volumes?to?attach?or?mount?for?pod?"default"/"nginx-7b4d5d9fd-nqgfz".?list?of?unmounted?volumes=[nginx-data].?list?of?unattached?volumes=[root-certificate?default-token-q2vft?nginx-data]這是因?yàn)橹恢С?RWO ( ReadWriteOnce – the volume can be mounted as read-write by a single node ) 的 volume 正常情況下在 Kubernetes 集群中只能被一個(gè)母機(jī) attach,由于宕機(jī)母機(jī)無法執(zhí)行 volume detach 操作,其它母機(jī)上的 pod 如果使用相同的 volume 會(huì)被掛住,最終導(dǎo)致容器創(chuàng)建一直阻塞并報(bào)錯(cuò):Multi-Attach?error?for?volume?"pvc-7f68c087-9e56-11ea-a2ef-5254002f7cc9"?Volume?is?already?used?by?pod(s)?nginx-7b4d5d9fd-nqgfz解決辦法是采用支持 RWX ( ReadWriteMany – the volume can be mounted as read-write by many nodes ) 讀寫模式的 volume。另外如果必須采用只支持 RWO 模式的 volume,則可以執(zhí)行如下命令強(qiáng)制刪除 pod,如下:$?kubectl?delete?pods/nginx-7b4d5d9fd-nqgfz?--force?--grace-period=0之后,對(duì)于新創(chuàng)建的 pod,attachDetachController 會(huì)在 6 mins(代碼寫死)后強(qiáng)制 detach volume,并正常 attach,如下:W0811 04:01:25.024422 1 reconciler.go:328] Multi-Attach error for volume "pvc-e97c6ce6-d8a6-11ea-b832-7a866c097df1" (UniqueName: "kubernetes.io/rbd/k8s:kubernetes-dynamic-pvc-f35fc6fa-d8a6-11ea-bd98-aeb6842de1e3") from node "10.0.0.3" Volume is already exclusively attached to node 10.0.0.2 and can't be attached to anotherI0811 04:01:25.024480 1 event.go:209] Event(v1.ObjectReference{Kind:"Pod", Namespace:"default", Name:"default-nginx-6584f7ddb7-jx9s2", UID:"5322240f-db87-11ea-b832-7a866c097df1", APIVersion:"v1", ResourceVersion:"28275287", FieldPath:""}): type: 'Warning' reason: 'FailedAttachVolume' Multi-Attach error for volume "pvc-e97c6ce6-d8a6-11ea-b832-7a866c097df1" Volume is already exclusively attached to one node and can't be attached to anotherW0811 04:07:25.047767 1 reconciler.go:232] attacherDetacher.DetachVolume started for volume "pvc-e97c6ce6-d8a6-11ea-b832-7a866c097df1" (UniqueName: "kubernetes.io/rbd/k8s:kubernetes-dynamic-pvc-f35fc6fa-d8a6-11ea-bd98-aeb6842de1e3") on node "10.0.0.2" This volume is not safe to detach, but maxWaitForUnmountDuration 6m0s expired, force detachingI0811 04:07:25.047860 1 operation_generator.go:500] DetachVolume.Detach succeeded for volume "pvc-e97c6ce6-d8a6-11ea-b832-7a866c097df1" (UniqueName: "kubernetes.io/rbd/k8s:kubernetes-dynamic-pvc-f35fc6fa-d8a6-11ea-bd98-aeb6842de1e3") on node "10.0.0.2"I0811 04:07:25.148094 1 reconciler.go:288] attacherDetacher.AttachVolume started for volume "pvc-e97c6ce6-d8a6-11ea-b832-7a866c097df1" (UniqueName: "kubernetes.io/rbd/k8s:kubernetes-dynamic-pvc-f35fc6fa-d8a6-11ea-bd98-aeb6842de1e3") from node "10.0.0.3"I0811 04:07:25.148180 1 operation_generator.go:377] AttachVolume.Attach succeeded for volume "pvc-e97c6ce6-d8a6-11ea-b832-7a866c097df1" (UniqueName: "kubernetes.io/rbd/k8s:kubernetes-dynamic-pvc-f35fc6fa-d8a6-11ea-bd98-aeb6842de1e3") from node "10.0.0.3"I0811?04:07:25.148266???????1?event.go:209]?Event(v1.ObjectReference{Kind:"Pod",?Namespace:"default",?Name:"default-nginx-6584f7ddb7-jx9s2",?UID:"5322240f-db87-11ea-b832-7a866c097df1",?APIVersion:"v1",?ResourceVersion:"28275287",?FieldPath:""}):?type:?'Normal'?reason:?'SuccessfulAttachVolume'?AttachVolume.Attach?succeeded?for?volume?"pvc-e97c6ce6-d8a6-11ea-b832-7a866c097df1"而默認(rèn)的 6 mins 對(duì)于生產(chǎn)環(huán)境來說太長了,而且 Kubernetes 并沒有提供參數(shù)進(jìn)行配置,因此我向官方提了一個(gè) PR [11]用于解決這個(gè)問題,如下:--attach-detach-reconcile-max-wait-unmount-duration?duration???maximum?amount?of?time?the?attach?detach?controller?will?wait?for?a?volume?to?be?safely?unmounted?from?its?node.?Once?this?time?has?expired,?the?controller?will?assume?the?node?or?kubelet?are?unresponsive?and?will?detach?the?volume?anyway.?(default?6m0s)通過配置 attach-detach-reconcile-max-wait-unmount-duration,可以縮短替換 pod 成功運(yùn)行的時(shí)間。另外,注意 force detaching 邏輯只會(huì)在 pod 被 force delete 的時(shí)候觸發(fā),正常 delete 不會(huì)觸發(fā)該邏輯。

四、存儲(chǔ)

對(duì)于存儲(chǔ),可以分為 Kubernetes 系統(tǒng)存儲(chǔ)和應(yīng)用存儲(chǔ),系統(tǒng)存儲(chǔ)專指 etcd;而應(yīng)用存儲(chǔ)一般來說只考慮 persistent volume 。

1. 系統(tǒng)存儲(chǔ) - etcd

etcd 使用 Raft 一致性算法[12]( leader selection + log replication + safety ) 中的 leader selection 來實(shí)現(xiàn)節(jié)點(diǎn)宕機(jī)下的高可用問題,如下所示:

2. 應(yīng)用存儲(chǔ) - persistent volume

這里考慮存儲(chǔ)是部署在集群外的情況(通常情況)。如果一個(gè)母機(jī)宕機(jī)了,由于沒有對(duì)外部存儲(chǔ)集群產(chǎn)生破壞,因此不會(huì)影響其它母機(jī)上應(yīng)用訪問 pv 存儲(chǔ)。而對(duì)于 Kubernetes 存儲(chǔ)本身組件功能 ( in-tree, flexVolume, external-storage 以及 csi ) 的影響實(shí)際上可以歸納為對(duì)存儲(chǔ)插件應(yīng)用的影響,這里以 csi 為例子進(jìn)行說明:通過實(shí)現(xiàn)對(duì)上述 StatefulSet/Deployment 工作負(fù)載類型應(yīng)用 ( CSI Driver+Identity Controller以及external-attacher+external-provisioner ) 的高可用即可。

五、應(yīng)用

1. Stateless Application

對(duì)于無狀態(tài)的服務(wù)(通常部署為 deployment 工作負(fù)載),我們可以直接通過設(shè)置反親和+多副本來實(shí)現(xiàn)高可用,例如 nginx 服務(wù):apiVersion: apps/v1kind: Deploymentmetadata:name: web-serverspec:selector: matchLabels: app: web-storereplicas: 3template: metadata: labels: app: web-store spec: affinity: podAntiAffinity: requiredDuringSchedulingIgnoredDuringExecution: - labelSelector: matchExpressions: - key: app operator: In values: - web-store topologyKey: "kubernetes.io/hostname" containers: - name: web-app image: nginx:1.16-alpine如果其中一個(gè) pod 所在母機(jī)宕機(jī)了,則在 endpoint controller 踢掉該 pod backend 后,服務(wù)訪問正常。這類服務(wù)通常依賴于其它有狀態(tài)服務(wù),例如:WebServer,APIServer 等。

2. Stateful Application

對(duì)于有狀態(tài)的服務(wù),可以按照高可用的實(shí)現(xiàn)類型分類如下:(1)RWX Type對(duì)于本身基于多副本實(shí)現(xiàn)高可用的應(yīng)用來說,我們可以直接利用反親和+多副本進(jìn)行部署(一般部署為 deployment 類型),后接同一個(gè)存儲(chǔ)(支持 ReadWriteMany,例如:Cephfs or Ceph RGW ),實(shí)現(xiàn)類似無狀態(tài)服務(wù)的高可用模式。其中,docker distribution,helm chartmuseum 以及 harbor jobservice 等都屬于這種類型。(2)Special Type對(duì)于特殊類型的應(yīng)用,例如 database,它們一般有自己定制的高可用方案,例如常用的主從模式。這類應(yīng)用通常以 statefulset 的形式進(jìn)行部署,每個(gè)副本對(duì)接一個(gè) pv,在母機(jī)宕機(jī)的情況下,由應(yīng)用本身實(shí)現(xiàn)高可用(例如:master 選舉-主備切換)。其中,redis,postgres,以及各類db都基本是這種模式,如下是?redis?一主兩從三哨兵高可用方案還有更加復(fù)雜的高可用方案,例如 etcd 的 Raft 一致性算法:(3)Distributed Lock TypeKubernetes Controller 就是利用分布式鎖實(shí)現(xiàn)高可用。這里歸納了一些常用應(yīng)用實(shí)現(xiàn)高可用的方案。當(dāng)然了,各個(gè)應(yīng)用可以定制適合自身的高可用方案,不可能完全一樣。

結(jié)語

本文先介紹了 Kubernetes 集群高可用的整體架構(gòu),之后基于該架構(gòu)從網(wǎng)絡(luò),存儲(chǔ),以及應(yīng)用層面分析了當(dāng)節(jié)點(diǎn)宕機(jī)時(shí)可能會(huì)出現(xiàn)的問題以及對(duì)應(yīng)的解決方案,希望對(duì) Kubernetes 高可用實(shí)踐有所助益。實(shí)際生產(chǎn)環(huán)境需要綜合上述因素全面考慮,將整體服務(wù)的恢復(fù)時(shí)間控制在一個(gè)可以接受的范圍內(nèi)。

參考資料:

[1]?Stacked etcd topology:

https://kubernetes.io/docs/setup/production-environment/tools/kubeadm/ha-topology/#stacked-etcd-topology

[2]?Leader Election Mechanism:

https://github.com/kubernetes/client-go/tree/master/examples/leader-election

[3]?反親和:

https://kubernetes.io/docs/concepts/scheduling-eviction/assign-pod-node/#more-practical-use-cases

[4]?iptables代理模式:

https://kubernetes.io/docs/concepts/services-networking/service/#proxy-mode-iptables

[5]?retry with another backend:

https://kubernetes.io/docs/concepts/services-networking/service/#proxy-mode-iptables

[6]?Kubernetes Controller高可用詭異的15mins超時(shí):

https://duyanghao.github.io/kubernetes-ha-http-keep-alive-bugs/

[7]?tolerations:

https://kubernetes.io/docs/concepts/scheduling-eviction/taint-and-toleration/#taint-based-evictions

[8]?一直處于"Terminating"狀態(tài):

https://github.com/kubernetes/kubernetes/issues/55713#issuecomment-518340883

[9]?at most one semantics:

https://kubernetes.io/docs/tasks/run-application/force-delete-stateful-set-pod/#statefulset-considerations

[10]?by kubelet:

https://github.com/kubernetes/community/blob/master/contributors/design-proposals/storage/pod-safety.md#current-guarantees-for-pod-lifecycle

[11]?作者PR:

https://github.com/kubernetes/kubernetes/pull/93776

[12] Raft 一致性算法論文譯文:

https://www.infoq.cn/article/raft-paper/

[13] In Search of an Understandable Consensus Algorithm:

https://ramcloud.atlassian.net/wiki/download/attachments/6586375/raft.pdf

[14] add node shutdown KEP:

https://github.com/kubernetes/enhancements/pull/1116/files

[15] Recommended Mechanism for Deploying CSI Drivers on Kubernetes:

https://github.com/kubernetes/community/blob/master/contributors/design-proposals/storage/container-storage-interface.md#recommended-mechanism-for-deploying-csi-drivers-on-kubernetes

[16] Container Storage Interface (CSI):

https://github.com/container-storage-interface/spec/blob/master/spec.md

[17] Client should expose a mechanism to close underlying TCP connections:https://github.com/kubernetes/client-go/issues/374

文章推薦

自繪引擎時(shí)代,為什么Flutter能突出重圍?

總結(jié)

以上是生活随笔為你收集整理的golang检查tcp是否可用_宕机处理:Kubernetes集群高可用实战总结的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。

主站蜘蛛池模板: 91黄色大片 | 精品国产黄 | 91丝袜美女 | 日韩在线精品 | 国产精品久久久久久久久久久久久久久久久久 | 永久在线| 老熟妇仑乱一区二区av | 大陆日韩欧美 | 一区二区三区欧美 | 亚洲欧美激情在线 | 亚洲欧美成人一区二区 | 国产精品探花一区二区在线观看 | 中文字幕国产在线 | 手机在线播放av | 在线a| 亚洲激情 | 香蕉久久精品日日躁夜夜躁 | www.久久久久久久 | 少妇人妻偷人精品一区二区 | 少妇精品视频 | 欧美激情va永久在线播放 | 国产精品久久久久久久av | 午夜秋霞影院 | 久久综合影院 | 美女av网| 国产成人精品一区二区三区福利 | 日本黄色大片在线观看 | 亚洲不卡av一区二区 | 日韩精品一区二区三区无码专区 | 亚洲中出| 午夜大片在线观看 | 神马久久久久 | 欧美亚韩一区二区三区 | 热热热av | 一级精品毛片 | 黄色欧美一级片 | 古装做爰无遮挡三级聊斋艳谭 | 污污视频免费看 | 国产美女久久 | 亚洲中文无码av在线 | 久久亚洲免费 | 美女操操操 | 天天综合一区 | 日本少妇一级片 | 美女网站在线看 | 国内精品亚洲 | av网站地址 | 国产美女性生活 | 国外亚洲成av人片在线观看 | 羞羞在线观看 | 久久精品久久99 | 久久久夜色 | 亚洲逼逼 | 欧美一级片黄色 | 久久久黄色大片 | 亚洲精品网站在线 | 中国a级黄色片 | 婷婷色基地 | 丰满秘书被猛烈进入高清播放在 | 国产一区二区四区 | 免费人成网站 | 国产高潮久久 | 中文字幕在线观看一区二区三区 | 久久九九热 | 三女警花合力承欢猎艳都市h | 色一情| 欧美性在线观看 | 日韩一区二区三区四区五区 | 青草超碰| www.黄在线观看 | 久久这里 | 色乱码一区二区三在线看 | 精品一区二区成人免费视频 | 香蕉伊人 | 国产精品日韩无码 | 国产日产精品一区二区三区 | 免费看国产曰批40分钟粉红裤头 | 亚洲天堂黄色 | 天天射天天搞 | 91丨porny在线 | 四虎影院一区 | 日韩成人区 | 欧美一二在线 | 91福利在线播放 | 国产真人无遮挡作爱免费视频 | 日韩中文电影 | 久久精品国产99精品国产亚洲性色 | 亚洲手机在线 | 日本一区二区三区在线播放 | yy6080久久 | 国产精品福利视频 | 亚洲av熟女高潮一区二区 | 自拍偷拍999 | 免费a在线观看播放 | 解开人妻的裙子猛烈进入 | 久久久久久久久精 | 波多野42部无码喷潮在线 | 麻豆91在线播放 | 国产91影院 |