K8S源码剖析(Capabilities)
我们可以在pod、container中通过设置securityContext来限制container对宿节点的权限
但是有的时候我们需要给予container部分系统特权,那就需要额外配置capability,比如这样:
containers:
- name: sec-ctx-4
image: gcr.io/google-samples/node-hello:1.0
securityContext:
capabilities:
add: ["NET_ADMIN", "SYS_TIME"]
那实现原理:
- 初始化一个capability对象(这里注意是sync.once,保证分布式场景下只会创建一个),因为其在linux下是固定的列表
- 对于需要添加Privilege的container给予获取
// Capabilities defines the set of capabilities available within the system.
// For now these are global. Eventually they may be per-user
type Capabilities struct {
AllowPrivileged bool
// Pod sources from which to allow privileged capabilities like host networking, sharing the host
// IPC namespace, and sharing the host PID namespace.
PrivilegedSources PrivilegedSources
// PerConnectionBandwidthLimitBytesPerSec limits the throughput of each connection (currently only used for proxy, exec, attach)
PerConnectionBandwidthLimitBytesPerSec int64
}
var capInstance struct {
once sync.Once
lock sync.Mutex
capabilities *Capabilities
}
// Initialize the capability set. This can only be done once per binary, subsequent calls are ignored.
func Initialize(c Capabilities) {
// Only do this once
capInstance.once.Do(func() {
capInstance.capabilities = &c
})
}
// Setup the capability set. It wraps Initialize for improving usability.
func Setup(allowPrivileged bool, perConnectionBytesPerSec int64) {
Initialize(Capabilities{
AllowPrivileged: allowPrivileged,
PerConnectionBandwidthLimitBytesPerSec: perConnectionBytesPerSec,
})
}
// Get returns a read-only copy of the system capabilities.
func Get() Capabilities {
capInstance.lock.Lock()
defer capInstance.lock.Unlock()
// This check prevents clobbering of capabilities that might've been set via SetForTests
if capInstance.capabilities == nil {
Initialize(Capabilities{
AllowPrivileged: false,
PrivilegedSources: PrivilegedSources{
HostNetworkSources: []string{},
HostPIDSources: []string{},
HostIPCSources: []string{},
},
})
}
return *capInstance.capabilities
}