容器是被 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 module | kernel 是共用的,不歸容器管 |
| Linux 容器不能跑在 Windows kernel 上 | 它要的 kernel 介面根本不存在 |
docker exec 進去看到的 /bin、/etc 只是檔案——那些檔案是 Image 帶進來的應用層,不是一套獨立的 OS。同一台 Linux 上 Ubuntu 容器有 apt、Alpine 容器只有 apk,差別全在 image 帶了哪些檔案。