前言


Docker 在DockerCon 2017大会上发布了一个自己的操作系统,宣称LinuxKit,安全,精简,强移植性。经过研究后发现LinuxKit就是kernel+busybox实现的一个微缩linux系统,其中直接安装了containerd和runc服务。其他服务全部都使用容器启动。一句话概括,LinuxKit就是希望在操作系统层面除了containerd之外其他服务都跑在容器中,这是一个几乎全部服务都在容器中的操作系统。

LinuxKit的使用


先介绍下LinuxKit是如何使用的。

项目地址:https://github.com/linuxkit/linuxkit

LinuxKit工程提供了工具来构建我们自己的操作系统。

  • moby 通过yml文件的描述,构建自定义的操作系统。

  • linuxkit 用来帮忙在不同平台启动镜像的工具。

首先安装moby和linuxkit工具和下载linuxkit代码

go get -u github.com/linuxkit/linuxkit/src/cmd/mobygo get -u github.com/linuxkit/linuxkit/src/cmd/linuxkitgit clone https://github.com/linuxkit/linuxkit

然后开始编译定制化的linux操作系统,我们使用LinuxKit提供的linuxkit.yml来进行编译

cd linuxkitmoby build linuxkit.yml

编译完成后,我们可以看到新出现的文件,这就是通过linuxkit.yml编译出来的内核和ramdisk

linuxkit-bzImage  编译出的kernellinuxkit-cmdline  启动时候的grub需要带的参数。linuxkit-efi.iso  EFI启动镜像linuxkit-initrd.img 一个ramdisklinuxkit.iso  BIOS启动镜像

接下来可以通过linuxkit工具来启动这个系统。

linuxkit run linuxkit

linuxkit 会根据系统自动选择合适的hypervisor来启动镜像。 由于我在linux上,所以启动的时候使用了kvm来启动虚拟机。

Welcome to LinuxKit                         ##.                   ## ## ## ==                ## ## ## ## ## ===            / "" "" "" "" "" "" "" "" "" \ ___ / = = =       ~~~ { ~~~~~~~~~~~~~~~~~ / === --~~~            \ ______ o __ /              \ \ __ /               \ ____ \ _______ /

启动时候可以看到我们可爱的小鲸鱼。这时候我们订制的专门跑容器的系统就完成了。

这里看一下系统启动了那些程序

/ # pstree/ # pstreeinit-+-containerd-+-containerd-shim---nginx---nginx     |-containers---ctr     |-sh---pstree     `-sh

使用默认的linuxkit.yml 其实就是启动了一个nginx服务。而且这个系统中的init程序直接启动了containerd。以后所有的服务都是通过容器启动的。

linuxkit分析


通过刚才的使用介绍可以看到,其实lilnuxkit是给用户提供了一种通过yml来订制自己的微缩操作系统的方式。那么我们还是先从这个linuxkit.yml文件来看。

#指定了需用的内核版本,以及启动参数kernel:  image: "linuxkit/kernel:4.9.x"  cmdline: "console=ttyS0 console=tty0 page_poison=1"#指定init程序init:  - linuxkit/init:42fe8cb1508b3afed39eb89821906e3cc7a70551  - linuxkit/runc:b0fb122e10dbb7e4e45115177a61a3f8d68c19a9  - linuxkit/containerd:60e2486a74c665ba4df57e561729aec20758daed  - linuxkit/ca-certificates:eabc5a6e59f05aa91529d80e9a595b85b046f935#指定了启动时候的会运行的系统容器,执行一次就会停止的。onboot:  - name: sysctl    image: "linuxkit/sysctl:2cf2f9d5b4d314ba1bfc22b2fe931924af666d8c"    net: host    pid: host    ipc: host    capabilities:     - CAP_SYS_ADMIN    readonly: true  - name: binfmt    image: "linuxkit/binfmt:8881283ac627be1542811bd25c85e7782aebc692"    binds:     - /proc/sys/fs/binfmt_misc:/binfmt_misc    readonly: true  - name: dhcpcd    image: "linuxkit/dhcpcd:48e249ebef6a521eed886b3bce032db69fbb4afa"    binds:     - /var:/var     - /tmp/etc:/etc    capabilities:     - CAP_NET_ADMIN     - CAP_NET_BIND_SERVICE     - CAP_NET_RAW    net: host    command: ["/sbin/dhcpcd", "--nobackground", "-f", "/dhcpcd.conf", "-1"]#在镜像生命周期中都要启动的系统服务services:  - name: rngd    image: "linuxkit/rngd:c42fd499690b2cb6e4e6cb99e41dfafca1cf5b14"    capabilities:     - CAP_SYS_ADMIN    oomScoreAdj: -800    readonly: true  - name: nginx    image: "nginx:alpine"    capabilities:     - CAP_NET_BIND_SERVICE     - CAP_CHOWN     - CAP_SETUID     - CAP_SETGID     - CAP_DAC_OVERRIDE    net: host#镜像中包含的文件及内容files:  - path: etc/docker/daemon.json    contents: '{"debug": true}'trust:  image:    - linuxkit/kernel#输出的文件,kernel,initrd,bios-iso和efi-isooutputs:  - format: kernel+initrd  - format: iso-bios  - format: iso-efi

