fix(headscale): backup CronJob uses pod_affinity for RWO PVC access
The backup CronJob was stuck in ContainerCreating because it couldn't mount the proxmox-lvm RWO PVC from a different node. Fixed by: - Adding pod_affinity to co-locate with the headscale pod (same node) - Mounting both data PVC (read-only) and NFS backup PVC (write) - Adding integrity check pattern from vaultwarden backup - Setting concurrency_policy=Replace and ttl_seconds_after_finished=10
This commit is contained in:
parent
f14c227a98
commit
cdfa1b7e92
1 changed files with 39 additions and 9 deletions
|
|
@ -409,42 +409,72 @@ resource "kubernetes_config_map" "headscale-config" {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
# Backup CronJob — sqlite3 .backup to NFS for cloud sync pickup
|
# Backup CronJob — sqlite3 .backup from proxmox-lvm to NFS for cloud sync pickup
|
||||||
|
# Uses pod_affinity to co-locate with headscale pod (required for RWO PVC access)
|
||||||
resource "kubernetes_cron_job_v1" "headscale_backup" {
|
resource "kubernetes_cron_job_v1" "headscale_backup" {
|
||||||
metadata {
|
metadata {
|
||||||
name = "headscale-backup"
|
name = "headscale-backup"
|
||||||
namespace = kubernetes_namespace.headscale.metadata[0].name
|
namespace = kubernetes_namespace.headscale.metadata[0].name
|
||||||
}
|
}
|
||||||
spec {
|
spec {
|
||||||
|
concurrency_policy = "Replace"
|
||||||
schedule = "0 */6 * * *"
|
schedule = "0 */6 * * *"
|
||||||
successful_jobs_history_limit = 1
|
successful_jobs_history_limit = 1
|
||||||
failed_jobs_history_limit = 1
|
failed_jobs_history_limit = 3
|
||||||
job_template {
|
job_template {
|
||||||
metadata {}
|
metadata {}
|
||||||
spec {
|
spec {
|
||||||
|
backoff_limit = 3
|
||||||
|
ttl_seconds_after_finished = 10
|
||||||
template {
|
template {
|
||||||
metadata {}
|
metadata {}
|
||||||
spec {
|
spec {
|
||||||
|
affinity {
|
||||||
|
pod_affinity {
|
||||||
|
required_during_scheduling_ignored_during_execution {
|
||||||
|
label_selector {
|
||||||
|
match_labels = {
|
||||||
|
app = "headscale"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
topology_key = "kubernetes.io/hostname"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
container {
|
container {
|
||||||
name = "backup"
|
name = "backup"
|
||||||
image = "keinos/sqlite3:latest"
|
image = "docker.io/library/alpine"
|
||||||
command = ["/bin/sh", "-c", <<-EOT
|
command = ["/bin/sh", "-c", <<-EOT
|
||||||
mkdir -p /mnt/headscale-backup && \
|
set -euxo pipefail
|
||||||
sqlite3 /mnt/db.sqlite ".backup /mnt/headscale-backup/db.sqlite.bak" && \
|
apk add --no-cache sqlite
|
||||||
|
now=$(date +"%Y_%m_%d_%H_%M")
|
||||||
|
mkdir -p /backup
|
||||||
|
sqlite3 /data/db.sqlite ".backup /backup/db.sqlite.bak"
|
||||||
echo "Backup completed at $(date)"
|
echo "Backup completed at $(date)"
|
||||||
EOT
|
EOT
|
||||||
]
|
]
|
||||||
volume_mount {
|
volume_mount {
|
||||||
name = "nfs-data"
|
name = "data"
|
||||||
mount_path = "/mnt"
|
mount_path = "/data"
|
||||||
|
read_only = true
|
||||||
|
}
|
||||||
|
volume_mount {
|
||||||
|
name = "backup"
|
||||||
|
mount_path = "/backup"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
volume {
|
volume {
|
||||||
name = "nfs-data"
|
name = "data"
|
||||||
persistent_volume_claim {
|
persistent_volume_claim {
|
||||||
claim_name = kubernetes_persistent_volume_claim.data_proxmox.metadata[0].name
|
claim_name = kubernetes_persistent_volume_claim.data_proxmox.metadata[0].name
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
volume {
|
||||||
|
name = "backup"
|
||||||
|
persistent_volume_claim {
|
||||||
|
claim_name = module.nfs_data.claim_name
|
||||||
|
}
|
||||||
|
}
|
||||||
restart_policy = "OnFailure"
|
restart_policy = "OnFailure"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue