diff --git a/QUICKSTART.md b/QUICKSTART.md index 64c5f66..280e486 100644 --- a/QUICKSTART.md +++ b/QUICKSTART.md @@ -39,13 +39,13 @@ cilium install https://raw.githubusercontent.com/metallb/metallb/v0.13.5/config/manifests/metallb-native.yaml ```shell -kubectl apply -f metallb/00-manifest.yml +kubectl apply -f infra/metallb/00-manifest.yml ``` ## Configure MetalLB ```shell -kubectl apply -f metallb/01-configuration.yml +kubectl apply -f infra/metallb/01-configuration.yml ``` # Traefik @@ -64,8 +64,10 @@ terraform plan terraform apply ``` -## Create test application "whoami" with IngressRoutes +## Test application + +If not already created with Terraform run ```shell -kubectl apply -f whoami/00-whoami.yml +kubectl apply -f apps/whoami/00-whoami.yml ``` \ No newline at end of file diff --git a/README.md b/README.md index b568d09..19e0bf2 100644 --- a/README.md +++ b/README.md @@ -82,6 +82,7 @@ Install Cilium cilium install ``` +// TODO: Directly by Helm chart ```shell helm template --namespace kube-system cilium cilium/cilium --version 1.12.1 --set cluster.id=0,cluster.name=kubernetes,encryption.nodeEncryption=false,kubeProxyReplacement=disabled,operator.replicas=1,serviceAccounts.cilium.name=cilium,serviceAccounts.operator.name=cilium-operator,tunnel=vxlan ``` @@ -112,74 +113,43 @@ Installation https://raw.githubusercontent.com/metallb/metallb/v0.13.5/config/manifests/metallb-native.yaml ```shell -kubectl apply -f metallb/00-manifest.yml +kubectl apply -f infra/metallb/00-manifest.yml ``` Configure IP-pool and advertise as Level 2 https://metallb.universe.tf/configuration/ ```yaml -kubectl apply -f metallb/01-configuration.yml +kubectl apply -f infra/metallb/01-configuration.yml ``` # Traefik -## Install using Helm +## Install using Terraform and Helm ```shell -kubectl apply -f volumes/volumes.yml +terraform init +terraform plan +terraform apply ``` **NB:** It appears we need the "volume-permissions" init container for Traefik if using `StorageClass` with provisioner `kubernetes.io/no-provisioner` -```shell -helm install --values=helm/traefik-values.yaml traefik traefik/traefik -``` - -## Traefik IngressRoute Custom Resource Definition (CRD) - -https://doc.traefik.io/traefik/v2.8/routing/providers/kubernetes-crd/ -https://doc.traefik.io/traefik/v2.8/user-guides/crd-acme/ - -Create Custom Resource Definitions for Traefik - -```shell -kubectl apply -f traefik/00-crd-definition.yml -kubectl apply -f traefik/01-crd-rbac.yml -``` - -## Service - -Create service for exposing Traefik deployment - -```shell -kubectl apply -f traefik/02-service.yml -``` - -## Deployment - -Create deployment for Traefik - -```shell -kubectl apply -f traefik/03-deployment.yml -``` - ## Port forward Traefik -Port forward Traefik ports from 8000 to 80 for http and 4443 to 443 for https. +Port forward Traefik ports in router from 8000 to 80 for http and 4443 to 443 for https. IP can be found with `kubectl get svc`. # Test-application -Create a test-application with +Create a test-application (if not already created with Terraform) with ```shell -kubectl apply -f whoami/00-whoami.yml +kubectl apply -f apps/whoami/00-whoami.yml ``` -`whoami` should now be available using https at `https://test.ratatoskr.myddns.rocks/tls` -and using http at `http://test.ratatoskr.myddns.rocks/notls`. +`whoami` should now be available at `https://whoami.${DOMAIN}`. # Cleanup @@ -188,16 +158,4 @@ kubectl drain ratatoskr --delete-emptydir-data --force --ignore-daemonsets sudo kubeadm reset sudo iptables -F && sudo iptables -t nat -F && sudo iptables -t mangle -F && sudo iptables -X sudo ipvsadm -C -``` - -# TODO - -## Deploy using Terraform - -https://registry.terraform.io/providers/hashicorp/kubernetes/latest/docs/guides/getting-started - -```shell -terraform plan -terraform apply -``` - +``` \ No newline at end of file diff --git a/apps/arr/00-arr.yaml b/apps/arr/00-arr.yaml new file mode 100644 index 0000000..f685766 --- /dev/null +++ b/apps/arr/00-arr.yaml @@ -0,0 +1,404 @@ +--- +## Namespace +apiVersion: v1 +kind: Namespace +metadata: + name: arr + labels: + name: arr +--- +# Qbittorrent +--- +## Service for exposing Qbittorrent +apiVersion: v1 +kind: Service +metadata: + namespace: arr + name: qbittorrent +spec: + type: LoadBalancer + ports: + - name: web + port: 8112 + - name: a + port: 11010 + protocol: TCP + - name: b + port: 11011 + protocol: TCP + - name: c + port: 11012 + protocol: TCP + - name: d + port: 11013 + protocol: TCP + - name: e + port: 11014 + protocol: TCP + - name: f + port: 11015 + protocol: TCP + - name: a1 + port: 11010 + protocol: UDP + - name: b1 + port: 11011 + protocol: UDP + - name: c1 + port: 11012 + protocol: UDP + - name: d1 + port: 11013 + protocol: UDP + - name: e1 + port: 11014 + protocol: UDP + - name: f1 + port: 11015 + protocol: UDP + selector: + app: qbittorrent +--- +## Deployment for Sonarr +kind: Deployment +apiVersion: apps/v1 +metadata: + namespace: arr + name: qbittorrent + labels: + app: qbittorrent +spec: + replicas: 1 + selector: + matchLabels: + app: qbittorrent + template: + metadata: + labels: + app: qbittorrent + spec: + volumes: + - name: qbittorrent-config + hostPath: + path: "/mnt/sdb1/homelab/config/qbittorrent" + - name: media-data + hostPath: + path: "/mnt/sdb1/data" + containers: + - name: qbittorrent + image: lscr.io/linuxserver/qbittorrent:14.3.9.99202110311443-7435-01519b5e7ubuntu20.04.1-ls166 + volumeMounts: + - mountPath: "/config" + name: qbittorrent-config + - mountPath: "/app/data" + name: media-data + env: + - name: PUID + value: "1000" + - name: PGID + value: "1000" + - name: TZ + value: Europe/Oslo + - name: WEBUI_PORT + value: "8112" + ports: + - name: web + containerPort: 8112 + - containerPort: 11010 + protocol: TCP + - containerPort: 11011 + protocol: TCP + - containerPort: 11012 + protocol: TCP + - containerPort: 11013 + protocol: TCP + - containerPort: 11014 + protocol: TCP + - containerPort: 11015 + protocol: TCP + - containerPort: 11010 + protocol: UDP + - containerPort: 11011 + protocol: UDP + - containerPort: 11012 + protocol: UDP + - containerPort: 11013 + protocol: UDP + - containerPort: 11014 + protocol: UDP + - containerPort: 11015 + protocol: UDP +--- +# Prowlarr +--- +## Service for exposing Prowlarr +apiVersion: v1 +kind: Service +metadata: + namespace: arr + name: prowlarr +spec: + type: LoadBalancer + ports: + - name: web + port: 9696 + selector: + app: prowlarr +--- +## Deployment for Prowlarr +kind: Deployment +apiVersion: apps/v1 +metadata: + namespace: arr + name: prowlarr + labels: + app: prowlarr +spec: + replicas: 1 + selector: + matchLabels: + app: prowlarr + template: + metadata: + labels: + app: prowlarr + spec: + volumes: + - name: prowlarr-config + hostPath: + path: "/mnt/sdb1/homelab/config/prowlarr" + containers: + - name: prowlarr + image: lscr.io/linuxserver/prowlarr:develop + volumeMounts: + - mountPath: "/config" + name: prowlarr-config + env: + - name: PUID + value: "1000" + - name: PGID + value: "1000" + - name: TZ + value: Europe/Oslo + ports: + - name: web + containerPort: 9696 +--- +# Sonarr +--- +## Service for exposing Sonarr +apiVersion: v1 +kind: Service +metadata: + namespace: arr + name: sonarr +spec: + type: LoadBalancer + ports: + - name: web + port: 8989 + selector: + app: sonarr +--- +## Deployment for Sonarr +kind: Deployment +apiVersion: apps/v1 +metadata: + namespace: arr + name: sonarr + labels: + app: sonarr +spec: + replicas: 1 + selector: + matchLabels: + app: sonarr + template: + metadata: + labels: + app: sonarr + spec: + volumes: + - name: sonarr-config + hostPath: + path: "/mnt/sdb1/homelab/config/sonarr" + - name: media-data + hostPath: + path: "/mnt/sdb1/data" + containers: + - name: sonarr + image: lscr.io/linuxserver/sonarr + volumeMounts: + - mountPath: "/config" + name: sonarr-config + - mountPath: "/app/data" + name: media-data + env: + - name: PUID + value: "1000" + - name: PGID + value: "1000" + - name: TZ + value: Europe/Oslo + ports: + - name: web + containerPort: 8989 +--- +# Radarr +--- +## Service for exposing Radarr +apiVersion: v1 +kind: Service +metadata: + namespace: arr + name: radarr +spec: + type: LoadBalancer + ports: + - name: web + port: 7878 + selector: + app: radarr +--- +## Deployment for Radarr +kind: Deployment +apiVersion: apps/v1 +metadata: + namespace: arr + name: radarr + labels: + app: radarr +spec: + replicas: 1 + selector: + matchLabels: + app: radarr + template: + metadata: + labels: + app: radarr + spec: + volumes: + - name: radarr-config + hostPath: + path: "/mnt/sdb1/homelab/config/radarr" + - name: media-data + hostPath: + path: "/mnt/sdb1/data" + containers: + - name: radarr + image: lscr.io/linuxserver/radarr + volumeMounts: + - mountPath: "/config" + name: radarr-config + - mountPath: "/app/data" + name: media-data + env: + - name: PUID + value: "1000" + - name: PGID + value: "1000" + - name: TZ + value: Europe/Oslo + ports: + - name: web + containerPort: 7878 +--- +# Lidarr +--- +## Service for exposing Lidarr +apiVersion: v1 +kind: Service +metadata: + namespace: arr + name: lidarr +spec: + type: LoadBalancer + ports: + - name: web + port: 8686 + selector: + app: lidarr +--- +## Deployment for Lidarr +kind: Deployment +apiVersion: apps/v1 +metadata: + namespace: arr + name: lidarr + labels: + app: lidarr +spec: + replicas: 1 + selector: + matchLabels: + app: lidarr + template: + metadata: + labels: + app: lidarr + spec: + volumes: + - name: lidarr-config + hostPath: + path: "/mnt/sdb1/homelab/config/lidarr" + - name: media-data + hostPath: + path: "/mnt/sdb1/data" + containers: + - name: lidarr + image: lscr.io/linuxserver/lidarr + volumeMounts: + - mountPath: "/config" + name: lidarr-config + - mountPath: "/app/data" + name: media-data + env: + - name: PUID + value: "1000" + - name: PGID + value: "1000" + - name: TZ + value: Europe/Oslo + ports: + - name: web + containerPort: 8686 +--- +## IngressRoute +--- +apiVersion: traefik.containo.us/v1alpha1 +kind: IngressRoute +metadata: + name: ingressroute-arr + namespace: arr +spec: + entryPoints: + - websecure + routes: + - match: Host(`torrent.stonegarden.dev`) + kind: Rule + services: + - name: qbittorrent + port: 8112 + - match: Host(`prowlarr.stonegarden.dev`) + kind: Rule + services: + - name: prowlarr + port: 9696 + - match: Host(`sonarr.stonegarden.dev`) + kind: Rule + services: + - name: sonarr + port: 8989 + - match: Host(`radarr.stonegarden.dev`) + kind: Rule + services: + - name: radarr + port: 7878 + - match: Host(`lidarr.stonegarden.dev`) + kind: Rule + services: + - name: lidarr + port: 8686 + tls: + certResolver: letsencrypt \ No newline at end of file diff --git a/apps/plex/00-plex.yaml b/apps/plex/00-plex.yaml new file mode 100644 index 0000000..0d5d287 --- /dev/null +++ b/apps/plex/00-plex.yaml @@ -0,0 +1,227 @@ +--- +## Namespace +apiVersion: v1 +kind: Namespace +metadata: + name: plex + labels: + name: plex + +--- +### StorageClass for config +#apiVersion: storage.k8s.io/v1 +#kind: StorageClass +#metadata: +# name: plex-config +#provisioner: kubernetes.io/no-provisioner +#volumeBindingMode: WaitForFirstConsumer +#--- +### Config +#apiVersion: v1 +#kind: PersistentVolume +#metadata: +# name: plex-config-pv +#spec: +# capacity: +# storage: 2Gi +# volumeMode: Filesystem +# accessModes: +# - ReadWriteOnce +# persistentVolumeReclaimPolicy: Retain +# storageClassName: plex-config +# local: +# path: "/mnt/sdb1/homelab/config/plex" +# nodeAffinity: +# required: +# nodeSelectorTerms: +# - matchExpressions: +# - key: kubernetes.io/hostname +# operator: In +# values: +# - ratatoskr +#--- +### Persistent Volume Claim for config +#apiVersion: v1 +#kind: PersistentVolumeClaim +#metadata: +# name: plex-config +#spec: +# storageClassName: plex-config +# accessModes: +# - ReadWriteOnce +# resources: +# requests: +# storage: 2Gi +#--- +### StorageClass for media-data +#apiVersion: storage.k8s.io/v1 +#kind: StorageClass +#metadata: +# name: media-data +#provisioner: kubernetes.io/no-provisioner +#volumeBindingMode: WaitForFirstConsumer +#--- +### PersistentVolume for media-data +#apiVersion: v1 +#kind: PersistentVolume +#metadata: +# name: media-data-pv +#spec: +# capacity: +# storage: 1.8Ti +# volumeMode: Filesystem +# accessModes: +# - ReadWriteOnce +# persistentVolumeReclaimPolicy: Retain +# storageClassName: media-data +# local: +# path: "/mnt/sdb1/data" +# nodeAffinity: +# required: +# nodeSelectorTerms: +# - matchExpressions: +# - key: kubernetes.io/hostname +# operator: In +# values: +# - ratatoskr +#--- +### Persistent Volume Claim for media-data +#apiVersion: v1 +#kind: PersistentVolumeClaim +#metadata: +# name: media-data +#spec: +# storageClassName: media-data +# accessModes: +# - ReadWriteOnce +# resources: +# requests: +# storage: 1.8Ti +--- +## Service for exposing Plex +apiVersion: v1 +kind: Service +metadata: + namespace: plex + name: plex +spec: + type: LoadBalancer + ports: + - name: web + port: 32400 + - name: a + port: 1900 + protocol: UDP + - name: b + port: 3005 + - name: c + port: 8324 + - name: d + port: 32410 + protocol: UDP + - name: e + port: 32412 + protocol: UDP + - name: f + port: 32413 + protocol: UDP + - name: g + port: 32414 + protocol: UDP + - name: h + port: 32469 + selector: + app: plex +--- +## Deployment for Plex +kind: Deployment +apiVersion: apps/v1 +metadata: + namespace: plex + name: plex + labels: + app: plex +spec: + replicas: 1 + selector: + matchLabels: + app: plex + template: + metadata: + labels: + app: plex + spec: + volumes: + - name: plex-config + hostPath: + path: "/mnt/sdb1/homelab/config/plex" + - name: media-data + hostPath: + path: "/mnt/sdb1/data" + #- name: plex-config-pv + # persistentVolumeClaim: + # claimName: plex-config + #- name: media-data-pv + # persistentVolumeClaim: + # claimName: media-data + containers: + - name: plex + image: lscr.io/linuxserver/plex + volumeMounts: + - mountPath: "/config" + name: plex-config + - mountPath: "/app/data" + name: media-data + #- mountPath: "/config" + # name: plex-config-pv + #- mountPath: "/app/data" + # name: media-data-pv + env: + - name: PUID + value: "1000" + - name: PGID + value: "1000" + - name: TZ + value: Europe/Oslo + ports: + - name: web + containerPort: 32400 + - name: a + containerPort: 1900 + protocol: UDP + - name: b + containerPort: 3005 + - name: c + containerPort: 8324 + - name: d + containerPort: 32410 + protocol: UDP + - name: e + containerPort: 32412 + protocol: UDP + - name: f + containerPort: 32413 + protocol: UDP + - name: g + containerPort: 32414 + protocol: UDP + - name: h + containerPort: 32469 +--- +## IngressRoute for Plex +apiVersion: traefik.containo.us/v1alpha1 +kind: IngressRoute +metadata: + name: ingressroute-plex + namespace: plex +spec: + entryPoints: + - websecure + routes: + - match: Host(`plex.stonegarden.dev`) + kind: Rule + services: + - name: plex + port: 32400 + tls: + certResolver: letsencrypt diff --git a/whoami/00-whoami.yml b/apps/whoami/00-whoami.yml similarity index 82% rename from whoami/00-whoami.yml rename to apps/whoami/00-whoami.yml index b74732f..7157494 100644 --- a/whoami/00-whoami.yml +++ b/apps/whoami/00-whoami.yml @@ -1,11 +1,18 @@ +# Namespace for whoami +apiVersion: v1 +kind: Namespace +metadata: + name: whoami + label: + name: whoami + --- # Service for exposing deployment of whoami apiVersion: v1 kind: Service metadata: - namespace: default + namespace: whoami name: whoami - spec: type: LoadBalancer ports: @@ -20,11 +27,10 @@ spec: kind: Deployment apiVersion: apps/v1 metadata: - namespace: default + namespace: whoami name: whoami labels: app: whoami - spec: replicas: 2 selector: @@ -47,8 +53,8 @@ spec: apiVersion: traefik.containo.us/v1alpha1 kind: IngressRoute metadata: - name: ingressroutetls - namespace: default + name: ingressroute-whoami + namespace: whoami spec: entryPoints: - websecure diff --git a/metallb/00-manifest.yml b/infra/metallb/00-manifest.yml similarity index 100% rename from metallb/00-manifest.yml rename to infra/metallb/00-manifest.yml diff --git a/metallb/01-configuration.yml b/infra/metallb/01-configuration.yml similarity index 100% rename from metallb/01-configuration.yml rename to infra/metallb/01-configuration.yml diff --git a/volumes/volumes.yml b/infra/volumes/00-traefik.yml similarity index 96% rename from volumes/volumes.yml rename to infra/volumes/00-traefik.yml index 4f16400..4959329 100644 --- a/volumes/volumes.yml +++ b/infra/volumes/00-traefik.yml @@ -8,7 +8,7 @@ volumeBindingMode: WaitForFirstConsumer apiVersion: v1 kind: PersistentVolume metadata: - name: traefik-certs-pv + name: traefik-cert-pv spec: capacity: storage: 128Mi diff --git a/whoami/01-whoami2.yml b/whoami/01-whoami2.yml deleted file mode 100644 index 845cfcd..0000000 --- a/whoami/01-whoami2.yml +++ /dev/null @@ -1,68 +0,0 @@ -# Namespace for whoami -apiVersion: v1 -kind: Namespace -metadata: - name: whoami - ---- -# Service for exposing deployment of whoami -apiVersion: v1 -kind: Service -metadata: - namespace: whoami - name: whoami - -spec: - type: LoadBalancer - ports: - - protocol: TCP - name: web - port: 80 - selector: - app: whoami - ---- -# Deployment of whoami -kind: Deployment -apiVersion: apps/v1 -metadata: - namespace: whoami - name: whoami - labels: - app: whoami - -spec: - replicas: 2 - selector: - matchLabels: - app: whoami - template: - metadata: - labels: - app: whoami - spec: - containers: - - name: whoami - image: traefik/whoami - ports: - - name: web - containerPort: 80 - ---- -# IngressRoute for secure whoami address -apiVersion: traefik.containo.us/v1alpha1 -kind: IngressRoute -metadata: - name: ingressroutetls - namespace: whoami -spec: - entryPoints: - - websecure - routes: - - match: Host(`whoami2.stonegarden.dev`) - kind: Rule - services: - - name: whoami - port: 80 - tls: - certResolver: letsencrypt \ No newline at end of file