---
# System prepended metadata

title: OCI (Open Container Initiative)
tags: [Container, Docker, OCI]

---

# OCI (Open Container Initiative)
![OCI](https://opencontainers.org/img/logos/OCI-logo.svg)

`OCI` 是 Linux Foundation 所提出的計畫，主要是希望能夠針對 Linux Container (容器) 制定一個基於作業系統層級的虛擬化開放標準。

Docker 一直以來便是 Linux Container 框架的標準，所以 `OCI` 也是基於 Docker 去做設計和制訂的。因此這套標準和 Docker 非常相似，也使得 Docker 可以和其他基於 `OCI` 的容器框架可以兼容。

目前 `OCI` 也已經制定出了兩個標準: Runtime Specification 和 Image Specification。

<!-- more -->

## Runtime Spec
Runtime Spec 主要是在規範如何控制 Container。

標準的 Container 是把應用程式和其所依賴的所有套件、檔案或設定一起封裝成可以獨立運作及移動到其他環境的格式。而封裝起來的檔案可以在任何一個符合此種格式檔案執行的環境下執行且不需要依賴額外的套件或檔案，也不在乎執行此檔案的機器和檔案內容。

上述對 Container 的標準定義可以用貨輪載運貨物來做比喻。每一個貨櫃都會裝載著不同的貨物，這些貨櫃可以被抬起、堆疊、鎖定、裝載、卸載和標記。不論貨櫃的內容物是什麼也不管貨輪是哪一艘，只要統一了貨櫃的格式，就可以定義一組更精簡、更有效的運作流程。

### Container 的五大原則
#### 1. 擁有標準運作流程
標準的 Container 要制定一組運作的流程，Container 可以被建立、啟動、停止；也可以被複製、備份；還要可以被下載、上傳。
    
#### 2. 不論內容是什麼都可以使用
Container 的內容不論是什麼，對於標準運作流程來說，執行的方式都是一樣的。

#### 3. 不論機器的基礎架構是什麼都可以運作
不論是伺服器、桌上型電腦、筆記型電腦等，只要機器上有支援 OCI 就可以運作。

#### 4. 為了自動化而設計
因為有標準的運作流程，也不管內容和基礎架構是什麼，所以非常適合以自動化的方式來運作。

#### 5. 工業級別的交付
藉由上述所提到的優點，標準的 Container 可以讓開發者們簡化流程並且自動化的交付開發完成的應用程式。

### Container 的三大規範
在 Spec 裡對 Container 主要有三大規範 : 
* FileSystem Bundle (檔案系統資料夾)
* Configuration (設定檔)
* Runtime and Lifecycle (運行時的生命週期)

### FileSystem Bundle
FileSystem Bundle 是檔案系統的資料夾，也就是把執行時所需要的檔案和設定全部放進一個資料夾，執行時就可以依據這個資料夾來啟動 Container。

### Configuration
設定檔會根據不同的作業系統有不同的規範，而檔案內會明確的表示出建立 Container 所需要的所有參數，包含環境變數、執行的流程和[沙盒](https://zh.wikipedia.org/wiki/%E6%B2%99%E7%9B%92_(%E9%9B%BB%E8%85%A6%E5%AE%89%E5%85%A8))的功能設定。

Container 運行時的環境必須依照設定檔來建立，若無法依照設定檔來建立則應該為建立失敗。此規範主要是確保 Container 的運行能有一致的環境。

### Runtime and Lifecycle
Container 運行最重要的就是要知道 Container 的狀態、操作方式及生命週期。因此此規範也制定了查詢容器狀態時需回傳的訊息、如何操作 Container 和 Container 從啟動到關閉的整個過程。

## Image Spec
Image Spec 主要是在規範如何建立 Image。

下圖說明了 Image 的組成。
![Image Spec](https://i.imgur.com/oazpX91.png)

當應用程式要包裝成 Image 時，需要具備以下規範: 
* **Image Layer Filesystem Changeset** 
此規範定義了如何序列化以及新增、刪除、修改文件系統成為一個 [Blob](https://zh.wikipedia.org/wiki/%E4%BA%8C%E9%80%B2%E4%BD%8D%E5%A4%A7%E5%9E%8B%E7%89%A9%E4%BB%B6)，而這個 Blob 稱之為 Layer。
Image 透過以層層堆疊的方式建構出來，成為完整的一個文件系統。每一層就是一個 Layer，Layer 會儲存該次建構所需要的文件以及與上一層之間產生的變化。

* **Image Configuration**
定義文件系統所需的一些資訊，例如 : 參數、環境變數和工作目錄等等。也紀錄了每個 Layer 的順序及轉換成 Runtime Filesystem Bundle 的配置資訊。

* **Image Manifest**
Image Manifest 包含了這個 Image 的組成，像是有哪些 Layer 和 Config。而一個 Manifest 文件的內容只會對應到一個平台(架構或是作業系統)。

* **Image Index** 
Image Index 包含了一個列表，列表中因應不同的平台會對應到不同的 Image Manifest 文件，並使用 Index 作為取得 Image Manifest 的索引。 Image Index 可以確保 Image 可以跨平台使用。
所以，當使用者在下載 Image 時，會根據不同的平台先在 Image Index 文件中找到對應的 Index，再利用這個 Index 找到對應的 Image Manifest。
    
* **Image Layout**
Image Layout 是一個目錄結構，代表了這個 Image 的內容。其中包含了 [Blobs 資料夾](https://github.com/opencontainers/image-spec/blob/master/image-layout.md#blobs)、OCI-Layout 和 Image Index。 Blobs 資料夾中儲存了許多的 Blob，每個 Blob 即為真正的實體文件，例如 : Manifest、Config、Layer。而 OCI-Layout 則只有儲存 Layout 的版本。

* **Conversion**
描述如何將 Image 轉換成 Runtime 的 Filesystem Bundle。

* **Descriptor**
描述一個目標內容的位置。Descriptor 包含內容的類型、ID (digest)、大小，所以當取得了 Image Manifest 後，就可以從 Manifest 裡記錄的每個 Content Descriptor 找出 ID，再利用 ID 逐一的去下載對應的 Blob。
Descriptor 的 ID 採用 [Secure Hash Algorithm](https://zh.wikipedia.org/wiki/SHA%E5%AE%B6%E6%97%8F) 來進行編碼，因此在搜尋 Blob 時是使用[內容尋址](https://lorbook.com/block-cheese/18287/)而不是位置尋址，以提升安全性。

看完了上面介紹的這些規範，你可能還是不太清楚他們之間的關係，下圖簡單的整理出了 Image Layout 的關聯。

![Image Layout](https://i.imgur.com/WFVC1jz.png)

可以看到 manifest、config、layer 都被序列化成為 Blob，每個 Blob 有一個經過 SHA 編碼的 ID 並且同時存放在 Blobs 資料夾裡。當需要用到此文件時再去 Blobs 資料夾裡面搜尋 Blob 的 ID。
這張圖也大致詮釋了 Image Spec 所要制定的規範。

## Summary
OCI 定義了兩大標準來規範 Container，透過規範可以讓符合 OCI 標準的容器框架都可以兼容。

本篇介紹了兩個標準的基本概念，詳細的內容會在下一篇來做介紹。

## 參考
[1][取代docker的容器技術: Podman 、Buildah 、Skopeo、Kata container](https://ithelp.ithome.com.tw/articles/10220754)
[2][再見 Docker，是時候擁抱下一代容器工具了](https://juejin.im/post/5d8b27f8e51d4577e86d0d4b?utm_source=gold_browser_extension)
[3][Open Container Initiative (OCI) Standard, Image Spec](https://insujang.github.io/2019-10-10/open-container-initiative-image-spec/)
[4][淺談 Container 實現原理, 以 Docker 為例(I)](https://www.hwchiu.com/container-design-i.html)
[5][The 5 principles of Standard Containers](https://github.com/opencontainers/runtime-spec/blob/master/principles.md)
[6][走進docker(04)：什么是容器的runtime?](https://segmentfault.com/a/1190000009583199)
[7][Google開源沙盒容器Runtime gVisor，與VM一樣安全但更輕巧](https://www.ithome.com.tw/news/122908)
[8][docker OCI runtime](https://www.itread01.com/content/1546084756.html)
[9][OCI Image Spec 鏡像格式規範](https://www.jianshu.com/p/712273fd1cfd)
[10][深入淺出容器鏡像的一生](https://blog.k8s.li/Exploring-container-image.html)

###### tags: `Container` `Docker` `OCI`