技术解析系列 | PouchContainer 支持 LXCFS 实现高可靠容器隔离
2018-08-02 15:41
639 查看
划重点
本周起 PouchContainer 启动核心技术专家解析系列文章,第一篇文章将深入剖析 LXCFS 适用业务场景和原理,对 LXCFS 感兴趣的同学不要错过
引言
PouchContainer 是 Alibaba 开源的一款容器运行时产品,当前最新版本是 0.3.0,代码地址位于:https://github.com/alibaba/pouch。PouchContainer 从设计之初即支持 LXCFS,实现高可靠容器隔离。Linux 使用 cgroup 技术实现资源隔离,然而容器内仍然挂载宿主机的 /proc 文件系统,用户在容器内读取 /proc/meminfo 等文件时,获取的是宿主机的信息。容器内缺少的/proc 视图隔离会带来一系列的问题,进而拖慢或阻碍企业业务容器化。LXCFS (https://github.com/lxc/lxcfs) 是开源 FUSE 文件系统,用以解决
/proc 视图隔离问题,使容器在表现层上更像传统的虚拟机。本文首先介绍 LXCFS 适用业务场景, 剖析 LXCFS ,最后简要介绍 LXCFS 在 PouchContainer 内部集成的工作。
LXCFS 业务场景
在物理机和虚拟机时代,公司内部逐渐形成了自己的一套工具链,诸如编译打包、应用部署、统一监控等,这些工具已经为部署在物理机和虚拟机中的应用提供了稳定的服务。接下来将从监控、运维工具、应用部署等方面详细阐述 LXCFS 在上述业务容器化过程中发挥的作用。监控和运维工具
大部分的监控工具,依赖 /proc 文件系统获取系统信息。以阿里巴巴为例,阿里巴巴的部分基础监控工具是通过 tsar(https://github.com/alibaba/tsar) 收集信息。而 tsar 对内存、CPU 信息的收集,依赖 /proc 文件系统。我们可以下载 tsar 的源码,查看 tsar 对 /proc 目录下一些文件的使用:1$ git remote -v 2origin https://github.com/alibaba/tsar.git (fetch) 3origin https://github.com/alibaba/tsar.git (push) 4$ grep -r cpuinfo . 5./modules/mod_cpu.c: if ((ncpufp = fopen("/proc/ cpuinfo", "r")) == NULL) { 6:tsar letty$ grep -r meminfo . 7./include/define.h:#define MEMINFO "/proc/meminfo" 8./include/public.h:#define MEMINFO "/proc/meminfo" 9./info.md:内存的计数器在/proc/meminfo,里面有一些关键项 10./modules/mod_proc.c: /* read total mem from /proc/meminfo */ 11./modules/mod_proc.c: fp = fopen("/proc/meminfo", "r"); 12./modules/mod_swap.c: * Read swapping statistics from /proc/vmstat & /proc/meminfo. 13./modules/mod_swap.c: /* read /proc/meminfo */ 14$ grep -r diskstats . 15./include/public.h:#define DISKSTATS "/proc/diskstats" 16./info.md:IO的计数器文件是:/proc/diskstats,比如: 17./modules/mod_io.c:#define IO_FILE "/proc/diskstats" 18./modules/mod_io.c:FILE *iofp; /* /proc/diskstats*/ 19./modules/mod_io.c: handle_error("Can't open /proc/diskstats", !iofp);可以看到,tsar 对进程、IO、CPU 的监控都依赖 /proc 文件系统。当容器内 /proc 文件系统提供的是宿主机资源信息时,这类监控不能监控容器内信息。为了满足业务需求,需要适配容器监控,甚至需要单独为容器内监控开发另一套监控工具。这种改变势必会拖慢甚至阻碍企业现存业务容器化的步伐,容器技术要尽可能兼容公司原有的工具链,兼顾工程师的使用习惯。PouchContainer 支持 LXCFS 可以解决上述问题,依赖 /proc 文件系统的监控、运维工具,部署在容器内或宿主机上对工具是透明的,现存监控、运维工具无需适配或重新开发,即可平滑迁移到容器内,实现容器内的监控和运维。接下来让我们从实例中直观感受一下,在一台 Ubuntu 虚拟机中安装 PouchContainer 0.3.0 :
1# uname -a 2Linux p4 4.13.0-36-generic #40~16.04.1-Ubuntu SMP Fri Feb 16 23:25:58 UTC 2018 x86_64 x86_64 x86_64 GNU/Linuxsystemd 拉起 pouchd ,默认不开启 LXCFS,此时创建的容器无法使用 LXCFS 的功能,我们看一下容器内相关 /proc 文件的内容:
1# systemctl start pouch 2# head -n 5 /proc/meminfo 3MemTotal: 2039520 kB 4MemFree: 203028 kB 5MemAvailable: 777268 kB 6Buffers: 239960 kB 7Cached: 430972 kB 8root@p4:~# cat /proc/uptime 92594341.81 2208722.33 10# pouch run -m 50m -it registry.hub. docker.com/library/busybox:1.28 11/ # head -n 5 /proc/meminfo 12MemTotal: 2039520 kB 13MemFree: 189096 kB 14MemAvailable: 764116 kB 15Buffers: 240240 kB 16Cached: 433928 kB 17/ # cat /proc/uptime 182594376.56 2208749.32可以看到,在容器内看到的 /proc/meminfo、uptime 文件的输出与宿主机一致,虽然启动容器的时候指定了内存为 50M,/proc/meminfo 文件并未体现出容器内的内存限制。在宿主机内启动 LXCFS 服务,手动拉起 pouchd 进程,并指定相应的 LXCFS 相关参数:
1# systemctl start lxcfs 2# pouchd -D --enable-lxcfs --lxcfs /usr/bin/lxcfs >/tmp/1 2>&1 & 3[1] 32707 4# ps -ef |grep lxcfs 5root 698 1 0 11:08 ? 00:00:00 /usr/bin/lxcfs /var/lib/lxcfs/ 6root 724 32144 0 11:08 pts/22 00:00:00 grep --color=auto lxcfs 7root 32707 32144 0 11:05 pts/22 00:00:00 pouchd -D --enable-lxcfs --lxcfs /usr/bin/lxcfs启动容器,获取相应的文件内容:
1# pouch run --enableLxcfs -it -m 50m registry.hub.docker.com/library/busybox:1.28 2/ # head -n 5 /proc/meminfo 3MemTotal: 51200 kB 4MemFree: 50804 kB 5MemAvailable: 50804 kB 6Buffers: 0 kB 7Cached: 4 kB 8/ # cat /proc/uptime 910.00 10.00使用 LXCFS 启动的容器,读取容器内 /proc 文件,可以得到容器内的相关信息。
业务应用
对于大部分对系统依赖较强的应用,应用的启动程序需要获取系统的内存、CPU 等相关信息,从而进行相应的配置。当容器内的 /proc 文件无法准确反映容器内资源的情况,会对上述应用造成不可忽视的影响。例如对于一些 Java 应用,也存在启动脚本中查看 /proc/meminfo 动态分配运行程序的堆栈大小,当容器内存限制小于宿主机内存时,会发生分配内存失败引起的程序启动失败。对于 DPDK 相关应用,应用工具需要根据 /proc/cpuinfo 获取 CPU 信息,得到应用初始化 EAL 层所使用的 CPU 逻辑核。如果容器内无法准确获取上述信息,对于 DPDK 应用而言,则需要修改相应的工具。PouchContainer 集成 LXCFS
PouchContainer 从 0.1.0 版开始即支持 LXCFS,具体实现可以参见: https://github.com/alibaba/pouch/pull/502 .简而言之,容器启动时,通过-v 将宿主机上 LXCFS 的挂载点 /var/lib/lxc/lxcfs/proc/ 挂载到容器内部的虚拟 /proc 文件系统目录下。此时在容器内部 /proc 目录下可以看到,一些列proc文件,包括 meminfo, uptime, swaps, stat, diskstats, cpuinfo 等。具体使用参数如下:1-v /var/lib/lxc/:/var/lib/lxc/:shared 2-v /var/lib/lxc/lxcfs/proc/uptime:/proc/uptime 3-v /var/lib/lxc/lxcfs/proc/swaps:/proc/swaps 4-v /var/lib/lxc/lxcfs/proc/stat:/proc/stat 5-v /var/lib/lxc/lxcfs/proc/diskstats:/proc/diskstats 6-v /var/lib/lxc/lxcfs/proc/meminfo:/proc/meminfo 7-v /var/lib/lxc/lxcfs/proc/cpuinfo:/proc/cpuinfo为了简化使用,pouch create 和 run 命令行提供参数
--enableLxcfs, 创建容器时指定上述参数,即可省略复杂的
-v参数。经过一段时间的使用和测试,我们发现由于lxcfs重启之后,会重建proc和cgroup,导致在容器里访问 /proc 出现
connect failed错误。为了增强 LXCFS 稳定性,在 PR:https://github.com/alibaba/pouch/pull/885 中,refine LXCFS 的管理方式,改由 systemd 保障,具体实现方式为在 lxcfs.service 加上 ExecStartPost 做 remount 操作,并且遍历使用了 LXCFS 的容器,在容器内重新 mount。
总结
PouchContainer 支持 LXCFS 实现容器内 /proc 文件系统的视图隔离,将大大减少企业存量应用容器化的过程中原有工具链和运维习惯的改变,加快容器化进度。有力支撑企业从传统虚拟化到容器虚拟化的平稳转型。相关文章推荐
- 技术解析系列 | PouchContainer 支持 LXCFS 实现高可靠容器隔离
- 技术解析系列 | PouchContainer 富容器技术
- 技术解析系列 | PouchContainer CRI的设计与实现
- 深入解析阿里 PouchContainer 如何实现容器原地升级
- 技术解析系列 | 阿里 PouchContainer 资源管理探秘
- Spring源码解析之IoC容器系列的设计实现(IoC容器系列概况)
- Spring技术内幕——深入解析Spring架构与设计原理(一)IOC实现原理
- 微软软件实现技术授课系列内容之三:Project in C++ Coding Practice
- 使用C++实现SDK之WebBrowser容器 系列的一个补充. 关于GetHtmlDocumentX()
- 微软软件实现技术授课系列内容之五:软件测试基础
- 【Spring源码--IOC容器的实现】(三)BeanDefinition的载入和解析【I】
- 实时音视频互动系列(下):基于 WebRTC 技术的实战解析
- WCF广州本田整车销售系统技术解析(一) 新建项目与登陆验证功能实现
- Android实现XML解析技术
- Lucene总结系列(三)--总述优化方案和呈现实时内存索引实现(结合RAMDirectory源码解析)
- Spring技术内幕笔记 -- IoC容器的实现
- Spring源码解析-IOC容器的实现
- 两种方式实现TinyOS对MSP430F26&54系列的支持
- 秋色园QBlog技术原理解析:博客一键安装工具技术实现[附源码下载]
- Spring技术内幕——深入解析Spring架构与设计原理(一)IOC实现原理