利用 LinuxKit 打造基於容器的 Linux 子系統

利用 LinuxKit 打造基於容器的 Linux 子系統

LinuxKit 是 DockerCon 2017 中推出的工具之一,其主要是以 Container 來建立最小、不可變的 Linux 作業系統映像檔框架,Docker 公司一直透過 LinuxKit 來建立相關產品,如 Docker for Mac 等。由於要最快的了解功能,因此這邊透過建立簡單的映像檔來學習。

在開始前需要準備完成一些事情:

  • 安裝 Git client
  • 安裝 Docker engine,這邊建立使用 Docker-ce 17.06.0
  • 安裝 GUN make 工具
  • 安裝 GUN tar 工具

建構 Moby 工具

首先我們要建構名為 Moby 的工具,這個工具主要提供指定的 YAML 檔來執行描述的建構流程與功能,並利用 Docker 來建構出 Linux 作業系統。在本教學中,最後我們會利用 xhyve 這個 OS X 的虛擬化來提供執行系統實例,當然也可以透過官方的 HyperKit 來進行。

首先透過 Git 來抓取 LinuxKit repos,並進入建構 Moby:

$ git clone https://github.com/linuxkit/linuxkit.git $ cd linuxkit $ make && sudo make install $ moby version moby version 0.0 commit: 4db06aa1732b44a8cadd9c8577df0aa5c716e701

建立 Linux 映像檔

當完成建構 Moby 工具後,就可以透過撰寫 YAML 檔來描述 Linux 的建構功能與流程了,這邊建立一個 Docker + SSH 的 Linux 映像檔。首先建立檔名為docker-sshd.yml的檔案,然後加入以下內容:

kernel: image: linuxkit/kernel:4.9.36 cmdline: "console=tty0 console=ttyS0" init: - linuxkit/init:14a38303ee9dcb4541c00e2b87404befc1ba2083 - linuxkit/runc:a0f2894e50bacbd1ff82be41edff8b8e06e0b161 - linuxkit/containerd:389e67c3c1fc009c1315f32b3e2b6659691a3ad4 - linuxkit/ca-certificates:67acf038c44bb191ebb704ec7bb39a1524052cdf onboot: - name: sysctl image: linuxkit/sysctl:d1a43c7c91e92374766f962dc8534cf9508756b0 services: - name: getty image: linuxkit/getty:0bd92d5f906491c20e4177c57f965338fe5a8c5f env: - INSECURE=true - name: rngd image: linuxkit/rngd:1516d5d70683a5d925fe475eb1b6164a2f67ac3b - name: dhcpcd image: linuxkit/dhcpcd:4b7b8bb024cebb1bbb9c8026d44d7cbc8e202c41 - name: sshd image: linuxkit/sshd:89b2e91d7d1bf2f40220be0e3ed586e74746cceb files: - path: root/.ssh/authorized_keys source: ~/.ssh/id_rsa.pub mode: "0600" optional: true trust: org: - linuxkit

這邊說明幾個 YAML 格式意義:

  • kernel: 指定 Docker 映像檔的核心版本,會包含一個 Linux 核心與檔案系統的 tar 檔,會將核心建構在/kernel目錄中
  • init: 是一個 Docker Container 的 init 行程基礎,裡面包含initcontainerdrunC與其他等工具
  • onboot: 指定要建構的系統層級工具,會依據定義順序來執行,該類型如: dhcpd 與 ntpd 等
  • services: 指定要建構服務,通常會是系統開啟後執行,如 ngnix、apache2
  • files:要複製到該 Linux 系統映像檔中的檔案
  • trust:主要指定 Docker Content Trust 對哪些建構的元件進行加密驗證

更多 YAML 格式說明可以參考官方 LinuxKit YAML。目前 LinuxKit 的映像檔來源可以參考 Docker Hub

撰寫完後,就可以透過 Moby 工具進行建構 Linux 映像檔了:

$ moby build sshd.yml Extract kernel image: linuxkit/kernel:4.9.x Pull image: linuxkit/kernel:4.9.x ... Create outputs: sshd-kernel sshd-initrd.img sshd-cmdline

完成後會看到以下幾個檔案:

  • docker-sshd-kernel: 為 RAW Kernel 映像檔
  • docker-sshd-initrd.img: 為初始化 RAW Disk 檔案
  • docker-sshd-cmdline: Command line options 檔案

測試映像檔

當完成建構映像檔後,就可以透過一些工具來進行測試,這邊採用 xhyve 來執行實例,首先透過 Git 取得 xhyve repos,並建構與安裝:

$ git clone https://github.com/mist64/xhyve $ cd xhyve $ make && cp build/xhyve /usr/local/bin/ $ xhyve Usage: xhyve [-behuwxMACHPWY] [-c vcpus] [-g <gdb port>] [-l <lpc>] [-m mem] [-p vcpu:hostcpu] [-s <pci>] [-U uuid] -f <fw>

xhyve 是 FreeBSD 虛擬化技術 bhyve 的 OS X 版本,是以 Hypervisor.framework 為基底的上層工具,這是除了 VirtualBox 與 VMwar 的另外選擇,並且該工具非常的輕巧,只有幾 KB 的容量。

接著撰寫 xhyve 腳本來啟動映像檔:

#!/bin/sh KERNEL="sshd-kernel" INITRD="sshd-initrd.img" CMDLINE="console=ttyS0 console=tty0 page_poison=1" MEM="-m 1G" PCI_DEV="-s 0:0,hostbridge -s 31,lpc" LPC_DEV="-l com1,stdio" ACPI="-A" #SMP="-c 2" # sudo if you want networking enabled NET="-s 2:0,virtio-net" xhyve $ACPI $MEM $SMP $PCI_DEV $LPC_DEV $NET -f kexec,$KERNEL,$INITRD,"$CMDLINE"

修改KERNELINITRD為 docker-sshd 的映像檔。

完成後就可以進行啟動測試:

$ chmod u+x run.sh $ sudo ./run.sh Welcome to LinuxKit ## . ## ## ## == ## ## ## ## ## === /"""""""""""""""""\___/ === ~~~ {~~ ~~~~ ~~~ ~~~~ ~~~ ~ / ===- ~~~ \______ o __/ \ \ __/ \____\_______/ ... (ns: getty) linuxkit-f65c15deb778:~# ip -4 a 1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN qlen 1 inet 127.0.0.1/8 brd 127.255.255.255 scope host lo valid_lft forever preferred_lft forever 2: eth0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP qlen 1000 inet 192.168.64.4/24 brd 192.168.64.255 scope global eth0 valid_lft forever preferred_lft forever

驗證映像檔服務

當看到上述結果後,表示作業系統開啟無誤,這時候我們要測試系統服務是否正常,首先透過 SSH 來進行測試,在剛剛新增的 ssh public key 主機上執行以下:

$ ssh root@192.168.64.4 (ns: sshd) linuxkit-f65c15deb778:~# uname -r 4.9.36-linuxkit (ns: sshd) linuxkit-f65c15deb778:~# exit

最後關閉虛擬機可以透過以下指令完成:

moby-aa16c789d03b:~# halt Terminated

撰文: 白凱仁 迎棧科技軟體工程師

訂閱電子報

Select list(s)*

 

Loading