tft每日頭條

 > 生活

 > kubernetes學習手冊

kubernetes學習手冊

生活 更新时间:2024-08-16 16:52:01

建立可靠和高可用的分布式系統是一項宏大的任務。本節将介紹部分最佳實踐用例,這些用例使基于kubernetes的系統能夠可靠地工作,還能應對各種類型的故障。

4.2.1 創建高可用性集群

要創建一個高可用性Kubernetes集群,主組件必須是冗餘的。這意味着etcd必須以集群的形式部署(常常是跨3個或5個節點的集群),并且Kubernetes API服務器必須是冗餘的。如果有必要,則Heapster存儲之類的輔助集群管理服務也可進行冗餘部署。圖4.1展示了一個典型的可靠和高可用的Kubernetes集群,其中包含幾個負載均衡的主節點,每個主節點包含完整的主組件和etcd組件。

這并非配置高可用性集群的唯一方法。例如,為優化機器的工作負載部署單例etcd集群或者為etcd集群配置比其他主節點更多的冗餘。

kubernetes學習手冊(高可用性最佳實踐)1

圖4.1 可靠和高可用性的Kubernetes集群

4.2.2 确保節點可靠

節點或某些組件可能發生故障,但許多故障都是暫時的。一些基本的保障可确保Docker 後台支撐服務和Kubelet在發生故障時自動重啟。

如果運行CoreOS、現代的Debian-based OS(Ubuntu≥16.04版本)或任何其他使用Systemd作為其初始化機制的操作系統,則很容易将Docker和Kubelet部署為自啟動後台支撐服務,代碼如下所示。

systemctl enable docker systemctl enable kublet

對于其他操作系統,Kubernetes項目為其高可用性用例提供了Monit,讀者可根據需求自行選擇任意過程監視器。

4.2.3 保護集群狀态

Kubernetes集群狀态存儲在etcd集群中,etcd集群被設計得非常可靠,且分布在多個節點上。将這些能力應用到可靠和高可用的Kubernetes集群上非常重要。

1.etcd集群

在etcd群集中至少應該有3個節點。如果讀者需要更強的可靠性和冗餘,則可以使用5個、7個或任何其他奇數個節點。考慮到網絡分裂的情況,節點的數量必須是奇數的。

為了創建一個集群,etcd節點應該能夠發現彼此。有幾種方法可以做到這一點。

2.靜态發現

通過靜态發現,可以直接管理每個etcd的IP地址/主機名。這并不意味着可以在Kubernetes集群之外管理etcd集群,或對etcd集群的健康運行狀态負責。etcd節點将作為Pod運行,并在需要時自動重新啟動。

假設etcd集群包含3個節點,代碼如下所示。

etcd-1 10.0.0.1 etcd-2 10.0.0.2 etcd-2 10.0.0.3

每個節點将接收這個初始集群信息作為命令行信息,代碼如下所示。

--initial-cluster etcd-1=http://10.0.0.1:2380,etcd- 2=http://10.0.0.2:2380,etcd-3=http://10.0.0.3:2380 --initial-cluster-state new

或者,接收其作為環境變量,代碼如下所示。

ETCD_INITIAL_CLUSTER="etcd-1=http://10.0.0.1:2380,etcd- 2=http://10.0.0.2:2380,etcd-3=http://10.0.0.3:2380" ETCD_INITIAL_CLUSTER_STATE=new

3.etcd發現

使用etcd發現,可以使用現有的集群來讓新集群的節點發現彼此。當然,這需要新的集群節點能夠訪問現有的集群。如果讀者不擔心依賴項和安全隐患,也可以使用https://discovery.etcd.io上的公共etcd發現服務。

讀者需要創建一個發現令牌,如有必要可以指定集群大小,默認值為3,如下代碼中是需要輸入的命令。

$ curl https://discovery.etcd.io/new?size=3 https://discovery.etcd.io/3e86b59982e49066c5d813af1c2e2579cbf573de

在使用發現服務時,需要将令牌作為命令行參數傳遞,代碼如下所示。

--discovery https://discovery.etcd.io/3e86b59982e49066c5d813af1c2e2579cbf573de

