容器與 Pod


現在 Docker 的流行程度越來越高,越來越多的公司使用 Docker 打包和部署項目。但是也有很多公司只是追求新技術,將以前的單體應用直接打包為鏡像,代碼、配置方式等各方面保持不變,使用 Docker 后,並沒有帶來多大的便利,反而使得配置、啟動過程變得更加繁雜,更難調試。

本章將討論容器與 Pod 的關系,了解如何更好地將應用容器化。

什么是容器化應用
containerized applications 指容器化的應用,我們常常說使用鏡像打包應用程序,使用 Docker 發布、部署應用程序,那么當你的應用成功在 Docker 上運行時,稱這個應用是 containerized applications。

定義:

[Success] 定義

Containerized applications are bundled with their required libraries, binaries, and configuration files into a container.

容器化的應用程序與它們所需的庫、二進制文件和配置文件綁定到一個容器中。

通常,容器都包含一個應用程序,以及正確執行二進制程序所需的依賴庫、文件等,例如 Linux 文件系統+應用程序組成一個簡單的容器。通過將容器限制為單個進程,問題診斷和更新應用程序都變得更加容易。與 VM(虛擬機)不同,容器不包含底層操作系統,因此容器被認為是輕量級的。Kubernentes 容器屬於開發領域。

容器在操作系統之上,提供了 CPU、內存、網絡、存儲等資源的虛擬化,為應用在不同服務器里提供了一致的運行時環境。開發者可以通過容器創建一個可預測的環境,能夠保證在開發、調試、生產時的環境都是一致的,減少開發團隊和運維團隊可以減少調試和診斷問題時,因環境差異帶來的麻煩。同時,應用運行在一個沙盒中,對應用和系統進行了隔離,提高了安全性,還能限制應用程序使用的計算資源。

當然,並不是說能夠將一個應用程序打包到容器中運行,就可以鼓吹產品;並不是每個應用程序都是容器化的優秀對象,例如在 DDD 設計中被稱為大泥球的應用程序,具有設計復雜、依賴程度高、程序不穩定等確定,這種難以遷移、難以配置的應用程序明顯是失敗的產品。

在多年經驗中,許多開發者對容器化技術進行了總結,這些強有力的經驗、理論形成十二個雲計算應用程序因素指導原則:

  1. Codebase: One codebase tracked in revision control, many deploys

代碼庫: 一個代碼庫可以在版本控制和多份部署中被跟蹤。一般使用 github 等對代碼進行管理。

  1. Dependencies: Explicitly declare and isolate dependencies

依賴項: 顯式聲明和隔離依賴項。

  1. Config: Store config in the environment

配置:在環境中存儲配置。

  1. Backing services: Treat backing services as attached resources

支持服務:將支持服務視為附加資源(可拓展,而不是做成大泥球)。

  1. Build, release, run: Strictly separate build and run stages

構建、發布、運行: 嚴格區分構建和運行階段(連 Debug、Release 都沒有區分的產品是真的垃圾)。

  1. Processes: Execute the app as one or more stateless processes

過程:應用程序作為一個或多個無狀態過程執行。

  1. Port binding: Export services via port binding

端口綁定:可通過端口綁定服務對外提供服務。

  1. Concurrency: Scale out via the process model

並發性:通過 process 模型進行擴展。

  1. Disposability: Maximize robustness with fast startup and graceful shutdown

可處理性: 快速啟動和完美關機,最大限度地增強健壯性。

  1. Dev/prod parity: Keep development, staging, and production as similar as possible

開發/生產一致:盡可能保持開發中、演示時和生產時的相似性。

  1. Logs: Treat logs as event streams

Logs:將日志視為事件流。

  1. Admin processes: Run admin/management tasks as one-off processes

管理流程:將管理/管理任務作為一次性流程運行。

上述內容可能有筆者翻譯不到位的地方,讀者可閱讀原文了解:https://12factor.net/

容器位於開發人員技能列表之中,開發人員需要掌握如何容器化應用。

另外,在一個產品中,好的容器化規范或方法,具有以下特點:

使用聲明式的格式進行設置自動化,以最大限度地減少新開發人員加入項目的時間和成本;
與底層操作系統之間有一個干凈的契約(資源隔離、統一接口),在執行環境之間提供最大的可移植性;
適合部署在現代雲平台上,無需服務器和系統管理;
最大限度地減少開發和生產之間的差異,實現持續部署以實現最大敏捷性;
並且可以在不對工具、架構或開發實踐進行重大更改的情況下進行擴展。
在制作雲原生應用的過程中,可以參考雲計算應用程序因素指導原則,設計更加優秀的產品。

