10個小技巧提高 Kubernetes 容器效率

近年來,容器以及 Kubernetes 成為開發者以及企業用戶重點關注的技術趨勢,本文總結了構建和管理容器的十個重要技巧來優化 IT 成本並提高效率。

容器是 Kubernetes 中應用程序的核心載體。當創建 Kubernetes 工作負載,例如創建用於調度、擴容或者升級應用程序的規則時,首先需要創建一個容器鏡像,然後通過該鏡像來運行服務或 Kubernetes 工作負載。在完成對鏡像的測試並與應用程序其餘代碼整合後,用戶通常會將鏡像推送到容器註冊中心。但在推送之前,仍然有很多實戰技巧可以幫助構建和管理容器。

通過 Kubernetes,用戶可以自動擴展業務,而整個過程很少出現甚至零宕機,從而優化 IT 成本並提高系統可靠性。

1、使用最新 Kubernetes 模式

隨著 Kubernetes 不斷推出新功能,其應用模式也在逐步改變。為了確保 Kubernetes 集群遵循當前最新 Kubernetes 的應用模式,用戶需要定期查閱Kubernetes 官方文檔以及每一個版本的發佈說明。


2、複用基礎鏡像以節省時間

在 Kubernetes 集群中創建應用容器時,用戶需要構建一個 Docker 基礎鏡像,然後在此鏡像基礎上構建部分或全部應用容器。有很多應用共享依賴項、庫和配置,因此可以在基礎鏡像完成對共享部分進行配置,從而實現複用。

Docker Hub和Google Container 註冊中心有數千個可供下載的基礎鏡像,這些鏡像已經預先完成應用配置,隨時可以投入使用,這可以節省大量時間。

10個小技巧提高 Kubernetes 容器效率

3、不要輕易相信任何鏡像

儘管使用預先構建的鏡像很方便,但要格外小心並確保對其運行特定漏洞掃描。

一些開發人員會從 Docker Hub 中獲取一個其他用戶創建的基礎鏡像,然後將這個容器推送到生產環境,而這一切只是因為乍一看這個鏡像包含了所需要的包。

這裡有很多錯誤:鏡像中的代碼版本可能不正確;這些代碼可能有漏洞;或者更糟糕的情形是該項目可能已經被故意綁定了惡意軟件。

為了緩解上述問題,用戶可以通過 Snyder 或 Twistlock 來運行靜態分析,然後將其整合到 CI/CD(持續集成和持續交付)管道中,進而掃描所有容器漏洞。

一般來說,一旦在基礎鏡像中發現漏洞,用戶就應該重新構建整個鏡像,而不是僅僅修復漏洞。容器應該是不變的,因此,需要引入補丁重新構建和部署鏡像。

4、優化基礎鏡像

從最精簡、最可行的基礎鏡像開始,然後在此基礎上構建軟件包。通過這種方式,可以準確掌握容器中的全部內容。

較小的基礎鏡像也可以減少開銷。例如,應用可能只有 5MB 大小,如果要添加一個現成的 Node.js 鏡像,然後再安裝所有的庫,整個鏡像很可能會變成 600MB 大小,但實際上並不需要這些額外的庫。

因此,儘量保持最精簡的鏡像可以使:

  • 構建更快
  • 存儲空間更小
  • 鏡像拉取更快
  • 潛在攻擊面更小

5、確保容器只運行一個進程

同保持基礎鏡像最小化類似的是,確保每個容器只有一個進程。容器的生命週期與它託管的應用程序相同,這意味著每個容器應該只包含一個父進程。

10個小技巧提高 Kubernetes 容器效率


按照Google Cloud的說法,把容器當作虛擬機並同時運行多個進程是一個常見的錯誤。雖然容器可以實現這種方式,但這樣就無法使用 Kubernetes 的自我修復屬性。

通常,容器和應用應該同時啟動;同樣,當應用停止時,容器也應該停止。如果在一個容器中有多個進程,可能會出現應用程序狀態混雜的情形,這將導致 Kubernetes 無法確定一個容器是否健康。

6、正確處理 Linux 信號

