Example Drone CI Kubernetes manifests

Update 9/22/2016: This blog post was eventually used to create a drone-on-kubernetes demo repository. Check that out for more up-to-date examples.

I've been evaluating Drone, with the goal to get it running on Kubernetes. I figured I'd share some very preliminary manifests, for anyone who else may be tinkering. How to use these is outside of the scope of this article, but Google Container Engine is an easy way to get going.

The first order of business is to create a service to serve as an entrypoint. The end result of this on Google Cloud is a Network Load Balancer with a public IP. The creation of the load balancer is handled by Kubernetes. Here's the manifest I used (HTTPS-only, in my case).

apiVersion: v1
kind: Service
metadata:
  name: droneio
  labels:
    name: droneio
spec:
  ports:
    - port: 443
      protocol: TCP
      targetPort: 443
  selector:
    name: droneio
  type: LoadBalancer

After setting a DNS entry up to point at the load balancer's public IP, the next step was to get a replication controller set up.

apiVersion: v1
kind: ReplicationController
metadata:
  name: droneio
  labels:
    name: droneio
spec:
  replicas: 1
  selector:
    name: droneio
  template:
    metadata:
      labels:
        name: droneio
    spec:
      containers:
        - image: drone/drone:0.4
          name: droneio
          env:
            # HTTP Listen Address
            - name: SERVER_ADDR
              value: ":443"
            # HTTPS private key
            - name: SERVER_KEY
              value: /etc/secrets/proxykey
            - name: SERVER_CERT
              value: /etc/secrets/proxycert
            # DB stuff
            - name: DATABASE_DRIVER
              value: sqlite3
            # This ends up being a mounted Google Cloud Disk.
            - name: DATABASE_CONFIG
              value: /var/lib/drone/drone.sqlite
            # RCS stuff
            - name: REMOTE_DRIVER
              value: bitbucket
            # TODO: Move these into secrets.
            - name: REMOTE_CONFIG
              value: https://bitbucket.org?client_id=YOUR_CLIENT_ID_HERE&client_secret=YOUR_CLIENT_SECRET_HERE&open=true
          ports:
            - containerPort: 443
              protocol: TCP
          volumeMounts:
            # Contains our SSL certs/keys
            - mountPath: /etc/secrets
              name: aclima-io-ssl
              readOnly: true
            # Persist our configs in an SQLite DB in here
            - mountPath: /var/lib/drone
              name: droneio-sqlite-db
            # Enables Docker in Docker
            - mountPath: /var/run/docker.sock
              name: docker-socket
            - mountPath: /var/lib/docker
              name: docker-lib
      volumes:
        - name: aclima-io-ssl
          secret:
            secretName: aclima-io-ssl
        - name: droneio-sqlite-db
          gcePersistentDisk:
            pdName: droneio-sqlite-db
            fsType: ext4
        - name: docker-socket
          hostPath:
            path: /var/run/docker.sock
        - name: docker-lib
          hostPath:
            path: /var/lib/docker

A bit lengthy, but we're using the Kubernetes Secrets API to store our SSL certs/keys. Our data store is SQLite, persisted with Kubernetes gcePersistentDisk. You can replace this with something else if you aren't on Google Cloud, or switch to one of the other DBs that Drone supports.

While I have glossed over a lot of details, this was enough to get us up and running well enough to start evaluating Drone.

Here are a few ideas for future improvements:

  • The keys in REMOTE_CONFIG should be stored in the Secrets API. There is currently (Kubernetes 1.0) no direct way to pull a secret directly into an environment variable in the manifest. The current workaround seems to be to create a shell script to use as the Docker container's entrypoint, pulling the values from the mounted secrets volume and stuffing them in environment variables.
  • HTTP -> HTTPS redirect (if you please).
  • X.509 auth might be a good idea, depending on your usage case.
  • DB persistence in something other than SQLite for any more active installs.