1. 程式人生 > >K8S生產環境中實踐高可靠的配置和技巧都有哪些?

K8S生產環境中實踐高可靠的配置和技巧都有哪些?

K8S環境中實踐高可靠的配置和技巧都有哪些?

磁碟型別及大小

磁碟型別:

  • 推薦使用ssd 磁碟
  • 對於worker節點,建立叢集時推薦使用掛載資料盤。這個盤是專門給/var/lib/docker 存放本地映象。可以避免後續因映象太多而造成磁碟根目錄容量不夠的情況。在執行一段時間後,本地會存在很多無用的映象。比較快捷的方式就是,先下線這臺機器,重新構建這個磁碟,然後再上線。

磁碟大小:
kubernetes節點需要的磁碟空間也不小,Docker映象、系統日誌、應用日誌都儲存在磁碟上。建立kubernetes叢集的時候,要考慮每個節點上要部署的pod數量,每個pod的日誌大小、映象大小、臨時資料,再加上系統預留的值。

kubernetes叢集中作業系統佔用3G左右的磁碟空間,建議預留8G左右的磁碟空間。剩餘空間考慮到給kubernetes資源物件使用。

是否立即構建worker節點

  1. 構建節點考慮初始節點數量和後續增加的節點和證書問題。

網路選擇

  1. 如果需要連線外部的一些服務,如rds等,則需要考慮複用原有的VPC,而不是建立一個新的VPC。因為VPC間是隔離的,您可以建立一個新的交換機,把kubernetes的機器都放在這個交換機網路下,從而便於管理。
  2. 在kubernetes叢集建立時,需要選定好網路外掛,後續如果需要更新網路外掛,或多或少都會對生產業務造成一定影響。當前主流的網路外掛有:calico、flannel和terway(阿里雲)
  3. pod網路cidr不能設定太小,如果太小,可以支援的節點數量就會受限。這個值的設定需要和pod節點數量綜合考慮。例如:pod網路cidr的網段是/16,那麼就會256*256個地址,如果每個節點數量是128,則最多可以支援512個節點。

使用多可用區

  1. 阿里雲支援多地域,每個地域下面又有不同的可用區。可用區是指在同一個地域內,店裡和網路互相地理的物理區域。多可用區能夠實現跨區域的容災能力。同時也會帶來額外的網路時延。建立kubernetes叢集時,您可以選擇建立多可用區kubernetes叢集。其實對於裸機部署來講,跨機房網路只要3層可達既可以。

宣告每個pod的resource

在使用kubernetes叢集時,經常會遇到:在一個節點上排程了太多的pod,導致節點負載太高,沒法正常對外提供服務的問題。

為避免上述問題,在kubernetes中部署pod時,您可以指定pod需要的request及limit的資源,kubernetes在部署這個pod時,就會根據pod的需求找到一個具有充足空閒資源的節點部署這個pod。下面例子中就聲明瞭nginx這個pod需要1核CPU,1024M記憶體,執行實際應用不能超過2核CPU和4096MB記憶體。
apiVersion: v1 kind: Pod metadata: name: nginx spec: containers: - name: nginx image: nginx resources: # 資源宣告 requests: memory: "1024Mi" cpu: "1000m" limits: memory: "4096Mi" cpu: "2000m"
kubernetes採用靜態資源排程方式,對於每個節點上的剩餘資源,是這樣計算的:節點剩餘資源=節點總資源-已經分配出去的資源,並不是實際使用的資源。如果您自己手動裕興一個很耗資源的程式,kubernetes並不能感知到。
另外所有的pod上都要宣告resource。對於沒有宣告resource的pod,它被排程到某個節點後,kubernetes也不會在對應的節點上扣掉這個pod使用的資源。可能會導致節點上排程過去的太多的pod。

日誌和監控方向

  1. 需要提前測試好是否配置elkF叢集來實現日誌的監控,實現之後對於每個pod的日誌的儲存和採集,需要提前配置(包括動態新增pod和動態新增節點時是否能夠自動採集日誌和儲存日誌)。
  2. 需要提前測試prometheus監控和grafana圖形展示(動態新增pod節點監控和node監控)。

啟動時等待下游服務,不要直接退出