還可以将其作為環境變量傳遞,代碼如下所示。

ETCD_DISCOVERY=https://discovery.etcd.io/3e86b59982e49066c5d813af1c2e2579cbf573de

值得注意的是,發現服務僅與初始集群的初始引導有關,一旦啟動集群并使用初始節點運行,就使用單獨的協議從正在運行的集群中添加和删除節點,這樣便不會對公共etcd發現服務保持永久的依賴性。

4.DNS發現

也可以使用DNS并通過SRV記錄來建立發現,SRV記錄可以包含或者不包含TLS,本書不涉及這部分内容,讀者可以通過尋找etcd DNS發現來尋找解決方案。

5.etcd.yaml文件

根據發現的思路,在每個節點上啟動etcd實例的命令和在etcd.yaml Pod清單中的配置略有不同。清單應複制粘貼到每個etcd節點的/etc/kubernetes/manifests中。

如下代碼展示了etcd.yaml清單文件的不同部分。

APIVersion: v1 kind: Pod metadata: name: etcd-server spec: hostNetwork: true containers: - image: gcr.io/google_containers/etcd:2.0.9 name: etcd-container

初始部分包含Pod的名稱,指定它使用的主機網絡,并定義一個名為etcd- container的容器。然後,最關鍵的部分是所使用的Docker鏡像。在如下代碼所示的案例中,它是etcd: 2.0.9,類似于在etcd V2中。

command: - /usr/local/bin/etcd - --name - <name> - --initial-advertise-peer-urls - http://<node ip>:2380 - --listen-peer-urls - http://<node ip>:2380 - --advertise-client-urls - http://<node ip>:4001 - --listen-client-urls - http://127.0.0.1:4001 - --data-dir - /var/etcd/data - --discovery - <discovery token>