文件比较简单,通过阅读文件可以看到,通过指定不同的容器镜像,最终可以帮助我们生成想要的 镜像。

生成了镜像,我们自然要研究一下这个linuxkit操作系统和现在发行版linux有哪些区别。

在使用linuxkit启动时,可以看到qemu相关的参数。

/usr/bin/docker-current run -i --rm -v /home/git/linuxkit:/tmp -w /tmp --device /dev/kvm linuxkit/qemu:17f052263d63c8a2b641ad91c589edcbb8a18c82 qemu-system-x86_64 -device virtio-rng-pci -smp 1 -m 1024 -enable-kvm -machine q35,accel=kvm:tcg -kernel linuxkit-bzImage -initrd linuxkit-initrd.img -append console=ttyS0 console=tty0 page_poison=1 -nographic

观察后可以发现,在启动虚拟机时候,并没有挂载硬盘,而是使用了指定kernel和ramdisk的方式来进行的。

这样看来linuxkit其实就是一个使用kernel和ramdisk直接启动的操作系统。 而ramdisk就包含了服务的容器镜像,在init程序启动之后,就通过containerd来拉起服务。linuxkit的init程序是用shell编写,因此我们这里也打开来看看。

#!/bin/shsetup_console() {    tty=${1%,*}    speed=${1#*,}    inittab="$2"    securetty="$3"    line=    term="linux"    [ "$speed" = "$1" ] && speed=115200    case "$tty" in    ttyS*|ttyAMA*|ttyUSB*|ttyMFD*)        line="-L"        term="vt100"        ;;    tty?)        line=""        speed="38400"        term=""        ;;    esac    # skip consoles already in inittab    grep -q "^$tty:" "$inittab" && return    echo "$tty::once:cat /etc/issue" >> "$inittab"    echo "$tty::respawn:/sbin/getty -n -l /bin/sh $line $speed $tty $term" >> "$inittab"    if ! grep -q -w "$tty" "$securetty"; then        echo "$tty" >> "$securetty"    fi}#在/mnt 下挂载了tmpfs/bin/mount -t tmpfs tmpfs /mnt#将根目录下的所有内容都copy到了/mnt下/bin/cp -a / /mnt 2>/dev/null/bin/mount -t proc -o noexec,nosuid,nodev proc /procfor opt in $(cat /proc/cmdline); do    case "$opt" in    console=*)        setup_console ${opt#console=} /mnt/etc/inittab /mnt/etc/securetty;;    esacdone#进行操作系统根目录的切换 /mnt 这里的/sbin/init 其实是软连接到busyboxexec /bin/busybox switch_root /mnt /sbin/init

文件内容依然简单可以看到,init程序给/mnt挂载了tmpfs系统,这是一个内存文件系统。然后将ramdisk中的所有内容都copy到了/mnt下,然后切换根目录到 /mnt。然后交给busybox继续启动。 busybox接着就开始启动containerd,并通过runc启动系统应用容器等。

linuxkit使用场景


从官方的描述来看,Linuxkit为每种容器提供了一个基于容器的方法,生成轻量级Linux子系统。当为特定硬件或者拥有特定功能定制系统时非常有用。每个LinuxKit子系统都有其自己的Linux核心,而每个系统守护进程或者系统服务都是一个容器。这些Linux子系统一旦被打包成ISO镜像,就可以用来启动物理机或者虚拟环境。Docker以提供的服务方式维护这些子系统。

这里其实可以看到Linuxkit解决了docker一直以来的问题容器和host共享内核,以至于有些应用不能够很好的在docker上使用的问题。 linuxkit具有的特点: - Linuxkit作为一个操作系统,本身可以在物理机或者虚拟机上启动。 - linuxkit是只读文件系统,并且相当轻量级只有60M左右,可以被应用在无盘启动系统中。 - linuxkit的理念同docker理念一脉相承。不同的镜像对应不同的应用,灵活,轻量,无状态。

可以预见到,可以直接在裸机上通过pxe来启动对应的linuxkit镜像,或者使用虚拟机快速启动linuxkit镜像,用户已经无需再预先搭建docker平台来启动容器。可以说linuxkit给容器化带来了更广阔的前景。


©著作权归作者所有:来自51CTO博客作者mob604756fa4732的原创作品,如需转载,请注明出处,否则将追究法律责任

更多相关文章

  1. 提供坚固耐用的笔记本电脑的合作技术
  2. centos7 测试网速教程
  3. 2018,新开始,新起点!
  4. 苹果Mac图片批量压缩重命名添加水印工具:PhotoBulk
  5. 在苹果Mac上如何隐藏桌面图标?
  6. Python如何进行内存管理?
  7. 组件化思维对于一个UI设计来说有多重要?
  8. 人生首套房子的重要性,怎么买对,怎么置换?
  9. 前端教程分享:HTTP请求Content-Type你知道是做什么的吗?

随机推荐

  1. Android Service组件(1)
  2. Android(安卓)invalidate 与postInvalida
  3. Android学习笔记(11)---关于布局的一些小事
  4. Android 音频简介(转)
  5. Android导入项目时Android jar包丢失的解
  6. Android(安卓)StrictMode使用
  7. Android 中自定义View(四)
  8. 讲给Android程序员看的前端教程(20)——f
  9. android 全局变量 Application
  10. Android 生态详解