Now that I have a Kubernetes environment up and running, it’s time to deploy my first app: Syncthing. This is a service that will allow me to keep my music library in sync between my PC (running iTunes) and my home server, from which I can stream music to my home music system.

Samba

Unrelated to the deployment of Syncthing, but relevant to the overall goal of the exercise, was the use of Samba. This was used to set up a share on the local network so that devices could stream music files from this server. Thus, the location of where Syncthing would save these files was important.

Docker

There is an official docker container available for Syncthing on DockerHub: syncthing/syncthing:latest.

I was able to get this up and running easily, directly in Docker, however I was sure that I wanted to orchestrate this container using Kubernetes, so I moved on quickly to Microk8s.

Microk8s

Network access

As expected, a NodePort was needed to expose the Syncthing UI to the local network.

Permissions

One of the challenges / worries that I had when considering how to run Syncthing with Microk8s was how it would access the host file system. I didn’t want it to just create it’s own folders for mounting storage within the Docker container. I knew there would be a lot of data copied to/from the server and it needed to be on a separate physical disk, mounted at /data/ on the host.

In order to get this working, I implemented the following combination:

  • Creating a local user (on the host) for running the service.
  • Granting that user (and it’s default group) access to the Syncthing data and config folders.
  • Instructing the Docker container to run using the UID/GID of that user.
# Under spec/template/spec/containers:
    env:
    - name: PUID
      value: "110" # local account UID
    - name: PGID
      value: "110" # local account GID
    securityContext:
      runAsUser: 110
      runAsGroup: 110
  • Finally, the paths on the local host were mapped into the container:
# Under spec/template/spec/containers:
    volumeMounts:
    - mountPath: /var/syncthing
      name: syncthing-config
    - mountPath: /data/syncthing
      name: syncthing-data
# Under spec/template/spec/
volumes:
  - name: syncthing-config
    hostPath:
      path: /data/syncthing/config
      type: Directory
  - name: syncthing-data
    hostPath:
      path: /data/syncthing
      type: Directory

It didn’t seem necessary to create a PersistentVolumeClaim for this one-off instance.