是否可以在 GCP kubernetes 内运行 gcsfuse 而无需特权模式?

Ami*_*dav 6 fuse kubernetes gcsfuse kubernetes-pod

按照本指南,我尝试在 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"]
Run Code Online (Sandbox Code Playgroud)

但是,我想在 GKE 集群中不使用特权模式运行 gcsfuse。我认为(由于诸如此类的问题可以使用某些标志运行 docker 映像,并且无需在特权模式下运行它。

GKE 有没有办法在不以特权模式运行容器的情况下运行 gcsfuse?

Pet*_*epo 6

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

现在终于可以在没有privileged: true或 的情况下安装设备了CAP_SYS_ADMIN

你需要的是

  • Kubelet 设备管理器,允许容器以安全的方式直接访问主机设备。设备管理器通过 Kubelet 设备 API 明确指定可用的设备。我使用了这个隐藏的宝石: https: //gitlab.com/arm-research/smarter/smarter-device-manager

  • 定义设备管理器提供的设备列表- 添加/dev/YOUR_DEVICE_NAME到此列表中,请参见下面的示例。

  • 通过 Pod 规范中的设备管理器请求设备resources.requests.smarter-devices/YOUR_DEVICE_NAME: 1

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

我在 Kubernetes Github 问题中写下了关于 /dev/fuse 的详细发现。请参阅此评论中的示例设置以及上面的更多技术细节。

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

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

apiVersion: v1
kind: ConfigMap
metadata:
  name: smarter-device-manager
  namespace: device-manager
data:
  conf.yaml: |
    - devicematch: ^fuse$
      nummaxdevices: 20
Run Code Online (Sandbox Code Playgroud)

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

# Pod spec: 
          resources:
            limits:
              smarter-devices/fuse: 1
              memory: 512Mi
            requests:
              smarter-devices/fuse: 1
              cpu: 10m
              memory: 50Mi
Run Code Online (Sandbox Code Playgroud)

作为 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
Run Code Online (Sandbox Code Playgroud)


hug*_*aka 3

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

您可以授予所有权限,也可以通过安装 /dev/fuse 并仅授予 SYS_ADMIN 功能(这仍然是一个重要的权限)来执行更细粒度的操作。

我认为我们可以将问题改写为:我们可以在没有 SYS_ADMIN 功能的情况下运行 GCSFuse 吗?

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

对于大多数项目来说,这并不是什么难事。您可能需要针对您的威胁模型采取行动,并确定它是否可能对您的生产构成安全风险。