Compare commits

2 Commits

Author SHA1 Message Date
f36e06de46 Correct pathing 2025-01-22 19:31:30 +00:00
aa2242d3bd Add all the servarr bits 2025-01-22 19:24:48 +00:00
40 changed files with 958 additions and 1058 deletions

1
.gitignore vendored
View File

@@ -1 +0,0 @@
*.agekey

View File

@@ -1,8 +1,10 @@
creation_rules: creation_rules:
- path_regex: secret.yaml$ - path_regex: secret.yaml$
encrypted_regex: ^(data|stringData)$ encrypted_regex: ^(data|stringData)$
# server vscode # tower
# kairos # k8s
age: >- # Little laptop
age1ntfcrf5fz43da6k9h4um06u8mejjsqg005jm6rwmt9wff949s58qqwx8tv, age: >-
age1tuwkrnucc6a7eplpthm980z20lq6tnxjqkarfskwsyv9t3gxxc9qw5vj7x age1ntfcrf5fz43da6k9h4um06u8mejjsqg005jm6rwmt9wff949s58qqwx8tv,
age1gnxrrychharz0cyapjhu3nnzzzhc38slwfpq5h5rsq7pphuk4q6shhx3ll,
age159065m47ffp6xveh8f4q0hwf4554wr902ecawyld7mnaa8dfnerq2q3220

View File

@@ -1,41 +0,0 @@
apiVersion: v1
kind: Secret
metadata:
name: gluetun-env
stringData:
TZ: ENC[AES256_GCM,data:1Qc++nXCtW8Cixy4uA==,iv:8DfkaFEa9w9quxnP7xOJoi7vS5JvK7rpDPEplJV4UGc=,tag:v3TMeVVltnS1wlz3HbXqig==,type:str]
VPN_SERVICE_PROVIDER: ENC[AES256_GCM,data:Cc/yqmVmNw==,iv:fWWJUUtgvcP/ILuhkkybWLrh4fLsyYjrb0bOHyTn0I0=,tag:wEqJ9VaYL/dWwQgYUDZeGg==,type:str]
VPN_TYPE: ENC[AES256_GCM,data:e3/Pr2DBFg==,iv:eQtcNh34rZMcgp8cCaUhqB/23JWGebEA7kOD76tM1iQ=,tag:m1xYFsi2ituPNnVvNWmQQw==,type:str]
SERVER_COUNTRIES: ENC[AES256_GCM,data:MC8z2bPK5yTGsOQ=,iv:dJfwfqxLdd/cedWuSlLwGZn14eW1+Im/2+MSC1ldhNM=,tag:pAKK06O8AGiG03TeRkdtWA==,type:str]
FIREWALL_INPUT_PORTS: ENC[AES256_GCM,data:lOtPRm9CDgA/soo=,iv:Prcfoqvu8OAMMIoAwC/UBzC5gyEP9J/K9e7ZcI/B4Yc=,tag:o7cltWh/RzUu2+ahL/nC3Q==,type:str]
OPENVPN_CIPHERS: ENC[AES256_GCM,data:37hTpNZms8BKA+c=,iv:6qp+Lo0GTz4DV+m2Jc2xd7R05pP4WAtpV7Xlv4swoRA=,tag:2X1frGnd9Xffmifu0uG48A==,type:str]
OPENVPN_USER: ENC[AES256_GCM,data:Ei4dvkwiBeTo4cpUB8wSzg==,iv:uDefNem9MvGBnQSxANEXc3C6iHnlxyi/CVNQvw9twN0=,tag:zaM8xIKRRp2kUiStNT+n+w==,type:str]
sops:
kms: []
gcp_kms: []
azure_kv: []
hc_vault: []
age:
- recipient: age1ntfcrf5fz43da6k9h4um06u8mejjsqg005jm6rwmt9wff949s58qqwx8tv
enc: |
-----BEGIN AGE ENCRYPTED FILE-----
YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBJMEN6dm1PTmFKbG9qRHha
MmZyRndIVStDMWFMNGw0WVNHNW9UQ050RFJRClNZc0Y1UUMzZVhtTTRuclNBT3d1
K3J5VmQxSUpLeExKNzJsQjJHZjJ2Y1EKLS0tIEFWbWlCMWpqL3BKeVRzaTIwTmJW
UDZaNDhEd0NQdHk5MUYrNG5xR2F4NzQKeswlMX0DSp2TBGMg8og0vsjqWpqdILhI
wDeMFO9+lNt61lpv0T+1DMQkqBApGuUiMQ8kh5vzUenAl+kE0ov7tw==
-----END AGE ENCRYPTED FILE-----
- recipient: age1tuwkrnucc6a7eplpthm980z20lq6tnxjqkarfskwsyv9t3gxxc9qw5vj7x
enc: |
-----BEGIN AGE ENCRYPTED FILE-----
YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBOUnNveHVWMDc4WXhjR2xz
RW5WUGViVHczd2VoVFEzajZoRkJNdGJJQldjCjE0MGtGYnhLaFpseitDOWJBK1JE
RHRUcmhodEgvOTAxbzd1UlRQYlZzQnMKLS0tIHZJUTZpSzBaYms5S3BJOE4wZ3FZ
VnBZWWUyM0xVa1kwWkJyZWVJY0orSlkKwMGLI+iBSKrkrJdca+2yp0ZmeNMPgPGr
4dK9OxPAjwXx7caK+bv+wMsAHeledga7F4KNYLXN8OhGOiF0Bi7HtA==
-----END AGE ENCRYPTED FILE-----
lastmodified: "2025-01-24T20:18:44Z"
mac: ENC[AES256_GCM,data:cqLdb0hR4KUyxZpkXoezREg5+pLxiD080+AIMKDe4uT8MxNRdBfj7d+e9reCbi4Ev9Z1Os3Ds2B/IaS5xIbiS5xm9b1FhIoOogJkIKY3YbkU2ifnvtrddQua9S3X0/JD/fJ6Dp4OFsS6cIWccahdR9plbMTXW5Ex/MZdiId6oUU=,iv:CDpY2i6QMyvvenGlxvdYYtf4p5RVd/ALndxlDnk/7cQ=,tag:IF7DmCc0tMsLTaIub+c2hQ==,type:str]
pgp: []
encrypted_regex: ^(data|stringData)$
version: 3.9.0

