Install the k8s cluster if not alreadly installed 1 2 microk8s enable dns storage helm3 microk8s status
Pull the helm chart 1 2 microk8s helm repo add truecharts https://charts.truecharts.org/ microk8s helm pull truecharts/transmission
Modify the values.yaml file to set the configuration 1 2 3 tar -xvf ./transmission-*.tgz cd transmission cat values.yamls
Make the data directory CONTAINER_ROOT_PATH
1 2 3 mkdir -p CONTAINER_ROOT_PATH sudo chown -R 777 CONTAINER_ROOT_PATH
Create Persistent Volumes and Persistent Volume Claims Transmission can think you deleted all your files if the harddisk containing your files fails to mount and the configuration files are on a different disk.
Persistent Volumes Config transmission-config-pv.yaml
HOSTNAME: Local computer hostname
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 apiVersion: v1 kind: PersistentVolume metadata: name: transmission-config-pv spec: capacity: storage: 100Gi volumeMode: Filesystem accessModes: - ReadWriteOnce persistentVolumeReclaimPolicy: Retain storageClassName: local-storage local: path: CONTAINER_ROOT_PATH/config # This must exist on the host nodeAffinity: required: nodeSelectorTerms: - matchExpressions: - key: kubernetes.io/hostname operator: In values: - HOSTNAME
microk8s kubectl apply -f transmission-config-pv
1 2 3 microk8s kubectl get pv NAME CAPACITY ACCESS MODES RECLAIM POLICY STATUS CLAIM STORAGECLASS REASON AGE transmission-config-pv 100Gi RWO Retain Bound default/transmission-config-pvc local-storage 9m44s
Data transmission-data-pv.yaml
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 apiVersion: v1 kind: PersistentVolume metadata: name: transmission-data-pv spec: capacity: storage: 5Ti volumeMode: Filesystem accessModes: - ReadWriteOnce persistentVolumeReclaimPolicy: Retain storageClassName: local-storage local: path: CONTAINER_ROOT_PATH/data # This must exist on the host nodeAffinity: required: nodeSelectorTerms: - matchExpressions: - key: kubernetes.io/hostname operator: In values: - HOSTNAME
microk8s kubectl apply -f transmission-data-pv.yaml
microk8s kubectl get pv
1 2 3 NAME CAPACITY ACCESS MODES RECLAIM POLICY STATUS CLAIM STORAGECLASS REASON AGE transmission-config-pv 100Gi RWO Retain Bound default/transmission-config-pvc local-storage 3h28m transmission-data-pv 5Ti RWO Retain Bound default/transmission-data-pvc local-storage 19s
Persistent Volume Claims Config transmission-config-pvc.yaml Bonds to transmission-config-pv
1 2 3 4 5 6 7 8 9 10 11 12 apiVersion: v1 kind: PersistentVolumeClaim metadata: name: transmission-config-pvc spec: storageClassName: local-storage # Empty string must be explicitly set otherwise default StorageClass will be set accessModes: - ReadWriteOnce volumeName: transmission-config-pv resources: requests: storage: 100Gi
microk8s kubectl apply -f transmission-config-pvc.yaml
Data transmission-data-pvc.yaml Bonds to transmission-data-pvc
1 2 3 4 5 6 7 8 9 10 11 12 apiVersion: v1 kind: PersistentVolumeClaim metadata: name: transmission-data-pvc spec: storageClassName: local-storage # Empty string must be explicitly set otherwise default StorageClass will be set accessModes: - ReadWriteOnce volumeName: transmission-data-pv resources: requests: storage: 5Ti
microk8s kubectl apply -f transmission-data-pvc.yaml
microk8s kubectl get pvc
1 2 3 NAME STATUS VOLUME CAPACITY ACCESS MODES STORAGECLASS AGE transmission-config-pvc Bound transmission-config-pv 100Gi RWO local-storage 3h21m transmission-data-pvc Bound transmission-data-pv 5Ti RWO local-storage 51s
Pull the syncthing helm chart 1 2 3 microk8s helm repo add truecharts https://charts.truecharts.org/ microk8s helm repo update microk8s helm pull truecharts/transmission
Modify the values.yaml file to set the configuration We’re going to set the transmission configuration within the container.
1 2 3 tar -xvf ./transmission-*.tgz cd transmission nano values.yamls
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 image: repository: tccr.io/truecharts/transmission pullPolicy: IfNotPresent tag: v4.0.3@sha256:245158e56dae5ca2da2cac5e9e85d4879685e8f302ed955ba144162d504307e4 service: main: ports: main: port: WEBGUI_PORT_NUMBER torrent: enabled: true ports: torrent: enabled: true port: TRANSMISSION_PORT protocol: tcp torrentudp: enabled: true port: TRANSMISSION_PORT protocol: udp workload: main: podSpec: containers: main: probes: liveness: enabled: true type: tcp startup: enabled: true type: tcp readiness: enabled: true type: tcp env: # PUID: 1001 # URL is set here so it wont be able to get overwritten by the user # as this will break the probes, if the need arises we can expose it. TRANSMISSION__RPC_URL: "/transmission" TRANSMISSION__RPC_USERNAME: "USERNAME" TRANSMISSION__RPC_PASSWORD: "RANDOM_PASSWORD" TRANSMISSION__RPC_AUTHENTICATION_REQUIRED: true # TRANSMISSION__ALT_SPEED_DOWN: 50 # TRANSMISSION__ALT_SPEED_ENABLED: false # TRANSMISSION__ALT_SPEED_TIME_BEGIN: 540 # TRANSMISSION__ALT_SPEED_TIME_DAY: 127 # TRANSMISSION__ALT_SPEED_TIME_ENABLED: false # TRANSMISSION__ALT_SPEED_TIME_END: 1020 # TRANSMISSION__ALT_SPEED_UP: 50 # TRANSMISSION__BIND_ADDRESS_IPV4: "0.0.0.0" # TRANSMISSION__BIND_ADDRESS_IPV6: "::" # TRANSMISSION__BLOCKLIST_ENABLED: true # TRANSMISSION__BLOCKLIST_URL: "https://github.com/Naunter/BT_BlockLists/releases/download/v.1/bt_blocklists.gz" TRANSMISSION__CACHE_SIZE_MB: 4 # TRANSMISSION__DHT_ENABLED: true TRANSMISSION__DOWNLOAD_DIR: "/data/Completed" # TRANSMISSION__DOWNLOAD_QUEUE_ENABLED: true # TRANSMISSION__DOWNLOAD_QUEUE_SIZE: 5 # TRANSMISSION__ENCRYPTION: 1 # TRANSMISSION__IDLE_SEEDING_LIMIT: 30 # TRANSMISSION__IDLE_SEEDING_LIMIT_ENABLED: false TRANSMISSION__INCOMPLETE_DIR: "/data/Incomplete" # TRANSMISSION__INCOMPLETE_DIR_ENABLED: true # TRANSMISSION__LPD_ENABLED: false # TRANSMISSION__MESSAGE_LEVEL: 2 # TRANSMISSION__PEER_CONGESTION_ALGORITHM: "" # TRANSMISSION__PEER_ID_TTL_HOURS: 6 # TRANSMISSION__PEER_LIMIT_GLOBAL: 200 # TRANSMISSION__PEER_LIMIT_PER_TORRENT: 50 TRANSMISSION__PEER_PORT: "{{ .Values.service.torrent.ports.torrent.port }}" # TRANSMISSION__PEER_PORT_RANDOM_HIGH: 65535 # TRANSMISSION__PEER_PORT_RANDOM_LOW: 49152 # TRANSMISSION__PEER_PORT_RANDOM_ON_START: false # TRANSMISSION__PEER_SOCKET_TOS: default" # TRANSMISSION__PEX_ENABLED: true # TRANSMISSION__PORT_FORWARDING_ENABLED: false # TRANSMISSION__PREALLOCATION: 1 # TRANSMISSION__PREFETCH_ENABLED: true # TRANSMISSION__QUEUE_STALLED_ENABLED: true # TRANSMISSION__QUEUE_STALLED_MINUTES: 30 # TRANSMISSION__RATIO_LIMIT: 2 # TRANSMISSION__RATIO_LIMIT_ENABLED: false # TRANSMISSION__RENAME_PARTIAL_FILES: true # TRANSMISSION__RPC_BIND_ADDRESS: "0.0.0.0" # TRANSMISSION__RPC_ENABLED: true # TRANSMISSION__RPC_HOST_WHITELIST: "" # TRANSMISSION__RPC_HOST_WHITELIST_ENABLED: false TRANSMISSION__RPC_PORT: "{{ .Values.service.main.ports.main.port }}" # TRANSMISSION__RPC_WHITELIST: "" # TRANSMISSION__RPC_WHITELIST_ENABLED: false # TRANSMISSION__SCRAPE_PAUSED_TORRENTS_ENABLED: true # TRANSMISSION__SCRIPT_TORRENT_DONE_ENABLED: false # TRANSMISSION__SCRIPT_TORRENT_DONE_FILENAME: "" # TRANSMISSION__SEED_QUEUE_ENABLED: false # TRANSMISSION__SEED_QUEUE_SIZE: 10 # TRANSMISSION__SPEED_LIMIT_DOWN: 100 # TRANSMISSION__SPEED_LIMIT_DOWN_ENABLED: false # TRANSMISSION__SPEED_LIMIT_UP: 100 # TRANSMISSION__SPEED_LIMIT_UP_ENABLED: false # TRANSMISSION__START_ADDED_TORRENTS: true # TRANSMISSION__TRASH_ORIGINAL_TORRENT_FILES: false # TRANSMISSION__UMASK: 2 # TRANSMISSION__UPLOAD_SLOTS_PER_TORRENT: 14 # TRANSMISSION__UTP_ENABLED: true # TRANSMISSION__WATCH_DIR: "/watch" # TRANSMISSION__WATCH_DIR_ENABLED: false persistence: config: enabled: true mountPath: "/config" type: pvc existingClaim: transmission-config-pvc data: enabled: true mountPath: "/data" type: pvc existingClaim: transmission-data-pvc portal: open: enabled: true manifestManager: enabled: false
Install the helm chart with our values.yaml file 1 microk8s helm install syncthing-server truecharts/syncthing --values ./values.yaml
Check the status of the installed application. 1 2 3 4 5 microk8s status microk8s kubectl describe pods microk8s kubectl microk8s kubectl logs microk8s kubectl describe pods
Common Errors Error from server (BadRequest): container in pod is waiting to start: ContainerCreating You probably need to change the permissions on the PV directory. This path is what is written in the PersistentVolume in the path variable. A quick chmod -R 777 to this path will most likely fix the issue. The conatiner should update the permissions once it runs.
Service yaml file We need to expose the service to the outside world. Thankfully microk8s has a built in loadbalancer called metallb
WEBGUI_PORT_NUMBER: The port you wish to run the webgui on TRANSMISSION_PORT: The port Transmission uses to comminicate with external parties.
transmission-service.yaml
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 apiVersion: v1 kind: Service metadata: name: transmission-service spec: type: LoadBalancer selector: app.kubernetes.io/name: transmission ports: - name: transmission-tcp protocol: TCP port: TRANSMISSION_PORT targetPort: TRANSMISSION_PORT - name: transmission-udp protocol: UDP port: TRANSMISSION_PORT targetPort: TRANSMISSION_PORT - name: transmission-rpc-tcp protocol: TCP port: WEBGUI_PORT_NUMBER # web gui port targetPort: WEBGUI_PORT_NUMBER externalIPs: - A.B.C.D
More information herehttps://medium.com/swlh/kubernetes-external-ip-service-type-5e5e9ad62fcd
Apply the service 1 microk8s kubectl apply -f ./transmission-service.yaml
Confirm the service is active 1 microk8s kubectl get services transmission-service
1 2 NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE transmission-service LoadBalancer A.B.C.D X.Y.Z.A TRANSMISSION_PORT:TRANSMISSION_PORT_2/TCP,TRANSMISSION_PORT:TRANSMISSION_PORT_2 /UDP,WEBGUI_PORT_NUMBER:31056/TCP 9h
Firewall Rules This assumes you are using ufw. ufw is bascally a wrapper for IPTABLES. If you have ever used IPTABLES before you understand why ufw exists.https://docs.syncthing.net/users/firewall.html
1 2 3 4 5 6 7 8 sudo ufw default allow routed sudo ufw allow from A.B.C.0/24 to any port WEBGUI_PORT_NUMBER proto tcp sudo ufw allow from E.F.G.H/24 to any port TRANSMISSION_PORT proto tcp sudo ufw allow from E.F.G.H/24 to any port TRANSMISSION_PORT proto udp sudo ufw status
References https://kubernetes.io/docs/concepts/services-networking/service/