Skip to content

githedgehog/k8s-tpm-device-plugin

Repository files navigation

k8s-tpm-device-plugin

License: Apache 2.0

This is a Kubernetes device plugin to make TPM devices accessible from Kubernetes pods without the need to run pods in privileged mode. The initial goal for this plugin was to enable the rust keylime agent to run on Kubernetes (without the need of privileged mode).

Overview

In a nutshell the plugin consists actually of two plugins which allows you to pass through the /dev/tpmrm0 or /dev/tpm0 devices. Using the former device is preferred, and the latter one should usually only be used if the Linux kernel version of the cluster is <4.12.

Note that particularly when you are relying on the /dev/tpm0 device that the host is not already holding full access to it. This could be the case if you are running tpm2-abrmd which is not recommended any longer.

As mentioned below only one pod can hold the /dev/tpm0 device at a time. Up to N pods on a host can gain access to the /dev/tpmrm0 device. This value is configurable and can be overwritten at installation time with for example an additional command-line flag while installing the helm chart: --set pluginSettings.numTpmRmDevices=128. By default up to 64 pods can gain access to the /dev/tpmrm0 device on a host. Note that this number is totally arbitrary, and can unfortunately not be handled differently because of the way how devices are allocated by the Kubernetes device manager.

Requirements

The following requirements must be met to run the TPM device plugin:

  • obviously, it only makes sense to run this device plugin on nodes which offer a TPM device (duh) - use a custom nodeSelector for the DaemonSet if you need to be selective
  • Kubernetes 1.26 is a requirement at this point because this is when the device manager went GA - I'm afraid that if you have device plugins deployed as a feature before and you want to use this plugin, you need to modify the helm chart in this repo to remove this requirement.

Known Compatibility

So far the plugin has only been tested on vanilla Kubernetes clusters running on Fedora nodes. It would be great to get confirmation contributions from folks who were successfully using this on some of the common cloud platforms. Please open an issue and/or PR for it!

Installation

The TPM device plugin must be deployed as a Kubernetes DaemonSet. It comes packaged as a helm chart. Run the following to deploy this helm chart in your Kubernetes cluster

helm upgrade --install hhtpmplugin oci://ghcr.io/githedgehog/k8s-tpm-device-plugin/helm-charts/k8s-tpm-device-plugin

If you want (or need) to make modifications to the installation, take a look at the values.yaml file.

Usage

This is the preferred methodYou can request the /dev/tpmrm0 device like the following in the resource limits section of a container spec:

    resources:
      limits:
        githedgehog.com/tpmrm: 1

In edge cases, and when you truly need it, you can similarly request the /dev/tpm0 device like this:

    resources:
      limits:
        githedgehog.com/tpm: 1

NOTE: The /dev/tpm0 device can always be allocated only to one pod on a host at the same time. It is generally not advisable to use this device at all if your Linux kernel has support for the /dev/tpmrm0 device.

Example

Here is a full pod yaml example which provides full access to the TPM device without the need for any elevated privileges or capabilities:

---
apiVersion: v1
kind: Pod
metadata:
  name: tpm-device-test
spec:
  terminationGracePeriodSeconds: 1
  containers:
  - name: tpm-device-test
    image: fedora:latest
    command:
    - /bin/bash
    - -c
    - while true; do sleep 3600; done
    resources:
      limits:
        githedgehog.com/tpmrm: 1
    securityContext:
      allowPrivilegeEscalation: false
      capabilities:
        drop: ["ALL"]

You can test this pod by running the following commands:

kubectl exec -ti tpm-device-test -- /bin/bash

dnf install -y tpm2-tools
tpm2_getcap --list
tpm2_getrandom --hex 16