容器是被 namespace 與 cgroups 關起來的普通行程

容器裡沒有一個獨立的作業系統。從主機角度看,容器裡的程式就是一個普通的 Linux process(主機 ps aux 看得到),只是被 kernel 用三道機制關起來。

三道機制

  • Namespace — 決定它看得到什麼:PID / Network / Mount namespace 各自給它一份獨立視野。不是別人被藏起來,是它根本沒有那個視野。(PID = Process Identifier,作業系統給每個 process 的身分證號;容器裡看到的 PID 從 1 開始,是 PID namespace 重新編過的,跟主機上那個號碼不同。)
  • Cgroups — 決定它能用多少--memory 512m--cpus 1.5 背後就是它。超過上限被 kernel 直接殺掉,就是 OOMKilled(exit code 137)。
  • Union File System — 決定它的檔案長怎樣:多層唯讀層疊起來,最上面加一層可寫層。

這個理解能解釋的現象

現象原因
啟動只要 1 秒只是啟動一個 process,不用開機一套 OS
image 可以小到 5MB不含 kernel,只有應用層檔案
容器停了資料就沒了可寫層綁在容器上,容器刪了那層就沒了
容器裡改不了主機時間、載不了 kernel modulekernel 是共用的,不歸容器管
Linux 容器不能跑在 Windows kernel 上它要的 kernel 介面根本不存在

docker exec 進去看到的 /bin/etc 只是檔案——那些檔案是 Image 帶進來的應用層,不是一套獨立的 OS。同一台 Linux 上 Ubuntu 容器有 apt、Alpine 容器只有 apk,差別全在 image 帶了哪些檔案。

延伸:VM 與容器的差別在有沒有自己的 kernelContainer