View File

@@ -0,0 +1,41 @@
apiVersion: v1
kind: Secret
metadata:
name: gluetun-env
stringData:
TZ: ENC[AES256_GCM,data:LJEpoJ4aVy5Qf8w7zg==,iv:IOxz/scZUCqEhasCje3X64MCddTzrtcnOp/6wg0SHEU=,tag:PTfTjdbClLj6fnXWJFedDw==,type:str]
VPN_SERVICE_PROVIDER: ENC[AES256_GCM,data:ttMPiwizhg==,iv:TmptqgLRaugwq3NiGxOvM9NdnkflNLQsYoRp8fIXq0c=,tag:fXeinqe8eUn/a+MNbiKrzw==,type:str]
VPN_TYPE: ENC[AES256_GCM,data:1GAuiUTCew==,iv:yZFHMMXt4Z4PR5tUJ0e7k8bJbjTFPY46X2AW6LB68xE=,tag:gtveZD34ZzXXHSekDPi93Q==,type:str]
SERVER_COUNTRIES: ENC[AES256_GCM,data:D6O0wIPGYMBzL28=,iv:p4RoFg0iSGrLRzkw5cbOj9F0Ty+soASiwgDbwHsn2rU=,tag:PeMGdEoYSJjKv5jkiaQn3w==,type:str]
FIREWALL_INPUT_PORTS: ENC[AES256_GCM,data:IDFDixwvkY4YG1A=,iv:FyDaKtjza6zC1g5soqhvi5MmjGV5Ap3tFBht3zx6emM=,tag:HyNwf1wRhBoRq1CaRAtH+Q==,type:str]
OPENVPN_CIPHERS: ENC[AES256_GCM,data:V/VGTVVTlCsz1dg=,iv:eK6noWENyRrR5lUd8XwuAOgKz3MX1kqY3VKwvBQy0h4=,tag:JOH3Eym5k6DiBoUgpvePoA==,type:str]
OPENVPN_USER: ENC[AES256_GCM,data:RnZRnVakr1tPraU7PF3J1Q==,iv:1cXVtF4VfYq8Y41HVndFraxoZtwM/r4EHsowfRucBko=,tag:UgkcS89V7QKOF7ZS5Qqi+g==,type:str]
sops:
kms: []
gcp_kms: []
azure_kv: []
hc_vault: []
age:
- recipient: age1ntfcrf5fz43da6k9h4um06u8mejjsqg005jm6rwmt9wff949s58qqwx8tv
enc: |
-----BEGIN AGE ENCRYPTED FILE-----
YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBpc3pXZzMraGJONnVHRGta
Y0J6aDB0R0NMWmpMSFcyTTk5bkJaU3NPUldJCjgydmdOZGdoaUVCb2F2amVndnFZ
VUgxeW1IRlRUdWRydkg4TzdSTkY5b2sKLS0tIEdCcGFBMkJ2MldMMUlsaUpoeEhF
RUhxNlF4NTRROXVMWExuNi9hRmJBMWcKkSzzsaY7I46F15Y11c+9J4EcoT7lqG83
dSdTUHsbvNBsYYGYFUkHpRr7XEgnWWecV3lpzoVYLnmvJXCwFCK8Ug==
-----END AGE ENCRYPTED FILE-----
- recipient: age1gnxrrychharz0cyapjhu3nnzzzhc38slwfpq5h5rsq7pphuk4q6shhx3ll
enc: |
-----BEGIN AGE ENCRYPTED FILE-----
YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBPVEtQbTF1eVhmM0xsd2tU
b1R5ME1PRVkrbCtTRHdFM1BWSEcrMEhEUTE4Ck5aWkQvZThOMVJpN2x2Z053WTcz
bDVnQTFhYjV0QWZJbC9KaG9IVlY0T1UKLS0tIDkxaXJVWlQrK2VqODBHY3RDTzBR
QUFpRStodHhkTmxjNEpXQ2UxSjArN0EKnzsoVUTuiJIzTlhKNCSZpPHiRRs+KSAF
cyZPHvxn+xebB0jkMF6awXhruPdKHwNeijGKTzVm2RtKgjX+2YMaUg==
-----END AGE ENCRYPTED FILE-----
lastmodified: "2024-09-13T19:04:15Z"
mac: ENC[AES256_GCM,data:gXXZVu6iVZ6wqlKe4WDpQABHoxirZ1suZnaiQ+ru4sOPEQSGr2k6qyTA4uXcxSbtiw9g3JX9N34ZB2I3jNPbS+I2sfOvEr1VWe639k9OUDcWNOMEWNjK+PIiF9x81SJab9og4Z/2mdFuRXDAG9CHX6Q/sLEbsP3vpZgXeL7Xs38=,iv:yJeJPq2InZN+ewWd4yvSPTjNNo9MSgzbbxBUHL2ZCjs=,tag:2qCHVAvsucnr8yA0dkMXkA==,type:str]
pgp: []
encrypted_regex: ^(data|stringData)$
version: 3.9.0

