4

k8s中如何用DaemonSet在大量节点上执行脚本

 1 year ago
source link: https://blog.shell909090.org/blog/archives/2888/
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.
neoserver,ios ssh client

如何使用DaemonSet执行特权代码

简单点说,最低有三个条件。

  1. spec.hostPID is true.
  2. spec.containers.securityContext.privileged is true.
  3. 镜像里有nsenter.

条件1主要是为了让你能找到host的mnt namespace,然后你用条件3里的nsenter来在这个namespace里执行代码。就像这样。

/usr/bin/nsenter -m/proc/1/ns/mnt bash /runOnHost.sh

host上如何执行脚本

nsenter在host namespace下执行的时候,是不访问容器内文件系统的(或者很麻烦)。所以在host上执行脚本,最简单的办法就是拷过去。

cp /srv/runOnHost.sh /host/runOnHost.sh
/usr/bin/nsenter -m/proc/1/ns/mnt bash /runOnHost.sh
rm /host/runOnHost.sh

这就引出了一个新要求。如果要复制文件,pod需要挂载host文件系统。

      containers:
        volumeMounts:
        - mountPath: /host
          name: host-mount
      volumes:
      - hostPath:
          path: /
          type: ""
        name: host-mount

如何访问网络

注意,虽然我们进入了host的mnt namespace,但是network用的还是容器的。如果你的代码不需要网络,或者容器网络就能工作,那很好。如果需要host网络,那么需要设置spec.hostNetwork为true。

最简化镜像

很幸运的是,ubuntu官方镜像带了bashnsenter,因此不单独pack一个image来执行脚本是可能的。

  1. 使用ubuntu镜像。
  2. 用文件目录创建一个ConfigMap。
  3. 在DaemonSet里引用这个ConfigMap并且mount。

      containers:
        volumeMounts:
        - mountPath: /srv
          name: scripts
      volumes:
      - configMap:
          defaultMode: 0755
          name: rce-testing
        name: scripts
    

Put all together

runOnHost.sh: 随意

runOnPod.sh:

#!/bin/bash

cp /srv/runOnHost.sh /host/runOnHost.sh
/usr/bin/nsenter -m/proc/1/ns/mnt bash /runOnHost.sh
rm /host/runOnHost.sh
sleep 864000000

用以下命令生成一个ConfigMap,内容是上述两个文件。

kubectl create configmap rce-testing --from-file=srv/

rce-testing.yaml:

apiVersion: apps/v1
kind: DaemonSet
metadata:
  labels:
    app: rce-testing
  name: rce-testing
spec:
  selector:
    matchLabels:
      app: rce-testing
  template:
    metadata:
      labels:
        app: rce-testing
    spec:
      hostPID: true
      hostNetwork: true
      containers:
      - name: ubuntu
        image: ubuntu
        imagePullPolicy: IfNotPresent
        command:
        - /bin/bash
        args:
        - /srv/runOnPod.sh
        securityContext:
          privileged: true
        volumeMounts:
        - mountPath: /srv
          name: scripts
        - mountPath: /host
          name: host-mount
      volumes:
      - configMap:
          defaultMode: 0755
          name: rce-testing
        name: scripts
      - hostPath:
          path: /
          type: ""
        name: host-mount

其他注意事项

PodSecurityPolicy可能会阻止你开特权pod,注意解锁。


Recommend

About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK