blog

Part 3 of 5: Kubernetes intel-gpu-plugin

Intel gpu plugin did not come with native Helm chart, so given yaml manifests were converted to terraform and kubernetes resources.

Note that this manifest only supports ARC B70 Pro carfs as has only this expression block:

matchExpressions = {
  vendor = {
    op    = "In",
    value = ["8086"]
  }
  class = {
    op    = "In",
    value = ["0300"]
  }
}

Full manifest:

resource "kubernetes_manifest" "nodefeaturerule_intel_gpu" {
  manifest = {
    apiVersion = "nfd.k8s-sigs.io/v1alpha1"
    kind       = "NodeFeatureRule"
    metadata = {
      name = "intel-gpu"
    }
    spec = {
      rules = [
        {
          name = "intel.gpu"
          labels = {
            "intel.feature.node.kubernetes.io/gpu" = true
          }
          matchFeatures = [
            {
              feature = "pci.device"
              matchExpressions = {
                vendor = {
                  op : "In",
                  value = ["8086"]
                }
                class = {
                  op : "In",
                  value : ["0300", "0380"]
                }
              }
              matchAny = [
                {
                  matchFeatures = [
                    {
                      feature : "kernel.loadedmodule"
                      matchExpressions = {
                        i915 = {
                          op = "Exists"
                        }
                      }
                    },
                    {
                      feature : "kernel.enabledmodule"
                      matchExpressions = {
                        i915 = {
                          op = "Exists"
                        }
                      }
                    },
                    {
                      feature : "kernel.loadedmodule"
                      matchExpressions = {
                        xe = {
                          op = "Exists"
                        }
                      }
                    },
                    {
                      feature : "kernel.enabledmodule"
                      matchExpressions = {
                        xe = {
                          op = "Exists"
                        }
                      }
                    }
                  ]
                }
              ]
            }
          ]
        }
      ]
    }
  }

  depends_on = [helm_release.nfd]
}

resource "kubernetes_manifest" "nodefeaturerule_intel_gpu_platform_labeling" {
  manifest = {
    apiVersion = "nfd.k8s-sigs.io/v1alpha1"
    kind       = "NodeFeatureRule"
    metadata = {
      name = "intel-gpu-platform-labeling"
    }
    spec = {
      rules = [
        {
          name = "intel.gpu.fractionalresources"
          extendedResources = {
            "gpu.intel.com/millicores" = "@local.label.gpu.intel.com/millicores"
            "gpu.intel.com/memory.max" = "@local.label.gpu.intel.com/memory.max"
            "gpu.intel.com/tiles"      = "@local.label.gpu.intel.com/tiles"
          }
          matchFeatures = [
            {
              feature = "local.label"
              matchExpressions = {
                "gpu.intel.com/millicores" = { op = "Exists" }
                "gpu.intel.com/memory.max" = { op = "Exists" }
                "gpu.intel.com/tiles"      = { op = "Exists" }
              }
            }
          ]
        },
        {
          name           = "intel.gpu.generic.count.300"
          labelsTemplate = "gpu.intel.com/device-id.0300-{{ (index .pci.device 0).device }}.count={{ len .pci.device }}"
          matchFeatures = [
            {
              feature = "pci.device"
              matchExpressions = {
                vendor = {
                  op    = "In",
                  value = ["8086"]
                }
                class = {
                  op    = "In",
                  value = ["0300"]
                }
              }
            }
          ]
        }
      ]
    }
  }

  depends_on = [helm_release.nfd]
}

resource "kubernetes_namespace_v1" "intel_gpu_plugin" {
  metadata {
    name = "intel-gpu-plugin"
  }
}