容器通過 Linux 信號來控制其內部進程的生命週期。為了將應用的生命週期與容器聯繫起來,需要確保應用能夠正確處理 Linux 信號。

Linux 內核使用了諸如 SIGTERM、SIGKILL 和 SIGINIT 等信號來終止進程。但是,容器內的 Linux 會使用不同的方式來執行這些常見信號,如果執行結果同信號默認結果不符,將會導致錯誤和中斷髮生。

創建專門的 init 系統有助於解決此問題,比如專門針對容器的Linux Tini系統。這個工具正確註冊了信號處理程序(比如 PID),容器化應用可以正確執行 Linux 信號,從而正常關閉孤立進程和殭屍進程,完成內存回收。

7、充分利用 Docker 的緩存構建機制

容器鏡像由一系列鏡像層組成,這些鏡像層通過模板或 Dockerfile 中的指令生成。這些層以及構建順序通常被容器平臺緩存。例如,Docker 就有一個可以被不同層複用的構建緩存。這個緩存可以使構建更快,但是要確保當前層的所有父節點都保存了構建緩存,並且這些緩存沒有被改變過。簡單來講,需要把不變的層放在前面,而把頻繁改變的層放在後面。

例如,假設有一個包含步驟 X、Y 和 Z 的構建文件,對步驟 Z 進行了更改,構建文件可以在緩存中重用步驟 X 和 Y,因為這些層在更改 Z 之前就已經存在,這樣可以加速構建過程。但是,如果改變了步驟 X,緩存中的層就不能再被複用。

雖然這是一種方便的行為,可以節省時間,但是必須確保所有鏡像層都是最新的,而不是從舊的、過時的緩存構建而成。

8、使用類似 Helm 的包管理器

Helm作為 Kubernetes 的非官方軟件包管理器,可以幫助安裝和更新集群中運行的共同負載和容器。Helm 可以使用Chart聲明自定義應用程序依賴項,並提供滾動升級和回滾工具。

用戶可以通過現有基礎鏡像為 Kubernetes 集群提供通用服務,如數據庫或 Web 服務;也可以為內部應用程序創建自定義基礎鏡像,創建自定義的 Charts 可以簡化部署,減少開發團隊的工作負擔和重複性工作。

9、使用標籤和語義化版本號

作為基本原則,用戶不應該使用:latest標記。對大多數開發人員來說,這是顯而易見的。如果不為容器添加自定義標籤,它將嘗試從鏡像倉庫中拉取最新版本,而最新的容器可能並沒有包括需要的更改。

在創建自定義鏡像時,使用鏡像標籤和語義化版本號來追蹤對 Docker 容器的更改。當它們在 Kubernetes 集群中運行時,Kubernetes 通過鏡像標籤確定應該運行哪個版本。在選擇 Docker 鏡像版本機制時,應該同時考慮生產負載和開發流程兩種情況,這樣才能在 Kubernetes 中獲得更好的效果。

10、安全

在很多情況下,當構建 Docker 鏡像時,需要讓容器內的應用程序訪問敏感數據,例如 API 令牌、私鑰和數據庫連接字符串等。

將這些秘密信息嵌入到容器中並不是一個安全的解決方案,即使只是保存到一個私有容器鏡像中。將未加密的隱私數據作為 Docker 鏡像的一部分進行處理會面臨無數額外的安全風險,包括網絡和鏡像註冊表的安全性,而 Docker 架構本身也決定了無法對容器中未加密的敏感數據進行優化。

相反,用戶可以通過使用Kubernetes Secrets 對象將隱私信息存儲在容器外面,這樣更簡單、安全。

Kubernetes 提供了一個 Secrets 抽象,允許在 Docker 鏡像或 Pod 定義之外存儲隱私數據。用戶可以通過掛載卷或環境變量的方式把這些信息加載到容器中。更新時,只需更換相關服務的 Pod 並使用新的證書即可。用戶也可以通過 Hashicorp Vault 以及Bitnami Sealed Secrets來保存隱私數據。

原文鏈接:https://www.jianshu.com/p/3870b815a966,本文轉自公眾號“K8S 中文社區”。


分享到:


相關文章: