是否可以 运行 gcsfuse 在 GCP kubernetes 中没有特权模式?

Is it possible to run gcsfuse without privileged mode inside GCP kubernetes?

在此 guide 之后,我正在尝试 运行 GKE 中的 pod 内的 gcsfuse。下面是我正在使用的部署清单:

apiVersion: extensions/v1beta1
kind: Deployment
metadata:
  name: gcsfuse-test
spec:
  replicas: 1
  template:
    metadata:
      labels:
        app: gcsfuse-test
    spec:
      containers:
        - name: gcsfuse-test
          image: gcr.io/project123/gcs-test-fuse:latest
          securityContext:
            privileged: true
            capabilities:
              add:
                - SYS_ADMIN
          lifecycle:
            postStart:
              exec:
                command: ["mkdir", "/mnt"]
                command: ["gcsfuse", "-o", "nonempty", "cloudsql-p8p", "/mnt"]
            preStop:
              exec:
                command: ["fusermount", "-u", "/mnt"]

但是,我想 运行 在我的 GKE 集群中没有特权模式的 gcsfuse。 我认为(因为像 these 这样的问题)可以 运行 具有某些标志的 docker 图像,并且不需要 运行 在特权模式下.

在 GKE 中有什么方法可以 运行 gcsfuse 而无需 运行 在特权模式下连接容器?

特权模式意味着您已启用所有功能,请参阅 。因此,在您的示例中添加 CAP_SYS_ADMIN 看起来是多余的。

您可以授予所有特权,也可以通过挂载 /dev/fuse 并仅授予 SYS_ADMIN 能力(这仍然是一个重要的权限)来做一些更细粒度的事情。

我认为我们可以将问题改写为:我们可以 运行 没有能力 SYS_ADMIN 的 GCSFuse 吗?

实际上它看起来不可行,你可以在这里找到相关的 docker 问题:https://github.com/docker/for-linux/issues/321.

对于大多数项目来说,这并不难。您可能想根据您的威胁模型采取行动,并决定它是否对您的生产构成安全风险。

编辑 2022 年 4 月 26 日:有关从此答案派生的进一步开发的回购协议,请参阅 https://github.com/samos123/gke-gcs-fuse-unprivileged

现在终于可以在没有 privileged: trueCAP_SYS_ADMIN 的情况下安装设备了!

你需要的是

我花了很多时间来解决这个问题,所以我希望在这里分享的信息能帮助其他人进行探索。

我在关于 /dev/fuse 的 Kubernetes Github 问题中写下了我的详细发现。请参阅上面的 example setup in this comment 和更多技术细节。

上面链接的评论中的示例:

通过设备管理器允许 FUSE 设备:

apiVersion: v1
kind: ConfigMap
metadata:
  name: smarter-device-manager
  namespace: device-manager
data:
  conf.yaml: |
    - devicematch: ^fuse$
      nummaxdevices: 20

通过设备管理器请求 /dev/fuse:

# Pod spec: 
          resources:
            limits:
              smarter-devices/fuse: 1
              memory: 512Mi
            requests:
              smarter-devices/fuse: 1
              cpu: 10m
              memory: 50Mi

作为 DaemonSet 的设备管理器:

# https://gitlab.com/arm-research/smarter/smarter-device-manager/-/blob/master/smarter-device-manager-ds.yaml
apiVersion: apps/v1
kind: DaemonSet
metadata:
  name: smarter-device-manager
  namespace: device-manager
  labels:
    name: smarter-device-manager
    role: agent
spec:
  selector:
    matchLabels:
      name: smarter-device-manager
  updateStrategy:
    type: RollingUpdate
  template:
    metadata:
      labels:
        name: smarter-device-manager
      annotations:
        node.kubernetes.io/bootstrap-checkpoint: "true"
    spec:
      ## kubectl label node pike5 smarter-device-manager=enabled
      # nodeSelector:
      #   smarter-device-manager : enabled
      priorityClassName: "system-node-critical"
      hostname: smarter-device-management
      hostNetwork: true
      dnsPolicy: ClusterFirstWithHostNet
      containers:
      - name: smarter-device-manager
        image: registry.gitlab.com/arm-research/smarter/smarter-device-manager:v1.1.2
        imagePullPolicy: IfNotPresent
        securityContext:
          allowPrivilegeEscalation: false
          capabilities:
            drop: ["ALL"]
        resources:
          limits:
            cpu: 100m
            memory: 15Mi
          requests:
            cpu: 10m
            memory: 15Mi
        volumeMounts:
          - name: device-plugin
            mountPath: /var/lib/kubelet/device-plugins
          - name: dev-dir
            mountPath: /dev
          - name: sys-dir
            mountPath: /sys
          - name: config
            mountPath: /root/config
      volumes:
        - name: device-plugin
          hostPath:
            path: /var/lib/kubelet/device-plugins
        - name: dev-dir
          hostPath:
            path: /dev
        - name: sys-dir
          hostPath:
            path: /sys
        - name: config
          configMap:
            name: smarter-device-manager