Kubernetes Drone Runner for Raspberry Pi

From our previous post we've setup our Drone CI Server on Kubernetes, and in this post we will deploy a Kubernetes Runner, which will be responsible for running our CI tasks.

The Drone Runners and Drone Server uses the same RPC Secret in order for them to authorize the runners to talk to the server.

From our previous post, we created the drone-rpc-secret secret and we are exposing it as a environment variable: DRONE_RPC_SECRET. Since we already created the secret, we will be using it in our deployment manifest.

RBAC

First we need to deploy the Drone RBAC, our drone-runner-rbac.yaml:

kind: Role  
apiVersion: rbac.authorization.k8s.io/v1  
metadata:  
  namespace: default
  name: drone
rules:  
- apiGroups:
  - ""
  resources:
  - secrets
  verbs:
  - create
  - delete
- apiGroups:
  - ""
  resources:
  - pods
  - pods/log
  verbs:
  - get
  - create
  - delete
  - list
  - watch
  - update

---
kind: RoleBinding  
apiVersion: rbac.authorization.k8s.io/v1  
metadata:  
  name: drone
  namespace: default
subjects:  
- kind: ServiceAccount
  name: default
  namespace: default
roleRef:  
  kind: Role
  name: drone
  apiGroup: rbac.authorization.k8s.io

Let's deploy the rbac:

$ kubectl apply -f drone-runner-rbac.yaml

Deployment

In our Kubernetes Runner deployment, we need to specify the following:

  • DRONE_RPC_HOST
  • DRONE_RPC_HOST
  • DRONE_RPC_SECRET
  • DRONE_RUNNER_NAME
  • DRONE_RUNNER_MAX_PROCS
  • DRONE_RUNNER_LABELS (optional)

If you decide to use DRONE_RUNNER_LABELS your .drone.yml need to use the specific labels that you've set for your task to run on the configured runner.

This is just so that the runner is aware of the drone server and where and how to reach it, for more information have a look at the documentation

Our deployment manifest, drone-runner.yaml:

apiVersion: apps/v1  
kind: Deployment  
metadata:  
  name: drone-runner
  labels:
    app.kubernetes.io/name: drone-runner
spec:  
  replicas: 1
  selector:
    matchLabels:
      app.kubernetes.io/name: drone-runner
  template:
    metadata:
      labels:
        app.kubernetes.io/name: drone-runner
    spec:
      containers:
      - name: drone-runner
        image: drone/drone-runner-kube:linux-arm
        ports:
        - containerPort: 3000
        env:
        - name: DRONE_RPC_HOST
          value: drone.yourdomain.com
        - name: DRONE_RPC_PROTO
          value: https
        - name: DRONE_RPC_SECRET
          valueFrom:
            secretKeyRef:
              name: drone-rpc-secret
              key: env.DRONE_RPC_SECRET
        - name: DRONE_RUNNER_NAME
          value: drone-kubernetes-runner
        - name: DRONE_RUNNER_MAX_PROCS
          value: "5"
        - name: DRONE_DEBUG
          value: "false"
        - name: DRONE_TRACE
          value: "false"
        - name: DRONE_RUNNER_LABELS
          value: "hardware:rpi,runnerid:default"

Deploy the runner:

$ kubectl apply -f drone-runner.yaml

Once your deployment has rolled out, you should be able to see:

$ kubectl get deployment -l app.kubernetes.io/name=drone-runner -o wide
NAME           READY   UP-TO-DATE   AVAILABLE   AGE   CONTAINERS     IMAGES                              SELECTOR  
drone-runner   1/1     1            1            1d   drone-runner   drone/drone-runner-kube:linux-arm   app.kubernetes.io/name=drone-runner