INFO[0000] libcontainerd: new containerd process, pid: 19717
WARN[0000] containerd: low RLIMIT_NOFILE changing to max current=1024 max=4096
INFO[0001] [graphdriver] using prior storage driver "aufs"
INFO[0003] Graph migration to content-addressability took 0.63 seconds
WARN[0003] Your kernel does not support swap memory limit.
WARN[0003] mountpoint for pids not found
INFO[0003] Loading containers: start.
INFO[0003] Firewalld running: false
INFO[0004] Removing stale sandbox ingress_sbox (ingress-sbox)
INFO[0004] Default bridge (docker0) is assigned with an IP address 172.17.0.0/16. Daemon option --bip can be used to set a preferred IP address
INFO[0004] Loading containers: done.
INFO[0004] Listening for local connections addr=/var/lib/docker/swarm/control.sock proto=unix
INFO[0004] Listening for connections addr=[::]:2377 proto=tcp
INFO[0004] 61c88d41fce85c57 became follower at term 12
INFO[0004] newRaft 61c88d41fce85c57 [peers: [], term: 12, commit: 290, applied: 0, lastindex: 290, lastterm: 12]
INFO[0004] 61c88d41fce85c57 is starting a new election at term 12
INFO[0004] 61c88d41fce85c57 became candidate at term 13
INFO[0004] 61c88d41fce85c57 received vote from 61c88d41fce85c57 at term 13
INFO[0004] 61c88d41fce85c57 became leader at term 13
INFO[0004] raft.node: 61c88d41fce85c57 elected leader 61c88d41fce85c57 at term 13
INFO[0004] Initializing Libnetwork Agent Listen-Addr=0.0.0.0 Local-addr=192.168.0.47 Adv-addr=192.168.0.47 Remote-addr =
INFO[0004] Daemon has completed initialization
INFO[0004] Initializing Libnetwork Agent Listen-Addr=0.0.0.0 Local-addr=192.168.0.47 Adv-addr=192.168.0.47 Remote-addr =
INFO[0004] Docker daemon commit=7392c3b graphdriver=aufs version=1.12.5
INFO[0004] Gossip cluster hostname eonSpider-3e64aecb2dd5
INFO[0004] API listen on /var/run/docker.sock
INFO[0004] No non-localhost DNS nameservers are left in resolv.conf. Using default external servers : [nameserver 8.8.8.8 nameserver 8.8.4.4]
INFO[0004] IPv6 enabled; Adding default IPv6 external servers : [nameserver 2001:4860:4860::8888 nameserver 2001:4860:4860::8844]
INFO[0000] Firewalld running: false
mkdir -p ~/golang/src/github.com/opencontainers/
cd ~/golang/src/github.com/opencontainers/
git clone https://github.com/opencontainers/runc
cd ./runc
make
sudo make install
原文地址
文章首发
这片文章旨在想您介绍Containerd在docker架构中的集成。
让我们先来定义Docker Daemon然后看它是如何定义进docker架构和Containerd当中的。
Docker Daemon
像进程有守护进程一样(Like the init has its daemon), cron有crond, dhcp有dhcpd, Docker 也有自己的守护进程dockerd。
你能使用下面的命令列出所有的Linux的守护进程:
译者注:
并且在输出中grep出dockerd
你可可能会看到
docker-containerd-shim
,我们将要这篇文章的后面去讲解。如果你已经运行了docker,那么当你在命令后输入
dockerd
的时候会出现类似下面的信息:现在让我们来停止docker:
然后在命令行使用
dockerd
命令运行守护进程。使用
dockerd
在命令行运行docker的守护进程是一个很好的debug工具,你能在命令行上看到真实的运行轨迹。现在如果你在另一个窗口运行或者删除一个容器,你就能看到docker的守护进程连接了docker的客户端和容器。
下面是docker的全局架构(docker的C/S架构):
Containerd
它的目的是破坏docker架构中的模块化(its purpose is breaking up more modularity to Docker architecture)和与其他行业参(云提供者以及编排服务)与者相比更加中立。
据Solomon Hykes说,截止到2016年的4月,被包含在Docker 1.11中的Containerd已经被部署在数百万的机器中,宣布扩展Containerd的roadmap得到了许多云提供厂商的一件,这些云厂商包括阿里云,AWS,谷歌,IBM,微软和其他容器生态系统的活跃成员。
更多的docker引擎的功能将要被添加到containerd中,以至于containerd 1.0将要提供在linux或者windows上管理容器的所有原语:
你可能为了构建,传输,运行容器化应用继续使用docker,但是如果你寻找一种标准化组建那么你可以考虑containerd。
Docker Engine 1.11是第一个基于runC(基于OCI技术的runtime)和containerd构建的版本。下图是containerd的集成架构:
Open Container Initiative (OCI)组织成立于2015年的6月,旨在建立容器的通用标准为了避免在容器系统内部可能存在的碎片和分裂。
它包含两个标准:
runtime规范概述了如何在磁盘上解压文件系统包。
如果你导出和提出一个镜像你能看到这个json的文件。下面的这个例子,我们将要使用busybox作为例子:
现在我们在rootfs中已经有一个提取出来的busybox的镜像。
我们能够通过下面的命令生成config.json这个文件:
生成的配置文件如下:
现在你就可以编辑这个配置文件里面的内容,然后不通过docker启动一个容器,通过runc:
首先在你第一次用它的时候要先安装它:
你也能通过源文件安装它:
runC是一个完全符合规范的容器运行时,它允许你扩展(spin)一个容器,能与它们进行交互并且管理它们的声明周期,这要是为什么一个引擎(比如docker)构建的容器,能够在另一个容器中运行的原因。
容器作为runC的一个子进程,也能不通过守护进程(docker的守护进程)切入一些变量到系统之中。
runC构建在libcontainer上,libcontainer也是为docker引擎安装提供相同的容器库。在docker1.11之前,docker引擎用来管理存储,网络,容器以及镜像等等,现在docker的架构被拆为了四个部分:
为了运行一个容器,docker engine创建了一镜像,然后把它传递给containerd,然后containerd去调用containerd-shm ,containerd-shm 再去调用runC去运行这个容器。containerd-shim 允许runC在创建容器之后退出。这样我们就可以运行无守护进程的容器,因为我们没必要去为容器运行长时间的runtime进程。
目前,容器通过runC(经由containerd)创建的,但是可能通过另一种非runC的二进制暴露出相同的docker命令行以及接收OCI包。
你能在你的机器上看到不同的runtime通过下面的命令:
如果用的默认的会得到下面的输出:
通过下面的命令你可以增加一个runtime:
按流程它们只是一个containerd-shim,它管理标准的IO的先入先出队列,和保证在容器挂掉的时候能启动容器。
它也负责发送容器退出的状态给像docker这样的上层。
下图是当前的docker的架构。
Containerd实现了容器runtime,声明周期的支持和执行(create, start, stop, pause, resume, exec, signal & delete)这些特性。其他的特性(比如存储,日志等)被其他的组件实现。下图是Containerd Github 的一个图,展示了不同的特性并告诉这个特性是是否在范围Containerd之内。
我们运行容器:
如果你运行
ps aux
命令,你能注意到docker-containerd-shim和容器运行通过下面的一些参数关联:这是具有正确格式的完整行:
db5218c494190c11a2fcc9627ea1371935d7021e86b5f652221bdac1cf182843是你创建容器之后能看到的id。
总结
Docker的每个版本都在变化和发展,但有一些重大变化,比如Containerd的集成。在这篇文章中,我们已经看到了在这次集成(Containerd的集成)之后Docker发生了什么变化,以及OCI(在Docker的帮助下)如何通过引入使用独立运行时的可能性来改变容器世界。