遊戲應用可能會有一些外部依賴,例如需要從資料庫(DB)讀取資料或者依賴另一個服務的介面。應用啟動的時候,外部依賴尾部都能滿足。手工運維的時候,通常採用依賴不滿足立即退出的方式,也就是所謂的failfast,但是在kubernetes中,這種策略不再適用。原因在於kubernetes中多數運維操作是自動的,不需要人工接入,例如部署應用,您不用自己選擇節點,再到節點上啟動應用,應用fail,不用手動重啟,kubernetes會自動重啟應用。負載增高,還可以通過HPA自動擴容。
針對啟動時依賴不滿足這個場景,假設有兩個應用A和B,A依賴B,對A來說就是依賴不滿足。如果A還是按照傳統的方式直接退出,當B啟動之後,A也不會再啟動,必須人工介入處理才行。
kubernetes的最好的方式就是啟動時檢查依賴,如果不滿足,輪訓等待,而不是直接退出。可以通過Init Container(https://kubernetes.io/docs/concepts/workloads/pods/init-containers/?spm=a2c63.p38356.879954.9.79896be3WGvb05#what-can-init-containers-be-used-for)完成這個功能。

配置restart policy

pod執行過程中程序退出是個很常見的問題,無論是程式碼裡面的一個BUG,還是佔用記憶體還多,都會導致應用程序退出,pod退出。您可以在pod上配置restart Policy,都能實現pod掛掉之後在自動重啟。
apiVersion: v1 kind: Pod metadata: name: tomcat spec: containers: - name: tomcat image: tomcat restartPolicy: OnFailure #
restart Policy有三個可選值

  • Always:總是自動重啟
  • OnFailure:異常退出才自動重啟(程序退出狀態非0)
  • Never:從不重啟

配置Liveness Probe和Readiness Probe

Pod處於running狀態和pod能正常提供服務是完全不同的概念,一個running狀態的pod,裡面的程序可能發生了死鎖而無法提供服務。但是因為pod還是running的,kubernetes也不會自動重啟這個pod。所有我們要在所有pod上配置liveness probe,探測pod是否真的存活,是否還能提供服務。如果liveness probe發現了問題,kubernetes會自動重啟pod。
readiness probe 用於探測pod是不是可以對外提供服務。應用啟動過程中需要一些時間完成初始化,在這個過程中是沒法對外提供服務的,通過readiness probe,可以告訴ingress 或者service能不能把流量繼續轉發到這個pod上,當pod出現問題的時候,readiness probe能夠避免新流量繼續轉發給這個pod。
apiVersion: v1 kind: Pod metadata: name: tomcat spec: containers: - name: tomcat image: tomcat livenessProbe: httpGet: path: /index.jsp port: 8080 initialDelaySeconds: 3 periodSeconds: 3 readinessProbe: httpGet: path: /index.jsp port: 8080

每個程序一個容器

很多剛剛接觸容器的人按照舊習慣把容器當做虛擬機器(VM)使用,在一個容器裡面放置多個程序:監控程序、日誌程序、sshd程序、甚至整個systemd。這樣操作存在兩個問題:
- 判斷pod整體的資源佔用會變複雜,不方便實施前面提到resource limit。
- 容器內只有一個程序的情況,程序掛了,外面的容器引擎可以清楚的感知到,然後重啟容器。如果容器內有多個程序,某個程序掛了,容器未必受影響,外部的容器引擎感知不到容器內有程序退出,也不會對容器做任何的操作,但是實際上容器已經不能正常工作了。
如果有好幾個程序需要進行協同工作,在kubernetes裡也可以實現,例如nginx和php-fpm,通過unix domain socket通訊,我們可以用一個包含兩個容器的pod,unix socker放在兩個容器的共享volume中。

確保不存在SPOF(Single Point of Failure)

如果應用只有一個示例,當例項失敗的時候,雖然kubernetes能夠重啟例項,但是中間不可避免的存在一段時間的不可用。甚至更新應用,釋出一個新版本的時候,也會出現這種情況。在kubernetes裡,儘量避免直接使用pod,儘可能的使用deployment/Statefulset,並且讓應用至少有兩個pod以上