以默认方式启动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上可以通过getcap和setcap来查询/操作文件的capability。
容器的privileged
了解了capabilities之后,现在很清楚了问题的所在。就是docker为了安全,在启动容器的时候限制了容器进程的capabilities,就算以root用户启动也是如此。
而--privileged则是赋予了所有的capabilities,但是这样显然是一种不安全的偷懒的手段。应该按照最小权限原则,只赋予需要的capability,参考前面的capabilities文档即可。