Docker on Yarn 实战

在Docker on Yarn 总体设计中已经提到我们采取了DockerContianer的方案,我们在具体的实践中基于Hadoop-2.7.1 源码做了一些完善和改造。

客户端Container 的无缝切换

由于我们之前还有很多任务跑在DefaultContainer和LinuxContainer上,
所以需要实现客户端能通过参数控制我们任务运行的Container类型。
我们通过改造ContainersLaunch和增加三种Container实例的缓存实现了三种不同类型Container的无缝切换。

DockerContainer 的CPU隔离

DockerContainer 的CPU限制方面参照LinuxContainer 的限制、具体算法是这样的。

1) 通过NodeManagerHardwareUtils中的getContainersCores获取Containers 最高可以获取的CPU核心数yarnProcessors

2) 通过containerVCores*yarnProcessors /nodeVCores 来获取每个Container应该获取的ContainerCPU。

3) 根据CgroupsLCEResourcesHandler的getOverallLimits方法把ContainerCPU转化对应的Cgroup中对应的cfs_period_us和cfs_quota_us ,而cpuShares的设定则是根据ContainerVcores *1024(CPU 默认的权重)。

DockerContainer 的内存隔离

DockerContainer 内存隔离方面有两中不同的方案。
一种是继续使用之前ContainerMonitor 的内存隔离、另外一种是使用Cgroup的内存隔离机制。

1) 社区里面讨论中有人认为Cgroup内存隔离是有问题的,Cgroup 强制内存限制策略不容许内存瞬间峰值。但也有人指出把memory.limit_in_bytes设置大一些和利用Cgroup中memory.soft_limit_in_bytes的内存回收策略是可以避免内存瞬间峰值的。
详情可参阅YARN-1856,出于对当前众多任务的考虑我们选择了前者。

2) ContainerMonitor 的内存隔离方案还出现DockerContainer获取不了Pid的Bug。
详情可参阅YARN-3080,我们对这个Bug也进行了修复。

DockerContainer 的安全

DockerContainer的安全问题也是我们较为关注的一个问题。DockerContainer 的安全性主要表现为
1) 用root去运行你的ContainerLanuch脚本
2) 在容器里面和容器外面对待用户的权限是否一致
我们修改了DockerContainer启动时的参数,让Yarn用户运行ContainerLanuch脚本,同时我们 把/etc/passwd、/etc/shadow、/etc/group挂载进Docker里面用来达到容器里和容器外的权限一致的标准关于是否挂载/etc/passwd、/etc/shadow、/etc/group这些文件社区也正在谈论当中。
如果有兴趣的话可以参阅YARN-5360

Docker 方面的改造

对于Docker 方面我们也做了相应的改善,如之前在测试集群里面我们的日志把Docker默认的目录/var/lib/docker写满,我们通过这次把Docker的默认目录修改成数据盘而非系统挂载盘,还对Docker的日志进行了限制文件的大小和文件的滚动个数。

更多实践敬请期待Docker on Yarn 实践二

参考资料

Isolating YARN Applications in Docker Containers
Umbrella issue for Yarn launched Docker Containers
Support Docker Containers In LinuxContainerExecutor
Cgroups cease to work in RHEL7
Docker
Docker Blog