用于 kubernetes 的 DaemonSet 在特权模式下工作正常,但即使添加了所有 linux 功能也会失败

Posted

技术标签:

【中文标题】用于 kubernetes 的 DaemonSet 在特权模式下工作正常,但即使添加了所有 linux 功能也会失败【英文标题】:A DaemonSet for kubernetes works fine while in privileged mode, but fails even if all linux capabilties are added 【发布时间】:2019-06-27 14:12:18 【问题描述】:

我有一个在 kubernetes 集群中以特权模式运行的守护程序集。这是守护程序集的 YAML 规范。

apiVersion: extensions/v1beta1
kind: DaemonSet
metadata:
  name: my-daemon
spec:
  template:
    metadata:
      labels:
        app: my-daemon
    spec:
      hostNetwork: true
      serviceAccountName: my-sa-account
      containers:
      - name: my-daemon
        image: akhilerm/my-daemon:0.5
        imagePullPolicy: Always
        securityContext:
          privileged: true
...
...

我没有使用privileged:true,而是转向Linux 功能来授予对DaemonSet 的权限。因此,我将所有 linux 功能添加到容器中并删除了privileged:true。这是新的 YAML 规范

apiVersion: extensions/v1beta1
kind: DaemonSet
metadata:
  name: my-daemon
spec:
  template:
    metadata:
      labels:
        app: my-daemon
    spec:
      hostNetwork: true
      serviceAccountName: my-sa-account
      containers:
      - name: my-daemon
        image: akhilerm/my-daemon:0.5
        imagePullPolicy: Always
        securityContext:
          capabilities:
            add: ["NET_BROADCAST", "NET_ADMIN", ..all CAPs..,"SYS_ADMIN"]
...
...

但是当使用 linux 功能时,守护进程的行为与预期不同。在这两种情况下,容器内/proc/1/status 中的权限位图都是相同的。

...
SigPnd: 0000000000000000
ShdPnd: 0000000000000000
SigBlk: 0000000000010000
SigIgn: 0000000000000004
SigCgt: 0000000000014002
CapInh: 0000003fffffffff
CapPrm: 0000003fffffffff
CapEff: 0000003fffffffff
CapBnd: 0000003fffffffff
CapAmb: 0000000000000000
...

在 kubernetes 中通过 pod 使用 linux 功能时,我还需要设置其他字段或权限吗?

【问题讨论】:

【参考方案1】:

我不是 100% 确定,但这个问题可能在缺少的 capabilities: 字段中。

apiVersion: extensions/v1beta1
kind: DaemonSet
metadata:
  name: my-daemon
spec:
  template:
    metadata:
      labels:
        app: my-daemon
    spec:
      hostNetwork: true
      serviceAccountName: my-sa-account
      containers:
      - name: my-daemon
        image: akhilerm/my-daemon:0.5
        imagePullPolicy: Always
        securityContext:
          capabilities:
            add: ["NET_BROADCAST", "NET_ADMIN", ..all CAPs..,"SYS_ADMIN"]
...
...

apiVersion: extensions/v1beta1
kind: DaemonSet
metadata:
  name: my-daemon
spec:
  template:
    metadata:
      labels:
        app: my-daemon
    spec:
      hostNetwork: true
      serviceAccountName: my-sa-account
      containers:
      - name: my-daemon
        image: akhilerm/my-daemon:0.5
        imagePullPolicy: Always
        securityContext:
          capabilities:
            add:
            - NET_BROADCAST
            - NET_ADMIN
            - ...
            - SYS_ADMIN
...
...

测试它,如果有任何成功,请告诉我。如果没有 - 我将尝试更深入地挖掘并为您提供另一种解决方案。 我在所有示例中都找到了这种格式,所以希望它会有所帮助。 作为一个真实的例子,我可以为您提供kubernetes-the-not-so-hard-way-with-ansible-ingress-with-traefik文章,并提供下一个解释:

securityContext:
  capabilities:
    drop:
    - ALL
    add:
    - NET_BIND_SERVICE

如果没有这个设置,我们将无法在端口 80 上绑定 Traefik 并且 443(对于所有想要使用端口的服务基本上都是如此

或者1个来自Kubernetes官方security-context的文章,不过这次的配置是针对Pod的:

apiVersion: v1
kind: Pod
metadata:
  name: security-context-demo-4
spec:
  containers:
  - name: sec-ctx-4
    image: gcr.io/google-samples/node-hello:1.0
    securityContext:
      capabilities:
        add: ["NET_ADMIN", "SYS_TIME"]

希望这会对你有所帮助。

【讨论】:

Capabilities 字段已经存在,错过了复制粘贴。在问题中更新了相同的内容。我尝试了您在答案中给出的两个选项。还是没有变化。此外,在特权模式下,/dev 目录拥有的设备比运行所有功能的设备多

以上是关于用于 kubernetes 的 DaemonSet 在特权模式下工作正常,但即使添加了所有 linux 功能也会失败的主要内容,如果未能解决你的问题,请参考以下文章

云原生之kubernetes实战k8s集群下的DaemonSet 高级资源对象

Docker&Kubernetes ❀ Kubernetes集群Pod控制器 - DaemonSet(DS)

Kubernetes的pod控制器之DaemonSet

Kubernetes基础_06_DaemonSet全解析(每个Node都有的Pod)

Kubernetes基础_06_DaemonSet全解析(每个Node都有的Pod)

Docker&Kubernetes ❀ Kubernetes集群Pod控制器 - DaemonSet(DS)