Enabling GPIO use from kubernetes pod

So I’ve been working on a side hardware project, building a cyberdeck-style computer. This has been a passion / fun project, but it’s been great to get deeper into working with hardware.

For this project, I’m using a Raspberry Pi 4B as the base, and I’m running kubernetes on that device. If you want steps on how to get kubernetes deployed on a Raspberry Pi, see my blog post. Now as part of that, I have different sensors and devices connected to that RPi via a breadboard. And I wanted to build applications that engage with the different peripheral devices, but from within a pod. So the question becomes…how do I mount the appropriate elements to the pod so that it is able to communicate with the hardware from a pod in kubernetes.

Setting up the hardware

So to start with, the question becomes, how is the breadboard set up. Given the following pin diagram:

Raspberry Pi pin diagram

For more information see Raspberry Pi Documentation

And in this case I made the following connections via the breadboard:

GPIO Pin 26 – Resistor => LED GPIO Pin 4 – Button

And here’s a picture

Picture of Breadboard wired up with a button and an LED.

Python Application

The following is the code I wrote to control access to the LED. The goal of this is to build in a flashlight LED, so when you press the button, it turns on the LED, and when you release it turns it off. So the code is nothing particularly special but here it is:

from gpiozero import Button, LED 
from signal import pause

class Flashlight:
    def __init__(self, led_pin, button_pin):
        self.led = LED(led_pin)
        self.button = Button(button_pin)

        self.button.when_pressed = self.led.on
        self.button.when_released = self.led.off

    def run(self):
        print("Flashlight app is running")
        pause()

if __name__ == "__main__":
    print("Flashlight app started")
    print("Setting up GPIO pins")
    flashlight = Flashlight(led_pin=26, button_pin=4)
    flashlight.run()

Now for the above to work, I needed to build out a DockerFile to build the container image, so I can add this to a pod.

FROM ubuntu:22.04
# Copy Code File
COPY . /app
# Set the working directory
WORKDIR /app
# Install dependencies
RUN apt-get update
# Install Python3
RUN apt-get install -y python3-pip
# Install Python3 GPIO
RUN apt-get install -y python3-gpiozero

RUN chmod +x /app/main.py

CMD ["python3", "./main.py"]

In the above, it is important to note that I’m installing the python3-gpiozero module to support the code above.

Kubernetes YAML

Now given the above, the question is how do we mount the necessary elements for GPIO-Zero to work. The following is the yaml I ended up using:

apiVersion: v1
kind: Namespace
metadata:
  name: bat-utility
---
apiVersion: v1
kind: Pod
metadata:
  name: flashlight-pod
  namespace: bat-utility
spec:
  containers:
  - name: flashlight-container
    image: localhost:5000/flashlight:latest
    securityContext:
      privileged: true
    volumeMounts:
    - name: gpiomem4-device
      mountPath: /dev/gpiomem
  volumes:
  - name: gpiomem4-device
    hostPath:
      path: /dev/gpiomem
      type: CharDevice  

The key elements being the following:

    volumeMounts:
    - name: gpiomem4-device
      mountPath: /dev/gpiomem
  volumes:
  - name: gpiomem4-device
    hostPath:
      path: /dev/gpiomem
      type: CharDevice  

Notice that this mounts the required directories locally, this directory is actually a shortcut for mapping the GPIO Peripheral memory range. So by exposing this directory, our GPIO-Zero module doesn’t know the difference between running locally or running in a pod.

Leave a Reply

Your email address will not be published. Required fields are marked *