Pod
最簡單的說法就是將多個容器打包起來一起運行,這個整體就是 Pod。

[Info] 提示

在上一章的 Docker 網絡中,介紹了 container 網絡模式,Pod 正是通過這種網絡模式,讓 Pod 中的容器共享網絡,也就是說,Pod 中的容器,網絡是互通的,容器之間不能使用相同的端口。

Pod 是 Kubernetes 集群中最小的執行單位。在 Kubernetes 中,容器不直接在集群節點上運行,而是將一個或多個容器封裝在一個 Pod 中,接着將 Pod 調度到節點上運行,這些容器會一起被運行、停止,它們是一個整體。

Pod 中的所有容器共享相同的資源和本地網絡,從而簡化了 Pod 中應用程序之間的通訊。在 Pod 中,所有容器中的進程共享網絡,可以通過 127.0.0.1、localhost 相互進行訪問。詳見 3.1 章 中 "Pod 共享網絡和存儲" 一節。

一個簡單的 Pod,其結構如下:

Pod多容器

[Info] 提示

Pod 啟動時會啟動一個容器,K8S 給這個容器分配虛擬 IP,接着,其他容器使用 container 網絡模式,連接到這個容器中,此時有容器共享網絡。

隨着 Pod 負載的增加,Kubernetes 可以自動復制 Pod 以達到預期的可拓展性(部署更多的 Pod 提供相同的服務,負載均衡)。因此,設計一個盡可能精簡的 Pod 是很重要的,降低因復制擴容、減少收縮過程中帶來的資源損失。

前面提到,容器應當是無狀態的,所以拓展 Pod 時,每個實例都提供了一模一樣的服務,這些 Pod 分配到不同的節點上,可以利用更多的 CPU、內存資源。

fzjh1

在第三章中,我們會更加詳細地學習 Pod,這里就不再贅述。

容器與 Pod 的區別
容器包含執行特定流程或函數所需的代碼(編譯后的二進制可執行程序)。在 Kubernetes 之前,可以直接在物理或虛擬服務器上運行容器,但是缺乏 Kubernetes 集群所提供的可伸縮性和靈活性。

Pod 為容器提供了一種抽象,可以將一個或多個應用程序包裝到一個 Pod 中,而 Pod 是 Kubernetes 集群中最小的執行單元。例如 Pod 可以包含初始化容器,這些容器為其它應用提供了准備環境,然后在應用程序開始執行前終結。Pod 是集群中復制的最小單位,Pod 中的容器作為整體被擴展或縮小。

pod1

例如對應前后端分離的項目,可能不需要把前端文件和后端程序放在一起,而是分別放在兩個容器中。然后通過 Pod,將這兩個容器作為一組服務打包在一起。

節點
Pod 是 Kubernetes 中最小的執行單元,而 Node 是 Kubernetes 中最小的計算硬件單元,節點可以是物理的本地服務器,也可以是虛擬機,節點即使宿主服務器,可以運行 Docker 的機器。

與容器一樣,Node 提供了一個抽象層。多個 Node 一起工作形成了 Kubernetes 集群,它可以根據需求的變化自動分配工作負載,增加或減少在節點上的 Pod 數量。如果 A 節點和 B 節點的硬件資源是一致的,那么 A 、B 兩個節點是等價的,如果 A 節點失敗,它將自動從集群中移除,由 B 節點接管,不會出現問題。

每個節點都運行着一個名為 kubelet 的組件,它是節點的主要組件,Kubernetes 與集群控制平面組件(API Server)通信,所有對節點有影響的操作都會通過 kubectl 控制此節點。kubelet 也是 master 節點跟 worker 節點之間直接通訊的唯一組件。

node結構

kubelet 的一些功能有:

在節點上創建、更新、刪除容器;
參與調度 Pod;
為容器創建和掛載卷;
使用命令查看 Pod 、容器,例如 exec、log 等時,需要通過 kubelet;
例如,集群有 A、B 兩個節點,Pod 部署在哪里了,這不是用戶關心的事情,用戶在想看到容器的日志,可以隨便找集群中的一台主機,執行命令,Kubernetes 會自動尋找容器所在的節點,然后kubectl 取得需要的內容。

另外節點上還有 proxy,主要是為 Pod 提供代理服務,外界可通過此代理,使用節點的 IP 訪問 Pod 中的容器。

proxy


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM