On Dockercon 2017, Linux Kit, an architecture that creates the smallest Linux OS image in a container, was released.
Does that sound cool? Several clouds I saw an article on the Internet [about starting LinuxKit on Mac OS with Xhyve]. The best way to learn the tool is to make the best use of it. The author of the original article went back to Austin after the meeting and began to study it on the plane. Next, he went back to Austin. Several clouds Just share this article with you.
First of all, we need to prepare the following environment:
A Mac after 2010 (CPU supports EPT)
OS X 10.10.3 or later
Git Client
Docker running (example 17.04.0-ce-mac7 (16352))
GNU make
GNU tar
Homebrew
After preparation, follow the following steps.
Install Xhyve
The first step is to install Xhyve. Xhyve is a virtual machine operating system running in OSx's Hypervisor. Its architecture allows virtual machines to run in user space. This is what Docker prepared for MAC users. There are many ways to do this, but the simplest is to use Homebrew. Installation on Machine——
$ brew update $ brew install --HEAD xhyve
After the installation is completed, verify that it runs according to the following code:
$ xhyve -h
If you see the output containing various available flags, you are ready to move on to the next step.
Building Moby
The second step is to build the Moby tool. This tool provides read. Yaml's feature points will be explained in detail later, and a variety of Docker commands will be executed to build Linux OS. If you like, you can now run Image.
This is more convenient than the Moby's Hyperkit project. Kernel and Initrdimages take less time to build than a qcow image, so if you need to repeat Xhyve quickly, this is a good way to do it.
First, CD to any favorite working directory, and Clone Linux Kit repo:
$ git clone https://github.com/linuxkit/linuxkit.git
Next install Moby binary:
$ cd linuxkit $ make $ sudo make install
When you're done, you need to be ready to build your first Linux image using LinuxKit.
Customize and build Linux images
After completing these prerequisites, the first image is created. The LinuxKit project includes some examples, some of which also do live Demo in Dockercon. Create a simple image in Onboot that can start Redis instance, which is faster than starting from a complex point of view!
First, start a Yaml file that describes the Linux image, and then pull out the instance to get the basic Docker image and add an entry to 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
Now take a quick look at this file. Before going into more detail (as you can see in the Linux Kit git repo), we will focus on the following points——
The first part is the "base" image, which defines Kernel and Kernel command line parameters.
Next, there are some OCI-compatible Linux Kit images required by Init; then, there is the Onboot section, which describes other basic images that need to be started by RunC sequence before other services are started.
Then there's Services, also OCI-compatible mirrors, which are started and maintained by Container.
Finally, specify the output file information that Moby will create during the build process. Next, build the mirror.
$ moby build linux-redis
The following output information is visible——
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 following files are created:
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
Operation and Output
Now the image is set up and ready to run.
First, you have to create a script that tells Xhyve how to mirror instances as virtual machines. Before that, it was emphasized that a Qcow image could be output through the Moby tool.
Then use Moby run to run Image just like VM. Xhyve is recommended because no other on-linuxkt operating system can run on the Hypervisor architecture.
Here's one thing you need to do to run the image: a copy of the Xhyve parameters defined to create the virtual machine. The main project in this script is captured from the Moby build process.
Here is an example of starting 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"
Once the file has been created, make it executable and run it. There are some matters needing attention in the current link:
1. If any VPN is connected to the wireless network, please turn it off. Because there are some known traffic path problems when VPN runs.
2. If you are going to prepare a network connection to the virtual machine, you need to execute some superuser scripts.
Run it when it's okay:
$ chown 755 linux-redis.sh $ sudo ./linux-redis.sh
When the virtual machine runs, there will be a set of Output Fly, and finally, on the new virtual machine, there will be a command line:
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: ftp: 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 / #
When Redis server is running, see what happens:
/ # 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 / #
It seems that the default port of EDIS for the machine is 6379. Now, see if it can be seen and accessed on the Internet. First, find the IP address of the virtual machine:
/ # 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
The ip address is 192.168.64.17. From the Max OS X host, Netcat is used to test the connection status and server status:
$ nc 192.168.64.17 6379 ping +PONG
Once you have finished Poking around, type halt to close the virtual machine
/ # halt
Concluding remarks
Now we have an available Linux Kit image running in the OS X virtual machine.
However, this is just the beginning. You can use this template to create other images and customize what you want. At the same time, you don't have to use Redis to try to replace your own Docker images and start the virtual machine.
In subsequent articles, I will also try to use other Moby projece tools, such as Infrakit and Hyperkit, to demonstrate more capabilities of Linuxkt OS Images.
Links to the original text:
http://www.nebulaworks.com/bl...
Welcome your attention Several People Cloud Wechat Public Accounts If there are any follow-up articles, we will follow up as soon as possible.