Compare commits
2
Commits
main
..
f0d89bf554
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
f0d89bf554 | ||
|
|
4359113490 |
@@ -1,32 +0,0 @@
|
|||||||
# Authentik is deployed from its official Helm chart, while this repository's
|
|
||||||
# wrapper chart also owns its PostgreSQL cluster, backups, and persistent data.
|
|
||||||
# The database is created first with Authentik disabled so the existing Docker
|
|
||||||
# database can be restored before any new server or worker touches it.
|
|
||||||
#
|
|
||||||
# Deliberately NO resources-finalizer.argocd.argoproj.io here. This Application
|
|
||||||
# owns identity data, and deleting its Git entry must not cascade into deleting
|
|
||||||
# PostgreSQL or Authentik's uploaded files.
|
|
||||||
apiVersion: argoproj.io/v1alpha1
|
|
||||||
kind: Application
|
|
||||||
metadata:
|
|
||||||
name: authentik
|
|
||||||
namespace: argocd
|
|
||||||
spec:
|
|
||||||
project: default
|
|
||||||
|
|
||||||
source:
|
|
||||||
repoURL: https://tea.ahmza.com/ahmza.com/k8s-starter-pack.git
|
|
||||||
targetRevision: main
|
|
||||||
path: apps/authentik
|
|
||||||
|
|
||||||
destination:
|
|
||||||
server: https://kubernetes.default.svc
|
|
||||||
namespace: authentik
|
|
||||||
|
|
||||||
syncPolicy:
|
|
||||||
automated:
|
|
||||||
prune: true
|
|
||||||
selfHeal: true
|
|
||||||
syncOptions:
|
|
||||||
- CreateNamespace=true
|
|
||||||
- ServerSideApply=true
|
|
||||||
@@ -1,16 +0,0 @@
|
|||||||
# The upstream Authentik chart is initially disabled. This wrapper first
|
|
||||||
# creates PostgreSQL, backup configuration, and persistent file storage so the
|
|
||||||
# existing installation can be restored before Authentik starts.
|
|
||||||
apiVersion: v2
|
|
||||||
name: authentik-app
|
|
||||||
description: Deploys Authentik with CloudNativePG and off-cluster backups
|
|
||||||
version: 0.1.0
|
|
||||||
type: application
|
|
||||||
|
|
||||||
dependencies:
|
|
||||||
- name: authentik
|
|
||||||
# Pin each release explicitly: Authentik database migrations require
|
|
||||||
# sequential, verified upgrades through every release train.
|
|
||||||
version: 2026.8.5
|
|
||||||
repository: https://charts.goauthentik.io
|
|
||||||
condition: authentikDeployment.enabled
|
|
||||||
@@ -1,18 +0,0 @@
|
|||||||
# Authentik keeps uploaded icons and branding under /data. The PostgreSQL dump
|
|
||||||
# does not include these files, so this separate Longhorn volume is restored
|
|
||||||
# from the source VM's data/ directory before Authentik is enabled.
|
|
||||||
apiVersion: v1
|
|
||||||
kind: PersistentVolumeClaim
|
|
||||||
metadata:
|
|
||||||
name: authentik-data
|
|
||||||
namespace: {{ .Release.Namespace }}
|
|
||||||
annotations:
|
|
||||||
# Uploaded files are identity-service state. Never let Argo CD prune the
|
|
||||||
# volume automatically because a template was renamed or removed.
|
|
||||||
argocd.argoproj.io/sync-options: Prune=false
|
|
||||||
spec:
|
|
||||||
accessModes:
|
|
||||||
- ReadWriteOnce
|
|
||||||
resources:
|
|
||||||
requests:
|
|
||||||
storage: 5Gi
|
|
||||||
@@ -1,103 +0,0 @@
|
|||||||
# Backups live outside the cluster so a Longhorn or cluster-wide failure does
|
|
||||||
# not remove both PostgreSQL and its recovery data. Credentials are produced by
|
|
||||||
# the encrypted SopsSecret in this chart.
|
|
||||||
apiVersion: barmancloud.cnpg.io/v1
|
|
||||||
kind: ObjectStore
|
|
||||||
metadata:
|
|
||||||
name: authentik-backups
|
|
||||||
namespace: {{ .Release.Namespace }}
|
|
||||||
spec:
|
|
||||||
retentionPolicy: 30d
|
|
||||||
configuration:
|
|
||||||
destinationPath: s3://ahmza-talos-cnpg-backups/authentik/
|
|
||||||
endpointURL: https://s3.eu-central-003.backblazeb2.com
|
|
||||||
s3Credentials:
|
|
||||||
accessKeyId:
|
|
||||||
name: backblaze-b2-credentials
|
|
||||||
key: ACCESS_KEY_ID
|
|
||||||
secretAccessKey:
|
|
||||||
name: backblaze-b2-credentials
|
|
||||||
key: ACCESS_SECRET_KEY
|
|
||||||
region:
|
|
||||||
name: backblaze-b2-credentials
|
|
||||||
key: AWS_REGION
|
|
||||||
wal:
|
|
||||||
compression: gzip
|
|
||||||
# Require Backblaze's S3-compatible SSE-B2 encryption rather than
|
|
||||||
# relying only on the bucket's default encryption policy.
|
|
||||||
encryption: AES256
|
|
||||||
maxParallel: 2
|
|
||||||
data:
|
|
||||||
compression: gzip
|
|
||||||
encryption: AES256
|
|
||||||
jobs: 2
|
|
||||||
# Backblaze implements the S3 API but does not require every optional AWS
|
|
||||||
# checksum behavior. These settings avoid incompatible optional checksums.
|
|
||||||
instanceSidecarConfiguration:
|
|
||||||
env:
|
|
||||||
- name: AWS_REQUEST_CHECKSUM_CALCULATION
|
|
||||||
value: when_required
|
|
||||||
- name: AWS_RESPONSE_CHECKSUM_VALIDATION
|
|
||||||
value: when_required
|
|
||||||
---
|
|
||||||
# One PostgreSQL instance is enough initially: Longhorn replicates its volume
|
|
||||||
# across workers and can reattach it after a node failure. A second database
|
|
||||||
# instance can be added later if shorter failover time justifies another full
|
|
||||||
# copy of the data and WAL.
|
|
||||||
apiVersion: postgresql.cnpg.io/v1
|
|
||||||
kind: Cluster
|
|
||||||
metadata:
|
|
||||||
name: authentik-postgres
|
|
||||||
namespace: {{ .Release.Namespace }}
|
|
||||||
annotations:
|
|
||||||
# Argo CD may update this database but must never delete it automatically
|
|
||||||
# merely because a manifest or parent Application was removed from Git.
|
|
||||||
argocd.argoproj.io/sync-options: Prune=false
|
|
||||||
spec:
|
|
||||||
instances: 1
|
|
||||||
imageName: >-
|
|
||||||
ghcr.io/cloudnative-pg/postgresql:16.13-202603020816-standard-trixie
|
|
||||||
|
|
||||||
bootstrap:
|
|
||||||
initdb:
|
|
||||||
database: authentik
|
|
||||||
owner: authentik
|
|
||||||
|
|
||||||
storage:
|
|
||||||
# The default StorageClass is Longhorn. Omitting storageClass here keeps the
|
|
||||||
# database on that established replicated storage path.
|
|
||||||
size: 10Gi
|
|
||||||
|
|
||||||
resources:
|
|
||||||
requests:
|
|
||||||
cpu: 250m
|
|
||||||
memory: 512Mi
|
|
||||||
limits:
|
|
||||||
cpu: "2"
|
|
||||||
memory: 2Gi
|
|
||||||
|
|
||||||
plugins:
|
|
||||||
- name: barman-cloud.cloudnative-pg.io
|
|
||||||
# CloudNativePG defaults this to true. Keeping it explicit prevents Argo
|
|
||||||
# CD from reporting harmless drift between Git and the live resource.
|
|
||||||
enabled: true
|
|
||||||
isWALArchiver: true
|
|
||||||
parameters:
|
|
||||||
barmanObjectName: authentik-backups
|
|
||||||
---
|
|
||||||
# CloudNativePG cron expressions have six fields; the leading zero is seconds.
|
|
||||||
# WAL is archived continuously, while this creates a full base backup nightly.
|
|
||||||
apiVersion: postgresql.cnpg.io/v1
|
|
||||||
kind: ScheduledBackup
|
|
||||||
metadata:
|
|
||||||
name: authentik-postgres-daily
|
|
||||||
namespace: {{ .Release.Namespace }}
|
|
||||||
spec:
|
|
||||||
schedule: "0 0 2 * * *"
|
|
||||||
immediate: false
|
|
||||||
backupOwnerReference: self
|
|
||||||
cluster:
|
|
||||||
name: authentik-postgres
|
|
||||||
method: plugin
|
|
||||||
pluginConfiguration:
|
|
||||||
name: barman-cloud.cloudnative-pg.io
|
|
||||||
@@ -1,30 +0,0 @@
|
|||||||
apiVersion: isindir.github.com/v1alpha3
|
|
||||||
kind: SopsSecret
|
|
||||||
metadata:
|
|
||||||
name: authentik-secrets
|
|
||||||
namespace: authentik
|
|
||||||
spec:
|
|
||||||
secretTemplates:
|
|
||||||
- name: authentik-secrets
|
|
||||||
data:
|
|
||||||
AUTHENTIK_SECRET_KEY: ENC[AES256_GCM,data:xwd512Zty1VmOcc79UK2MxgLG5PaSApHhhwZRkqNz2w6HbLMSx+QvbODTfIZ0pq+HfQHxQMTY5FeX7t6TKR9toI5tG6B5202Bf85U9Lph4ssVfGC7fU/2WBsdELmtJIxxPjrzpcoQBfybOaR,iv:/J5e8Ej1KmuiEaOm8lZkikx7eStmScUA6lc0civVpdY=,tag:+gxczl/b3K4KnF8LcSkHKQ==,type:str]
|
|
||||||
- name: backblaze-b2-credentials
|
|
||||||
data:
|
|
||||||
ACCESS_KEY_ID: ENC[AES256_GCM,data:4FjHGgdeDwbA22ekQr1jv2qDn+5xxEMqgB1wWanL8nXvt8EV,iv:csE6cZ0ifFFC0bq12eMGBwSuchH0u1lqbXflywoR9FY=,tag:xMhjAvxicV1nUpfBfJAKBw==,type:str]
|
|
||||||
ACCESS_SECRET_KEY: ENC[AES256_GCM,data:XWHpbgZWbfl3REQDraRMUemcRvoACdaE2hjgkcYFgpZGkSZQ3jO7/fg4tDo=,iv:bGvTZy9N/ooxykqki0WkaUMI5qORbceSjprLnUu2k1A=,tag:67LlMIj+wvhj++Li/WtEAw==,type:str]
|
|
||||||
AWS_REGION: ENC[AES256_GCM,data:TL4IGaKv2/LD1/PTL1JY0l/J+N8=,iv:JZtM2V0nwimMJaR5o7qK9Rx1FC6jTuFbknU/2qBrwYs=,tag:tUgyYeAYjEGxTAlnky679w==,type:str]
|
|
||||||
sops:
|
|
||||||
age:
|
|
||||||
- enc: |
|
|
||||||
-----BEGIN AGE ENCRYPTED FILE-----
|
|
||||||
YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSB4WDgwRkExNHhXa05hSkcy
|
|
||||||
ZVVUam44a0pVR2hTZk5oOTdWdzkvSGlWODJVCnp6REpkUWVBV2g0MXNVKzdCVG1t
|
|
||||||
aE9YQ25icitBWGJqQ3NtUjd1cCtRUk0KLS0tIHNPeFVkeFVGUlYxT3Nhd2UrVnl2
|
|
||||||
NlhTZFV1YVRSM2JJYk1WRnRiUFppMXMKtqNp3OzKTeBKWXos0+wUmn6YGEDXubtc
|
|
||||||
UPX7lOkLI6qaKg8+3HZV3x9yKgtaT32WF9faMBQhvxFMrhRR3UTTlQ==
|
|
||||||
-----END AGE ENCRYPTED FILE-----
|
|
||||||
recipient: age1udejf5qa66rd6yvj5r8dz0fjnqfh0quf4t339c3cpqr26mkx2ydq3zel07
|
|
||||||
encrypted_regex: ^(data|stringData)$
|
|
||||||
lastmodified: "2026-10-16T15:59:11Z"
|
|
||||||
mac: ENC[AES256_GCM,data:bqT+3/x/1DAgRRxjIXlxwNLiXT2f0rD7WxUk6RGBikOD0sZKBvCZVh4qTEVUIf2U6siZBgue39Gqa5eBlCCzx+rq/JxbKdsNd5klythOzmuaKSlOaIimSZLR9Ye1KJMGPkZI4G7eE5CAM17WJ5MMZDkhP9CtscRPEQ/AgHbVUSg=,iv:JqtI7n6uMkQ9lKr4oGGEA6czFtvoDrG510aLmltCdmI=,tag:1LU4a4Mlrxh8btQw4MY0eQ==,type:str]
|
|
||||||
version: 3.13.3
|
|
||||||
@@ -1,135 +0,0 @@
|
|||||||
# The trial server is enabled only after the source database and files have
|
|
||||||
# been restored. Its worker and Ingress remain disabled until cutover, which
|
|
||||||
# prevents background jobs and production traffic reaching this clone.
|
|
||||||
authentikDeployment:
|
|
||||||
enabled: true
|
|
||||||
|
|
||||||
authentik:
|
|
||||||
global:
|
|
||||||
# Server and worker share one ReadWriteOnce Longhorn volume. Recreate stops
|
|
||||||
# the old Pods before replacements start, allowing the volume to move nodes
|
|
||||||
# instead of leaving a rolling update blocked by a multi-attach error.
|
|
||||||
deploymentStrategy:
|
|
||||||
type: Recreate
|
|
||||||
|
|
||||||
# CloudNativePG generates this connection Secret. Referencing individual
|
|
||||||
# keys avoids duplicating its generated database password in Git or SOPS.
|
|
||||||
env:
|
|
||||||
- name: AUTHENTIK_POSTGRESQL__HOST
|
|
||||||
valueFrom:
|
|
||||||
secretKeyRef:
|
|
||||||
name: authentik-postgres-app
|
|
||||||
key: host
|
|
||||||
- name: AUTHENTIK_POSTGRESQL__PORT
|
|
||||||
valueFrom:
|
|
||||||
secretKeyRef:
|
|
||||||
name: authentik-postgres-app
|
|
||||||
key: port
|
|
||||||
- name: AUTHENTIK_POSTGRESQL__NAME
|
|
||||||
valueFrom:
|
|
||||||
secretKeyRef:
|
|
||||||
name: authentik-postgres-app
|
|
||||||
key: dbname
|
|
||||||
- name: AUTHENTIK_POSTGRESQL__USER
|
|
||||||
valueFrom:
|
|
||||||
secretKeyRef:
|
|
||||||
name: authentik-postgres-app
|
|
||||||
key: username
|
|
||||||
- name: AUTHENTIK_POSTGRESQL__PASSWORD
|
|
||||||
valueFrom:
|
|
||||||
secretKeyRef:
|
|
||||||
name: authentik-postgres-app
|
|
||||||
key: password
|
|
||||||
# `require` encrypts traffic to PostgreSQL without depending on a public
|
|
||||||
# CA; CloudNativePG rotates its private in-cluster certificates itself.
|
|
||||||
- name: AUTHENTIK_POSTGRESQL__SSLMODE
|
|
||||||
value: require
|
|
||||||
# Authentik 2026.8 only honors forwarded HTTPS and client-address headers
|
|
||||||
# from explicit trusted proxies. This is the smallest aggregate covering
|
|
||||||
# all current node Pod subnets, so ingress-nginx stays trusted if moved.
|
|
||||||
- name: AUTHENTIK_LISTEN__TRUSTED_PROXY_CIDRS
|
|
||||||
value: 10.244.0.0/21
|
|
||||||
|
|
||||||
# The same Longhorn claim carries three restored source directories. Each
|
|
||||||
# subPath is mounted where the upstream container expects it.
|
|
||||||
volumes:
|
|
||||||
- name: authentik-data
|
|
||||||
persistentVolumeClaim:
|
|
||||||
claimName: authentik-data
|
|
||||||
volumeMounts:
|
|
||||||
- name: authentik-data
|
|
||||||
mountPath: /data
|
|
||||||
subPath: data
|
|
||||||
- name: authentik-data
|
|
||||||
mountPath: /templates
|
|
||||||
subPath: custom-templates
|
|
||||||
- name: authentik-data
|
|
||||||
mountPath: /certs
|
|
||||||
subPath: certs
|
|
||||||
|
|
||||||
authentik:
|
|
||||||
# This SOPS-managed Secret contains the source installation's exact secret
|
|
||||||
# key, preserving encrypted configuration and existing identity semantics.
|
|
||||||
existingSecret:
|
|
||||||
secretName: authentik-secrets
|
|
||||||
|
|
||||||
# CloudNativePG supplies PostgreSQL; do not deploy the bundled database.
|
|
||||||
postgresql:
|
|
||||||
enabled: false
|
|
||||||
|
|
||||||
server:
|
|
||||||
# One server is sufficient for this homelab; Kubernetes recreates it if the
|
|
||||||
# Pod fails, while PostgreSQL and uploaded files live on persistent storage.
|
|
||||||
replicas: 1
|
|
||||||
# UID/GID 1000 matches the restored Docker files and satisfies this
|
|
||||||
# namespace's restricted Pod Security policy without running as root.
|
|
||||||
securityContext:
|
|
||||||
runAsNonRoot: true
|
|
||||||
runAsUser: 1000
|
|
||||||
runAsGroup: 1000
|
|
||||||
fsGroup: 1000
|
|
||||||
containerSecurityContext:
|
|
||||||
allowPrivilegeEscalation: false
|
|
||||||
capabilities:
|
|
||||||
drop:
|
|
||||||
- ALL
|
|
||||||
seccompProfile:
|
|
||||||
type: RuntimeDefault
|
|
||||||
resources:
|
|
||||||
requests:
|
|
||||||
cpu: 250m
|
|
||||||
memory: 512Mi
|
|
||||||
limits:
|
|
||||||
cpu: "2"
|
|
||||||
memory: 2Gi
|
|
||||||
# Route the LAN hostname through the cluster's shared ingress-nginx IP.
|
|
||||||
# DNS-01 issuance and HTTPS routing were proven against Let's Encrypt's
|
|
||||||
# staging service before switching to this browser-trusted issuer.
|
|
||||||
ingress:
|
|
||||||
enabled: true
|
|
||||||
ingressClassName: nginx
|
|
||||||
annotations:
|
|
||||||
cert-manager.io/cluster-issuer: letsencrypt-prod
|
|
||||||
hosts:
|
|
||||||
- auth.ahmza.com
|
|
||||||
tls:
|
|
||||||
- secretName: authentik-tls
|
|
||||||
hosts:
|
|
||||||
- auth.ahmza.com
|
|
||||||
|
|
||||||
worker:
|
|
||||||
# One worker handles scheduled jobs, source synchronization, email, and
|
|
||||||
# management of Kubernetes-native outposts.
|
|
||||||
replicas: 1
|
|
||||||
securityContext:
|
|
||||||
runAsNonRoot: true
|
|
||||||
runAsUser: 1000
|
|
||||||
runAsGroup: 1000
|
|
||||||
fsGroup: 1000
|
|
||||||
containerSecurityContext:
|
|
||||||
allowPrivilegeEscalation: false
|
|
||||||
capabilities:
|
|
||||||
drop:
|
|
||||||
- ALL
|
|
||||||
seccompProfile:
|
|
||||||
type: RuntimeDefault
|
|
||||||
@@ -1,26 +0,0 @@
|
|||||||
# This ArgoCD application deploys bazarr to manage subtitles for the media library
|
|
||||||
# This application pulls its image from hotio as they're generally light weight.
|
|
||||||
apiVersion: argoproj.io/v1alpha1
|
|
||||||
kind: Application
|
|
||||||
metadata:
|
|
||||||
name: bazarr
|
|
||||||
namespace: argocd
|
|
||||||
# skipping resources-finalizer.argocd.argoproj.io as it as bazaarr will create its configs
|
|
||||||
spec:
|
|
||||||
project: default
|
|
||||||
|
|
||||||
source:
|
|
||||||
repoURL: https://tea.ahmza.com/ahmza.com/k8s-starter-pack.git
|
|
||||||
targetRevision: main
|
|
||||||
path: apps/bazarr
|
|
||||||
|
|
||||||
destination:
|
|
||||||
server: https://kubernetes.default.svc
|
|
||||||
namespace: bazarr
|
|
||||||
|
|
||||||
syncPolicy:
|
|
||||||
automated:
|
|
||||||
prune: true
|
|
||||||
selfHeal: true
|
|
||||||
syncOptions:
|
|
||||||
- CreateNamespace=true
|
|
||||||
@@ -1,64 +0,0 @@
|
|||||||
# bazarr image from hotio ghcr.io/hotio/bazarr
|
|
||||||
apiVersion: apps/v1
|
|
||||||
kind: Deployment
|
|
||||||
metadata:
|
|
||||||
name: bazarr
|
|
||||||
namespace: bazarr
|
|
||||||
spec:
|
|
||||||
# not critical infrastructure a single pod should be sufficient
|
|
||||||
replicas: 1
|
|
||||||
strategy:
|
|
||||||
type: Recreate
|
|
||||||
selector:
|
|
||||||
matchLabels:
|
|
||||||
app: bazarr
|
|
||||||
template:
|
|
||||||
metadata:
|
|
||||||
labels:
|
|
||||||
app: bazarr
|
|
||||||
spec:
|
|
||||||
containers:
|
|
||||||
- name: bazarr
|
|
||||||
image: ghcr.io/hotio/bazarr:release
|
|
||||||
imagePullPolicy: Always
|
|
||||||
env:
|
|
||||||
- name: PUID
|
|
||||||
value: "1000"
|
|
||||||
- name: PGID
|
|
||||||
value: "1000"
|
|
||||||
- name: UMASK
|
|
||||||
value: "002"
|
|
||||||
- name: TZ
|
|
||||||
value: "Europe/London"
|
|
||||||
ports:
|
|
||||||
- name: http
|
|
||||||
containerPort: 6767
|
|
||||||
protocol: TCP
|
|
||||||
volumeMounts:
|
|
||||||
- name: bazarr-config
|
|
||||||
mountPath: /config
|
|
||||||
# Mount each media directory directly instead of using subPath.
|
|
||||||
# The NFS export root is not listable by root-squashed clients, so
|
|
||||||
# kubelet cannot safely prepare subPath mounts from that root.
|
|
||||||
- name: movies
|
|
||||||
mountPath: /movies
|
|
||||||
- name: tv
|
|
||||||
mountPath: /tv
|
|
||||||
- name: anime
|
|
||||||
mountPath: /anime
|
|
||||||
volumes:
|
|
||||||
- name: bazarr-config
|
|
||||||
persistentVolumeClaim:
|
|
||||||
claimName: bazarr-data
|
|
||||||
- name: movies
|
|
||||||
nfs:
|
|
||||||
server: nas.ahmza.com
|
|
||||||
path: /srv/media/Movies
|
|
||||||
- name: tv
|
|
||||||
nfs:
|
|
||||||
server: nas.ahmza.com
|
|
||||||
path: /srv/media/TVShows
|
|
||||||
- name: anime
|
|
||||||
nfs:
|
|
||||||
server: nas.ahmza.com
|
|
||||||
path: /srv/media/Anime
|
|
||||||
@@ -1,25 +0,0 @@
|
|||||||
# routes for bazarr.ahmza.com through ingress-nginx (docs/11-ingress.md)
|
|
||||||
apiVersion: networking.k8s.io/v1
|
|
||||||
kind: Ingress
|
|
||||||
metadata:
|
|
||||||
name: bazarr
|
|
||||||
namespace: bazarr
|
|
||||||
annotations:
|
|
||||||
cert-manager.io/cluster-issuer: letsencrypt-prod
|
|
||||||
spec:
|
|
||||||
tls:
|
|
||||||
- hosts:
|
|
||||||
- bazarr.ahmza.com
|
|
||||||
# cert-manager keeps this up to date. nothing to do by hand
|
|
||||||
secretName: bazarr-tls
|
|
||||||
rules:
|
|
||||||
- host: bazarr.ahmza.com
|
|
||||||
http:
|
|
||||||
paths:
|
|
||||||
- path: /
|
|
||||||
pathType: Prefix
|
|
||||||
backend:
|
|
||||||
service:
|
|
||||||
name: bazarr
|
|
||||||
port:
|
|
||||||
number: 6767
|
|
||||||
@@ -1,4 +0,0 @@
|
|||||||
apiVersion: v1
|
|
||||||
kind: Namespace
|
|
||||||
metadata:
|
|
||||||
name: bazarr
|
|
||||||
@@ -1,12 +0,0 @@
|
|||||||
# create a longhorn pvc for bazarr's config (see docs/06-longhorn.md)
|
|
||||||
apiVersion: v1
|
|
||||||
kind: PersistentVolumeClaim
|
|
||||||
metadata:
|
|
||||||
name: bazarr-data
|
|
||||||
namespace: bazarr
|
|
||||||
spec:
|
|
||||||
accessModes:
|
|
||||||
- ReadWriteOnce
|
|
||||||
resources:
|
|
||||||
requests:
|
|
||||||
storage: 2Gi
|
|
||||||
@@ -1,12 +0,0 @@
|
|||||||
apiVersion: v1
|
|
||||||
kind: Service
|
|
||||||
metadata:
|
|
||||||
name: bazarr
|
|
||||||
namespace: bazarr
|
|
||||||
spec:
|
|
||||||
selector:
|
|
||||||
app: bazarr
|
|
||||||
ports:
|
|
||||||
- name: http
|
|
||||||
port: 6767
|
|
||||||
targetPort: http
|
|
||||||
@@ -7,11 +7,3 @@ cert-manager:
|
|||||||
# separate manual step. `installCRDs` is the older, deprecated name for
|
# separate manual step. `installCRDs` is the older, deprecated name for
|
||||||
# this same setting.
|
# this same setting.
|
||||||
enabled: true
|
enabled: true
|
||||||
|
|
||||||
# Technitium serves a private, split-horizon ahmza.com zone, while DNS-01
|
|
||||||
# challenge TXT records are created in the public Cloudflare zone. Use
|
|
||||||
# public resolvers for ACME self-checks so cert-manager sees the same TXT
|
|
||||||
# record Let's Encrypt sees; ordinary Pods still use normal cluster DNS.
|
|
||||||
extraArgs:
|
|
||||||
- --dns01-recursive-nameservers-only
|
|
||||||
- --dns01-recursive-nameservers=1.1.1.1:53,8.8.8.8:53
|
|
||||||
|
|||||||
@@ -1,34 +0,0 @@
|
|||||||
# CloudNativePG manages PostgreSQL databases as Kubernetes resources. The
|
|
||||||
# companion Barman Cloud plugin sends database backups and transaction logs to
|
|
||||||
# object storage; installing both here gives future apps one shared database
|
|
||||||
# operator without forcing them to share one PostgreSQL server.
|
|
||||||
#
|
|
||||||
# Deliberately NO resources-finalizer.argocd.argoproj.io here. PostgreSQL
|
|
||||||
# clusters managed by this operator hold application data, so removing this
|
|
||||||
# Application must not cascade into a surprise deletion of database machinery.
|
|
||||||
apiVersion: argoproj.io/v1alpha1
|
|
||||||
kind: Application
|
|
||||||
metadata:
|
|
||||||
name: cloudnative-pg
|
|
||||||
namespace: argocd
|
|
||||||
spec:
|
|
||||||
project: default
|
|
||||||
|
|
||||||
source:
|
|
||||||
repoURL: https://tea.ahmza.com/ahmza.com/k8s-starter-pack.git
|
|
||||||
targetRevision: main
|
|
||||||
path: apps/cloudnative-pg
|
|
||||||
|
|
||||||
destination:
|
|
||||||
server: https://kubernetes.default.svc
|
|
||||||
namespace: cnpg-system
|
|
||||||
|
|
||||||
syncPolicy:
|
|
||||||
automated:
|
|
||||||
prune: true
|
|
||||||
selfHeal: true
|
|
||||||
syncOptions:
|
|
||||||
- CreateNamespace=true
|
|
||||||
# Both dependencies install cluster-wide CRDs. Server-side apply avoids
|
|
||||||
# annotation-size limits and lets Kubernetes handle CRD fields safely.
|
|
||||||
- ServerSideApply=true
|
|
||||||
@@ -1,19 +0,0 @@
|
|||||||
# One umbrella chart installs the PostgreSQL operator and its current backup
|
|
||||||
# plugin together. Applications create their own independent PostgreSQL
|
|
||||||
# Cluster resources; these shared controllers hold no application data.
|
|
||||||
apiVersion: v2
|
|
||||||
name: cloudnative-pg-app
|
|
||||||
description: >-
|
|
||||||
Installs CloudNativePG and the Barman Cloud object-storage backup plugin
|
|
||||||
version: 0.1.0
|
|
||||||
type: application
|
|
||||||
|
|
||||||
dependencies:
|
|
||||||
- name: cloudnative-pg
|
|
||||||
# Pin versions so an unrelated Git sync cannot silently upgrade the
|
|
||||||
# controller responsible for every PostgreSQL database in the cluster.
|
|
||||||
version: 0.29.1
|
|
||||||
repository: https://cloudnative-pg.github.io/charts
|
|
||||||
- name: plugin-barman-cloud
|
|
||||||
version: 0.8.1
|
|
||||||
repository: https://cloudnative-pg.github.io/charts
|
|
||||||
@@ -1,27 +0,0 @@
|
|||||||
# This Argo CD Application deploys Lidarr to manage the music library.
|
|
||||||
# It uses Hotio's lightweight Lidarr container image.
|
|
||||||
apiVersion: argoproj.io/v1alpha1
|
|
||||||
kind: Application
|
|
||||||
metadata:
|
|
||||||
name: lidarr
|
|
||||||
namespace: argocd
|
|
||||||
# Omit the cascading finalizer so deleting this Application does not
|
|
||||||
# automatically delete Lidarr's config-bearing PersistentVolumeClaim.
|
|
||||||
spec:
|
|
||||||
project: default
|
|
||||||
|
|
||||||
source:
|
|
||||||
repoURL: https://tea.ahmza.com/ahmza.com/k8s-starter-pack.git
|
|
||||||
targetRevision: main
|
|
||||||
path: apps/lidarr
|
|
||||||
|
|
||||||
destination:
|
|
||||||
server: https://kubernetes.default.svc
|
|
||||||
namespace: lidarr
|
|
||||||
|
|
||||||
syncPolicy:
|
|
||||||
automated:
|
|
||||||
prune: true
|
|
||||||
selfHeal: true
|
|
||||||
syncOptions:
|
|
||||||
- CreateNamespace=true
|
|
||||||
@@ -1,70 +0,0 @@
|
|||||||
# Lidarr image maintained by Hotio: ghcr.io/hotio/lidarr.
|
|
||||||
apiVersion: apps/v1
|
|
||||||
kind: Deployment
|
|
||||||
metadata:
|
|
||||||
name: lidarr
|
|
||||||
namespace: lidarr
|
|
||||||
spec:
|
|
||||||
# not critical infrastructure a single pod should be sufficient
|
|
||||||
replicas: 1
|
|
||||||
strategy:
|
|
||||||
type: Recreate
|
|
||||||
selector:
|
|
||||||
matchLabels:
|
|
||||||
app: lidarr
|
|
||||||
template:
|
|
||||||
metadata:
|
|
||||||
labels:
|
|
||||||
app: lidarr
|
|
||||||
spec:
|
|
||||||
containers:
|
|
||||||
- name: lidarr
|
|
||||||
image: ghcr.io/hotio/lidarr:release
|
|
||||||
imagePullPolicy: Always
|
|
||||||
env:
|
|
||||||
- name: PUID
|
|
||||||
value: "1000"
|
|
||||||
- name: PGID
|
|
||||||
value: "1000"
|
|
||||||
- name: UMASK
|
|
||||||
value: "002"
|
|
||||||
- name: TZ
|
|
||||||
value: "Europe/London"
|
|
||||||
ports:
|
|
||||||
- name: http
|
|
||||||
containerPort: 8686
|
|
||||||
protocol: TCP
|
|
||||||
volumeMounts:
|
|
||||||
- name: lidarr-config
|
|
||||||
mountPath: /config
|
|
||||||
# Mount each media directory directly instead of using subPath.
|
|
||||||
# The NFS export root is not listable by root-squashed clients, so
|
|
||||||
# kubelet cannot safely prepare subPath mounts from that root.
|
|
||||||
- name: music
|
|
||||||
mountPath: /music
|
|
||||||
- name: torrents
|
|
||||||
mountPath: /data/torrents
|
|
||||||
- name: usenet
|
|
||||||
mountPath: /data/usenet
|
|
||||||
- name: import
|
|
||||||
mountPath: /data/import
|
|
||||||
volumes:
|
|
||||||
- name: lidarr-config
|
|
||||||
persistentVolumeClaim:
|
|
||||||
claimName: lidarr-data
|
|
||||||
- name: music
|
|
||||||
nfs:
|
|
||||||
server: nas.ahmza.com
|
|
||||||
path: /srv/media/Music
|
|
||||||
- name: torrents
|
|
||||||
nfs:
|
|
||||||
server: nas.ahmza.com
|
|
||||||
path: /srv/media/torrents
|
|
||||||
- name: usenet
|
|
||||||
nfs:
|
|
||||||
server: nas.ahmza.com
|
|
||||||
path: /srv/media/usenet
|
|
||||||
- name: import
|
|
||||||
nfs:
|
|
||||||
server: nas.ahmza.com
|
|
||||||
path: /srv/media/import
|
|
||||||
@@ -1,25 +0,0 @@
|
|||||||
# Route lidarr.ahmza.com through ingress-nginx (docs/11-ingress.md).
|
|
||||||
apiVersion: networking.k8s.io/v1
|
|
||||||
kind: Ingress
|
|
||||||
metadata:
|
|
||||||
name: lidarr
|
|
||||||
namespace: lidarr
|
|
||||||
annotations:
|
|
||||||
cert-manager.io/cluster-issuer: letsencrypt-prod
|
|
||||||
spec:
|
|
||||||
tls:
|
|
||||||
- hosts:
|
|
||||||
- lidarr.ahmza.com
|
|
||||||
# cert-manager keeps this up to date. nothing to do by hand
|
|
||||||
secretName: lidarr-tls
|
|
||||||
rules:
|
|
||||||
- host: lidarr.ahmza.com
|
|
||||||
http:
|
|
||||||
paths:
|
|
||||||
- path: /
|
|
||||||
pathType: Prefix
|
|
||||||
backend:
|
|
||||||
service:
|
|
||||||
name: lidarr
|
|
||||||
port:
|
|
||||||
number: 8686
|
|
||||||
@@ -1,4 +0,0 @@
|
|||||||
apiVersion: v1
|
|
||||||
kind: Namespace
|
|
||||||
metadata:
|
|
||||||
name: lidarr
|
|
||||||
@@ -1,13 +0,0 @@
|
|||||||
# Store Lidarr's config on a Longhorn volume (see docs/06-longhorn.md).
|
|
||||||
apiVersion: v1
|
|
||||||
kind: PersistentVolumeClaim
|
|
||||||
metadata:
|
|
||||||
name: lidarr-data
|
|
||||||
namespace: lidarr
|
|
||||||
spec:
|
|
||||||
accessModes:
|
|
||||||
- ReadWriteOnce
|
|
||||||
resources:
|
|
||||||
requests:
|
|
||||||
# Album artwork and the music database outgrew the original 2Gi volume.
|
|
||||||
storage: 10Gi
|
|
||||||
@@ -1,12 +0,0 @@
|
|||||||
apiVersion: v1
|
|
||||||
kind: Service
|
|
||||||
metadata:
|
|
||||||
name: lidarr
|
|
||||||
namespace: lidarr
|
|
||||||
spec:
|
|
||||||
selector:
|
|
||||||
app: lidarr
|
|
||||||
ports:
|
|
||||||
- name: http
|
|
||||||
port: 8686
|
|
||||||
targetPort: http
|
|
||||||
@@ -47,7 +47,7 @@ spec:
|
|||||||
# The publishing workflow replaces this bootstrap tag with an
|
# The publishing workflow replaces this bootstrap tag with an
|
||||||
# immutable OCI digest. Never deploy the mutable latest tag after
|
# immutable OCI digest. Never deploy the mutable latest tag after
|
||||||
# bootstrap: recording the digest makes rollbacks and audits reliable.
|
# bootstrap: recording the digest makes rollbacks and audits reliable.
|
||||||
image: tea.ahmza.com/ahmza.com/mcpacks-site@sha256:c9983dd9c31562f6518388f4d66f308e00cc229264b248536db8b4be7e7845db
|
image: tea.ahmza.com/ahmza.com/mcpacks-site@sha256:276316400b26a5d50a9938694edf99bb6ea9d5cd6e0bc5b8f6ea581b0db0d5f2
|
||||||
imagePullPolicy: Always
|
imagePullPolicy: Always
|
||||||
ports:
|
ports:
|
||||||
- name: http
|
- name: http
|
||||||
|
|||||||
@@ -1,26 +0,0 @@
|
|||||||
# This ArgoCD application deploys soulsync to manage media discovery.
|
|
||||||
# The Deployment pins a reviewed SoulSync release for repeatable GitOps syncs.
|
|
||||||
apiVersion: argoproj.io/v1alpha1
|
|
||||||
kind: Application
|
|
||||||
metadata:
|
|
||||||
name: soulsync
|
|
||||||
namespace: argocd
|
|
||||||
# skipping resources-finalizer.argocd.argoproj.io as soulsync will create configs
|
|
||||||
spec:
|
|
||||||
project: default
|
|
||||||
|
|
||||||
source:
|
|
||||||
repoURL: https://tea.ahmza.com/ahmza.com/k8s-starter-pack.git
|
|
||||||
targetRevision: main
|
|
||||||
path: apps/soulsync
|
|
||||||
|
|
||||||
destination:
|
|
||||||
server: https://kubernetes.default.svc
|
|
||||||
namespace: soulsync
|
|
||||||
|
|
||||||
syncPolicy:
|
|
||||||
automated:
|
|
||||||
prune: true
|
|
||||||
selfHeal: true
|
|
||||||
syncOptions:
|
|
||||||
- CreateNamespace=true
|
|
||||||
@@ -1,117 +0,0 @@
|
|||||||
# Pin SoulSync so an upstream `latest` update cannot change the running app
|
|
||||||
# without a reviewed Git commit.
|
|
||||||
apiVersion: apps/v1
|
|
||||||
kind: Deployment
|
|
||||||
metadata:
|
|
||||||
name: soulsync
|
|
||||||
namespace: soulsync
|
|
||||||
spec:
|
|
||||||
# not critical infra, a single pod should suffice
|
|
||||||
replicas: 1
|
|
||||||
strategy:
|
|
||||||
type: Recreate
|
|
||||||
selector:
|
|
||||||
matchLabels:
|
|
||||||
app: soulsync
|
|
||||||
template:
|
|
||||||
metadata:
|
|
||||||
labels:
|
|
||||||
app: soulsync
|
|
||||||
spec:
|
|
||||||
containers:
|
|
||||||
- name: soulsync
|
|
||||||
image: boulderbadgedad/soulsync:3.5.9
|
|
||||||
imagePullPolicy: IfNotPresent
|
|
||||||
env:
|
|
||||||
- name: PUID
|
|
||||||
value: "1000"
|
|
||||||
- name: PGID
|
|
||||||
value: "1000"
|
|
||||||
- name: UMASK
|
|
||||||
value: "022"
|
|
||||||
- name: PYTHONPATH
|
|
||||||
value: "/app"
|
|
||||||
- name: SOULSYNC_CONFIG_PATH
|
|
||||||
value: "/app/config/config.json"
|
|
||||||
- name: TZ
|
|
||||||
value: "Europe/London"
|
|
||||||
ports:
|
|
||||||
# HTTPS terminates at ingress-nginx, which forwards the UI and both
|
|
||||||
# OAuth callback paths to SoulSync's main web server on this port.
|
|
||||||
- name: http
|
|
||||||
containerPort: 8008
|
|
||||||
protocol: TCP
|
|
||||||
# Kubernetes ignores the Docker image's HEALTHCHECK, so define probes
|
|
||||||
# here to keep traffic away until SoulSync has actually started and to
|
|
||||||
# restart it if its web server later stops responding.
|
|
||||||
startupProbe:
|
|
||||||
httpGet:
|
|
||||||
path: /
|
|
||||||
port: http
|
|
||||||
periodSeconds: 5
|
|
||||||
timeoutSeconds: 3
|
|
||||||
failureThreshold: 24
|
|
||||||
readinessProbe:
|
|
||||||
httpGet:
|
|
||||||
path: /
|
|
||||||
port: http
|
|
||||||
periodSeconds: 10
|
|
||||||
timeoutSeconds: 5
|
|
||||||
failureThreshold: 3
|
|
||||||
livenessProbe:
|
|
||||||
httpGet:
|
|
||||||
path: /
|
|
||||||
port: http
|
|
||||||
periodSeconds: 30
|
|
||||||
timeoutSeconds: 10
|
|
||||||
failureThreshold: 3
|
|
||||||
# Match the upstream Compose defaults: scheduling reserves enough for
|
|
||||||
# normal operation while limits protect the rest of the cluster.
|
|
||||||
resources:
|
|
||||||
requests:
|
|
||||||
cpu: 500m
|
|
||||||
memory: 512Mi
|
|
||||||
limits:
|
|
||||||
cpu: "2"
|
|
||||||
memory: 2Gi
|
|
||||||
volumeMounts:
|
|
||||||
- name: soulsync-db
|
|
||||||
mountPath: /app/data
|
|
||||||
- name: soulsync-config
|
|
||||||
mountPath: /app/config
|
|
||||||
- name: soulsync-logs
|
|
||||||
mountPath: /app/logs
|
|
||||||
- name: usenet-downloads
|
|
||||||
mountPath: /data/usenet
|
|
||||||
- name: torrent-downloads
|
|
||||||
mountPath: /data/torrents
|
|
||||||
- name: downloads
|
|
||||||
mountPath: /app/downloads
|
|
||||||
- name: music
|
|
||||||
mountPath: /app/Transfer
|
|
||||||
volumes:
|
|
||||||
- name: soulsync-db
|
|
||||||
persistentVolumeClaim:
|
|
||||||
claimName: soulsync-db
|
|
||||||
- name: soulsync-config
|
|
||||||
persistentVolumeClaim:
|
|
||||||
claimName: soulsync-config
|
|
||||||
- name: soulsync-logs
|
|
||||||
persistentVolumeClaim:
|
|
||||||
claimName: soulsync-logs
|
|
||||||
- name: usenet-downloads
|
|
||||||
nfs:
|
|
||||||
server: nas.ahmza.com
|
|
||||||
path: /srv/media/usenet
|
|
||||||
- name: torrent-downloads
|
|
||||||
nfs:
|
|
||||||
server: nas.ahmza.com
|
|
||||||
path: /srv/media/torrents
|
|
||||||
- name: downloads
|
|
||||||
nfs:
|
|
||||||
server: nas.ahmza.com
|
|
||||||
path: /srv/media/torrents
|
|
||||||
- name: music
|
|
||||||
nfs:
|
|
||||||
server: nas.ahmza.com
|
|
||||||
path: /srv/media/Music
|
|
||||||
@@ -1,28 +0,0 @@
|
|||||||
# routes for soulsync.ahmza.com through ingress-nginx (docs/11-ingress.md)
|
|
||||||
apiVersion: networking.k8s.io/v1
|
|
||||||
kind: Ingress
|
|
||||||
metadata:
|
|
||||||
name: soulsync
|
|
||||||
namespace: soulsync
|
|
||||||
annotations:
|
|
||||||
cert-manager.io/cluster-issuer: letsencrypt-prod
|
|
||||||
spec:
|
|
||||||
# Select ingress-nginx explicitly rather than relying on whichever ingress
|
|
||||||
# controller happens to be configured as the cluster-wide default.
|
|
||||||
ingressClassName: nginx
|
|
||||||
tls:
|
|
||||||
- hosts:
|
|
||||||
- soulsync.ahmza.com
|
|
||||||
# cert-manager keeps this up to date. nothing to do by hand
|
|
||||||
secretName: soulsync-tls
|
|
||||||
rules:
|
|
||||||
- host: soulsync.ahmza.com
|
|
||||||
http:
|
|
||||||
paths:
|
|
||||||
- path: /
|
|
||||||
pathType: Prefix
|
|
||||||
backend:
|
|
||||||
service:
|
|
||||||
name: soulsync
|
|
||||||
port:
|
|
||||||
number: 8008
|
|
||||||
@@ -1,4 +0,0 @@
|
|||||||
apiVersion: v1
|
|
||||||
kind: Namespace
|
|
||||||
metadata:
|
|
||||||
name: soulsync
|
|
||||||
@@ -1,41 +0,0 @@
|
|||||||
# Keep SoulSync's databases and downloaded artwork on Longhorn so they survive
|
|
||||||
# Pod replacement (see docs/06-longhorn.md).
|
|
||||||
apiVersion: v1
|
|
||||||
kind: PersistentVolumeClaim
|
|
||||||
metadata:
|
|
||||||
name: soulsync-db
|
|
||||||
namespace: soulsync
|
|
||||||
spec:
|
|
||||||
accessModes:
|
|
||||||
- ReadWriteOnce
|
|
||||||
resources:
|
|
||||||
requests:
|
|
||||||
storage: 10Gi
|
|
||||||
---
|
|
||||||
# Configuration can contain connection settings and OAuth tokens, so persist it
|
|
||||||
# without putting those credentials in this public Git repository.
|
|
||||||
apiVersion: v1
|
|
||||||
kind: PersistentVolumeClaim
|
|
||||||
metadata:
|
|
||||||
name: soulsync-config
|
|
||||||
namespace: soulsync
|
|
||||||
spec:
|
|
||||||
accessModes:
|
|
||||||
- ReadWriteOnce
|
|
||||||
resources:
|
|
||||||
requests:
|
|
||||||
storage: 1Gi
|
|
||||||
---
|
|
||||||
# Persistent logs remain available when the container is recreated and make
|
|
||||||
# failures that happened before a restart easier to diagnose.
|
|
||||||
apiVersion: v1
|
|
||||||
kind: PersistentVolumeClaim
|
|
||||||
metadata:
|
|
||||||
name: soulsync-logs
|
|
||||||
namespace: soulsync
|
|
||||||
spec:
|
|
||||||
accessModes:
|
|
||||||
- ReadWriteOnce
|
|
||||||
resources:
|
|
||||||
requests:
|
|
||||||
storage: 2Gi
|
|
||||||
@@ -1,12 +0,0 @@
|
|||||||
apiVersion: v1
|
|
||||||
kind: Service
|
|
||||||
metadata:
|
|
||||||
name: soulsync
|
|
||||||
namespace: soulsync
|
|
||||||
spec:
|
|
||||||
selector:
|
|
||||||
app: soulsync
|
|
||||||
ports:
|
|
||||||
- name: http
|
|
||||||
port: 8008
|
|
||||||
targetPort: http
|
|
||||||
@@ -1,41 +0,0 @@
|
|||||||
# Cluster metrics collection for the external VictoriaMetrics and Grafana host.
|
|
||||||
# This Application installs only collectors and Kubernetes exporters: metrics
|
|
||||||
# are sent over NetBird to prd-vps-hel-01 and are not stored in this cluster.
|
|
||||||
apiVersion: argoproj.io/v1alpha1
|
|
||||||
kind: Application
|
|
||||||
metadata:
|
|
||||||
name: victoria-metrics
|
|
||||||
namespace: argocd
|
|
||||||
# The in-cluster pieces are stateless. Cascading deletion is safe because the
|
|
||||||
# durable metrics database lives on the external VPS, not in this namespace.
|
|
||||||
finalizers:
|
|
||||||
- resources-finalizer.argocd.argoproj.io
|
|
||||||
spec:
|
|
||||||
project: default
|
|
||||||
|
|
||||||
source:
|
|
||||||
repoURL: https://tea.ahmza.com/ahmza.com/k8s-starter-pack.git
|
|
||||||
targetRevision: main
|
|
||||||
path: apps/victoria-metrics
|
|
||||||
|
|
||||||
destination:
|
|
||||||
server: https://kubernetes.default.svc
|
|
||||||
namespace: monitoring
|
|
||||||
|
|
||||||
syncPolicy:
|
|
||||||
automated:
|
|
||||||
prune: true
|
|
||||||
selfHeal: true
|
|
||||||
# node-exporter reads host kernel and filesystem metrics through hostPath,
|
|
||||||
# hostNetwork, and hostPID. Scope the required privileged Pod Security
|
|
||||||
# profile to this dedicated monitoring namespace.
|
|
||||||
managedNamespaceMetadata:
|
|
||||||
labels:
|
|
||||||
pod-security.kubernetes.io/enforce: privileged
|
|
||||||
pod-security.kubernetes.io/audit: privileged
|
|
||||||
pod-security.kubernetes.io/warn: privileged
|
|
||||||
syncOptions:
|
|
||||||
- CreateNamespace=true
|
|
||||||
# VictoriaMetrics Operator CRDs are large. Server-side apply avoids the
|
|
||||||
# client-side last-applied annotation size limit and handles CRDs first.
|
|
||||||
- ServerSideApply=true
|
|
||||||
@@ -1,13 +0,0 @@
|
|||||||
# Umbrella chart for the official VictoriaMetrics Kubernetes monitoring stack.
|
|
||||||
# Argo CD renders this dependency from Git just like the existing Longhorn and
|
|
||||||
# MetalLB wrapper charts.
|
|
||||||
apiVersion: v2
|
|
||||||
name: victoria-metrics-app
|
|
||||||
description: Forwards Kubernetes and node metrics to external VictoriaMetrics
|
|
||||||
version: 0.1.0
|
|
||||||
dependencies:
|
|
||||||
- name: victoria-metrics-k8s-stack
|
|
||||||
# Pin the exact chart version so monitoring upgrades are explicit and
|
|
||||||
# reviewable rather than changing during an unrelated Argo CD sync.
|
|
||||||
version: 0.96.0
|
|
||||||
repository: oci://ghcr.io/victoriametrics/helm-charts
|
|
||||||
@@ -1,30 +0,0 @@
|
|||||||
# Scrapes Longhorn's own metrics (volume robustness, node and disk capacity)
|
|
||||||
# so the external Grafana can alert when a volume becomes degraded or faulted.
|
|
||||||
#
|
|
||||||
# Every longhorn-manager Pod serves /metrics on its `manager` port (9500)
|
|
||||||
# behind the longhorn-backend Service. A VMServiceScrape scrapes each Pod
|
|
||||||
# behind that Service, so metrics from managers on both storage workers are
|
|
||||||
# collected, not just whichever one a load-balanced request would hit.
|
|
||||||
#
|
|
||||||
# This lives in the victoria-metrics wrapper chart rather than the Longhorn
|
|
||||||
# app because it is monitoring configuration, and it depends on the
|
|
||||||
# VMServiceScrape CRD installed by this chart's operator. Sync wave "1" makes
|
|
||||||
# Argo CD apply it only after that CRD exists on a fresh install.
|
|
||||||
apiVersion: operator.victoriametrics.com/v1beta1
|
|
||||||
kind: VMServiceScrape
|
|
||||||
metadata:
|
|
||||||
name: longhorn
|
|
||||||
namespace: monitoring
|
|
||||||
annotations:
|
|
||||||
argocd.argoproj.io/sync-wave: "1"
|
|
||||||
spec:
|
|
||||||
namespaceSelector:
|
|
||||||
matchNames:
|
|
||||||
- longhorn-system
|
|
||||||
selector:
|
|
||||||
matchLabels:
|
|
||||||
app: longhorn-manager
|
|
||||||
endpoints:
|
|
||||||
- port: manager
|
|
||||||
path: /metrics
|
|
||||||
interval: 30s
|
|
||||||
@@ -1,89 +0,0 @@
|
|||||||
# Values for the upstream victoria-metrics-k8s-stack dependency. This cluster
|
|
||||||
# collects metrics only; durable storage and visualization run on the NetBird-
|
|
||||||
# connected VPS prd-vps-hel-01.ahmza.com (NetBird address 100.71.24.9).
|
|
||||||
victoria-metrics-k8s-stack:
|
|
||||||
# Identify this source if more clusters write to the same database later.
|
|
||||||
vmagent:
|
|
||||||
enabled: true
|
|
||||||
spec:
|
|
||||||
scrapeInterval: 30s
|
|
||||||
externalLabels:
|
|
||||||
cluster: gitops-starter
|
|
||||||
resources:
|
|
||||||
requests:
|
|
||||||
cpu: 100m
|
|
||||||
memory: 128Mi
|
|
||||||
limits:
|
|
||||||
memory: 512Mi
|
|
||||||
|
|
||||||
external:
|
|
||||||
vm:
|
|
||||||
# Queries are served from the VictoriaMetrics base URL. Remote write uses
|
|
||||||
# its Prometheus-compatible ingestion endpoint. NetBird encrypts the path
|
|
||||||
# between the Talos nodes and VPS, so no public endpoint is involved.
|
|
||||||
#
|
|
||||||
# The name resolves only through internal Technitium DNS (10.10.10.10),
|
|
||||||
# where an authoritative zone maps it to the VPS's NetBird address. If
|
|
||||||
# that address changes, update Technitium rather than this file.
|
|
||||||
read:
|
|
||||||
url: http://prd-vps-hel-01.ahmza.com:8428
|
|
||||||
write:
|
|
||||||
url: http://prd-vps-hel-01.ahmza.com:8428/api/v1/write
|
|
||||||
|
|
||||||
# Storage and UI already live on prd-vps-hel-01; do not duplicate them here.
|
|
||||||
vmsingle:
|
|
||||||
enabled: false
|
|
||||||
vmcluster:
|
|
||||||
enabled: false
|
|
||||||
vmdistributed:
|
|
||||||
enabled: false
|
|
||||||
grafana:
|
|
||||||
enabled: false
|
|
||||||
|
|
||||||
# Alert delivery is a separate follow-up once notification destinations are
|
|
||||||
# chosen. Disabling it also avoids deploying rules with nowhere to notify.
|
|
||||||
vmalert:
|
|
||||||
enabled: false
|
|
||||||
alertmanager:
|
|
||||||
enabled: false
|
|
||||||
defaultRules:
|
|
||||||
enabled: false
|
|
||||||
defaultDashboards:
|
|
||||||
enabled: false
|
|
||||||
|
|
||||||
# One node-exporter Pod runs on every node, including tainted control planes.
|
|
||||||
# Talos exposes the host root filesystem read-only; mount propagation is not
|
|
||||||
# needed and can be rejected by immutable hosts, so keep it disabled.
|
|
||||||
prometheus-node-exporter:
|
|
||||||
enabled: true
|
|
||||||
hostRootFsMount:
|
|
||||||
enabled: true
|
|
||||||
mountPropagation: None
|
|
||||||
resources:
|
|
||||||
requests:
|
|
||||||
cpu: 20m
|
|
||||||
memory: 32Mi
|
|
||||||
limits:
|
|
||||||
memory: 128Mi
|
|
||||||
|
|
||||||
# Talos binds the scheduler and controller-manager metrics endpoints to
|
|
||||||
# 127.0.0.1, and runs etcd as a host service rather than a Pod. Scraping them
|
|
||||||
# from vmagent would require exposing those control-plane ports on the LAN,
|
|
||||||
# so skip them; API server, kubelet, CoreDNS, and node metrics remain.
|
|
||||||
kubeScheduler:
|
|
||||||
enabled: false
|
|
||||||
kubeControllerManager:
|
|
||||||
enabled: false
|
|
||||||
kubeEtcd:
|
|
||||||
enabled: false
|
|
||||||
|
|
||||||
# kube-state-metrics reports desired/current Kubernetes object state (for
|
|
||||||
# example unavailable Deployment replicas), complementing host metrics.
|
|
||||||
kube-state-metrics:
|
|
||||||
enabled: true
|
|
||||||
resources:
|
|
||||||
requests:
|
|
||||||
cpu: 20m
|
|
||||||
memory: 64Mi
|
|
||||||
limits:
|
|
||||||
memory: 256Mi
|
|
||||||
+3
-24
@@ -32,22 +32,6 @@ on every node.
|
|||||||
| `10.10.10.204` | `talos-vba-ood` — worker02 (Proxmox VM on Titus) | 50000 | `https://10.10.10.204:50000` |
|
| `10.10.10.204` | `talos-vba-ood` — worker02 (Proxmox VM on Titus) | 50000 | `https://10.10.10.204:50000` |
|
||||||
| `10.10.10.210` | Cluster VIP (use this one, not a node's own address) | 6443 | `https://10.10.10.210:6443` |
|
| `10.10.10.210` | Cluster VIP (use this one, not a node's own address) | 6443 | `https://10.10.10.210:6443` |
|
||||||
|
|
||||||
## NetBird overlay
|
|
||||||
|
|
||||||
These addresses exist only inside the private NetBird overlay and are subject
|
|
||||||
to NetBird access policies. All Talos nodes use the official
|
|
||||||
`siderolabs/netbird` system extension.
|
|
||||||
|
|
||||||
| Address | What | Port(s) | URL(s) |
|
|
||||||
|---|---|---|---|
|
|
||||||
| `100.71.24.9` | `prd-vps-hel-01` — external Grafana and VictoriaMetrics host; internal name `prd-vps-hel-01.ahmza.com` (authoritative zone in Technitium) | 3000, 8428 | `http://prd-vps-hel-01.ahmza.com:3000`, `http://prd-vps-hel-01.ahmza.com:8428` |
|
|
||||||
| `100.71.236.121` | `ingress1` — Caddy HTTP origin gateway used by NetBird Reverse Proxy; the WireGuard overlay encrypts this leg | 80 | `http://100.71.236.121` |
|
|
||||||
| `100.71.121.67` | `talos-455-i3b` — control plane NetBird address | 50000 | `https://100.71.121.67:50000` |
|
|
||||||
| `100.71.157.217` | `talos-9xy-iuk` — control plane NetBird address | 50000 | `https://100.71.157.217:50000` |
|
|
||||||
| `100.71.242.40` | `talos-k1b-7j5` — control plane NetBird address | 50000 | `https://100.71.242.40:50000` |
|
|
||||||
| `100.71.3.210` | `talos-rss-v5l` — worker01 NetBird address | 50000 | `https://100.71.3.210:50000` |
|
|
||||||
| `100.71.29.51` | `talos-vba-ood` — worker02 NetBird address | 50000 | `https://100.71.29.51:50000` |
|
|
||||||
|
|
||||||
## MetalLB pool
|
## MetalLB pool
|
||||||
|
|
||||||
This dedicated service range is advertised to the MikroTik at
|
This dedicated service range is advertised to the MikroTik at
|
||||||
@@ -65,7 +49,6 @@ This dedicated service range is advertised to the MikroTik at
|
|||||||
| Address | What | Namespace | Port(s) | URL | Source |
|
| Address | What | Namespace | Port(s) | URL | Source |
|
||||||
|---|---|---|---|---|---|
|
|---|---|---|---|---|---|
|
||||||
| `10.10.60.10` | Argo CD UI/API (`argocd-server`) | `argocd` | 443 | `https://10.10.60.10` | Patched to `LoadBalancer` by hand — see [`docs/05-metallb.md`](05-metallb.md) |
|
| `10.10.60.10` | Argo CD UI/API (`argocd-server`) | `argocd` | 443 | `https://10.10.60.10` | Patched to `LoadBalancer` by hand — see [`docs/05-metallb.md`](05-metallb.md) |
|
||||||
| `10.10.60.11` | Reserved for the Authentik LDAP Outpost used by Jellyfin | `authentik` | 636 | `ldaps://10.10.60.11:636` | Planned Authentik deployment; verify the address and TLS certificate before migrating Jellyfin |
|
|
||||||
| `10.10.60.12` | ingress-nginx (shared, routes by hostname) | `ingress-nginx` | 80, 443 | `http://10.10.60.12`, `https://10.10.60.12` | [`apps/ingress-nginx/values.yaml`](../apps/ingress-nginx/values.yaml) — see [`docs/11-ingress.md`](11-ingress.md) |
|
| `10.10.60.12` | ingress-nginx (shared, routes by hostname) | `ingress-nginx` | 80, 443 | `http://10.10.60.12`, `https://10.10.60.12` | [`apps/ingress-nginx/values.yaml`](../apps/ingress-nginx/values.yaml) — see [`docs/11-ingress.md`](11-ingress.md) |
|
||||||
|
|
||||||
Add a row here every time you add a new app with its own dedicated
|
Add a row here every time you add a new app with its own dedicated
|
||||||
@@ -78,17 +61,13 @@ only when it's the protocol default (80 for `http://`, 443 for `https://`)
|
|||||||
|
|
||||||
## Hostnames routed through ingress-nginx
|
## Hostnames routed through ingress-nginx
|
||||||
|
|
||||||
Every real hostname routed to ingress-nginx's shared address
|
Every real DNS record pointing at ingress-nginx's shared address
|
||||||
(`10.10.60.12`), and which app it reaches. Public DNS is hosted on
|
(`10.10.60.12`), and which app it reaches. All hosted on Cloudflare.
|
||||||
Cloudflare; internal overrides are served by Technitium where noted.
|
|
||||||
|
|
||||||
| Hostname | App | Namespace | TLS | Source |
|
| Hostname | App | Namespace | TLS | Source |
|
||||||
|---|---|---|---|---|
|
|---|---|---|---|---|
|
||||||
| `demo.ahmza.com` | Demo app | `demo` | Yes — `letsencrypt-prod`, real trusted cert (see [`docs/12-cert-manager.md`](12-cert-manager.md)) | [`apps/demo/ingress.yaml`](../apps/demo/ingress.yaml) |
|
| `demo.ahmza.com` | Demo app | `demo` | Yes — `letsencrypt-prod`, real trusted cert (see [`docs/12-cert-manager.md`](12-cert-manager.md)) | [`apps/demo/ingress.yaml`](../apps/demo/ingress.yaml) |
|
||||||
| `auth.ahmza.com` | Authentik identity provider | `authentik` | Yes — `letsencrypt-prod`, trusted certificate and browser login verified; Technitium routes LAN clients to `10.10.60.12`. For public traffic, NetBird terminates public TLS and proxies HTTP through its encrypted WireGuard overlay to Caddy on `ingress1`; Caddy then uses certificate-validated HTTPS with `auth.ahmza.com` as SNI and the HTTP `Host` when connecting to ingress-nginx at `10.10.60.12:443` | [`apps/authentik/values.yaml`](../apps/authentik/values.yaml) |
|
|
||||||
| `mc.ahmza.com` | Packwiz modpack files | `mcpacks` | Yes — `letsencrypt-prod`, real trusted certificate | [`apps/mcpacks/ingress.yaml`](../apps/mcpacks/ingress.yaml) |
|
| `mc.ahmza.com` | Packwiz modpack files | `mcpacks` | Yes — `letsencrypt-prod`, real trusted certificate | [`apps/mcpacks/ingress.yaml`](../apps/mcpacks/ingress.yaml) |
|
||||||
| `bazarr.ahmza.com` | Bazarr subtitle manager | `bazarr` | Yes — `letsencrypt-prod`, real trusted certificate; Technitium overrides Cloudflare's NetBird route on the LAN | [`apps/bazarr/ingress.yaml`](../apps/bazarr/ingress.yaml) |
|
|
||||||
| `soulsync.ahmza.com` | SoulSync media discovery | `soulsync` | Configured for `letsencrypt-prod`; verify the certificate after the first deployment; Technitium routes LAN clients to `10.10.60.12` | [`apps/soulsync/ingress.yaml`](../apps/soulsync/ingress.yaml) |
|
|
||||||
|
|
||||||
Add a row here every time you point a new hostname at this cluster (see
|
Add a row here every time you point a new hostname at this cluster (see
|
||||||
[`docs/11-ingress.md`](11-ingress.md)). The DNS record itself lives in
|
[`docs/11-ingress.md`](11-ingress.md)). The DNS record itself lives in
|
||||||
@@ -100,7 +79,7 @@ Addresses from the range above that aren't spoken for yet. Update this
|
|||||||
alongside the table above so it's obvious at a glance what's safe to hand
|
alongside the table above so it's obvious at a glance what's safe to hand
|
||||||
to the next app.
|
to the next app.
|
||||||
|
|
||||||
- `10.10.60.13-10.10.60.250`
|
- `10.10.60.11`, `10.10.60.13-10.10.60.250`
|
||||||
|
|
||||||
(`whoami`'s former `10.10.60.12` was reclaimed here after that app was
|
(`whoami`'s former `10.10.60.12` was reclaimed here after that app was
|
||||||
removed as the docs/08 exercise — it now belongs to ingress-nginx instead.
|
removed as the docs/08 exercise — it now belongs to ingress-nginx instead.
|
||||||
|
|||||||
+42
-49
@@ -5,14 +5,18 @@ This is the detailed, copy-pasteable companion to
|
|||||||
first for the explanations — this one is here so you have every exact
|
first for the explanations — this one is here so you have every exact
|
||||||
command in one place once you understand what they do.
|
command in one place once you understand what they do.
|
||||||
|
|
||||||
Throughout, use the three control-plane and two worker addresses recorded in
|
Throughout, replace `<NODE1_IP>`, `<NODE2_IP>`, `<NODE3_IP>` with your three
|
||||||
[`docs/network.md`](../docs/network.md), plus the cluster's shared VIP. Give
|
machines' real IP addresses, and `<VIP_IP>` with the shared address you
|
||||||
each machine a DHCP reservation (a fixed IP tied to its MAC address) before
|
picked (with Claude's help) for the cluster's VIP — see
|
||||||
installation so its address remains stable.
|
[`docs/02-talos-bootstrap.md`](../docs/02-talos-bootstrap.md#the-vip-one-address-for-a-cluster-that-moves).
|
||||||
|
Give each machine a DHCP reservation (a fixed IP tied to its MAC address)
|
||||||
|
in your router or hypervisor before you start, so none of these addresses
|
||||||
|
change under the cluster. Talos bakes them into certificates during setup,
|
||||||
|
and changing one later means starting over for that node.
|
||||||
|
|
||||||
Steps 1–2 below run **once, total**. Step 3 runs **once per node** (five
|
Steps 1–2 below run **once, total**. Steps 3 runs **once per node** (three
|
||||||
times, using the matching role configuration). Steps 4–6 run **once, total**;
|
times). Steps 4–6 run **once, total**, against whichever node you like
|
||||||
Talos API commands target a control-plane node, while Kubernetes uses the VIP.
|
(or, once it exists, the VIP).
|
||||||
|
|
||||||
All commands assume you're running them from the root of this repo.
|
All commands assume you're running them from the root of this repo.
|
||||||
|
|
||||||
@@ -22,10 +26,7 @@ All commands assume you're running them from the root of this repo.
|
|||||||
talosctl gen config gitops-starter https://<VIP_IP>:6443 \
|
talosctl gen config gitops-starter https://<VIP_IP>:6443 \
|
||||||
--output-dir _out \
|
--output-dir _out \
|
||||||
--config-patch-control-plane @talos/patch-controlplane.yaml \
|
--config-patch-control-plane @talos/patch-controlplane.yaml \
|
||||||
--config-patch-control-plane @talos/patch-netbird.yaml \
|
--config-patch-control-plane @talos/patch-longhorn.yaml
|
||||||
--config-patch-worker @talos/patch-worker.yaml \
|
|
||||||
--config-patch-worker @talos/patch-longhorn.yaml \
|
|
||||||
--config-patch-worker @talos/patch-netbird.yaml
|
|
||||||
```
|
```
|
||||||
|
|
||||||
Note the cluster endpoint here is the **VIP**, not any one node's address
|
Note the cluster endpoint here is the **VIP**, not any one node's address
|
||||||
@@ -37,12 +38,13 @@ This writes three files into `_out/` (already covered by this repo's
|
|||||||
`.gitignore` — they contain private keys and must never be committed):
|
`.gitignore` — they contain private keys and must never be committed):
|
||||||
|
|
||||||
- `controlplane.yaml` — the machine configuration for a control-plane
|
- `controlplane.yaml` — the machine configuration for a control-plane
|
||||||
node, with the Raspberry Pi/VIP and non-secret NetBird patches baked in.
|
node, with both patches baked in. Applied identically to all three
|
||||||
It is applied identically to all three control-plane nodes.
|
nodes — there's no separate worker config in this setup, since every
|
||||||
- `worker.yaml` — the machine configuration for the two Proxmox workers,
|
node is both.
|
||||||
with their role, Longhorn data-disk, and non-secret NetBird patches baked
|
- `worker.yaml` — a plain worker config, generated automatically but
|
||||||
in. The NetBird setup key is deliberately absent from both generated files;
|
unused here since every node in this repo's setup is both control plane
|
||||||
enrollment uses a short-lived key applied separately and revoked afterward.
|
and worker. Kept around for [`docs/09-growing-up.md`](../docs/09-growing-up.md),
|
||||||
|
where a fourth-and-beyond node uses exactly this file.
|
||||||
- `talosconfig` — *your* client credentials for talking to the Talos API on
|
- `talosconfig` — *your* client credentials for talking to the Talos API on
|
||||||
this cluster (equivalent in spirit to a kubeconfig, but for Talos itself
|
this cluster (equivalent in spirit to a kubeconfig, but for Talos itself
|
||||||
rather than Kubernetes).
|
rather than Kubernetes).
|
||||||
@@ -66,39 +68,34 @@ separate.
|
|||||||
|
|
||||||
## 3. Apply the configuration — once per node
|
## 3. Apply the configuration — once per node
|
||||||
|
|
||||||
Boot each machine from its architecture-appropriate custom Talos image (see
|
Boot each machine from your custom Talos ISO (see
|
||||||
[docs/01-prerequisites.md](../docs/01-prerequisites.md)). Each boots into
|
[docs/01-prerequisites.md](../docs/01-prerequisites.md)). Each boots into
|
||||||
"maintenance mode" — alive enough to accept configuration, with nothing
|
"maintenance mode" — alive enough to accept a configuration, with nothing
|
||||||
installed yet. Inspect its disks first:
|
installed yet. For **each** node in turn:
|
||||||
|
|
||||||
```sh
|
```sh
|
||||||
talosctl get disks --insecure --nodes <NODE_IP>
|
talosctl get disks --insecure --nodes <NODE_IP>
|
||||||
```
|
```
|
||||||
|
|
||||||
For each Raspberry Pi control plane, confirm `/dev/mmcblk0` is the intended
|
Confirm you see two disks: the one Talos will install itself to, and the
|
||||||
system disk, then apply the control-plane configuration:
|
≥900GB one `talos/patch-longhorn.yaml`'s `UserVolumeConfig` will claim for
|
||||||
|
Longhorn. Then:
|
||||||
|
|
||||||
```sh
|
```sh
|
||||||
talosctl apply-config --insecure \
|
talosctl apply-config --insecure \
|
||||||
--nodes <CONTROL_PLANE_IP> \
|
--nodes <NODE_IP> \
|
||||||
--file _out/controlplane.yaml
|
--file _out/controlplane.yaml
|
||||||
```
|
```
|
||||||
|
|
||||||
For each Proxmox worker, confirm `/dev/sda` is the Talos system disk and
|
|
||||||
`/dev/sdb` is the dedicated Longhorn disk selected by
|
|
||||||
`talos/patch-longhorn.yaml`, then apply the worker configuration:
|
|
||||||
|
|
||||||
```sh
|
|
||||||
talosctl apply-config --insecure \
|
|
||||||
--nodes <WORKER_IP> \
|
|
||||||
--file _out/worker.yaml
|
|
||||||
```
|
|
||||||
|
|
||||||
`--insecure` is required for this one command only: the node has no
|
`--insecure` is required for this one command only: the node has no
|
||||||
certificates yet, so talosctl cannot authenticate to it normally. This is
|
certificates yet, so talosctl can't authenticate to it normally. This is
|
||||||
the one moment during setup where you trust the local network. After applying
|
the one moment during setup where you're trusting the network — do this on
|
||||||
configuration, the node installs Talos and returns with authenticated API
|
a network you control. The node will reboot, install Talos to its system
|
||||||
access. Configure all three control planes and both workers before continuing.
|
disk, format and mount its second disk for Longhorn, and come back up
|
||||||
|
running the configuration you gave it — now *with* certificates, so every
|
||||||
|
command after this uses the secure path.
|
||||||
|
|
||||||
|
Repeat this for `<NODE1_IP>`, `<NODE2_IP>`, and `<NODE3_IP>` before moving on.
|
||||||
|
|
||||||
## 4. Bootstrap etcd — once, total
|
## 4. Bootstrap etcd — once, total
|
||||||
|
|
||||||
@@ -118,14 +115,12 @@ existing one. Running it again against an existing cluster can corrupt it.
|
|||||||
## 5. Get your kubeconfig
|
## 5. Get your kubeconfig
|
||||||
|
|
||||||
```sh
|
```sh
|
||||||
talosctl kubeconfig --nodes <CONTROL_PLANE_IP> .
|
talosctl kubeconfig --nodes <VIP_IP> .
|
||||||
```
|
```
|
||||||
|
|
||||||
Downloads a kubeconfig through a control-plane node's Talos API into the
|
Downloads a kubeconfig into the current directory (also gitignored —
|
||||||
current directory (also gitignored — it grants full cluster access). The
|
it grants full cluster access), pointed at the VIP rather than any one
|
||||||
resulting Kubernetes configuration points at the cluster VIP rather than one
|
node. Merge it with `~/.kube/config` or point `KUBECONFIG` at it directly:
|
||||||
specific control plane. Merge it with `~/.kube/config` or point `KUBECONFIG`
|
|
||||||
at it directly:
|
|
||||||
|
|
||||||
```sh
|
```sh
|
||||||
export KUBECONFIG=$PWD/kubeconfig
|
export KUBECONFIG=$PWD/kubeconfig
|
||||||
@@ -137,17 +132,15 @@ export KUBECONFIG=$PWD/kubeconfig
|
|||||||
kubectl get nodes
|
kubectl get nodes
|
||||||
```
|
```
|
||||||
|
|
||||||
Expect to see **five** nodes, `Ready`, within a couple of minutes (it takes
|
Expect to see **three** nodes, `Ready`, within a couple of minutes (it
|
||||||
a moment for the default CNI — Talos ships Flannel out of the box — to clear
|
takes a moment for the default CNI — Talos ships Flannel out of the box —
|
||||||
each node's networking checks).
|
to come up and clear each node's networking checks).
|
||||||
|
|
||||||
```text
|
```
|
||||||
NAME STATUS ROLES AGE VERSION
|
NAME STATUS ROLES AGE VERSION
|
||||||
talos-... Ready control-plane 90s v1.3x.x
|
talos-... Ready control-plane 90s v1.3x.x
|
||||||
talos-... Ready control-plane 85s v1.3x.x
|
talos-... Ready control-plane 85s v1.3x.x
|
||||||
talos-... Ready control-plane 80s v1.3x.x
|
talos-... Ready control-plane 80s v1.3x.x
|
||||||
talos-... Ready worker 75s v1.3x.x
|
|
||||||
talos-... Ready worker 70s v1.3x.x
|
|
||||||
```
|
```
|
||||||
|
|
||||||
If any node is stuck on `NotReady`, give it another minute before
|
If any node is stuck on `NotReady`, give it another minute before
|
||||||
|
|||||||
@@ -12,10 +12,9 @@
|
|||||||
# --- install image ---
|
# --- install image ---
|
||||||
# All three control planes are Raspberry Pi 4 systems currently installed on
|
# All three control planes are Raspberry Pi 4 systems currently installed on
|
||||||
# their microSD (`mmcblk0`). The Image Factory schematic contains the
|
# their microSD (`mmcblk0`). The Image Factory schematic contains the
|
||||||
# `rpi_generic` ARM64 overlay needed to boot this hardware and the NetBird
|
# `rpi_generic` ARM64 overlay needed to boot this hardware. Keep this custom
|
||||||
# system extension used for private overlay connectivity. Keep this custom
|
# installer reference during upgrades or the board-specific boot support may
|
||||||
# installer reference during upgrades or the board-specific boot support and
|
# be lost.
|
||||||
# NetBird binary may be lost.
|
|
||||||
#
|
#
|
||||||
# --- vip ---
|
# --- vip ---
|
||||||
# With three control-plane nodes, "the cluster's API server" isn't one
|
# With three control-plane nodes, "the cluster's API server" isn't one
|
||||||
@@ -39,8 +38,7 @@ cluster:
|
|||||||
machine:
|
machine:
|
||||||
install:
|
install:
|
||||||
disk: /dev/mmcblk0
|
disk: /dev/mmcblk0
|
||||||
image: "factory.talos.dev/metal-installer/\
|
image: factory.talos.dev/metal-installer/ee21ef4a5ef808a9b7484cc0dda0f25075021691c8c09a276591eedb638ea1f9:v1.13.8
|
||||||
d093bb68c464b87cc637765535dde5f68fbb040da44280617dd11a42d6c03988:v1.13.8"
|
|
||||||
network:
|
network:
|
||||||
interfaces:
|
interfaces:
|
||||||
# Raspberry Pi 4's built-in Ethernet interface is named `end0` by
|
# Raspberry Pi 4's built-in Ethernet interface is named `end0` by
|
||||||
|
|||||||
@@ -1,20 +0,0 @@
|
|||||||
# Persistent, non-secret configuration for the official SideroLabs NetBird
|
|
||||||
# system extension. Apply this patch to every Talos node alongside its normal
|
|
||||||
# role-specific patches.
|
|
||||||
#
|
|
||||||
# Enrollment still requires NB_SETUP_KEY, but that short-lived credential must
|
|
||||||
# never be committed to this public repository. Supply it separately from a
|
|
||||||
# silent shell prompt during first enrollment, revoke it after all nodes join,
|
|
||||||
# then remove it from the live ExtensionServiceConfig.
|
|
||||||
apiVersion: v1alpha1
|
|
||||||
kind: ExtensionServiceConfig
|
|
||||||
name: netbird
|
|
||||||
environment:
|
|
||||||
# Both endpoints use this installation's combined self-hosted NetBird URL.
|
|
||||||
- NB_MANAGEMENT_URL=https://netbird.ahmza.com
|
|
||||||
- NB_ADMIN_URL=https://netbird.ahmza.com
|
|
||||||
# Talos mounts /etc read-only. Prevent NetBird from repeatedly trying to
|
|
||||||
# rewrite resolv.conf and the OpenSSH client configuration there. Overlay
|
|
||||||
# networking remains active; NetBird-managed DNS is deliberately disabled.
|
|
||||||
- NB_DISABLE_DNS=true
|
|
||||||
- NB_DISABLE_SSH_CONFIG=true
|
|
||||||
@@ -8,9 +8,9 @@
|
|||||||
# claiming the wrong virtual disk.
|
# claiming the wrong virtual disk.
|
||||||
#
|
#
|
||||||
# The custom Image Factory installer contains Longhorn's `iscsi-tools` and
|
# The custom Image Factory installer contains Longhorn's `iscsi-tools` and
|
||||||
# `util-linux-tools` extensions plus `qemu-guest-agent` and NetBird. Keep this
|
# `util-linux-tools` extensions plus `qemu-guest-agent`. Keep this schematic
|
||||||
# schematic reference during future upgrades; switching to the stock installer
|
# reference during future upgrades; switching to the stock installer would
|
||||||
# would silently remove those extensions.
|
# silently remove those extensions.
|
||||||
#
|
#
|
||||||
# Both VMs use `ens18`. Their DHCP-reserved MAC addresses keep worker01 at
|
# Both VMs use `ens18`. Their DHCP-reserved MAC addresses keep worker01 at
|
||||||
# 10.10.10.203 and worker02 at 10.10.10.204 while DHCP supplies their gateway
|
# 10.10.10.203 and worker02 at 10.10.10.204 while DHCP supplies their gateway
|
||||||
@@ -26,8 +26,7 @@ machine:
|
|||||||
node.longhorn.io/create-default-disk: "true"
|
node.longhorn.io/create-default-disk: "true"
|
||||||
install:
|
install:
|
||||||
disk: /dev/sda
|
disk: /dev/sda
|
||||||
image: "factory.talos.dev/metal-installer/\
|
image: factory.talos.dev/metal-installer/88d1f7a5c4f1d3aba7df787c448c1d3d008ed29cfb34af53fa0df4336a56040b:v1.13.8
|
||||||
81fb1af7c03952593ba459c6c8b7fcc1268b6fe0cc80e6035ac629a741c183cc:v1.13.8"
|
|
||||||
network:
|
network:
|
||||||
interfaces:
|
interfaces:
|
||||||
- interface: ens18
|
- interface: ens18
|
||||||
|
|||||||
Reference in New Issue
Block a user