infra/talos/deploy-cluster-services.sh

194 lines
6.2 KiB
Bash
Executable file

#!/usr/bin/env bash
set -euo pipefail
# Talos Cluster Services Deployment Script
# This script deploys core infrastructure services in the correct order
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
VNTX_INFRA_DIR="$(dirname "$SCRIPT_DIR")"
echo "=== Talos Cluster Services Deployment ==="
echo ""
# Color output
GREEN='\033[0;32m'
YELLOW='\033[1;33m'
NC='\033[0m' # No Color
step() {
echo -e "${GREEN}==>${NC} $1"
}
wait_for_pods() {
local namespace=$1
local label=$2
local timeout=${3:-120}
echo "Waiting for pods in namespace $namespace with label $label..."
kubectl wait --for=condition=ready pod \
-l "$label" \
-n "$namespace" \
--timeout="${timeout}s" 2>/dev/null || true
}
# Step 0: Remove control-plane taint
step "0. Removing control-plane taint..."
kubectl taint nodes --all node-role.kubernetes.io/control-plane:NoSchedule- 2>/dev/null || echo "Taint already removed or not present"
echo ""
# Step 1: Deploy MetalLB
step "1. Deploying MetalLB..."
kubectl apply -f https://raw.githubusercontent.com/metallb/metallb/v0.14.9/config/manifests/metallb-native.yaml
echo "Waiting for MetalLB controller..."
wait_for_pods metallb-system component=controller 120
# Create memberlist secret if needed
kubectl get secret -n metallb-system memberlist &>/dev/null || \
kubectl create secret generic -n metallb-system memberlist \
--from-literal=secretkey="$(openssl rand -base64 128)"
echo "Waiting for MetalLB speakers..."
wait_for_pods metallb-system component=speaker 120
step "Applying MetalLB IP pool configuration..."
kubectl apply -f "$VNTX_INFRA_DIR/contexts/metallb/ipaddresspool.yaml"
echo ""
# Step 2: Deploy NFS Provisioner
step "2. Deploying NFS Provisioner..."
helm repo add nfs-subdir-external-provisioner https://kubernetes-sigs.github.io/nfs-subdir-external-provisioner/ 2>/dev/null || true
helm repo update
helm upgrade --install nfs-subdir-external-provisioner nfs-subdir-external-provisioner/nfs-subdir-external-provisioner \
--namespace nfs-provisioner \
--create-namespace \
--set nfs.server=10.0.0.253 \
--set nfs.path=/mnt/k8s/cluster \
--set storageClass.name=nfs \
--set storageClass.defaultClass=true \
--set storageClass.reclaimPolicy=Delete \
--wait
echo ""
# Step 3: Deploy Tailscale Operator
step "3. Deploying Tailscale Operator..."
# Set namespace to privileged for Tailscale proxies
kubectl create namespace tailscale 2>/dev/null || true
kubectl label namespace tailscale \
pod-security.kubernetes.io/enforce=privileged \
pod-security.kubernetes.io/audit=privileged \
pod-security.kubernetes.io/warn=privileged \
--overwrite
# Get Tailscale OAuth credentials from 1Password
TAILSCALE_CLIENT_ID=$(op item get almzem6nffphe3xv4pgxpkbaga --account=YOOATCZZSVGH7AD6VABUVPORLI --fields client_id --reveal)
TAILSCALE_CLIENT_SECRET=$(op item get almzem6nffphe3xv4pgxpkbaga --account=YOOATCZZSVGH7AD6VABUVPORLI --fields client_secret --reveal)
helm repo add tailscale https://pkgs.tailscale.com/helmcharts 2>/dev/null || true
helm repo update
helm upgrade --install tailscale-operator tailscale/tailscale-operator \
--namespace=tailscale \
--set-string oauth.clientId="$TAILSCALE_CLIENT_ID" \
--set-string oauth.clientSecret="$TAILSCALE_CLIENT_SECRET" \
--wait
echo ""
# Step 4: Deploy DNS Services (PowerDNS)
step "4. Deploying DNS Services (PowerDNS)..."
# Create PostgreSQL credentials secret from 1Password
kubectl create secret generic postgresql-credentials -n dns \
--from-literal="POSTGRES_USER=$(op item get t3nqhjmeci6msx4qouu64yfr3q --account=YOOATCZZSVGH7AD6VABUVPORLI --fields POSTGRES_USER --reveal)" \
--from-literal="POSTGRES_PASSWORD=$(op item get t3nqhjmeci6msx4qouu64yfr3q --account=YOOATCZZSVGH7AD6VABUVPORLI --fields POSTGRES_PASSWORD --reveal)" \
--from-literal="POSTGRES_DB=$(op item get t3nqhjmeci6msx4qouu64yfr3q --account=YOOATCZZSVGH7AD6VABUVPORLI --fields POSTGRES_DB --reveal)" \
--dry-run=client -o yaml | kubectl apply -f -
# Create PowerDNS API secret from 1Password
kubectl create secret generic powerdns-secrets -n dns \
--from-literal="API_KEY=$(op item get t3nqhjmeci6msx4qouu64yfr3q --account=YOOATCZZSVGH7AD6VABUVPORLI --fields POWERDNS_API_KEY --reveal)" \
--dry-run=client -o yaml | kubectl apply -f -
# Create PowerDNS config
kubectl create configmap powerdns-config -n dns --from-literal="pdns.conf=launch=gpgsql
gpgsql-host=10.0.0.252
gpgsql-port=5432
gpgsql-dbname=powerdns
gpgsql-user=powerdns
gpgsql-password=$(op item get t3nqhjmeci6msx4qouu64yfr3q --account=YOOATCZZSVGH7AD6VABUVPORLI --fields POSTGRES_PASSWORD --reveal)
gpgsql-dnssec=yes
receiver-threads=4
distributor-threads=4
reuseport=yes
max-tcp-connections=100
api=yes
api-key=$(op item get t3nqhjmeci6msx4qouu64yfr3q --account=YOOATCZZSVGH7AD6VABUVPORLI --fields POWERDNS_API_KEY --reveal)
webserver=yes
webserver-address=0.0.0.0
webserver-port=8081
webserver-allow-from=0.0.0.0/0
webserver-max-bodysize=10485760
local-address=0.0.0.0
local-port=53
log-dns-queries=yes
loglevel=6" \
--dry-run=client -o yaml | kubectl apply -f -
# Deploy PowerDNS services and deployment
kubectl apply -f "$VNTX_INFRA_DIR/contexts/dns/powerdns-service.yaml"
kubectl apply -f "$VNTX_INFRA_DIR/contexts/dns/powerdns-deployment.yaml"
echo "Waiting for PowerDNS..."
wait_for_pods dns app=powerdns 120
echo ""
# Step 5: Verify deployment
step "5. Verifying deployment..."
echo ""
echo "MetalLB Status:"
kubectl get pods -n metallb-system
echo ""
kubectl get ipaddresspool,l2advertisement -n metallb-system
echo ""
echo "NFS Provisioner Status:"
kubectl get pods -n nfs-provisioner
echo ""
kubectl get storageclass
echo ""
echo "Tailscale Operator Status:"
kubectl get pods -n tailscale
echo ""
echo ""
echo "DNS Services Status:"
kubectl get pods,svc -n dns
echo ""
echo -e "${GREEN}=== Deployment Complete ===${NC}"
echo ""
echo "Services deployed:"
echo " - MetalLB (Public LoadBalancer)"
echo " - NFS Provisioner (Storage from 10.0.0.253)"
echo " - Tailscale Operator (Private network access)"
echo " - PowerDNS (Authoritative DNS)"
echo ""
echo "External Dependencies:"
echo " - PostgreSQL: 10.0.0.252"
echo " - NFS: 10.0.0.253:/mnt/k8s/cluster"
echo ""
echo "LoadBalancer Services:"
kubectl get svc --all-namespaces -o wide | grep LoadBalancer || echo " No LoadBalancer services yet"