走进docker(03):如何绕过docker运行hello-world?

上一篇介绍了image的格式,这里咱们就来用一下hello-world这个image,看怎么输出和docker run hello-world一样的内容。git

相关工具

本文将用到三个工具,分别是skopeooci-image-toolsruncgithub

  • skopeo: 用来从Docker Hub上拉取image,并保存为OCI格式docker

  • oci-image-tools: 包含几个用来操做本地image的工具json

  • runc: 运行容器ubuntu

runc能够用docker自带的docker-runc命令替代,效果是同样的,skopeo的安装能够参考上一篇最后的介绍或者github上的主页,oci-image-tools的安装请参考github上的主页vim

获取hello-world的image

利用skopeo得到hello-world的oci格式的imagesegmentfault

dev@debian:~/images$ skopeo copy docker://hello-world oci:hello-world
dev@debian:~/images$ tree hello-world/
hello-world/
├── blobs
│   └── sha256
│       ├── 0a2ad94772e366c2b7f2266ca46daa0c38efe08811cf1c1dee6558fcd7f2b54e
│       ├── 78445dd45222097f5f8d5a16e48dc19c4ca162dcdb80010ab6f1ccfc7e2c0fa3
│       └── 998a60597add14861de504277c0d850e9181b1768011f51c7daaf694dfe975ef
├── oci-layout
└── refs
    └── latest

而后咱们看看hello-world这个image的文件系统都有些什么文件bash

#利用oci-image-tool unpack,将image解压到hello-world-filesystem目录
dev@debian:~/images$ mkdir hello-world-filesystem
dev@debian:~/images$ oci-image-tool unpack --ref latest hello-world hello-world-filesystem
dev@debian:~/images$ tree hello-world-filesystem/
hello-world-filesystem/
└── hello

0 directories, 1 file
dev@debian:~/images$ file hello-world-filesystem/hello
hello-world-filesystem/hello: ELF 64-bit LSB executable, x86-64, version 1 (SYSV), statically linked, BuildID[sha1]=4999eecfa472a2341b53954c0eca1e893f01305c, stripped

从上面的结果能够看出,hello-world这个image就只包含一个名字叫作hello的静态连接的可执行文件。app

根据image生成runtime的bundle

runtime的bundle就是运行容器时须要的东西的集合。编辑器

dev@debian:~/images$ mkdir hello-world-bundle
dev@debian:~/images$ oci-image-tool create --ref latest hello-world hello-world-bundle
dev@debian:~/images$ tree hello-world-bundle
hello-world-bundle
├── config.json
└── rootfs
    └── hello

1 directory, 2 files

从这里生成的bundle能够看出,bundle里面就是一个配置文件加上rootfs,rootfs里面的东西就是image里面的文件系统部分,config.json是对容器的描述,好比rootfs的路径,容器启动后要运行什么命令等,后续介绍runtime标准的时候再详细介绍。

使用runc运行该bundle

有了bundle后,就能够用runc来运行该容器了

这里直接用docker的docker-runc代替runc命令,若是你本身编译了opencontainer的runc,那么用runc命令也是同样的。

dev@debian:~/images$ cd hello-world-bundle/
#oci-image-tool帮咱们生成的config文件版本和runc须要的版本不一致,
#因此这里先将它删掉,而后用runc spec命令生成一个默认的config文件
dev@debian:~/images/hello-world-bundle$ rm config.json
dev@debian:~/images/hello-world-bundle$ docker-runc spec

#默认生成的config里面指定容器启动的进程为sh,
#咱们须要将它换成咱们的hello程序
#这里请用本身熟悉的编辑器修改config.json文件,
#将里面的"args": ["sh"]改为"args": ["/hello"]
dev@debian:~/images/hello-world-bundle$ vim config.json

#而后用runc运行该容器,这里命令行里的hello是给容器取的名字,
#能够是任意不和其它容器冲突的字符串
dev@debian:~/images/hello-world-bundle$ sudo docker-runc run hello
Hello from Docker!
This message shows that your installation appears to be working correctly.

To generate this message, Docker took the following steps:
 1. The Docker client contacted the Docker daemon.
 2. The Docker daemon pulled the "hello-world" image from the Docker Hub.
 3. The Docker daemon created a new container from that image which runs the
    executable that produces the output you are currently reading.
 4. The Docker daemon streamed that output to the Docker client, which sent it
    to your terminal.

To try something more ambitious, you can run an Ubuntu container with:
 $ docker run -it ubuntu bash

Share images, automate workflows, and more with a free Docker ID:
 https://cloud.docker.com/

For more examples and ideas, visit:
 https://docs.docker.com/engine/userguide/

结束语

该篇展现了如何不经过docker而运行hello-world容器,主要目的为了了解镜像以及runc之间的关系,同时也触发咱们思考一个问题,既然咱们能够绕过docker运行容器,那咱们为何还要用docker呢?

相关文章
相关标签/搜索