以默认方式启动docker容器,在容器里有很多操作是做不了的,即使是以root用户来操作也不行。 但是在启动的时候加上--privileged就可以解决这个问题。

这就引入了一个capabilities的概念

if ec.Privileged {
			p.Capabilities = caps.GetAllCapabilities()
}

linux capabilities

在linux capabilities之前,linux的权限只有特权和非特权。在内核2.2之后,对特权进行了进一步的划分,划分出来的每个单元就被称为capability。在capabilities中可以查看定义。

任意一个进程在执行特权操作的时候,都需要具有这个特权操作对应的capability。如果要 mount 一个文件系统,那么对应的进程需要有 CAP_SYS_ADMIN 这个 capability。

在linux的普通节点上,非root用户启动进程默认没有任务capability,root启动的进程具有所有的capability

在/proc下进程的status文件当中,可以找到CapEff这个值,这是个bitmap,每一个bit代表capability是否打开。

一个进程的capability是由其父进程以及自身的可执行文件的capability参数共同作用的。比如将iptables可执行文件加上 CAP_NET_ADMIN 的 capability,那么即使是非root用户也能具有权限执行。

在linux上可以通过getcapsetcap来查询/操作文件的capability。

容器的privileged

了解了capabilities之后,现在很清楚了问题的所在。就是docker为了安全,在启动容器的时候限制了容器进程的capabilities,就算以root用户启动也是如此。

--privileged则是赋予了所有的capabilities,但是这样显然是一种不安全的偷懒的手段。应该按照最小权限原则,只赋予需要的capability,参考前面的capabilities文档即可。