设为首页 收藏本站
查看: 2547|回复: 0

[经验分享] RunC 简介

[复制链接]

尚未签到

发表于 2018-9-21 09:25:44 | 显示全部楼层 |阅读模式
RunC 是什么?
  RunC 是一个轻量级的工具,它是用来运行容器的,只用来做这一件事,并且这一件事要做好。我们可以认为它就是个命令行小工具,可以不用通过 docker 引擎,直接运行容器。事实上,runC 是标准化的产物,它根据 OCI 标准来创建和运行容器。而 OCI(Open Container Initiative)组织,旨在围绕容器格式和运行时制定一个开放的工业化标准。

安装 runC
  RunC 是用 golang 创建的项目,因此编译它之前需要在本地安装 golang 的开发环境。Golang 的安装请参考《打造 golang 开发环境》一文,这里不再赘述。
  安装 libseccomp-dev
  RunC 默认的编译配置是支持 seccomp 的,所以我们需要先安装 libseccomp-dev:
  

$ sudo apt install libseccomp-dev  

  seccomp 的全称为 secure computing mode,即安全计算模型,这是 Linux 内核提供的功能。我们可以通过它来限制容器中进程的行为。关于 seccomp 的更多内容,请参考 Seccomp security profiles for Docker。
  获取 runC 的代码
  先创建 $GOPATH/src/github.com 目录:
  

$ mkdir -p $HOME/go/src/github.com  

  通过 go get 命令就可以从 github 上下载到 runC 的代码,但是要保证事先安装了 git:
  

$ go get github.com/opencontainers/runc  

  然后进入 $HOME/go/src/github.com/opencontainers/runc 目录,并 checkout 最新的稳定状态的代码 tag v1.0.0-rc5:
  

$ cd $HOME/go/src/github.com/opencontainers/runc  
$ git checkout v1.
0.0-rc5  

  查看代码当前的状态:
  

$ git status  

DSC0000.png

  v1.0.0-rc5 是当前最新的版本。
  编译并安装
  

$ make  
$
sudo make install  

DSC0001.png

  如上图所示,runC 被安装在了 /usr/local/sbin/runc 目录。
  可以通过 -v 选项查看一下版本号:
  

$ runc -v  

DSC0002.png

  至此,runC 就算是安装成功了。

准备 OCI bundle
  RunC 是运行容器的运行时,它负责利用符合标准的文件等资源运行容器,但是它不包含 docker 那样的镜像管理功能。所以要用 runC 运行容器,我们先得准备好容器的文件系统。所谓的 OCI bundle 就是指容器的文件系统和一个 config.json 文件。有了容器的文件系统后我们可以通过 runc spec 命令来生成 config.json 文件。使用 docker 可轻松的生成容器的文件系统,因为 runC 本来就是 docker 贡献给社区的嘛!
  下面我们准备一个运行 busybox 容器所需的文件系统:
  

$ docker pull busybox  
$
mkdir -p /tmp/mycontainer/rootfs  
$ cd
/tmp/mycontainer  
$ docker export $(docker create busybox)
| tar -C rootfs -xvf -  

  现在 rootfs 目录下就是 busybox 镜像的文件系统,然后生成 config.json 文件:
  

$ runc spec  

DSC0003.png

  如果直接使用生成的 config.json,接下来的演示不会太流畅,所以简单起见,我们稍微修改一下刚刚生成的 config.json 文件。就是把 "terminal": true 改为 false,把 "args": ["sh"] 改为 "args": ["sleep", "30"]:
DSC0004.png


理解容器状态转移
  在运行 busybox 容器前让我们先来看看 OCI 都定义了哪几种容器状态,以及这些状态是如何转移的。先看容器的状态:


  • creating:使用 create 命令创建容器,这个过程称为创建中。
  • created:容器已经创建出来,但是还没有运行,表示镜像文件和配置没有错误,容器能够在当前平台上运行。
  • running:容器里面的进程处于运行状态,正在执行用户设定的任务。
  • stopped:容器运行完成,或者运行出错,或者 stop 命令之后,容器处于暂停状态。这个状态,容器还有很多信息保存在平台中,并没有完全被删除。
  • paused:暂停容器中的所有进程,可以使用 resume 命令恢复这些进程的执行。
  下图则是对容器不同状态间转移的一个粗略描述:
DSC0005.png


RunC 命令
  要想了解 runC 都能干什么,最好是通过它提供的命令来操作容器。下面是笔者整理的 runC 命令的主要使用场景。
  查看帮助
  

$ runc -h  

  查看子命令的帮助
  

$ runc help subcommand  

  使用 create 命令创建容器
  进入到 /tmp/mycontainer 目录中:
  

$ cd /tmp/mycontainer  

  然后创建名为 mybusybox 的容器:
  

$ sudo runc create mybusybox  

  使用 list 命令查看当前存在的容器
  

$ sudo runc list  

DSC0006.png

  使用 state 命令查看容器的状态
  

$ sudo runc state mybusybox  

DSC0007.png

  注意图中的 "status": "created",当通过 create 成功创建了容器后,容器的状态就是 "created"。
  使用 ps 命令看看容器内运行的进程
  

$ sudo runc ps mybusybox  

DSC0008.png

  此时 mybusybox 容器内有一个名为 init 的进程在运行。
  使用 start 命令执行容器中定义的任务
  

$ sudo runc start   

  使用 start 命令启动容器后,让我们再用 ps 命令看看容器内运行了什么进程:
