2020-09-01 15:44:43 +00:00
*TODO: Files with sensitive data; move to Vault*
```
# line 6-8: services/Guacamole/configMap_Guacamole.yml
```
# Kubernetes.K3s.installLog
*3 VM's provisioned with Ubuntu Server 18.04*
2020-12-15 18:54:02 +00:00
< details > < summary > additional lvm configuration< / summary >
2021-01-13 11:38:38 +00:00
```shell
2020-12-15 18:54:02 +00:00
pvdisplay
pvcreate /dev/sdb
vgdisplay
vgcreate longhorn-vg /dev/sdb
lvdisplay
lvcreate -l 100%FREE -n longhorn-lv longhorn-vg
ls /dev/mapper
mkfs.ext4 /dev/mapper/longhorn--vg-longhorn--lv
#! add "UUID=<uuid> /mnt/blockstorage ext4 defaults 0 0" to /etc/fstab
mkdir /mnt/blockstorage
mount -a
```
< / details >
2020-09-01 15:44:43 +00:00
2021-06-14 14:42:22 +00:00
## K3s cluster
2020-09-01 15:44:43 +00:00
On first node:
2021-01-13 11:38:38 +00:00
```shell
2020-12-08 07:54:12 +00:00
curl -sfL https://get.k3s.io | sh -s - --disable local-path,traefik
2020-09-01 15:44:43 +00:00
cat /var/lib/rancher/k3s/server/token
kubectl config view --raw
```
On subsequent nodes:
2021-01-13 11:38:38 +00:00
```shell
2020-11-14 22:57:19 +00:00
curl -sfL https://get.k3s.io | K3S_URL=https://< fqdn or ip > :6443 K3S_TOKEN=< value from master > sh -
2020-09-01 15:44:43 +00:00
```
2020-11-15 16:19:26 +00:00
### 0) Configure automatic updates
2020-09-01 15:44:43 +00:00
Install Rancher's [System Upgrade Controller ](https://rancher.com/docs/k3s/latest/en/upgrades/automated/ ):
2021-01-13 11:38:38 +00:00
```shell
2020-10-16 07:10:23 +00:00
kubectl apply -f https://github.com/rancher/system-upgrade-controller/releases/download/v0.6.2/system-upgrade-controller.yaml
2020-09-01 15:44:43 +00:00
```
Apply a [server (master node) ](https://code.spamasaurus.com/djpbessems/Kubernetes.K3s.installLog/src/branch/master/system/UpgradeController/plan-Server.yml ) and [agent (worker node) ](https://code.spamasaurus.com/djpbessems/Kubernetes.K3s.installLog/src/branch/master/system/UpgradeController/plan-Agent.yml ) plan:
2021-01-13 11:38:38 +00:00
```shell
2020-09-01 15:44:43 +00:00
kubectl apply -f system/UpgradeController/plan-Server.yml -f system/UpgradeController/plan-Agent.yml
```
### 1) Persistent storage
2020-09-23 13:50:31 +00:00
#### 1.1) `storageClass` for SMB (CIFS):
2020-09-23 13:35:17 +00:00
See https://github.com/kubernetes-csi/csi-driver-smb:
2021-01-13 11:38:38 +00:00
```shell
2020-09-23 13:35:17 +00:00
curl -skSL https://raw.githubusercontent.com/kubernetes-csi/csi-driver-smb/master/deploy/install-driver.sh | bash -s master --
```
2020-11-10 16:37:52 +00:00
Store credentials in `secret` :
2021-01-13 11:38:38 +00:00
```shell
2020-11-10 16:37:52 +00:00
kubectl create secret generic smb-credentials --from-literal username=< < omitted > > --from-literal domain=< < omitted > > --from-literal password=< < omitted > >
```
2020-09-23 13:35:17 +00:00
2020-09-23 13:50:31 +00:00
#### 1.2) `flexVolume` for SMB (CIFS):
2021-01-13 11:38:38 +00:00
```shell
2020-09-01 15:44:43 +00:00
curl -Ls https://github.com/juliohm1978/kubernetes-cifs-volumedriver/blob/master/install.yaml -o storage/flexVolSMB/daemonSet-flexVolSMB.yml
```
Override drivername to something more sensible (see [storage/flexVolSMB/daemonSet-flexVolSMB.yml ](https://code.spamasaurus.com/djpbessems/Kubernetes.K3s.installLog/src/branch/master/storage/flexVolSMB/daemonSet-flexVolSMB.yml ))
2021-01-13 11:38:38 +00:00
```yaml
2020-09-01 15:44:43 +00:00
spec:
template:
spec:
containers:
- image: juliohm/kubernetes-cifs-volumedriver-installer:2.0
...
env:
- name: VENDOR
value: mount
- name: DRIVER
value: smb
...
```
Perform installation:
2021-01-13 11:38:38 +00:00
```shell
2020-09-01 15:44:43 +00:00
kubectl apply -f storage/flexVolSMB/daemonSet-flexVolSMB.yml
```
Wait for installation to complete (check logs of all installer-pods), then delete `daemonSet` :
2021-01-13 11:38:38 +00:00
```shell
2020-09-01 15:44:43 +00:00
kubectl delete -f storage/flexVolSMB/daemonSet-flexVolSMB.yml
```
Store credentials in `secret` :
2021-01-13 11:38:38 +00:00
```shell
2020-09-01 15:44:43 +00:00
kubectl create secret generic --type=mount/smb smb-secret --from-literal=username=< < omitted > > --from-literal=password=< < omitted > >
```
2020-09-23 13:50:31 +00:00
2020-11-14 22:57:19 +00:00
#### 1.3) `storageClass` for distributed block storage:
See [Longhorn Helm Chart ](https://longhorn.io/ ):
2021-01-13 11:38:38 +00:00
```shell
2020-11-14 22:57:19 +00:00
kubectl create namespace longhorn-system
helm repo add longhorn https://charts.longhorn.io
helm install longhorn longhorn/longhorn --namespace longhorn-system --values=storage/Longhorn/chart-values.yml
```
Expose Longhorn's dashboard through `IngressRoute` :
2021-01-13 11:38:38 +00:00
```shell
2020-11-14 22:57:19 +00:00
kubectl apply -f storage/Longhorn/ingressRoute-Longhorn.yml
```
2021-06-14 14:42:22 +00:00
Add additional `storageClass` with backup schedule:
2020-11-14 22:57:19 +00:00
***After** specifying a NFS backup target (syntax: `nfs://servername:/path/to/share` ) through Longhorn's dashboard*
2021-01-13 11:38:38 +00:00
```yaml
2020-11-14 22:57:19 +00:00
kind: StorageClass
apiVersion: storage.k8s.io/v1
metadata:
name: longhorn-dailybackup
provisioner: driver.longhorn.io
allowVolumeExpansion: true
parameters:
numberOfReplicas: "3"
staleReplicaTimeout: "2880"
fromBackup: ""
recurringJobs: '[{"name":"backup", "task":"backup", "cron":"0 0 * * *", "retain":14}]'
```
Then make this the new default `storageClass` :
2021-01-13 11:38:38 +00:00
```shell
2020-11-14 22:57:19 +00:00
kubectl patch storageclass longhorn-dailybackup -p '{"metadata": {"annotations":{"storageclass.kubernetes.io/is-default-class":"true"}}}'
2020-12-08 22:03:57 +00:00
#kubectl delete storageclass longhorn
2020-11-14 22:57:19 +00:00
```
2020-09-01 15:44:43 +00:00
### 2) Ingress Controller
##### 2.1) Create `configMap`, `secret` and `persistentVolumeClaim`
The `configMap` contains Traefik's static and dynamic config:
2021-01-13 11:38:38 +00:00
```shell
2020-11-10 16:37:52 +00:00
kubectl apply -f ingress/Traefik2.x/configMap-Traefik.yml
2020-09-01 15:44:43 +00:00
```
The `secret` contains credentials for Cloudflare's API:
2021-01-13 11:38:38 +00:00
```shell
2020-09-01 15:44:43 +00:00
kubectl create secret generic traefik-cloudflare --from-literal=CF_API_EMAIL=< < omitted > > --from-literal=CF_API_KEY=< < omitted > > --namespace kube-system
```
The `persistentVolumeClaim` will contain `/data/acme.json` (referenced as `existingClaim` ):
2021-01-13 11:38:38 +00:00
```shell
2020-11-10 16:37:52 +00:00
kubectl apply -f ingress/Traefik2.x/persistentVolumeClaim-Traefik.yml
2020-09-01 15:44:43 +00:00
```
##### 2.2) Install Helm Chart
See [Traefik 2.x Helm Chart ](https://github.com/containous/traefik-helm-chart ):
2021-01-13 11:38:38 +00:00
```shell
2020-09-01 15:44:43 +00:00
helm repo add traefik https://containous.github.io/traefik-helm-chart
helm repo update
helm install traefik traefik/traefik --namespace kube-system --values=ingress/Traefik2.x/chart-values.yml
```
##### 2.3) Replace `IngressRoute` for Traefik's dashboard:
2021-01-13 11:38:38 +00:00
```shell
2020-09-01 15:44:43 +00:00
kubectl apply -f ingress/Traefik2.x/ingressRoute-Traefik.yaml
kubectl delete ingressroute traefik-dashboard --namespace kube-system
```
### 3) Secret management
2021-06-14 14:42:22 +00:00
*Perform these steps **after** configuring persistent storage **and** ingress*
2020-09-01 15:44:43 +00:00
##### 3.1) Create `persistentVolume` and `ingressRoute`
2021-06-14 14:42:22 +00:00
*Requires specifying a `uid` & `gid` in the flexvolSMB-`persistentVolume`*
2021-01-13 11:38:38 +00:00
```shell
2020-11-10 16:37:52 +00:00
kubectl create namespace vault
2020-09-01 15:44:43 +00:00
kubectl apply -f services/Vault/persistentVolume-Vault.yml
kubectl apply -f services/Vault/ingressRoute-Vault.yml
```
##### 3.2) Install Helm Chart
2021-06-14 14:42:22 +00:00
*REMOVED; left for reference*
See [HashiCorp Vault ](https://www.vaultproject.io/docs/platform/k8s/helm/run ):
2021-01-13 11:38:38 +00:00
```shell
2020-09-01 15:44:43 +00:00
helm repo add hashicorp https://helm.releases.hashicorp.com
helm repo update
helm install vault hashicorp/vault --namespace vault --values=services/Vault/chart-values.yml
```
Configure Vault for use;
2021-06-14 14:42:22 +00:00
- ~~Enable Kubernetes authentication (see https://www.vaultproject.io/api-docs/auth/kubernetes)~~
2020-09-01 15:44:43 +00:00
- Store basic access policy template
- Enable `kv` -engine
```
# kubectl exec -n vault -it vault-0 -- sh
2020-11-10 16:37:52 +00:00
# It might be necessary to first login with an existing token:
# vault login
2020-09-01 15:44:43 +00:00
cat < < EOF > /home/vault/app-policy.hcl
path "secret*" {
capabilities = ["read"]
}
EOF
vault secrets enable -path=secret -version=2 kv
```
### 4) Services
##### 4.1) [Adminer](https://www.adminer.org/) <small>(SQL management)</small>
2021-01-13 11:38:38 +00:00
```shell
2020-11-10 16:37:52 +00:00
kubectl apply -f services/Adminer/configMap-Adminer.yml
kubectl apply -f services/Adminer/deploy-Adminer.yml
2020-09-01 15:44:43 +00:00
```
Vault configuration:
```
vault kv put secret/adminer \
sqlitepw=< value >
vault write auth/kubernetes/role/adminer \
bound_service_account_names=adminer \
bound_service_account_namespaces=default \
policies=adminer \
ttl=1h
vault policy write adminer /home/vault/app-policy.hcl
```
2021-06-14 14:42:22 +00:00
##### 4.2) [Vaultwarden](https://github.com/dani-garcia/vaultwarden) <small>(password manager)</small>
2020-09-01 15:44:43 +00:00
*Requires [mount.cifs ](https://linux.die.net/man/8/mount.cifs )' option `nobrl` *
2021-01-13 11:38:38 +00:00
```shell
2021-06-14 14:42:22 +00:00
kubectl apply -f services/Bitwarden/secret-Bitwarden.yml
2020-11-10 16:37:52 +00:00
kubectl apply -f services/Bitwarden/deploy-Bitwarden.yml
2020-09-01 15:44:43 +00:00
```
##### 4.3) [DroneCI](https://drone.io/) <small>(contineous delivery)</small>
2021-01-13 11:38:38 +00:00
```shell
2021-06-14 14:42:22 +00:00
kubectl apply -f services/DroneCI/secret-DroneCI.yml
2020-11-10 16:37:52 +00:00
kubectl apply -f services/DroneCI/deploy-DroneCI.yml
2020-09-01 15:44:43 +00:00
```
##### 4.4) [Gitea](https://gitea.io/) <small>(git repository)</small>
2021-01-13 11:38:38 +00:00
```shell
2020-11-10 16:37:52 +00:00
kubectl apply -f services/Gitea/deploy-Gitea.yml
2020-09-01 15:44:43 +00:00
```
##### 4.5) [Gotify](https://gotify.net/) <small>(notifications)</small>
2021-01-13 11:38:38 +00:00
```shell
2020-11-10 16:37:52 +00:00
kubectl apply -f services/Gotify/deploy-Gotify.yml
2020-09-01 15:44:43 +00:00
```
##### 4.6) [Guacamole](https://guacamole.apache.org/doc/gug/guacamole-docker.html) <small>(remote desktop gateway)</small>
*Requires specifying a `uid` & `gid` in both the `securityContext` of the MySQL container and the `persistentVolume` *
2021-01-13 11:38:38 +00:00
```shell
2020-11-10 16:37:52 +00:00
kubectl apply -f services/Guacamole/configMap-Guacamole.yml
kubectl apply -f services/Guacamole/deploy-Guacamole.yml
2020-09-01 15:44:43 +00:00
```
Wait for the included containers to start, then perform the following commands to initialize the database:
2021-01-13 11:38:38 +00:00
```shell
2020-09-01 15:44:43 +00:00
kubectl exec -i guacamole-< pod-id > --container guacamole -- /opt/guacamole/bin/initdb.sh --mysql > initdb.sql
kubectl exec -i guacamole-< pod-id > --container mysql -- mysql -uguacamole -pguacamole guacamole < initdb.sql
kubectl rollout restart deployment guacamole
```
2020-12-04 08:41:15 +00:00
##### 4.7) [Lighttpd](https://www.lighttpd.net/) <small>(webserver)</small>
2021-06-14 14:42:22 +00:00
*Serves various semi-containerized websites; respective webcontent is stored on fileshare*
2021-01-13 11:38:38 +00:00
```shell
2020-11-10 16:37:52 +00:00
kubectl apply -f services/Lighttpd/configMap-Lighttpd.yml
kubectl apply -f services/Lighttpd/deploy-Lighttpd.yml
2020-09-01 15:44:43 +00:00
kubectl apply -f services/Lighttpd/cronJob-Spotweb.yml
```
2021-06-14 14:42:22 +00:00
##### 4.8) PVR `namespace` <small>(automated media management)</small>
2020-10-16 07:10:23 +00:00
*Containers use shared resources to be able to interact with downloaded files*
2021-01-13 11:38:38 +00:00
```shell
2020-11-10 16:37:52 +00:00
kubectl create secret generic --type=mount/smb smb-secret --from-literal=username=< < omitted > > --from-literal=password=< < omitted > > -n pvr
2020-10-16 07:10:23 +00:00
kubectl apply -f services/PVR/persistentVolumeClaim-PVR.yml
kubectl apply -f services/PVR/storageClass-PVR.yml
```
2021-06-14 14:42:22 +00:00
###### 4.8.1) [NZBHydra](https://github.com/theotherp/nzbhydra2) <small>(index aggregator)</small>
2021-01-13 11:38:38 +00:00
```shell
2020-10-16 07:10:23 +00:00
kubectl apply -f services/PVR/deploy-NZBHydra.yml
```
2021-06-14 14:42:22 +00:00
###### 4.8.2) [Overseerr](https://overseerr.dev/) <small>(request management)</small>
```shell
kubectl apply -f services/PVR/deploy-Overseerr.yml
```
###### 4.8.3) [Plex](https://www.plex.tv/) <small>(media library)</small>
2020-11-14 22:57:19 +00:00
*Due to usage of symlinks, partially incompatible with SMB-share-backed storage*
2021-01-13 11:38:38 +00:00
```shell
2020-11-14 22:57:19 +00:00
kubectl apply -f services/PVR/deploy-Plex.yml
```
2020-11-21 14:59:09 +00:00
After deploying, Plex server needs to be *claimed* (=assigned to Plex-account):
2021-01-13 11:38:38 +00:00
```shell
2020-11-21 14:59:09 +00:00
kubectl get endpoints Plex -n PVR
```
Browse to the respective IP address (http://< nodeipaddress > :32400/web) and follow instructions.
2021-06-14 14:42:22 +00:00
###### 4.8.4) [Radarr](https://radarr.video/) <small>(movie management)</small>
2021-01-13 11:38:38 +00:00
```shell
2020-10-16 07:10:23 +00:00
kubectl apply -f services/PVR/deploy-Radarr.yml
```
2021-06-14 14:42:22 +00:00
###### 4.8.5) [Readarr](https://readarr.com/) <small>(book management)</small>
2021-01-13 11:38:38 +00:00
```shell
2020-10-16 07:10:23 +00:00
kubectl apply -f services/PVR/deploy-Readarr.yml
```
2021-06-14 14:42:22 +00:00
###### 4.8.6) [SABnzbd](https://sabnzbd.org/) <small>(download client)</small>
2021-01-13 11:38:38 +00:00
```shell
2020-10-16 07:10:23 +00:00
kubectl apply -f services/PVR/deploy-SABnzbd.yml
```
2021-06-14 14:42:22 +00:00
###### 4.8.7) [Sonarr](https://sonarr.tv/) <small>(tv management)</small>
2021-01-13 11:38:38 +00:00
```shell
2020-10-16 07:10:23 +00:00
kubectl apply -f services/PVR/deploy-Sonarr.yml
```
2021-06-14 14:42:22 +00:00
##### 4.9) [Shaarli](https://github.com/shaarli/Shaarli) <small>(bookmarks/notes)</small>
2021-01-13 11:38:38 +00:00
```shell
2020-11-10 16:37:52 +00:00
kubectl apply -f services/Shaarli/deploy-Shaarli.yml
2020-09-01 15:44:43 +00:00
```
2021-06-14 14:42:22 +00:00
##### 4.10) [Theia](https://theia-ide.org/) <small>(web IDE)</small>
2021-01-13 11:38:38 +00:00
```shell
2020-11-10 16:37:52 +00:00
kubectl apply -f services/Theia/deploy-Theia.yml
2020-09-01 15:44:43 +00:00
```
2021-06-14 14:42:22 +00:00
##### 4.11) [Traefik-Certs-Dumper](https://github.com/ldez/traefik-certs-dumper) <small>(certificate tooling)</small>
2021-01-13 11:38:38 +00:00
```shell
2020-09-01 15:44:43 +00:00
kubectl apply -f services/TraefikCertsDumper/deploy-TraefikCertsDumper.yml
```
2021-06-14 14:42:22 +00:00
##### 4.12) [Unifi-Controller]() <small>(wlan AP management)</small>
2021-01-13 11:38:38 +00:00
```shell
2020-12-08 22:03:57 +00:00
kubectl apply -f services/Unifi/deploy-Unifi.yml
```
*Change STUN port to non-default:*
2021-01-13 11:38:38 +00:00
```shell
2020-12-08 22:03:57 +00:00
kubectl exec --namespace unifi -it unifi-< uuid > -- /bin/bash
sed -e 's/# unifi.stun.port=3478/unifi.stun.port=3479/' -i /data/system.properties
exit
kubectl rollout restart deployment --namespace unifi unifi
```
*Update STUN url on devices:* < small > doesn't seem to work< / small >
2021-01-13 11:38:38 +00:00
```shell
2020-12-08 22:03:57 +00:00
ssh < username > @< ipaddress >
sed -e 's|stun://< ipaddress > |stun://< ipaddress > :3479|' -i /etc/persistent/cfg/mgmt
```
2020-09-01 15:44:43 +00:00
### 5) Miscellaneous
2021-06-14 14:42:22 +00:00
*Various notes/useful links*
2020-09-01 15:44:43 +00:00
* Replacement for [not-yet-deprecated ](https://github.com/kubernetes/kubectl/issues/151 ) `kubectl get all -A` :
2021-06-14 14:42:22 +00:00
2020-09-01 15:44:43 +00:00
kubectl get $(kubectl api-resources --verbs=list -o name | paste -sd, -) --ignore-not-found --all-namespaces
2020-11-14 22:57:19 +00:00
* `DaemonSet` to configure nodes' **sysctl** `fs.inotify.max-user-watches` :
2021-06-14 14:42:22 +00:00
2020-11-14 22:57:19 +00:00
kubectl apply -f system/InotifyMaxWatchers/daemonSet-InotifyMaxWatchers.yml
2021-01-05 13:37:30 +00:00
* Debug DNS lookups within the cluster:
2021-06-14 14:42:22 +00:00
2021-01-05 13:37:30 +00:00
kubectl run -it --rm dnsutils --restart=Never --image=gcr.io/kubernetes-e2e-test-images/dnsutils -- nslookup [-debug] [fqdn]
or
2021-06-14 14:42:22 +00:00
2021-01-05 13:37:30 +00:00
kubectl run -it --rm busybox --restart=Never --image=busybox:1.28 -- nslookup api.github.com [-debug] [fqdn]
* Delete namespaces stuck in `Terminating` state:
2021-06-14 14:42:22 +00:00
2021-01-05 13:37:30 +00:00
kubectl get namespace < name > -o json | jq -j '.spec.finalizers=null' > tmp.json
kubectl replace --raw "/api/v1/namespaces/< name > /finalize" -f ./tmp.json
rm ./tmp.json