View File

@@ -0,0 +1,8 @@
apiVersion: kustomize.config.k8s.io/v1beta1
kind: Kustomization
resources:
- ./gluetun
- ./prowlarr
- ./sonarr
# - ./radarr
# - ./lidarr

View File

@@ -0,0 +1,69 @@
apiVersion: apps/v1
kind: Deployment
metadata:
name: lidarr
spec:
minReadySeconds: 3
revisionHistoryLimit: 5
progressDeadlineSeconds: 60
strategy:
type: Recreate
selector:
matchLabels:
app: lidarr
template:
metadata:
annotations:
prometheus.io/scrape: "true"
prometheus.io/port: "9797"
labels:
app: sonarr
spec:
containers:
- image: ghcr.io/qdm12/gluetun:latest
name: gluetun
imagePullPolicy: Always
securityContext:
capabilities:
add: ["NET_ADMIN"]
ports:
- containerPort: 8989
envFrom:
- secretRef:
name: gluetun-env
resources:
limits:
cpu: 250m
memory: 500Mi
requests:
cpu: 10m
memory: 64Mi
- name: lidarr
image: lscr.io/linuxserver/lidarr:4.0.8
imagePullPolicy: IfNotPresent
livenessProbe:
httpGet:
path: /ping
port: 8989
initialDelaySeconds: 5
timeoutSeconds: 5
readinessProbe:
httpGet:
path: /ping
port: 8989
initialDelaySeconds: 5
timeoutSeconds: 5
resources:
limits:
cpu: 1000m
memory: 2Gi
requests:
cpu: 10m
memory: 64Mi
volumeMounts:
- name: config
mountPath: /config
volumes:
- name: config
persistentVolumeClaim:
claimName: lidarr

View File

@@ -0,0 +1,16 @@
apiVersion: traefik.io/v1alpha1
kind: IngressRoute
metadata:
name: lidarr
spec:
entryPoints:
- web
routes:
- match: Host(`lidarr.k3s`)
kind: Rule
services:
- name: lidarr
namespace: apps
nativeLB: true
kind: Service
port: 8989

View File

@@ -0,0 +1,11 @@
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: lidarr
spec:
accessModes:
- ReadWriteOncePod
storageClassName: local-path
resources:
requests:
storage: 5Gi

View File

@@ -0,0 +1,12 @@
apiVersion: v1
kind: Service
metadata:
name: lidarr
spec:
type: ClusterIP
selector:
app: lidarr
ports:
- name: http
port: 8989
targetPort: 8989

View File

@@ -0,0 +1,69 @@
apiVersion: apps/v1
kind: Deployment
metadata:
name: prowlarr
spec:
minReadySeconds: 3
revisionHistoryLimit: 5
progressDeadlineSeconds: 60
strategy:
type: Recreate
selector:
matchLabels:
app: prowlarr
template:
metadata:
annotations:
prometheus.io/scrape: "true"
prometheus.io/port: "9797"
labels:
app: prowlarr
spec:
containers:
- image: ghcr.io/qdm12/gluetun:latest
name: gluetun
imagePullPolicy: Always
securityContext:
capabilities:
add: ["NET_ADMIN"]
ports:
- containerPort: 8989
envFrom:
- secretRef:
name: gluetun-env
resources:
limits:
cpu: 250m
memory: 500Mi
requests:
cpu: 10m
memory: 64Mi
- name: prowlarr
image: lscr.io/linuxserver/prowlarr:4.0.8
imagePullPolicy: IfNotPresent
livenessProbe:
httpGet:
path: /ping
port: 8989
initialDelaySeconds: 5
timeoutSeconds: 5
readinessProbe:
httpGet:
path: /ping
port: 8989
initialDelaySeconds: 5
timeoutSeconds: 5
resources:
limits:
cpu: 1000m
memory: 2Gi
requests:
cpu: 10m
memory: 64Mi
volumeMounts:
- name: config
mountPath: /config
volumes:
- name: config
persistentVolumeClaim:
claimName: prowlarr

