kata 虛擬機器 libcontainer
單個容器
root@25a725e7599e:/# ls
bin dev home lost+found mnt proc run srv tmp var
boot etc lib media opt root sbin sys usr
root@25a725e7599e:/# ls var/
backups lib local lock mail opt run spool tmp
root@25a725e7599e:/# ls var/lib/docker/container/
ls: cannot access 'var/lib/docker/container/': No such file or directory
root@25a725e7599e:/# find ./ -name container
./run/kata-containers/shared/containers/ef4b70596e0b829af5fd9f14343f2c92a8da3d0d22ea1f23e83b14384fa4f1cc-da0bf2558a65810c-containerdir/go/src/container
./run/kata-containers/shared/containers/ef4b70596e0b829af5fd9f14343f2c92a8da3d0d22ea1f23e83b14384fa4f1cc-da0bf2558a65810c-containerdir/go/pkg/linux_arm64/container
./run/kata-containers/shared/containers/ef4b70596e0b829af5fd9f14343f2c92a8da3d0d22ea1f23e83b14384fa4f1cc/rootfs/containerdir/container
./sys/devices/system/container
./sys/bus/container
root@25a725e7599e:/# ip netns list
root@25a725e7599e:/#
雙容器
root@25a725e7599e:/# ls bin dev home lost+found mnt proc run srv tmp var boot etc lib media opt root sbin sys usr root@25a725e7599e:/# ip netns ls root@25a725e7599e:/# ls bin dev home lost+found mnt proc run srv tmp var boot etc lib media opt root sbin sys usr root@25a725e7599e:/# ls var/ backups lib local lock mail opt run spool tmp root@25a725e7599e:/# ls var/run kata-containers libcontainer lock mount sandbox-ns systemd
libcontainer實現原理
1、使用工廠Factory和容器配置container
libcontainer中的factory是建立一個邏輯概念上的“容器物件”,他並不是執行的容器,而只是包含又namespace和cgroups配置引數等的邏輯概念上的容器。
Factory建立容器的分為三步:
第一步,驗證容器引數的合法性,即:容器的啟動目錄(/var/lib/docker/container),容器ID,容器配置三者的合法性。
第二步,驗證將要上傳容器ID和現有執行容器ID之間沒有衝突。
第三步,在根目錄下建立(/var/lib/docker/container/{ContainerID})容器的工作目錄
第四步,返回一個Container物件,此物件包含容器ID、容器工作目錄、容器配置、初始化指令和引數,以及cgroup管理器等。
此時,如果執行完上述的步驟,表明容器已經建立完。
2、啟動邏輯容器container
在此過程中主要是建立兩個例項:
(1)process
上述第一步建立過程中,即:process過程
(2)parentprocess
第一步:建立一個管道,以後與外部程序通訊
第二步:根據邏輯容器建立一個程序啟動的cmd物件,此物件是從容器中獲取命令執行的引數(命令路徑、命令引數、輸入和輸出、執行命令的根目錄和程序管道pipe等)
第三步:為cmd物件新增一些環境變數
第四步:配置容器啟動的namespace,表明容器是在哪個名稱空間下啟動的。
第五步:將container中的容器配置和Process中的entrypoint資訊合併為一份容器配置並加入到ParentProcess中。
3、用邏輯容器建立物理容器
第一步:Docker daemon利用exec包執行initProcess.cmd,起作用是初始化一個namespace
第二步:把容器程序dockerinit 的PID加入到cgroup中管理
第三步:建立容器內部的網路裝置,包括lo和veth
第四步:通過管道傳送容器配置資訊給容器程序dockerinit
第五步:dockerinit 根據接收到的容器配置資訊啟動容器
4、Docker daemon 與容器之間的通訊
docker daemon與容器之間的通訊方式採用的檔案和檔案描述符,具體實現是:
pipe(int fd[2])建立管道 fd[1]端寫入資料, fd[0]端讀物資料
呼叫pipe函式時,建立的子程序會內嵌這個開啟的檔案描述符,對fd[1]寫入資料後可以在fd[0]端讀取,這樣通過管道父子程序之間就可以通訊了,最後當傳遞EOF訊號時兩個程序之間的通訊結束。