resource "kubernetes_daemon_set_v1" "intel_gpu_plugin" {
  metadata {
    name      = "intel-gpu-plugin"
    namespace = kubernetes_namespace_v1.intel_gpu_plugin.metadata[0].name
  }
  spec {
    selector {
      match_labels = {
        app = "intel-gpu-plugin"
      }
    }
    template {
      metadata {
        labels = {
          app = "intel-gpu-plugin"
        }
      }
      spec {
        service_account_name = "gpu-manager-sa"
        container {
          name = "intel-gpu-plugin"
          env {
            name = "NODE_NAME"
            value_from {
              field_ref {
                field_path = "spec.nodeName"
              }
            }
          }
          env {
            name = "HOST_IP"
            value_from {
              field_ref {
                field_path = "status.hostIP"
              }
            }
          }
          image             = "intel/intel-gpu-plugin:0.36.0"
          image_pull_policy = "IfNotPresent"
          args = [
            "-shared-dev-num=1",
            "-enable-monitoring",
            "-v=2"
          ]
          security_context {
            se_linux_options {
              type = "container_device_plugin_t"
            }
            read_only_root_filesystem  = true
            allow_privilege_escalation = false
            capabilities {
              drop = ["ALL"]
            }
            seccomp_profile {
              type = "RuntimeDefault"
            }
          }
          resources {
            requests = {
              memory = "45Mi"
              cpu    = "40m"
            }
            limits = {
              memory = "90Mi"
              cpu    = "100m"
            }
          }
          volume_mount {
            name       = "kubeletcrt"
            mount_path = "/var/lib/kubelet/pki/kubelet.crt"
          }
          volume_mount {
            name       = "nfd-features"
            mount_path = "/etc/kubernetes/node-feature-discovery/features.d/"
          }
          volume_mount {
            name       = "sysfsdevices"
            mount_path = "/sys/devices"
            read_only  = true
          }
          volume_mount {
            name       = "podresources"
            mount_path = "/var/lib/kubelet/pod-resources"
          }
          volume_mount {
            name       = "devfs"
            mount_path = "/dev/dri"
            read_only  = true
          }
          volume_mount {
            name       = "sysfsdrm"
            mount_path = "/sys/class/drm"
            read_only  = true
          }
          volume_mount {
            name       = "kubeletsockets"
            mount_path = "/var/lib/kubelet/device-plugins"
          }
          volume_mount {
            name       = "cdipath"
            mount_path = "/var/run/cdi"
          }
        }
        volume {
          name = "kubeletcrt"
          host_path {
            path = "/var/lib/kubelet/pki/kubelet.crt"
            type = "FileOrCreate"
          }
        }
        volume {
          name = "sysfsdevices"
          host_path {
            path = "/sys/devices"
          }
        }
        volume {
          name = "nfd-features"
          host_path {
            path = "/etc/kubernetes/node-feature-discovery/features.d/"
            type = "DirectoryOrCreate"
          }
        }
        volume {
          name = "podresources"
          host_path {
            path = "/var/lib/kubelet/pod-resources"
          }
        }
        volume {
          name = "devfs"
          host_path {
            path = "/dev/dri"
          }
        }
        volume {
          name = "sysfsdrm"
          host_path {
            path = "/sys/class/drm"
          }
        }
        volume {
          name = "kubeletsockets"
          host_path {
            path = "/var/lib/kubelet/device-plugins"
          }
        }
        volume {
          name = "cdipath"
          host_path {
            path = "/var/run/cdi"
            type = "DirectoryOrCreate"
          }
        }
        node_selector = {
          "kubernetes.io/arch"                   = "amd64"
          "intel.feature.node.kubernetes.io/gpu" = "true"
        }
      }
    }
  }

  depends_on = [
    kubernetes_manifest.nodefeaturerule_intel_gpu,
    kubernetes_manifest.nodefeaturerule_intel_gpu_platform_labeling,
    kubernetes_cluster_role_binding_v1.gpu_manager_rolebinding
  ]
}

resource "kubernetes_service_account_v1" "gpu_manager_sa" {
  metadata {
    name      = "gpu-manager-sa"
    namespace = kubernetes_namespace_v1.intel_gpu_plugin.metadata[0].name
  }
}

resource "kubernetes_cluster_role_v1" "gpu_manager_role" {
  metadata {
    name = "gpu-manager-role"
  }

  rule {
    api_groups = [""]
    resources  = ["pods", "nodes/proxy"]
    verbs      = ["list", "get"]
  }
}

resource "kubernetes_cluster_role_binding_v1" "gpu_manager_rolebinding" {
  metadata {
    name = "gpu-manager-rolebinding"
  }
  role_ref {
    api_group = "rbac.authorization.k8s.io"
    kind      = "ClusterRole"
    name      = kubernetes_cluster_role_v1.gpu_manager_role.metadata[0].name
  }
  subject {
    kind      = "ServiceAccount"
    name      = kubernetes_service_account_v1.gpu_manager_sa.metadata[0].name
    namespace = kubernetes_namespace_v1.intel_gpu_plugin.metadata[0].name
  }

  depends_on = [
    kubernetes_service_account_v1.gpu_manager_sa,
    kubernetes_cluster_role_v1.gpu_manager_role
  ]
}

← all posts