View File

@@ -0,0 +1,16 @@
apiVersion: traefik.io/v1alpha1
kind: IngressRoute
metadata:
name: prowlarr
spec:
entryPoints:
- web
routes:
- match: Host(`prowlarr.k3s`)
kind: Rule
services:
- name: prowlarr
namespace: apps
nativeLB: true
kind: Service
port: 8989

View File

@@ -1,6 +1,7 @@
apiVersion: kustomize.config.k8s.io/v1beta1 apiVersion: kustomize.config.k8s.io/v1beta1
kind: Kustomization kind: Kustomization
namespace: apps
resources: resources:
- books.yaml - pvc.yaml
# - tv.yaml - deployment.yaml
- service.yaml
- ingress.yaml

View File

@@ -0,0 +1,11 @@
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: prowlarr
spec:
accessModes:
- ReadWriteOncePod
storageClassName: local-path
resources:
requests:
storage: 5Gi

View File

@@ -0,0 +1,12 @@
apiVersion: v1
kind: Service
metadata:
name: prowlarr
spec:
type: ClusterIP
selector:
app: prowlarr
ports:
- name: http
port: 8989
targetPort: 8989

View File

@@ -0,0 +1,69 @@
apiVersion: apps/v1
kind: Deployment
metadata:
name: radarr
spec:
minReadySeconds: 3
revisionHistoryLimit: 5
progressDeadlineSeconds: 60
strategy:
type: Recreate
selector:
matchLabels:
app: radarr
template:
metadata:
annotations:
prometheus.io/scrape: "true"
prometheus.io/port: "9797"
labels:
app: radarr
spec:
containers:
- image: ghcr.io/qdm12/gluetun:latest
name: gluetun
imagePullPolicy: Always
securityContext:
capabilities:
add: ["NET_ADMIN"]
ports:
- containerPort: 8989
envFrom:
- secretRef:
name: gluetun-env
resources:
limits:
cpu: 250m
memory: 500Mi
requests:
cpu: 10m
memory: 64Mi
- name: radarr
image: lscr.io/linuxserver/radarr:4.0.8
imagePullPolicy: IfNotPresent
livenessProbe:
httpGet:
path: /ping
port: 8989
initialDelaySeconds: 5
timeoutSeconds: 5
readinessProbe:
httpGet:
path: /ping
port: 8989
initialDelaySeconds: 5
timeoutSeconds: 5
resources:
limits:
cpu: 1000m
memory: 2Gi
requests:
cpu: 10m
memory: 64Mi
volumeMounts:
- name: config
mountPath: /config
volumes:
- name: config
persistentVolumeClaim:
claimName: radarr

View File

@@ -0,0 +1,16 @@
apiVersion: traefik.io/v1alpha1
kind: IngressRoute
metadata:
name: radarr
spec:
entryPoints:
- web
routes:
- match: Host(`radarr.k3s`)
kind: Rule
services:
- name: radarr
namespace: apps
nativeLB: true
kind: Service
port: 8989

View File

@@ -1,6 +1,7 @@
apiVersion: kustomize.config.k8s.io/v1beta1 apiVersion: kustomize.config.k8s.io/v1beta1
kind: Kustomization kind: Kustomization
namespace: kube-system
resources: resources:
- configmap.yaml - pvc.yaml
- deployment.yaml - deployment.yaml
- service.yaml
- ingress.yaml

View File

@@ -0,0 +1,11 @@
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: radarr
spec:
accessModes:
- ReadWriteOncePod
storageClassName: local-path
resources:
requests:
storage: 5Gi

View File

@@ -0,0 +1,12 @@
apiVersion: v1
kind: Service
metadata:
name: radarr
spec:
type: ClusterIP
selector:
app: radarr
ports:
- name: http
port: 8989
targetPort: 8989

View File

@@ -24,14 +24,13 @@ spec:
name: gluetun name: gluetun
imagePullPolicy: Always imagePullPolicy: Always
securityContext: securityContext:
privileged: true
capabilities: capabilities:
add: ["NET_ADMIN"] add: ["NET_ADMIN"]
ports: ports:
- containerPort: 8989 - containerPort: 8989
envFrom: envFrom:
- secretRef: - secretRef:
name: gluetun-env name: gluetun-env
resources: resources:
limits: limits:
cpu: 250m cpu: 250m
@@ -42,11 +41,6 @@ spec:
- name: sonarr - name: sonarr
image: lscr.io/linuxserver/sonarr:4.0.8 image: lscr.io/linuxserver/sonarr:4.0.8
imagePullPolicy: IfNotPresent imagePullPolicy: IfNotPresent
env:
- name: PUID
value: "1000"
- name: PGID
value: "1000"
livenessProbe: livenessProbe:
httpGet: httpGet:
path: /ping path: /ping
@@ -69,15 +63,7 @@ spec:
volumeMounts: volumeMounts:
- name: config - name: config
mountPath: /config mountPath: /config
- name: smb-tower-books
mountPath: /mnt/books
readOnly: false
volumes: volumes:
- name: config - name: config
persistentVolumeClaim: persistentVolumeClaim:
claimName: sonarr claimName: sonarr
- name: smb-tower-books
nfs:
server: 192.168.1.100
path: /mnt/user/tv
readOnly: true

