在 Mac OS 的 Xhyve 引擎之上启动 LinuxKit 的玩法 - V2EX
V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
请不要在回答技术问题时复制粘贴 AI 生成的内容
dataman
V2EX    程序员

在 Mac OS 的 Xhyve 引擎之上启动 LinuxKit 的玩法

  •  
  •   dataman 2017-05-04 11:40:36 +08:00 3144 次点击
    这是一个创建于 3132 天前的主题,其中的信息可能已经有所发展或是发生改变。

    在 Dockercon2017 上发布了一个能够在容器内创建最小 Linux OS 镜像的架构 LinuxKit。

    听起来是不是很酷?数人云在外网上看到一篇关于 Mac OS with Xhyve 上启动 LinuxKit 的文章,学习工具最好的方法就是让它物尽其用,原文作者在与会后回奥斯汀的飞机上就已经着手研究它,接下来小数就把这篇文章跟大家简单地进行分享。


    首先,需要准备好以下环境:

    1. 一台 2010 年以后的 Mac ( CPU 支持 EPT )
    2. OS X 10.10.3 或更高版本
    3. Git 客户端
    4. Docker running (示例是 17.04.0-ce-mac7 (16352))
    5. GNU make
    6. GNU tar
    7. Homebrew

    准备完毕后,按照以下步骤实施。

    安装 Xhyve

    第一步,需要安装 Xhyve。Xhyve 是一个在 OSx ’ s Hypervisor 运行的虚拟机操作系统,其架构允许在用户空间内运行虚拟机。这是 Docker 为 MAC 用户准备的。有很多方法可以做到这一点,但最简单的莫过于用 Homebrew。在机器上安装

    $ brew update $ brew install --HEAD xhyve 

    安装完成后,检验是否按照如下代码运行:

    $ xhyve -h 

    如果看到包含各种可用 flags 的输出,那么可以准备进入下一步。

    构建 Moby

    第二步是构建 Moby 工具。此工具会提供读取。稍后会详细说明 Yaml 的功能点,执行多样化的 Docker 命令来建立 Linux OS,如果喜欢,现在就可以运行 Image。

    这比 Moby ’ s Hyperkit 项目要方便。建立 Kernel 和 Initrdimages 会比 a qcow image 耗时更少,所以,如果需要快速的重复 Xhyve,这是一个不错的实现方式。

    首先,CD 到任意一个喜欢的工作目录,并 Clone LinuxKit repo:

    $ git clone https://github.com/linuxkit/linuxkit.git 

    接下来安装 Moby binary:

    $ cd linuxkit $ make $ sudo make install 

    完成后,需要准备建立使用 LinuxKit 的首个 Linux image。

    定制和构建 Linux 映像

    完成这些先决条件后,先建立首个镜像。LinuxKit 项目包括一些例子,其中某些例子也在 Dockercon 做了现场 Demo。在 Onboot 建立一个能够启动 Redis instance 的简单镜像,这样比从复杂的角度入手更快!

    首先,启动一个能够描述 Linux image 的 Yaml file,接着拉取实例,将会拿到基础的 Docker image,并且给 Redis 增加一个入口。

    $ vi linux-redis.yaml kernel: image: "linuxkit/kernel:4.9.x" cmdline: "cOnsole=ttyS0 cOnsole=tty0 page_poison=1" init: - linuxkit/init:63eed9ca7a09d2ce4c0c5e7238ac005fa44f564b - linuxkit/runc:b0fb122e10dbb7e4e45115177a61a3f8d68c19a9 - linuxkit/containerd:18eaf72f3f4f9a9f29ca1951f66df701f873060b - linuxkit/ca-certificates:eabc5a6e59f05aa91529d80e9a595b85b046f935 onboot: - name: sysctl image: "linuxkit/sysctl:1f5ec5d5e6f7a7a1b3d2ff9dd9e36fd6fb14756a" net: host pid: host ipc: host capabilities: - CAP_SYS_ADMIN readonly: true - name: sysfs image: linuxkit/sysfs:6c1d06f28ddd9681799d3950cddf044b930b221c - name: binfmt image: "linuxkit/binfmt:8881283ac627be1542811bd25c85e7782aebc692" binds: - /proc/sys/fs/binfmt_misc:/binfmt_misc readonly: true - name: format image: "linuxkit/format:53748000acf515549d398e6ae68545c26c0f3a2e" binds: - /dev:/dev capabilities: - CAP_SYS_ADMIN - CAP_MKNOD - name: mount image: "linuxkit/mount:d2669e7c8ddda99fa0618a414d44261eba6e299a" binds: - /dev:/dev - /var:/var:rshared,rbind capabilities: - CAP_SYS_ADMIN rootfsPropagation: shared command: ["/mount.sh", "/var/lib/docker"] services: - name: rngd image: "linuxkit/rngd:3dad6dd43270fa632ac031e99d1947f20b22eec9" capabilities: - CAP_SYS_ADMIN oomScoreAdj: -800 readonly: true - name: dhcpcd image: "linuxkit/dhcpcd:57a8ef29d3a910645b2b24c124f9ce9ef53ce703" binds: - /var:/var - /tmp/etc:/etc capabilities: - CAP_NET_ADMIN - CAP_NET_BIND_SERVICE - CAP_NET_RAW net: host oomScoreAdj: -800 - name: ntpd image: "linuxkit/openntpd:a570316d7fc49ca1daa29bd945499f4963d227af" capabilities: - CAP_SYS_TIME - CAP_SYS_NICE - CAP_SYS_CHROOT - CAP_SETUID - CAP_SETGID net: host - name: redis image: "redis:3.0.7-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 outputs: - format: kernel+initrd 

    现在快速地查看下这个文件。在没有展开更详尽的介绍之前(那些在 LinuxKit git repo 中可以看到的),我们将聚焦在以下要点上

    开始的部分是“基础”镜像,定义了 Kernel 和 Kernel 命令行参数;

    紧接着,是一些 Init 所需的 OCI 兼容的 LinuxKit 镜像;在此之后,是 Onboot 部分,里面描述的是另外一些需要再其他服务启动之前由 RunC 顺序启动的基础镜像;

    再之后就是服务( Services )了,同样是 OCI 兼容的镜像,由 Containerd 启动并保持运行状态。

    最后,指定构建过程中 Moby 将要创建的输出文件信息。下面,构建镜像。

    $ moby build linux-redis 

    下列是可以看到的输出信息

    Extract kernel image: linuxkit/kernel:4.9.x Add init containers: Process init image: linuxkit/init:63eed9ca7a09d2ce4c0c5e7238ac005fa44f564b Process init image: linuxkit/runc:b0fb122e10dbb7e4e45115177a61a3f8d68c19a9 Process init image: linuxkit/containerd:18eaf72f3f4f9a9f29ca1951f66df701f873060b Process init image: linuxkit/ca-certificates:eabc5a6e59f05aa91529d80e9a595b85b046f935 Add onboot containers: Create OCI config for linuxkit/sysctl:1f5ec5d5e6f7a7a1b3d2ff9dd9e36fd6fb14756a Create OCI config for linuxkit/sysfs:6c1d06f28ddd9681799d3950cddf044b930b221c Create OCI config for linuxkit/binfmt:8881283ac627be1542811bd25c85e7782aebc692 Create OCI config for linuxkit/format:53748000acf515549d398e6ae68545c26c0f3a2e Create OCI config for linuxkit/mount:d2669e7c8ddda99fa0618a414d44261eba6e299a Add service containers: Create OCI config for linuxkit/rngd:3dad6dd43270fa632ac031e99d1947f20b22eec9 Create OCI config for linuxkit/dhcpcd:57a8ef29d3a910645b2b24c124f9ce9ef53ce703 Create OCI config for linuxkit/openntpd:a570316d7fc49ca1daa29bd945499f4963d227af Create OCI config for redis:3.0.7-alpine Add files: etc/docker/daemon.json Create outputs: linux-redis-bzImage linux-redis-initrd.img linux-redis-cmdline 

    以下是创建的文件:

    The raw kernel image (linux-redis-bzImage) The init ramdisk (linux-redis-initrd.img) The commandline options youll need to provide to xhyve in a file 

    运行和输出

    现在已经建立镜像,准备运行。

    首先,必须要创建一个告诉 Xhyve 如何实例镜像作为虚拟机的脚本。在这之前,着重强调,可以通过 Moby 工具输出一个 Qcow image。

    接着使用 Moby run 如同 VM 一样运行 Image。推荐使用 Xhyve,因为现在没有其他的 Non-linuxkt 操作系统能够在 Hypervisor 架构上运行。

    下面需要做一件事来运行镜像:一个为了建立虚拟机而定义的 Xhyve 参数的本。在这个脚本中主要的项目是从 Moby 构建流程中获取的。

    下面是一个启动 Redis server 的例子:

    $ vi linux-redis.sh #!/bin/sh KERNEL="linux-redis-bzImage" INITRD="linux-redis-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" 

    一旦文件已经创建,使之可执行并且运行它。目前的环节中有些需要注意的事项:

    1、如果有任何 VPN 连接到无线网络上,请关掉它。因为当 VPN 运行时会有一些已知的流量路径问题。

    2、如果准备网络连接虚拟机,需要执行一些超级用户的脚本。

    当没问题后运行它:

    $ chown 755 linux-redis.sh $ sudo ./linux-redis.sh 

    当虚拟机运行的时候将有一组 Output 会 Fly,最后,在新虚拟机上得到一个命令行:

    Welcome to LinuxKit ## . ## ## ## == ## ## ## ## ## === /"""""""""""""""""\___/ === ~~~ {~~ ~~~~ ~~~ ~~~~ ~~~ ~ / ===- ~~~ \______ o __/ \ \ __/ \____\_______/ / # [ 2.125127] IPVS: Creating netns size=2104 id=1 [ 2.125466] IPVS: ftp: loaded support on port[0] = 21 [ 2.156114] IPVS: Creating netns size=2104 id=2 [ 2.156496] IPVS: ftp: loaded support on port[0] = 21 [ 2.177714] tsc: Refined TSC clocksource calibration: 2193.340 MHz [ 2.178170] clocksource: tsc: mask: 0xffffffffffffffff max_cycles: 0x1f9d9f9c94d, max_idle_ns: 440795310624 ns [ 2.399509] IPVS: Creating netns size=2104 id=3 [ 2.400027] IPVS: ftp: loaded support on port[0] = 21 [ 2.670029] IPVS: Creating netns size=2104 id=4 [ 2.670555] IPVS: ftp: loaded support on port[0] = 21 [ 2.773492] random: dhcpcd: uninitialized urandom read (112 bytes read) [ 2.791653] random: redis-server: uninitialized urandom read (19 bytes read) [ 2.792066] random: redis-server: uninitialized urandom read (1024 bytes read) [ 2.911251] IPVS: Creating netns size=2104 id=5 [ 2.911770] IPVS: tp: loaded support on port[0] = 21 [ 2.935150] random: rngd: uninitialized urandom read (16 bytes read) [ 2.955187] random: crng init done [ 3.187797] clocksource: Switched to clocksource tsc / # 

    当 Redis server 正在运行时,看看发生了什么:

    / # netstat -an Active Internet connections (servers and established) Proto Recv-Q Send-Q Local Address Foreign Address State tcp 0 0 0.0.0.0:6379 0.0.0.0:* LISTEN tcp 0 0 :::6379 :::* LISTEN udp 0 0 192.168.64.17:44773 52.6.160.3:123 ESTABLISHED udp 0 0 192.168.64.17:44091 208.75.89.4:123 ESTABLISHED udp 0 0 0.0.0.0:68 0.0.0.0:* udp 0 0 192.168.64.17:33429 192.96.202.120:123 ESTABLISHED udp 0 0 192.168.64.17:39584 69.89.207.99:123 ESTABLISHED raw 0 0 ::%192:58 ::%32631:* 58 Active UNIX domain sockets (servers and established) Proto RefCnt Flags Type State I-Node Path unix 2 [ ACC ] STREAM LISTENING 14907 /var/run/dhcpcd.sock unix 2 [ ACC ] STREAM LISTENING 14909 /var/run/dhcpcd.unpriv.sock unix 2 [ ACC ] STREAM LISTENING 14248 /run/containerd/debug.sock unix 2 [ ACC ] STREAM LISTENING 14258 /run/containerd/containerd.sock unix 2 [ ACC ] STREAM LISTENING 15051 /var/run/ntpd.sock unix 3 [ ] STREAM CONNECTED 15055 unix 3 [ ] STREAM CONNECTED 15050 unix 2 [ ] DGRAM 15025 unix 3 [ ] STREAM CONNECTED 15054 unix 3 [ ] STREAM CONNECTED 15049 / # 

    看起来机器的 Redis 默认端口是 6379。现在,看它是否在网络上可以被看到和获取。首先,找到虚拟机的 IP 地址:

    / # ip a 1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN qlen 1 link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00 inet 127.0.0.1/8 brd 127.255.255.255 scope host lo valid_lft forever preferred_lft forever inet6 ::1/128 scope host valid_lft forever preferred_lft forever 2: bond0: <BROADCAST,MULTICAST400> mtu 1500 qdisc noop state DOWN qlen 1000 link/ether ca:41:0c:a4:ea:c2 brd ff:ff:ff:ff:ff:ff 3: dummy0: <BROADCAST,NOARP> mtu 1500 qdisc noop state DOWN qlen 1000 link/ether 1a:23:2d:47:af:d5 brd ff:ff:ff:ff:ff:ff 4: eth0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP qlen 1000 link/ether f2:94:56:b6:96:93 brd ff:ff:ff:ff:ff:ff inet 192.168.64.17/24 brd 192.168.64.255 scope global eth0 valid_lft forever preferred_lft forever inet6 fe80::f094:56ff:feb6:9693/64 scope link valid_lft forever preferred_lft forever 5: teql0: mtu 1500 qdisc noop state DOWN qlen 100 link/void 6: tunl0@NONE: mtu 1480 qdisc noop state DOWN qlen 1 link/ipip 0.0.0.0 brd 0.0.0.0 7: gre0@NONE: mtu 1476 qdisc noop state DOWN qlen 1 link/gre 0.0.0.0 brd 0.0.0.0 8: gretap0@NONE: <BROADCAST,MULTICAST> mtu 1462 qdisc noop state DOWN qlen 1000 link/ether 00:00:00:00:00:00 brd ff:ff:ff:ff:ff:ff 9: ip_vti0@NONE: mtu 1332 qdisc noop state DOWN qlen 1 link/ipip 0.0.0.0 brd 0.0.0.0 10: ip6_vti0@NONE: mtu 1500 qdisc noop state DOWN qlen 1 link/tunnel6 00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00 brd 00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00 11: sit0@NONE: mtu 1480 qdisc noop state DOWN qlen 1 link/sit 0.0.0.0 brd 0.0.0.0 12: ip6tnl0@NONE: mtu 1452 qdisc noop state DOWN qlen 1 link/tunnel6 00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00 brd 00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00 13: ip6gre0@NONE: mtu 1448 qdisc noop state DOWN qlen 1 link/[823] 00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00 brd 00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00 

    ip 地址是 192.168.64.17,从 Max OS X 主机,使用 Netcat 测试连接状态和服务器状态:

    $ nc 192.168.64.17 6379 ping +PONG 

    一旦完成 Poking around,键入 halt 关闭虚拟机

    / # halt 

    结束语

    现在我们就有了一个运行在 OS X 虚拟机中的可用的 LinuxKit image。 然而这也仅仅只是一个开始,可以用这个模板来创建其他镜像,定制你想要的东西。同时,不是一定需要使用 Redis,尝试替换成你自己服务的 Docker images,启动虚拟机。

    在之后的文章中,我还会尝试使用其他的 Moby projece tools,比如 Infrakit 和 Hyperkit,通过使用他们来展示 Linuxkt OS Images 更多的能力。

    原文链接: http://www.nebulaworks.com/blog/2017/04/23/getting-started-linuxkit-mac-os-x-xhyve/

    欢迎关注数人云微信公众号,如有后续文章我们会第一时间进行跟进!

    目前尚无回复
    关于     帮助文档     自助推广系统     博客     API     FAQ     Solana     1033 人在线   最高记录 6679       Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 73ms UTC 23:35 PVG 07:35 LAX 15:35 JFK 18:35
    Do have faith in what you're doing.
    ubao msn snddm index pchome yahoo rakuten mypaper meadowduck bidyahoo youbao zxmzxm asda bnvcg cvbfg dfscv mmhjk xxddc yybgb zznbn ccubao uaitu acv GXCV ET GDG YH FG BCVB FJFH CBRE CBC GDG ET54 WRWR RWER WREW WRWER RWER SDG EW SF DSFSF fbbs ubao fhd dfg ewr dg df ewwr ewwr et ruyut utut dfg fgd gdfgt etg dfgt dfgd ert4 gd fgg wr 235 wer3 we vsdf sdf gdf ert xcv sdf rwer hfd dfg cvb rwf afb dfh jgh bmn lgh rty gfds cxv xcv xcs vdas fdf fgd cv sdf tert sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf shasha9178 shasha9178 shasha9178 shasha9178 shasha9178 liflif2 liflif2 liflif2 liflif2 liflif2 liblib3 liblib3 liblib3 liblib3 liblib3 zhazha444 zhazha444 zhazha444 zhazha444 zhazha444 dende5 dende denden denden2 denden21 fenfen9 fenf619 fen619 fenfe9 fe619 sdf sdf sdf sdf sdf zhazh90 zhazh0 zhaa50 zha90 zh590 zho zhoz zhozh zhozho zhozho2 lislis lls95 lili95 lils5 liss9 sdf0ty987 sdft876 sdft9876 sdf09876 sd0t9876 sdf0ty98 sdf0976 sdf0ty986 sdf0ty96 sdf0t76 sdf0876 df0ty98 sf0t876 sd0ty76 sdy76 sdf76 sdf0t76 sdf0ty9 sdf0ty98 sdf0ty987 sdf0ty98 sdf6676 sdf876 sd876 sd876 sdf6 sdf6 sdf9876 sdf0t sdf06 sdf0ty9776 sdf0ty9776 sdf0ty76 sdf8876 sdf0t sd6 sdf06 s688876 sd688 sdf86