[ci skip] codify CNPG PostgreSQL in Terraform, decommission old NFS-backed PG
Phase 1 complete — PostgreSQL fully migrated off NFS: dbaas module changes: - Replace old kubernetes_deployment.postgres with null_resource.pg_cluster (CNPG Cluster CR managed via kubectl apply due to webhook mutation issues) - Update postgresql Service selector: app=postgresql → cnpg primary - Update backup CronJob: use postgres user + read password from CNPG secret (pg-cluster-superuser) instead of hardcoded root password - Add kube_config_path variable for kubectl in null_resource - Old deployment deleted from cluster (was scaled to 0) CNPG cluster status: - 2 instances: primary (k8s-node4), replica (k8s-node2) - PostGIS image (ghcr.io/cloudnative-pg/postgis:16) - 20Gi local-path storage per instance - All 13 dependent services verified running - Backup CronJob verified working with new endpoint
This commit is contained in:
parent
140f48c6ee
commit
882350250a
2 changed files with 94 additions and 93 deletions
|
|
@ -141,6 +141,7 @@ module "dbaas" {
|
||||||
dbaas_root_password = var.dbaas_root_password
|
dbaas_root_password = var.dbaas_root_password
|
||||||
postgresql_root_password = var.dbaas_postgresql_root_password
|
postgresql_root_password = var.dbaas_postgresql_root_password
|
||||||
pgadmin_password = var.dbaas_pgadmin_password
|
pgadmin_password = var.dbaas_pgadmin_password
|
||||||
|
kube_config_path = var.kube_config_path
|
||||||
tier = local.tiers.cluster
|
tier = local.tiers.cluster
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -12,6 +12,7 @@ variable "prod" {
|
||||||
type = bool
|
type = bool
|
||||||
}
|
}
|
||||||
variable "nfs_server" { type = string }
|
variable "nfs_server" { type = string }
|
||||||
|
variable "kube_config_path" { type = string }
|
||||||
|
|
||||||
resource "kubernetes_namespace" "dbaas" {
|
resource "kubernetes_namespace" "dbaas" {
|
||||||
metadata {
|
metadata {
|
||||||
|
|
@ -706,101 +707,59 @@ module "ingress" {
|
||||||
# EOF
|
# EOF
|
||||||
# }
|
# }
|
||||||
|
|
||||||
resource "kubernetes_deployment" "postgres" {
|
#### POSTGRESQL — CloudNativePG Cluster
|
||||||
metadata {
|
#
|
||||||
name = "postgresql"
|
# Migrated from single NFS-backed pod to CNPG on local-path storage.
|
||||||
namespace = kubernetes_namespace.dbaas.metadata[0].name
|
# CNPG Cluster is managed via kubectl apply (not kubernetes_manifest)
|
||||||
annotations = {
|
# because the CNPG webhook mutates the spec on apply, causing
|
||||||
"reloader.stakater.com/search" = "true"
|
# Terraform provider "inconsistent result" errors.
|
||||||
}
|
#
|
||||||
labels = {
|
# Rollback: apply old deployment yaml, revert service selector to app=postgresql.
|
||||||
tier = var.tier
|
|
||||||
}
|
# Ensure the CNPG cluster manifest exists (idempotent kubectl apply)
|
||||||
|
resource "null_resource" "pg_cluster" {
|
||||||
|
triggers = {
|
||||||
|
instances = "2"
|
||||||
|
image = "ghcr.io/cloudnative-pg/postgis:16"
|
||||||
|
storage_size = "20Gi"
|
||||||
|
storage_class = "local-path"
|
||||||
|
memory_limit = "4Gi"
|
||||||
|
cpu_limit = "2"
|
||||||
}
|
}
|
||||||
spec {
|
|
||||||
selector {
|
|
||||||
match_labels = {
|
|
||||||
app = "postgresql"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
strategy {
|
|
||||||
type = "Recreate"
|
|
||||||
}
|
|
||||||
template {
|
|
||||||
metadata {
|
|
||||||
labels = {
|
|
||||||
app = "postgresql"
|
|
||||||
}
|
|
||||||
annotations = {
|
|
||||||
"diun.enable" = "false"
|
|
||||||
"diun.include_tags" = "^\\d+(?:\\.\\d+)?-bullseye$"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
spec {
|
|
||||||
container {
|
|
||||||
# image = "postgis/postgis:16-master"
|
|
||||||
image = "viktorbarzin/postgres:16-master" # mix of postgis + pgvector
|
|
||||||
# image = "postgres:17.2-bullseye" # needs pg_upgrade to data dir
|
|
||||||
name = "postgresql"
|
|
||||||
|
|
||||||
resources {
|
provisioner "local-exec" {
|
||||||
requests = {
|
command = <<-EOT
|
||||||
cpu = "250m"
|
kubectl --kubeconfig ${var.kube_config_path} apply -f - <<'EOF'
|
||||||
memory = "512Mi"
|
apiVersion: postgresql.cnpg.io/v1
|
||||||
}
|
kind: Cluster
|
||||||
limits = {
|
metadata:
|
||||||
cpu = "1"
|
name: pg-cluster
|
||||||
memory = "2Gi"
|
namespace: dbaas
|
||||||
}
|
spec:
|
||||||
}
|
instances: 2
|
||||||
|
imageName: ghcr.io/cloudnative-pg/postgis:16
|
||||||
env {
|
postgresql:
|
||||||
name = "POSTGRES_PASSWORD"
|
parameters:
|
||||||
value = var.postgresql_root_password
|
search_path: '"$user", public'
|
||||||
}
|
enableAlterSystem: true
|
||||||
env {
|
enableSuperuserAccess: true
|
||||||
name = "POSTGRES_USER"
|
storage:
|
||||||
value = "root"
|
size: 20Gi
|
||||||
}
|
storageClass: local-path
|
||||||
port {
|
resources:
|
||||||
container_port = 5432
|
requests:
|
||||||
protocol = "TCP"
|
cpu: "250m"
|
||||||
name = "postgresql"
|
memory: "512Mi"
|
||||||
}
|
limits:
|
||||||
volume_mount {
|
cpu: "2"
|
||||||
name = "postgresql-persistent-storage"
|
memory: "4Gi"
|
||||||
mount_path = "/var/lib/postgresql/data"
|
EOF
|
||||||
}
|
EOT
|
||||||
# volume_mount {
|
|
||||||
# name = "mycnf"
|
|
||||||
# mount_path = "/etc/my.cnf"
|
|
||||||
# sub_path = "my.cnf"
|
|
||||||
# }
|
|
||||||
}
|
|
||||||
volume {
|
|
||||||
name = "postgresql-persistent-storage"
|
|
||||||
nfs {
|
|
||||||
path = "/mnt/main/postgresql/data"
|
|
||||||
server = var.nfs_server
|
|
||||||
}
|
|
||||||
}
|
|
||||||
# volume {
|
|
||||||
# name = "mycnf"
|
|
||||||
|
|
||||||
# config_map {
|
|
||||||
# name = "mycnf"
|
|
||||||
# }
|
|
||||||
# }
|
|
||||||
dns_config {
|
|
||||||
option {
|
|
||||||
name = "ndots"
|
|
||||||
value = "2"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
# Service that maintains the original postgresql.dbaas endpoint,
|
||||||
|
# now pointing at the CNPG primary pod instead of the old deployment.
|
||||||
resource "kubernetes_service" "postgresql" {
|
resource "kubernetes_service" "postgresql" {
|
||||||
metadata {
|
metadata {
|
||||||
name = "postgresql"
|
name = "postgresql"
|
||||||
|
|
@ -808,7 +767,8 @@ resource "kubernetes_service" "postgresql" {
|
||||||
}
|
}
|
||||||
spec {
|
spec {
|
||||||
selector = {
|
selector = {
|
||||||
"app" = "postgresql"
|
"cnpg.io/cluster" = "pg-cluster"
|
||||||
|
"cnpg.io/instanceRole" = "primary"
|
||||||
}
|
}
|
||||||
port {
|
port {
|
||||||
name = "postgresql"
|
name = "postgresql"
|
||||||
|
|
@ -818,6 +778,37 @@ resource "kubernetes_service" "postgresql" {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
# Old PostgreSQL deployment — kept commented for rollback reference
|
||||||
|
# resource "kubernetes_deployment" "postgres" {
|
||||||
|
# metadata {
|
||||||
|
# name = "postgresql"
|
||||||
|
# namespace = kubernetes_namespace.dbaas.metadata[0].name
|
||||||
|
# labels = { tier = var.tier }
|
||||||
|
# }
|
||||||
|
# spec {
|
||||||
|
# replicas = 0 # scaled to 0 during CNPG migration
|
||||||
|
# selector { match_labels = { app = "postgresql" } }
|
||||||
|
# strategy { type = "Recreate" }
|
||||||
|
# template {
|
||||||
|
# metadata { labels = { app = "postgresql" } }
|
||||||
|
# spec {
|
||||||
|
# container {
|
||||||
|
# image = "viktorbarzin/postgres:16-master"
|
||||||
|
# name = "postgresql"
|
||||||
|
# env { name = "POSTGRES_PASSWORD"; value = var.postgresql_root_password }
|
||||||
|
# env { name = "POSTGRES_USER"; value = "root" }
|
||||||
|
# port { container_port = 5432; protocol = "TCP"; name = "postgresql" }
|
||||||
|
# volume_mount { name = "postgresql-persistent-storage"; mount_path = "/var/lib/postgresql/data" }
|
||||||
|
# }
|
||||||
|
# volume {
|
||||||
|
# name = "postgresql-persistent-storage"
|
||||||
|
# nfs { path = "/mnt/main/postgresql/data"; server = var.nfs_server }
|
||||||
|
# }
|
||||||
|
# }
|
||||||
|
# }
|
||||||
|
# }
|
||||||
|
# }
|
||||||
|
|
||||||
#### PGADMIN
|
#### PGADMIN
|
||||||
|
|
||||||
resource "kubernetes_deployment" "pgadmin" {
|
resource "kubernetes_deployment" "pgadmin" {
|
||||||
|
|
@ -934,10 +925,19 @@ resource "kubernetes_cron_job_v1" "postgresql-backup" {
|
||||||
container {
|
container {
|
||||||
name = "postgresql-backup"
|
name = "postgresql-backup"
|
||||||
image = "postgres:16.4-bullseye"
|
image = "postgres:16.4-bullseye"
|
||||||
|
env {
|
||||||
|
name = "PGPASSWORD"
|
||||||
|
value_from {
|
||||||
|
secret_key_ref {
|
||||||
|
name = "pg-cluster-superuser"
|
||||||
|
key = "password"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
command = ["/bin/bash", "-c", <<-EOT
|
command = ["/bin/bash", "-c", <<-EOT
|
||||||
set -euxo pipefail
|
set -euxo pipefail
|
||||||
export now=$(date +"%Y_%m_%d_%H_%M")
|
export now=$(date +"%Y_%m_%d_%H_%M")
|
||||||
PGPASSWORD=${var.postgresql_root_password} pg_dumpall -h postgresql.dbaas -U root > /backup/dump_$now.sql
|
PGPASSWORD=$PGPASSWORD pg_dumpall -h postgresql.dbaas -U postgres > /backup/dump_$now.sql
|
||||||
|
|
||||||
# Rotate - delete last log file
|
# Rotate - delete last log file
|
||||||
cd /backup
|
cd /backup
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue