<p>Following this <a href="https://github.com/maciekrb/gcs-fuse-sample" rel="nofollow noreferrer">guide</a>,I am trying to run gcsfuse inside a pod in GKE. Below is the deployment manifest that I am using:</p>
<pre><code>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: [&quot;mkdir&quot;, &quot;/mnt&quot;]
                command: [&quot;gcsfuse&quot;, &quot;-o&quot;, &quot;nonempty&quot;, &quot;cloudsql-p8p&quot;, &quot;/mnt&quot;]
            preStop:
              exec:
                command: [&quot;fusermount&quot;, &quot;-u&quot;, &quot;/mnt&quot;]
</code></pre>
<p>However, I would like to run gcsfuse without the privileged mode inside my GKE Cluster.
I think (because of questions like <a href="https://stackoverflow.com/questions/48407184/gcsfuse-on-datalab-vm-machine-error-fusermount-fuse-device-not-found-try-mo">these</a> on SO) it is possible to run the docker image with certain flags and there will be no need to run it in privileged mode.</p>
<p>Is there any way in GKE to run gcsfuse without running the container in privileged mode?</p>

Amit Yadav
<p>Edit Apr 26, 2022: for a further developed repo derived from this answer, <strong>see <a href="https://github.com/samos123/gke-gcs-fuse-unprivileged" rel="nofollow noreferrer">https://github.com/samos123/gke-gcs-fuse-unprivileged</a></strong></p>
<p>Now it finally is possible to mount devices without <code>privileged: true</code> or <code>CAP_SYS_ADMIN</code>!</p>
<p>What you need is</p>
<ul>
<li><p>A Kubelet device manager which allows containers to have direct access to host devices in a secure way. The device manager explicitly given devices to be available via the Kubelet Device API. I used this hidden gem: <a href="https://gitlab.com/arm-research/smarter/smarter-device-manager" rel="nofollow noreferrer">https://gitlab.com/arm-research/smarter/smarter-device-manager</a>.</p>
</li>
<li><p>Define <a href="https://gitlab.com/arm-research/smarter/smarter-device-manager/-/blob/7eb7526956c59b9897a716922fd49566202b4e91/smarter-device-manager-configmap-rpi.yaml" rel="nofollow noreferrer">list of devices provided by the Device Manager</a> - add <code>/dev/YOUR_DEVICE_NAME</code> into this list, see example below.</p>
</li>
<li><p>Request a device via the Device Manager in the pod spec <code>resources.requests.smarter-devices/YOUR_DEVICE_NAME: 1</code></p>
</li>
</ul>
<p>I spent quite some time figuring this out so I hope sharing the information here will help someone else from the exploration.</p>
<p>I wrote my details findings in the Kubernetes Github issue about /dev/fuse. See an <a href="https://github.com/kubernetes/kubernetes/issues/7890#issuecomment-766088805" rel="nofollow noreferrer">example setup in this comment</a> and more technical details above that one.</p>
<p>Examples from the comment linked above:</p>
<p><strong>Allow FUSE devices via Device Manager</strong>:</p>
<pre><code>apiVersion: v1
kind: ConfigMap
metadata:
  name: smarter-device-manager
  namespace: device-manager
data:
  conf.yaml: |
    - devicematch: ^fuse$
      nummaxdevices: 20
</code></pre>
<p><strong>Request /dev/fuse via Device Manager:</strong></p>
<pre><code># Pod spec: 
          resources:
            limits:
              smarter-devices/fuse: 1
              memory: 512Mi
            requests:
              smarter-devices/fuse: 1
              cpu: 10m
              memory: 50Mi
</code></pre>
<p><strong>Device Manager as a DaemonSet</strong>:</p>
<pre><code># 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: &quot;true&quot;
    spec:
      ## kubectl label node pike5 smarter-device-manager=enabled
      # nodeSelector:
      #   smarter-device-manager : enabled
      priorityClassName: &quot;system-node-critical&quot;
      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: [&quot;ALL&quot;]
        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
</code></pre>
