---
# System prepended metadata

title: Docker概念
tags: [Docker]

---

---
tags: Docker
---
# Docker概念

### 雲原生容器設計原則：

#### * **唯一關注性原則（SCP）** #### 
在許多方面，唯一關注性原則與來自SOLID的SRP是類似的，它建議一個類應該只有一個責任。SRP背後的動機是每個責任是變更的一個軸心，一個類應該有，且也只有一個需要改變的理由。SCP原則中的“關注”一詞強調關注是一種更高層次的抽象的責任，而且它更好地將範圍描述為一個容器而不是一個類。雖然SRP的主要動機是變化原因的唯一性，而SCP的主要動機是容器鏡像重用和可替換性。如果你創建一個解決單個問題的容器，並且以功能完整的方式來實現，不同應用程序中的容器鏡像重用的可能性就會更高。

因此，SCP原則規定每個集容器都應該解決一個問題，並做得很好。 實現這一點，通常比在面向對象的世界中實現SRP更容易，容器通常管理的一個單一的進程，大多數情況下一個進程解決一個問題。
![image alt](https://res.cloudinary.com/martinliu/image/upload/scp.png)

如果你的容器化微服務需要解決多個問題，它可以使用這樣的模式，將多個容器用sidecar和init-containers的模式合並成一個部署單元（pod），這樣每個容器仍然是處理單個問題。同樣，您可以替換處理同樣問題的容器。 例如，將Web服務器容器或隊列實現容器，更新為更具可擴展性的容器。

---
#### * **高度可觀測性原則（HOP）** #### 
容器提供了一種統一的方式來打包和運行應用程序，將它們視為一個黑盒子對象。 但任何旨在成為雲原生公民的容器都必須提供API支持，要為運行時環境編寫接口（API），以觀察容器的健康狀況和行為。 這是自動化容器更新和生命周期回收的基本先決條件和統一的方式，從而提高系統的彈性和用戶體驗。
![image alt](https://res.cloudinary.com/martinliu/image/upload/hop.png)
實際上，您的容器化應用程序必須至少為其提供不同類型的健康檢查的API–活動和就緒等狀態。更好的應用程序的行為則必須提供其他手段來觀察容器化應用程序的狀態。應用程序應該將重要事件記錄到標準錯誤（STDERR）和標準輸出（STDOUT）中，從而通過統一的日志聚合工具（諸如Fluentd和Logstash之類的工具）進行分析，並與跟蹤和指標收集庫相結合，例如OpenTracing，Prometheus等。

將您的應用程序視為黑盒子，但實施所有必要的API以幫助平台對其進行觀測，並以最佳方式管理您的應用程序。

---
#### * **生命周期一致性原則（LCP）** #### 
HOP規定了你的容器提供供平台觀測的API。 LCP則規定：您的應用程序有辦法讀取來自平台的事件。 此外，除了獲得事件以外，容器還應該對這些事件相應地作出反應。這就是此原則名字由來。這幾乎就像在應用程序通過一個“寫入API”與平台進行交互。

![image alt](https://res.cloudinary.com/martinliu/image/upload/lcp.png)

來自管理平台的各種事件都是為了幫助您管理您的容器的生命周期的。決定處理哪些事件取決於您的應用程序 以及是否對這些事件做出反應。

但有些事件比其他事件更重要。例如，任何需要一個幹凈的關閉進程，這就需要捕獲信號：終止（SIGTERM）消息，並盡可能迅速關閉。 這是為了避免通過強制關閉信號：kill（SIGKILL），之後跟隨一個SIGTERM。

還有其他事件，例如PostStart和PreStop，可能對您的應用程序生命周期管理也非常重要。 例如，某些應用程序需要在服務之前進行預熱請求和一些需要在關閉幹凈之前釋放資源。

---
#### * **鏡像不可變性原則（IIP）** #### 
IMAGE IMMUTABILITY PRINCIPLE（IIP）容器化的應用程序是不可變更的，鏡像一旦完成了構建，預計在不同的環境中運行都不會改變。這意味著在因外部環境的不同，在需要的時候需要使用外部手法處理所依賴的外部配置數據，而不是每個環境修改或者構建不同的容器。而容器應用程序中的任何變更，都應該因此觸发構建新的容器映像，並在所有環境中重用它。相同於這個原理的，不可變服務器和不可變基礎架構的概念也很受歡迎，並且對於服務器/主機管理也是如此。

![image alt](https://res.cloudinary.com/martinliu/image/upload/iip.png)

在遵循IIP原則的情況下，應該防止為不同的環境創建相似的容器鏡像，要始終堅持為所有環境只配置一個容器映像。 這個原則允許在應用程序更新期間，采用自動回滾和前滾等做法，這是雲原生自動化的重要方面。

---
#### * **進程可處置性原則（PDP）** #### 
遷移到容器應用程序的主要動機之一是：容器需要盡可能做到臨時性，並做好在任何時候被另一個容器實例替換的準備。需要更換容器的原因有很多，比如：健康檢查失敗、縮容、應用程序將容器遷移到不同的主機，平台資源匱乏或其它的問題。

![image alt](https://res.cloudinary.com/martinliu/image/upload/pdp.png)
    
這意味著容器化的應用程序必須保持其狀態為向外擴展的或分布式和冗余的。這也意味著應用程序應該快速啟動和關閉，甚至為徹底的硬件故障做好準備。 實施這一原則的另一個有用的做法是創建小容器。 容器在雲原生環境可以自動調度並在不同的主機上啟動。較小的容器可以實現更快啟動時間，因為在重新啟動之前容器鏡像需要被物理地覆制到主機系統。

---
#### * **自包含性原則（S-CP）** #### 
這個原則規定一個容器應該在構建時包含所有需要的東西。容器的存在應該僅僅依賴於Linux®內核，在並添加相關額外的庫，在容器構建時加入它們。除了庫之外，它還應該包含語言運行時，應用程序平台（如果需要），以及運行所需的其他依賴關系，等運行容器化應用所需要的諸如此類的東西。

![image alt](https://res.cloudinary.com/martinliu/image/upload/s-cp.png)
    
唯一的例外是：由於不同環境之間差異，並且只能在運行時提供的配置; 例如，通過Kubernetes提供的ConfigMap。
某些應用程序由多個容器組件組成。 例如，容器化的Web應用程序也可能需要數據庫容器。 根據這個原則，並不建議合並兩個容器。相反，它建議的是數據庫容器只包含運行數據庫所需的所有內容，Web應用程序容器只包含運行Web應用程序所需的所有內容，如Web服務器。 在運行時，Web應用程序容器將根據需要依賴於並訪問數據庫容器。

---
#### * **運行時約束性原則（RCP）** #### 
S-CP從構建時的角度查看容器，並關注於生成的二進制文件及其內容。但是容器不僅僅是磁盤上一個只有尺寸大小的單一維度的黑盒子。 容器運行時有多個維度，例如內存使用維度，CPU使用維度等資源消耗維度。

![image alt](https://res.cloudinary.com/martinliu/image/upload/rcp.png)
    
這個RCP原則建議每個容器申報資源需求，並发送信息到平台。它應該分享容器的資源配置文件，從CPU，內存，網絡，磁盤的角度聲明。這影響到平台如何執行調度，自動擴展，容量 管理以及容器常規的服務級別協議（SLA）等。

除了向平台聲明容器的資源需求之外，還有一點也很重要， 應用被約束在使用所聲明的資源需求內。如果應用程序對資源的使用保持在約束的範圍內，則當資源匱乏发生時，平台不太可能將其終止和遷移。
    
----
# **結論**

創建良好的容器應用程序還需要熟悉其他容器相關的最佳實踐和技術。 盡管上述原則非常根本，適用於大多數用例，下面列出的最佳實踐在應用和不應用的時候，則需要判斷力。以下是一些與容器相關的更常見的最佳實踐：
* **鏡像要盡可能的小** 通過清理臨時文件，並避免安裝不必要的軟件包來構建小尺寸鏡像。 這減少了容器的尺寸，構建時間和覆制容器鏡像的網絡傳輸時間。
* **支持任意用戶ID** : 避免使用sudo命令或要求特定用戶名運行你的容器。
* **標記重要的端口** : 雖然可以在運行時指定端口號，然而使用EXPOSE命令在運行的時候指定，則可以讓鏡像的使用者更輕松。
* **為持久數據使用卷** : 在容器摧毀之後還需要保存的容器數據的，必須將數據寫入一個數據卷。
* **設置鏡像元數據** : 以標簽和注釋形式存在的鏡像元數據可以使您的容器鏡像更加實用，從而為使用您的容器的開发人員提供了更好的體驗。
* **使主機和鏡像同步** : 一些容器應用需要容器在某些屬性（如時間和機器ID）上與主機同步。