#!/usr/bin/env bash # scripts/dns-lab-setup.sh — 50-dns-resolution 랩 부트스트랩(멱등). # # 하는 일: # 1) self-signed 서버 인증서 생성(SAN=gslb.lab.internal) → secret gslb-tls # 2) cluster DNS ClusterIP 치환 후 lab-dns 적용 # 3) backends 적용 # 4) lab-dns ClusterIP 치환 후 client(fortio/netshoot) 적용 # 5) rollout 대기 후, GSLB 초기값 = backend-a IP 로 addn 기록 # # SE/VS/DR(변형)은 여기서 적용하지 않는다 — 실험 단계에서 dns-flip-test.sh 가 고른다. # # usage: bash scripts/dns-lab-setup.sh set -euo pipefail CTX="${CTX:-homelab}" NS="${NS:-dns-lab}" DIR="$(cd "$(dirname "$0")/.." && pwd)" SC="$DIR/scenarios/50-dns-resolution" WORK="$DIR/tmp/dns-lab"; mkdir -p "$WORK" K="kubectl --context=$CTX" echo "== [0] preflight ==" $K version --request-timeout=5s >/dev/null 2>&1 || { echo "!! API 도달 불가($CTX). 클러스터(VM) 상태 확인 필요."; exit 1; } echo "== [1] server cert(self-signed, SAN=gslb.lab.internal) ==" if [ ! -f "$WORK/tls.crt" ]; then openssl req -x509 -newkey rsa:2048 -nodes -days 365 \ -keyout "$WORK/tls.key" -out "$WORK/tls.crt" \ -subj "/CN=gslb.lab.internal" \ -addext "subjectAltName=DNS:gslb.lab.internal" >/dev/null 2>&1 fi echo "== [2] namespace + secret ==" $K apply -f "$SC/00-namespace.yaml" $K -n "$NS" create secret tls gslb-tls \ --cert="$WORK/tls.crt" --key="$WORK/tls.key" \ --dry-run=client -o yaml | $K apply -f - echo "== [3] lab-dns (cluster DNS ClusterIP 치환) ==" CLUSTER_DNS="$($K -n kube-system get svc coredns -o jsonpath='{.spec.clusterIP}' 2>/dev/null \ || $K -n kube-system get svc kube-dns -o jsonpath='{.spec.clusterIP}' 2>/dev/null)" [ -n "$CLUSTER_DNS" ] || { echo "!! cluster DNS Service(coredns/kube-dns)를 못 찾음"; exit 1; } echo " cluster DNS = $CLUSTER_DNS" sed "s/__CLUSTER_DNS__/$CLUSTER_DNS/g" "$SC/10-lab-dns.yaml" | $K apply -f - $K -n "$NS" rollout status deploy/lab-dns --timeout=90s echo "== [4] backends ==" $K apply -f "$SC/20-backends.yaml" $K -n "$NS" rollout status deploy/backend-a --timeout=90s $K -n "$NS" rollout status deploy/backend-b --timeout=90s echo "== [4b] GSLB 초기값 = backend-a (client rollout 전에 미리 기록 — 부분 실패에도 gslb 응답 유지) ==" IP_A="$($K -n "$NS" get svc backend-a -o jsonpath='{.spec.clusterIP}')" IP_B="$($K -n "$NS" get svc backend-b -o jsonpath='{.spec.clusterIP}')" $K -n "$NS" exec deploy/lab-dns -c writer -- sh -c "printf '%s gslb.lab.internal\n' '$IP_A' > /hosts/addn" echo " backend-a=$IP_A backend-b=$IP_B (gslb.lab.internal -> $IP_A)" echo "== [5] client (lab-dns ClusterIP + cluster domain 치환) ==" LABDNS_IP="$($K -n "$NS" get svc lab-dns -o jsonpath='{.spec.clusterIP}')" [ -n "$LABDNS_IP" ] || { echo "!! lab-dns ClusterIP 조회 실패"; exit 1; } # cluster domain 자동 발견 — kubespray 커스텀 도메인 대응(이 클러스터는 homelab.local, cluster.local 아님). # 하드코딩 시 istiod FQDN 이 틀려 sidecar XDS 불가 → Envoy 안 뜸(2026-07-01 실측). 실패하면 표준값으로 폴백. CLUSTER_DOMAIN="$($K -n kube-system get cm coredns -o jsonpath='{.data.Corefile}' 2>/dev/null \ | grep -oE 'kubernetes[[:space:]]+[^ ]+' | awk '{print $2}')" CLUSTER_DOMAIN="${CLUSTER_DOMAIN:-cluster.local}" echo " lab-dns = $LABDNS_IP · cluster domain = $CLUSTER_DOMAIN" sed -e "s/__LABDNS_IP__/$LABDNS_IP/g" -e "s/__CLUSTER_DOMAIN__/$CLUSTER_DOMAIN/g" "$SC/30-client.yaml" | $K apply -f - $K -n "$NS" rollout status deploy/fortio --timeout=120s $K -n "$NS" rollout status deploy/netshoot --timeout=120s echo echo "== ready ==" echo " DNS 확인: $K -n $NS exec deploy/netshoot -- dig +short gslb.lab.internal" echo " 실험 시작: bash scripts/dns-flip-test.sh strict mode1" echo " bash scripts/dns-flip-test.sh logical mode1"