View File

@@ -0,0 +1,7 @@
apiVersion: kustomize.config.k8s.io/v1beta1
kind: Kustomization
resources:
- pvc.yaml
- deployment.yaml
- service.yaml
- ingress.yaml

File diff suppressed because it is too large Load Diff

View File

@@ -24,4 +24,4 @@ spec:
prune: true prune: true
sourceRef: sourceRef:
kind: GitRepository kind: GitRepository
name: flux-system name: flux-system

View File

@@ -1,3 +1,4 @@
apiVersion: helm.toolkit.fluxcd.io/v2 apiVersion: helm.toolkit.fluxcd.io/v2
kind: HelmRelease kind: HelmRelease
metadata: metadata:
@@ -21,6 +22,6 @@ spec:
nodePathMap: [ nodePathMap: [
{ {
node: DEFAULT_PATH_FOR_NON_LISTED_NODES, node: DEFAULT_PATH_FOR_NON_LISTED_NODES,
paths: [/usr/local/data] paths: [/data]
} }
] ]

View File

@@ -1,15 +0,0 @@
apiVersion: helm.toolkit.fluxcd.io/v2
kind: HelmRelease
metadata:
name: csi-driver-smb
spec:
interval: 15m
releaseName: csi-driver-smb
chart:
spec:
chart: charts/latest/csi-driver-smb
sourceRef:
kind: GitRepository
name: csi-driver-smb-repo
targetNamespace: kube-system

View File

@@ -1,14 +0,0 @@
apiVersion: source.toolkit.fluxcd.io/v1
kind: GitRepository
metadata:
name: csi-driver-smb-repo
spec:
interval: 15m
url: https://github.com/kubernetes-csi/csi-driver-smb.git
ref:
tag: v1.16.0 #1.17.0 is broken, skip
ignore: |-
# exclude all
/*
# include charts directory
!/charts/

View File

@@ -1,8 +0,0 @@
apiVersion: kustomize.config.k8s.io/v1beta1
kind: Kustomization
namespace: kube-system
resources:
- helmrelease.yaml
- helmrepo.yaml
- secret.yaml
- ./tower-shares

View File

@@ -1,36 +0,0 @@
apiVersion: v1
kind: Secret
metadata:
name: samba-csi-tower-creds
stringData:
username: ENC[AES256_GCM,data:zbHk,iv:y5ss5LGgCYj8PMmO9T9zuNePCXSLjXZmU/EI2LfmwBw=,tag:5xdFuZHZnVzfRUIPzvZtlg==,type:str]
password: ENC[AES256_GCM,data:KIDJ,iv:6KoX5Weym87xDM0tFVFciNYxU3pz2gJ0WncvQDYiRRU=,tag:1WqoCUsIE7AKzsg8uANh7Q==,type:str]
sops:
kms: []
gcp_kms: []
azure_kv: []
hc_vault: []
age:
- recipient: age1ntfcrf5fz43da6k9h4um06u8mejjsqg005jm6rwmt9wff949s58qqwx8tv
enc: |
-----BEGIN AGE ENCRYPTED FILE-----
YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBqWWpqQ1R3Sm1GaGtkZnE3
ZXgybXNsMHd5V3ZzVHJBNHFrZVBudTZ0ZTE4Ck1lOHVPTG9XVlo5dzIvbW5rUU80
QnVCamtMdUV0bWtKUGRadVZjeEJNWjQKLS0tIHYvMEdMT2RjSXhmOHByOUw4Q2w4
OXFrVmJaNGVEakZpMFE5S25KREVtM00Kt+GH3RkMuTNXinjtR/Oub+QnM9zNbp0s
VNsDiumafmVturIzxtUMNprZRHghDRs3UMmMpRtNFfOwTo0jkE71Zg==
-----END AGE ENCRYPTED FILE-----
- recipient: age1tuwkrnucc6a7eplpthm980z20lq6tnxjqkarfskwsyv9t3gxxc9qw5vj7x
enc: |
-----BEGIN AGE ENCRYPTED FILE-----
YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBYQ04vTjdwQ2JLUTJucWh5
WFFBcndHcmxzb29kQVV0K1U3aXhFVURUWVFJCjBlNnZrOTZhY3owdEE5ZGJPQWNX
WFU2YWordVBSZk16NDlua1pBejFDeWMKLS0tIEhKZFdyRnNGdXVZSUk4eGc2LzI3
L29kdjY3dWVCcmFSNEdMaWZEejRaS0EKWl3D34w/Ik9v8s9LOtmsGTNsjzqywDqS
hSHrb9ySzcvDY9oxlgMP56dryl3/OyyrP0ACsAvf9o1bv8jUXZxCpw==
-----END AGE ENCRYPTED FILE-----
lastmodified: "2025-01-28T21:21:31Z"
mac: ENC[AES256_GCM,data:1RBIctoBp/bbjR2WTtnBDoJkerJjWOt13x9se8NOZwFO5R8oE/6/EI48j0rhAJmuJSQiljO5EJtm+pxSu+RdECXxaSnqL5a4HZ/O3Kogr1z4zL+5h9Jl+7oqdAMzDE/i/ejiC9pSq1fs5J8voWiq4O/SkPrJUk95SoTb89HRh0Y=,iv:H0UUSX9XvjqIeNvEkqCgFL9e0cbHWf/ASPERszk7Ehg=,tag:lk5bU4E2LiBZV3HJtdTb2A==,type:str]
pgp: []
encrypted_regex: ^(data|stringData)$
version: 3.9.0

View File

@@ -1,38 +0,0 @@
apiVersion: v1
kind: PersistentVolume
metadata:
annotations:
pv.kubernetes.io/provisioned-by: smb.csi.k8s.io
name: pv-smb-tower-books
spec:
capacity:
storage: 48Ti
accessModes:
- ReadWriteMany
persistentVolumeReclaimPolicy: Retain
storageClassName: smb
mountOptions:
- dir_mode=0777
- file_mode=0777
csi:
driver: smb.csi.k8s.io
# make sure this value is unique for every share in the cluster
volumeHandle: tower/books
volumeAttributes:
source: //192.168.1.100/books
nodeStageSecretRef:
name: samba-csi-tower-creds
namespace: kube-system
---
kind: PersistentVolumeClaim
apiVersion: v1
metadata:
name: pvc-smb-tower-books
spec:
accessModes:
- ReadWriteMany
resources:
requests:
storage: 48Ti
volumeName: pv-smb-tower-books
storageClassName: smb

View File

@@ -1,38 +0,0 @@
apiVersion: v1
kind: PersistentVolume
metadata:
annotations:
pv.kubernetes.io/provisioned-by: smb.csi.k8s.io
name: pv-smb-tower-tv
spec:
capacity:
storage: 48Ti
accessModes:
- ReadWriteMany
persistentVolumeReclaimPolicy: Retain
storageClassName: smb
mountOptions:
- dir_mode=0777
- file_mode=0777
csi:
driver: smb.csi.k8s.io
# make sure this value is unique for every share in the cluster
volumeHandle: tower/tv
volumeAttributes:
source: //192.168.1.100/tv
nodeStageSecretRef:
name: samba-csi-tower-creds
namespace: kube-system
---
kind: PersistentVolumeClaim
apiVersion: v1
metadata:
name: pvc-smb-tower-tv
spec:
accessModes:
- ReadWriteMany
resources:
requests:
storage: 48Ti
volumeName: pv-smb-tower-tv
storageClassName: smb

View File

@@ -1,22 +0,0 @@
apiVersion: v1
kind: ConfigMap
metadata:
name: samba-config
data:
FAIL_FAST: "true"
SAMBA_CONF_LOG_LEVEL: "2"
ACCOUNT_samba: samba
GROUPS_samba: samba
SAMBA_GLOBAL_STANZA: "map to guest = Bad User;guest account = samba;wins support = yes;load printers = no;protocol = SMB3"
SAMBA_VOLUME_CONFIG_share: |
[share]
path = /shares/data
comment = K3s share data
browseable = yes
writable = yes
read only = no
printable = no
public = yes
guest ok = yes
guest only = yes
force user = samba

View File

@@ -1,47 +0,0 @@
apiVersion: apps/v1
kind: Deployment
metadata:
name: samba
labels:
app: samba
spec:
replicas: 1
selector:
matchLabels:
app: samba
strategy:
type: Recreate
template:
metadata:
labels:
app: samba
spec:
containers:
- name: samba
image: ghcr.io/servercontainers/samba:a3.22.0-s4.21.4-r4
ports:
- containerPort: 445
resources:
limits:
cpu: 1000m
memory: 2Gi
requests:
cpu: 10m
memory: 64Mi
volumeMounts:
- mountPath: /shares/data
name: share-path
envFrom:
- configMapRef:
name: samba-config
hostNetwork: true
dnsPolicy: ClusterFirstWithHostNet
securityContext:
privileged: true
capabilities:
add: ["NET_ADMIN"]
volumes:
- name: share-path
hostPath:
path: /usr/local/data
type: DirectoryOrCreate

View File

@@ -2,11 +2,10 @@
install: install:
poweroff: true poweroff: true
image: quay.io/kairos/debian:bookworm-standard-amd64-generic-v3.3.0-k3sv1.32.0-k3s1 extra-dirs-rootfs:
- /data
image: "docker:gitea.home.joemonk.co.uk/joe/kairos-custom:1"
reset:
reboot: true
reset-persistent: true
users: users:
- name: "kairos" - name: "kairos"
@@ -30,4 +29,37 @@ stages:
- name: "Setup dns" - name: "Setup dns"
dns: dns:
nameservers: nameservers:
- 192.168.1.1 - 192.168.1.1
- name: "Set samba config"
files:
- path: /etc/samba/smb.conf
permissions: 0644
owner: 0
group: 0
content: |
[global]
workgroup = WORKGROUP
server role = standalone server
map to guest = bad user
####### Share Definitions #######
[data]
comment = Kairos File Server Share
path = /data
browseable = yes
writeable = yes
read only = no
guest ok = yes
force user = root
force group = root
public = yes
create mask = 777
force create mode = 777
security mask = 777
force security mode = 777
directory mask = 0777
force directory mode = 0777
directory security mask = 0777
force directory security mode = 0777

View File

@@ -1,83 +0,0 @@
---
apiVersion: v1
kind: Secret
metadata:
name: custom-script
namespace: system-upgrade
type: Opaque
stringData:
config.yaml: |
#cloud-config
install:
poweroff: true
image: quay.io/kairos/debian:bookworm-standard-amd64-generic-v3.3.0-k3sv1.32.0-k3s1
reset:
reboot: true
reset-persistent: true
users:
- name: "kairos"
passwd: "kairos"
groups:
- "admin"
ssh_authorized_keys:
- "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIAjAjv9cWzwoJhTlzdrDw47eIg9t51vMbXbf0he96mRK joemonk@hotmail.co.uk" # VSCode Container
- "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIFOzNQet/Vm/EXU8GR0D4I+QYIPiGL5rCKPgDPhjWKIU joemonk@hotmail.co.uk" # Laptop
# Enable K3s on the node.
k3s:
enabled: true # Set to true to enable K3s.
args:
- --disable=local-storage
stages:
boot:
- name: "Setup hostname"
hostname: "kairos"
- name: "Setup dns"
dns:
nameservers:
- 192.168.1.1
add-config-file.sh: |
#!/bin/sh
set -e
if diff /host/run/system-upgrade/secrets/custom-script/config.yaml /host/oem/90_custom.yaml >/dev/null; then
echo config present
exit 0
fi
# we can't cp, that's a symlink!
cat /host/run/system-upgrade/secrets/custom-script/config.yaml > /host/oem/90_custom.yaml
grub2-editenv /host/oem/grubenv set next_entry=statereset
sync
mount --rbind /host/dev /dev
mount --rbind /host/run /run
nsenter -i -m -t 1 -- reboot
exit 1
---
apiVersion: upgrade.cattle.io/v1
kind: Plan
metadata:
name: reset-and-reconfig
namespace: system-upgrade
spec:
concurrency: 2
# This is the version (tag) of the image.
version: "bookworm-standard-amd64-generic-v3.3.0-k3sv1.32.0-k3s1"
nodeSelector:
matchExpressions:
- { key: kubernetes.io/hostname, operator: Exists }
serviceAccountName: system-upgrade
cordon: false
upgrade:
image: quay.io/kairos/debian:bookworm-standard-amd64-generic-v3.3.0-k3sv1.32.0-k3s1
command:
- "/bin/bash"
- "-c"
args:
- bash /host/run/system-upgrade/secrets/custom-script/add-config-file.sh
secrets:
- name: custom-script
path: /host/run/system-upgrade/secrets/custom-script

View File

@@ -10,16 +10,13 @@
- Grab the latest image from https://github.com/kairos-io/kairos/releases, the image should have the format `kairos-debian-bookworm-standard-amd64-generic-v3.1.1-k3sv1.30.2+k3s1`. - Grab the latest image from https://github.com/kairos-io/kairos/releases, the image should have the format `kairos-debian-bookworm-standard-amd64-generic-v3.1.1-k3sv1.30.2+k3s1`.
The main things we're looking for are the latest debian, standard, amd64, then the versions of kairos (v3.1.1) and k3s (1.30.2). The main things we're looking for are the latest debian, standard, amd64, then the versions of kairos (v3.1.1) and k3s (1.30.2).
- Update the image at https://gitea.home.joemonk.co.uk/joe/kairos-custom to the latest kairos image and build it if additional tooling is needed in the image
- Burn to usb - Burn to usb
- Rufus can struggle with the image, Ventoy worked perfectly using the live image launch
- Boot from usb, live install and go to the config webui - Boot from usb, live install and go to the config webui
- If doing the firebat and it doesn't boot into bios or the drive, in grub press `c` then type `fwsetup` to reboot into bios
- Add the public keys to the config (from ~/.ssh - `ssh-keygen -t ed25519 -C "joemonk@hotmail.co.uk"`) - Add the public keys to the config (from ~/.ssh - `ssh-keygen -t ed25519 -C "joemonk@hotmail.co.uk"`)
- Update the image in the kairos-config to reflect the image being used, as well as any ssh keys or additional changes needed - Update the image at https://gitea.home.joemonk.co.uk/joe/kairos-custom to the latest kairos image and build it
- Put the kairos-config in, check shutdown and let it install - Update the image in the kairos-config to reflect that build
- Remove the usb & start the machine, wait for full boot - Put the kairos-config in, check the shutdown button and let it install
- ssh in with using the specific private key added in the config (i.e. from ~/.ssh - `ssh -i ./kairos kairos@192.168.1.101` or add the following to ~/.ssh/config to just use `ssh 192.168.1.101`) - Remove the usb, ssh in with using the specific private key (i.e. from ~/.ssh - `ssh -i ./kairos kairos@192.168.1.101` or add the following to ~/.ssh/config to just use `ssh 192.168.1.101`)
``` ```
Host 192.168.1.101 Host 192.168.1.101
@@ -28,24 +25,7 @@ Host 192.168.1.101
IdentityFile ~/.ssh/kairos IdentityFile ~/.ssh/kairos
``` ```
## Adding additional packages ## Adding additional
Go to https://gitea.home.joemonk.co.uk/joe/kairos-custom and add the new packages to the dockerfile
This image will be built when pushed
Follow the steps to upgrade/reinstall with the new image in the config - or just upgrade the image to the new image
## Upgrading
SSH into the server and run `sudo kairos-agent upgrade --source oci:gitea.home.joemonk.co.uk/joe/kairos-custom:3`, restart and confirm all is good then run `sudo kairos-agent upgrade --recovery --source oci:gitea.home.joemonk.co.uk/joe/kairos-custom:3` to update the recovery image too.
## Reset
A full reset is a bit of a pain, as as far as I can tell, the "normal" reset keeps the current k8s state and data, which is probably not why we're after resetting.
> :warning: This *will* delete everything.
First of all, ensure the system-update-controller is installed on kairos (run from server/pc with kairos context) - `kubectl apply -k github.com/rancher/system-upgrade-controller`
You can then modify the `kairos-reset.yaml` to include the latest images, and `kairos-config.yaml`, and apply it with `cat reset.yaml | kubectl apply -f -`
This should then take a few minutes to reset the machine and reboot, meaning we can ssh in, grab the kubeconfig and re-bootstrap flux to reinstall everything.
## Kubectl ## Kubectl
@@ -58,13 +38,7 @@ I use sops with age to encrypt keys etc in git.
Before pushing encrypted keys up, we'll need to re-encrypt them with a new key. Before pushing encrypted keys up, we'll need to re-encrypt them with a new key.
From a shell with sops and age installed, and an already known key under `$HOME/.config/sops/age/keys.txt` (or `%AppData%\sops\age\keys.txt`), create a new key in this repo `age-keygen -o age.agekey`. From a shell with sops and age installed, and an already known key under `$HOME/.config/sops/age/keys.txt` (or `%AppData%\sops\age\keys.txt`), create a new key in this repo `age-keygen -o age.agekey`.
Add that new public key to the `.sops.yaml` Add that new public key to the `.sops.yaml`, and push the secret key to the cluster with:
In fish you can updatekeys in every secret (can just change to the bash equivalent if using bash)
`for file in $(grep --include="*.yaml" -lr "sops:"); sops updatekeys -y $file; end`
Then push the secret key to the cluster with:
(This will need to be done after the initial flux bootstrap to get the namespace created, bt the keys should be updated first)
```sh ```sh
cat age.agekey | cat age.agekey |
@@ -73,13 +47,13 @@ kubectl create secret generic sops-age \
--from-file=age.agekey=/dev/stdin --from-file=age.agekey=/dev/stdin
``` ```
Delete age.agekey after sending it to the cluster. Update the encryption with `sops updatekeys`, then delete age.agekey.
### Using sops ### Using sops
#### Encrypting #### Encrypting
After creating a new secret, run `sops -e -i ./path/to/secret.yaml`. After creating a new secret, run `sops encrypt --in-place ./path/to/secret.yaml`.
#### Editing #### Editing
@@ -92,11 +66,6 @@ Install flux and everything in this repo with the following:
- `flux bootstrap git --private-key-file=/config/.ssh/gitea --url ssh://git@gitea.home.joemonk.co.uk:2222/joe/gitops.git --branch main --path=clusters/kairos` - `flux bootstrap git --private-key-file=/config/.ssh/gitea --url ssh://git@gitea.home.joemonk.co.uk:2222/joe/gitops.git --branch main --path=clusters/kairos`
### Reconcile
If changes aren't being brought across correctly (maybe the sops key has been updated after the flux bootstrap...), force a reconciliation with `flux reconcile source git flux-system`
TODO - I don't actually know if this works, or it's just a timed thing that coincides
## DNS ## DNS
We need to point a dns server to the server so we can access things via hostname rather than needing complex routing. We need to point a dns server to the server so we can access things via hostname rather than needing complex routing.
@@ -106,15 +75,8 @@ We need to point a dns server to the server so we can access things via hostname
- Make sure Services > UnboundDNS is active and working - Make sure Services > UnboundDNS is active and working
- In overrides, add the host as `*`, domain as `k3s` and value as the ip address of the server - In overrides, add the host as `*`, domain as `k3s` and value as the ip address of the server
You should be able to access `http://traefik.k3s/dashboard#/` (at the time of writing, looking to route this properly) You should be able to access `http://traefik.k3s:9000/dashboard#/` (at the time of writing, looking to route this properly)
## Grafana ## Grafana
Grab the admin user password from the `monitoring-grafana` secret Grab the admin user password from the `monitoring-grafana` secret
## Removing a PVC
After removing a pvc, you may need to force the removal by patching the finalize out
`kubectl delete pv <pv_name> --grace-period=0 --force`
`kubectl patch pv <pv_name> -p '{"metadata": {"finalizers": null}}'`