命令部分列出etcd正确操作所需的命令行參數。在以上代碼所示的案例中,因為使用了etcd發現機制,所以需要指定discovery标志。<name>、<node IP>和<discovery token>應該替換為唯一的名稱(主機名便是很好的選擇)、節點的IP地址和先前接收的發現令牌(對于所有節點相同的令牌)。`

ports: - containerPort: 2380 hostPort: 2380 name: serverport - containerPort: 4001 hostPort: 4001 name: clientport

在以上代碼所示的案例中,端口部分列出了服務器(2380)和客戶端(4001)端口,這些端口被映射到主機上的相同端口。

volumeMounts: - mountPath: /var/etcd name: varetcd - mountPath: /etc/ssl name: etcssl readOnly: true - mountPath: /usr/share/ssl name: usrsharessl readOnly: true - mountPath: /var/ssl name: varssl readOnly: true - mountPath: /usr/ssl name: usrssl readOnly: true - mountPath: /usr/lib/ssl name: usrlibssl readOnly: true - mountPath: /usr/local/openssl name: usrlocalopenssl readOnly: true - mountPath: /etc/openssl name: etcopenssl readOnly: true - mountPath: /etc/pki/tls name: etcpkitls readOnly: true

挂載部分列出/var/etcd處的varetcd挂載,etcd在其中寫入數據,還有一些etcd沒有修改的SSL和TLS隻讀挂載,代碼如下所示。

volumes: - hostPath: path: /var/etcd/data name: varetcd - hostPath: path: /etc/ssl name: etcssl - hostPath: path: /usr/share/ssl name: usrsharessl - hostPath: path: /var/ssl name: varssl - hostPath: path: /usr/ssl name: usrssl - hostPath: path: /usr/lib/ssl name: usrlibssl - hostPath: path: /usr/local/openssl name: usrlocalopenssl - hostPath: path: /etc/openssl name: etcopenssl - hostPath: path: /etc/pki/tls name: etcpkitls

volumes部分為映射到相應主機路徑的每個挂載提供一個存儲卷。雖然隻讀挂載尚且可行,但用戶也許會希望将varetcd卷映射到更健壯的網絡存儲,而不是僅僅依賴于etcd節點本身的冗餘。

6.驗證etcd集群

一旦etcd集群啟動并運行,就可以訪問etcdctl工具來檢查集群狀态和健康狀況。Kubernetes允許通過exec命令直接在Pod或容器中執行命令(類似于docker exec)。

建議的命令代碼如下所示。

  • etcdctl member list
  • etcdctl cluster-health
  • etcdctl set test ("yeah, it works!")
  • etcdctl get test (should return "yeah, it works!")
7.etcd v2與etcd v3

在本書撰寫時,Kubernetes 1.4僅支持etcd v2,但etcd v3有了顯著的改進,也增加了許多值得稱贊的新特性,例如以下特性。

  • 從JSON REST切換到protobufs gRPC,本地客戶端的性能提高了一倍。
  • 支持租賃與冗長的密鑰TTL,從而改進了性能。
  • 使用gRPC将多個Watch複用在一個連接上,而不是為每個Watch保持一個開放的連接。

etcd v3已被證明可以在Kubernetes上運行,但尚未被正式支持,這是一大進步,該項工作正在進行中。希望讀者讀到本書時,v3能正式被Kubernetes官方所支持。若非如此,也有可能将etcd v2遷移到etcd v3。

4.2.4 保護數據

保護集群狀态和配置很重要,但保護自身數據卻更為重要。如果集群狀态遭到破壞,那麼通常可以從頭開始重新構建集群(盡管在重建期間集群将不可用)。但是如果數據被破壞或丢失,那麼就會陷入麻煩。同樣的規則适用于冗餘,但是當Kubernetes集群狀态為動态時,大部分數據可能并不同步(非動态)。例如,許多曆史數據往往很重要,可以備份和恢複;實時數據可能會丢失,但整個系統可能會恢複到早期版本,并且隻受到暫時性的損壞。

4.2.5 運行冗餘API服務器

API服務器是無狀态的,從etcd集群中能獲取所有必要的數據。這意味着可以輕松地運行多個API服務器,而不需要在它們之間進行協調。一旦有多個API服務器運行,就可以把負載均衡器放在它們之前,使其對用戶透明。

4.2.6 用Kubernetes運行領導選舉

一些主組件(如調度器和控制器管理器)不能同時具有多個實例。多個調度器試圖将同一個Pod調度到多個節點或多次進入同一個節點将導緻混亂。高度可擴展的Kubernetes集群可以讓這些組件在領導者選舉模式下運行。這意味着雖然多個實例在運行,但是每次隻有一個實例是活動的,如果它失敗,則另一個實例被選為領導者并代替它。

Kubernetes通過--leader-elect标志支持這種模式。調度器和控制器管理器可以通過将它們各自的清單複制到/etc/kubernetes/manifests來部署為Pod。

如下代碼是調度器清單中的一個片段,它顯示了标志的用法。

command: - /bin/sh - -c - /usr/local/bin/kube-scheduler --master=127.0.0.1:8080 --v=2 --leader-elect=true 1>>/var/log/kube-scheduler.log 2>&1

如下代碼是控制器管理器清單中的一個片段,它顯示了标志的用法。

- command: - /bin/sh - -c - /usr/local/bin/kube-controller-manager --master=127.0.0.1:8080 --cluster-name=e2e-test-bburns --cluster-cidr=10.245.0.0/16 --allocate-node-cidrs=true --cloud- provider=gce --service-account-private-key-file=/srv/kubernetes/server. key --v=2 --leader-elect=true 1>>/var/log/kube-controller-manager.log 2>&1 image: gcr.io/google_containers/kube-controller-manager:fda24638d51a4 8baa13c35337fcd4793

需要注意的是,這裡無法像其他Pod那樣由Kubernetes自動重新啟動這些組件,因為這些組件負責重新啟動失敗Pod的Kubernetes組件,所以如果失敗,它們就不能重新啟動自己。此處必須有一個現成的組件來随時準備替換。

領導選舉用于應用程序

領導選舉對于應用程序也非常有用,但卻很難實施。幸運的是,Kubernetes有巧妙的辦法,它有一個文件化的程序,通過Google的Leader-elector容器來支持用戶申請的領導人選舉。基本概念是使用Kubernetes端點結合資源轉換和注解。當将這個容器作為輔助工具耦合到應用程序Pod中時,用戶将以非常流暢的方式獲得領導人選舉功能。

如下代碼展示了用3個Pod和一個叫作election的選擇程序來運行leader-elector。

> kubectl run leader-elector --image=gcr.io/google_containers/leader- elector:0.4 --replicas=3 -- --election=election –http=0.0.0.0:4040

稍後,會看到集群上出現3個新的Pod,稱為leader-elector-xxx,代碼如下所示。

> kubectl get pods NAME READY STATUS RESTARTS AGE echo-3580479493-n66n4 1/1 Running 12 22d leader-elector-916043122-10wjj 1/1 Running 0 8m leader-elector-916043122-6tmn4 1/1 Running 0 8m leader-elector-916043122-vui6f 1/1 Running 0 8m

但是哪個是主節點?如下代碼演示了如何查詢選舉端點。

> kubectl get endpoints election -o json { "kind": "Endpoints", "apiVersion": "v1", "metadata": { "name": "election", "namespace": "default", "selfLink": "/api/v1/namespaces/default/endpoints/election", "uid": "48ffc442-b451-11e6-9db1-c2777b74ca9d", "resourceVersion": "892261", "creationTimestamp": "2016-11-27T03:26:29Z", "annotations": { "control-plane.alpha.kubernetes.io/leader": "{\"holderIdentity\":\"leader-elector-916043122-10wjj\",\"leaseDura tionSeconds\":10,\"acquireTime\":\"2016-11-27T03:26:29Z\",\"renewTi me\":\"2016-11-27T03:38:02Z\",\"leaderTransitions\":0}" } }, "subsets": [] }

如果上述過程相對較難,則可以在metadata.annotations中查閱更多内容。為了便于檢測,我推薦使用jq程序進行切片和切割JSON。它對解析Kubernetes API或kubectl的輸出非常有用,代碼如下所示。

kubectl get endpoints election -o json | jq -r .metadata.annotations[] | jq .holderIdentity "leader-elector-916043122-10wjj"

如下代碼展示了如何删除領導,以證明選舉的有效性。

kubectl delete pod leader-elector-916043122-10wjj pod "leader-elector-916043122-10wjj" deleted

這樣,便有了一個新的領導,代碼如下所示。

kubectl get endpoints election -o json | jq -r .metadata.annotations[] | jq .holderIdentity "leader-elector-916043122-6tmn4"

還可以通過HTTP的方式找到領導,因為每個leader-elector容器通過運行在端口4 040的本地Web服務器公開領導。

Kubectl proxy http http://localhost:8001/api/v1/proxy/namespaces/default/pods/ leader-elector-916043122-vui6f:4040/ | jq .name "leader-elector-916043122-6tmn4"

本地Web服務器允許leader-elector容器充當同一個Pod中的主應用程序容器的邊車(sidecar)容器。由于應用程序容器與leader-elector容器共享相同的本地網絡,因此它可以訪問http://localhost:4040并獲得當前領導的名稱。隻有與所選領導共享Pod的應用程序容器才會運行應用程序,其他Pod中的其他應用程序容器将處于休眠狀态。如果它們收到請求,會轉發給領導,并且一些負載均衡技巧可以自動将所有請求發送給當前的領導。

4.2.7 使預演環境高度可用

高可用性十分重要,如果遇到了設置高可用性的問題,那将意味着有一個高度可用系統的商業案例。因此,在将集群部署到生産環境之前(除非是在生産環境中進行測試的Netflix),需要測試可靠且高度可用的集群。此外,理論上對集群的任何更改都可能會破壞高可用性,而不會破壞其他集群功能。

默認用戶需要測試可靠性和高可用性,那最好的方法便是創建一個可以盡可能地複制生産環境的預演環境,這可能會很昂貴,下面展示了幾種控制成本的方案。

  • Ad hoc HA預演環境:僅在HA測試期間創建一個大型HA集群。
  • 壓縮時間:提前創建有意義的事件流和場景,提供輸入,并快速連續地模拟情境。
  • 将HA測試與性能和壓力測試相結合:在性能和壓力測試結束時,對系統進行過載,并查看可靠性和高可用性配置如何處理負載。
4.2.8 測試高可用性

測試高可用性需要制定計劃并對系統有深入理解。每個測試的目标是揭示系統設計和/或實現中的缺陷,并提供足夠的覆蓋範圍,測試通過将能夠保證系統按預期運行。

在可靠性和高可用性領域,這意味着需要找出破壞系統的方法,并将它們重新組合在一起觀察效果。

這就需要以下幾種方式。

  • 全面列出可能出現的故障(包括合理的組合)。
  • 對于每一個可能的故障,需要清楚系統應該如何應對。
  • 一種誘發故障的方法。
  • 一種觀察系統反應的方法。

上述每種方式都很重要,根據以往經驗,最好的方法是增量執行它,并嘗試提出相對少量的通用故障類别和通用響應,而不是一個詳盡的、不斷變化的低級故障列表。

例如,一般故障類别是節點無響應的;一般響應可能是重新啟動節點,導緻故障的方式可能是停止節點的VM(如果它是VM),并且當節點停機時,系統仍然基于标準驗收測試,節點最終上升,系統恢複正常。開發者可能還想測試許多其他内容,例如問題是否被記錄、相關警報是否發給相應人員,以及是否更新了各種統計和報告。

需要注意的是,有時故障不能在單一的響應中解決。例如,在無響應節點的情況下,如果是硬件故障,那麼重新啟動将無濟于事。在這種情況下,第二響應開始執行,也許是新的VM被啟動、配置并連接到節點。在這種情況下,不能定義得太寬泛,可能需要為節點上特定類型的Pod/角色(etcd、Master、Worker、數據庫、監控)創建測試。

如果有更高的要求,則要花費比生産環境更多的時間來設置适當的測試環境和測試。

最重要的一點是,盡量做到非侵入性。這意味着在理想情況下,生産系統将不具有允許關閉其部分功能或将其配置為以降低的測試容量運行的測試特性。原因是它增加了系統的攻擊面,并且可能由于配置錯誤而意外觸發。理想情況下,開發者可以控制測試環境,而不需要修改将在生産中部署的代碼或配置。使用Kubernetes,通常很容易注入具有定制測試功能的Pod和容器,這些功能可以與生産環境中的系統組件交互,但永遠不能在生産中部署。

本節介紹了擁有一個可靠和高可用的集群需要些什麼(包括etcd、API服務器、調度器和控制器管理器),探讨了保護集群本身以及數據的最佳實踐,并特别關注啟動環境和測試的問題。

本文截選自《精通Kubernetes》第四章第4.2節。

kubernetes學習手冊(高可用性最佳實踐)2

  • k8s初學者指南,針對K8s1.10,具備豐富實操案例
  • 幫助讀者掌握在各種雲平台上設計和部署大型集群的技能

本書通過理論與實踐相結合,全方位地介紹Kubernetes這一容器編排的理想工具。本書共14章,涉及的主題包括理解Kubernetes架構,創建Kubernetes集群,監控、日志記錄和故障排除,高可用性和可靠性,配置Kubernetes安全、限制和賬戶,使用關鍵Kubernetes資源,管理Kubernetes存儲,使用Kubernetes運行有狀态應用程序,滾動更新、可伸縮性和配額,高級Kubernetes網絡,在雲平台和集群聯邦中運行Kubernetes,自定義Kubernetes API和插件,操作Kubernetes軟件包管理器以及Kubernetes的未來。本書綜合考慮不同環境和用例,使讀者了解如何創建大型系統并将其部署在Kubernetes上。在各章節主題中,讀者提供了豐富的實踐案例分析,娓娓道來,引人入勝。

本書可以作為Kubernetes的實踐參考手冊,聚焦于設計和管理Kubernetes集群,為開發人員、運維工程師詳細介紹了Kubernetes所提供的功能和服務。

,

更多精彩资讯请关注tft每日頭條,我们将持续为您更新最新资讯!

查看全部

相关生活资讯推荐

热门生活资讯推荐

网友关注

Copyright 2023-2024 - www.tftnews.com All Rights Reserved