DSC0009.png

  此时我们在 config.json 中定义的 sleep 进程在运行。再用 state 命令看看容器此时的状态,此时已经变成了 running!
  使用 exec 命令在容器中执行命令
  通过 exec 命令我们可以在处于 created 状态和 running 状态的容器中执行命令:
  

$ sudo runc exec mybusybox ls  

DSC00010.png

  当容器中的用户任务结束后,容器会变成 stopped 状态,这时就不能再通过 exec 执行其它的命令了。
  使用 delete 命令删除容器
  我们可以通过 delete 命令删除容器,当然,一般情况下是删除 stopped 状态的容器:
  

$ sudo runc delete mybusybox  

  使用 run 命令创建并运行容器
  就像 docker run 命令一样,它会创建容器并运行容器中的命令:
  

$ sudo runc run mybusybox  

  当容器中的命令退出后容器随即被删除。
  使用 kill 命令停止容器中的任务
  如果要停止一个容器中正在运行的任务,可以使用 kill 命令:
  

$ sudo runc kill mybusybox  

  默认它会优雅的结束容器中的进程,但是碰到特殊情况,你就得使用终极信号 9:
  

$ sudo runc kill mybusybox 9  

  使用 pause 命令暂停容器中的所有进程
  我们先启动容器 mybusybox,然后用 pause 命令暂停它:
  

$ sudo runc pause mybusybox  

DSC00011.png

  执行 pause 命令后,容器的状态由 running 变成了 paused。然后我们再通过 resume 命令恢复容器中进程的执行:
  

$ sudo runc resume mybusybox  

DSC00012.png

  此时容器的状态又恢复到了 running。
  使用 events 命令获取容器的资源使用情况
  events 命令能够向我们报告容器事件及其资源占用的统计信息:
  

$ sudo runc events mybusybox  

DSC00013.png


rootless containers
  前面我们运行的所有命令都是以 root 权限执行的。能不能以普通用户的权限运行容器呢?答案是可以的,并被称为 rootless。要想以 rootless 的方式运行容器,需要我们在生成容器的配置文件时就为 spec 命令指定 rootless 参数:
  

$ runc spec --rootless  

  并且在运行容器时通过 --root 参数指定一个存放容器状态的路径:
  

$ runc --root /tmp/runc run mybusybox  


容器的热迁移操作
  RunC 支持容器的热迁移操作,所谓热迁移就是将一个容器进行 checkpoint 操作,并获得一系列文件,使用这一系列文件可以在本机或者其他主机上进行容器的 restore 工作。这也是 checkpoint  和 restore 两个命令存在的原因。热迁移属于比较复杂的操作,目前 runC 使用了 CRIU 作为热迁移的工具。RunC 主要是调用 CRIU(Checkpoint and Restore in Userspace)来完成热迁移操作。CIRU 负责冻结进程,并将作为一系列文件存储在硬盘上。并负责使用这些文件还原这个被冻结的进程。

总结
  RunC 作为标准化容器运行时的一个实现目前已经被 docker 内置为默认的容器运行时。相信随着 runC 自身的成熟和完善会有越来越多的大厂把 runC 作为默认的容器运行时。
  参考:
  Runc Github
  OCI和runc容器标准化和docker
  OCI标准和runC原理解读



运维网声明 1、欢迎大家加入本站运维交流群:群②:261659950 群⑤:202807635 群⑦870801961 群⑧679858003
2、本站所有主题由该帖子作者发表,该帖子作者与运维网享有帖子相关版权
3、所有作品的著作权均归原作者享有,请您和我们一样尊重他人的著作权等合法权益。如果您对作品感到满意,请购买正版
4、禁止制作、复制、发布和传播具有反动、淫秽、色情、暴力、凶杀等内容的信息,一经发现立即删除。若您因此触犯法律,一切后果自负,我们对此不承担任何责任
5、所有资源均系网友上传或者通过网络收集,我们仅提供一个展示、介绍、观摩学习的平台,我们不对其内容的准确性、可靠性、正当性、安全性、合法性等负责,亦不承担任何法律责任
6、所有作品仅供您个人学习、研究或欣赏,不得用于商业或者其他用途,否则,一切后果均由您自己承担,我们对此不承担任何法律责任
7、如涉及侵犯版权等问题,请您及时通知我们,我们将立即采取措施予以解决
8、联系人Email:admin@iyunv.com 网址:www.yunweiku.com

所有资源均系网友上传或者通过网络收集,我们仅提供一个展示、介绍、观摩学习的平台,我们不对其承担任何法律责任,如涉及侵犯版权等问题,请您及时通知我们,我们将立即处理,联系人Email:kefu@iyunv.com,QQ:1061981298 本贴地址:https://www.yunweiku.com/thread-599223-1-1.html 上篇帖子: ubuntu go环境安装搭建 下篇帖子: 基于gin框架和jwt-go中间件实现小程序用户登陆和token验证
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

扫码加入运维网微信交流群X

扫码加入运维网微信交流群

扫描二维码加入运维网微信交流群,最新一手资源尽在官方微信交流群!快快加入我们吧...

扫描微信二维码查看详情

客服E-mail:kefu@iyunv.com 客服QQ:1061981298


QQ群⑦:运维网交流群⑦ QQ群⑧:运维网交流群⑧ k8s群:运维网kubernetes交流群


提醒:禁止发布任何违反国家法律、法规的言论与图片等内容;本站内容均来自个人观点与网络等信息,非本站认同之观点.


本站大部分资源是网友从网上搜集分享而来,其版权均归原作者及其网站所有,我们尊重他人的合法权益,如有内容侵犯您的合法权益,请及时与我们联系进行核实删除!



合作伙伴: 青云cloud

快速回复 返回顶部 返回列表