# lab-dns — GSLB 시뮬레이터(통제 가능한 authoritative DNS).
#
# 설계 핵심 3가지:
#  1) gslb.lab.internal(+ 작업D의 gslb-pt.lab.internal, TLS passthrough 전용 hostname)만
#     authoritative(hosts 플러그인, ttl 5s)로 응답하고, 나머지(istiod.istio-system.svc 등)는
#     cluster DNS로 forward 한다.
#     → 그래야 client sidecar가 xDS 대상(istiod)을 계속 resolve할 수 있다(자기완결형의 함정).
#  2) flip = shared emptyDir(/hosts/addn) 재작성. 파일엔 두 hostname 모두의 A record가
#     들어갈 수 있다("IP1 gslb.lab.internal\nIP2 gslb-pt.lab.internal\n..."). CoreDNS
#     hosts 플러그인의 reload 2s가 자동 재적재 → 즉시 반영(Corefile 자체 변경은 예외 — 아래 3) 참고).
#  3) CoreDNS 이미지는 distroless라 shell이 없어 exec-write 불가 →
#     같은 pod에 busybox 'writer' 사이드카를 붙여 그 컨테이너로 파일을 쓴다.
#     ⚠ 이건 hosts 파일(/hosts/addn) 재작성에만 해당 — Corefile 자체(이 ConfigMap의 zones
#     목록 등)를 바꾸면 top-level에 `reload` 플러그인이 없어 CoreDNS 프로세스가 자동으로
#     다시 읽지 않는다. Corefile을 바꿨으면 `kubectl rollout restart deploy/lab-dns` 필요
#     (2026-07-09 작업D: gslb-pt.lab.internal 존 추가 시 실측).
#
#  __CLUSTER_DNS__ 는 scripts/dns-lab-setup.sh 가 coredns/kube-dns ClusterIP로 치환한다.
---
apiVersion: v1
kind: ConfigMap
metadata:
  name: coredns-corefile
  namespace: dns-lab
data:
  Corefile: |
    .:53 {
        errors
        log
        # gslb.lab.internal(HTTP origination 경로) + gslb-pt.lab.internal(작업D: TLS
        # passthrough 경로, 별도 hostname) 둘 다 hosts 파일로 응답(ttl 5s). zones 인자에
        # 없는 이름(예: istiod.istio-system.svc)은 이 plugin 이 아예 매치하지 않고
        # 자동으로 forward 로 넘어간다 — gslb-pt 를 추가해도 기존 gslb.lab.internal 존
        # 동작/기존 forward 경로는 그대로다(additive, 2026-07-09 작업D에서 추가).
        hosts /hosts/addn gslb.lab.internal gslb-pt.lab.internal {
            ttl 5
            reload 2s
            fallthrough
        }
        forward . __CLUSTER_DNS__
        cache 5
    }
---
apiVersion: apps/v1
kind: Deployment
metadata:
  name: lab-dns
  namespace: dns-lab
  labels: { app: lab-dns }
spec:
  replicas: 1
  selector:
    matchLabels: { app: lab-dns }
  template:
    metadata:
      labels: { app: lab-dns }
      annotations:
        sidecar.istio.io/inject: "false"   # 인프라 컴포넌트 — 메시 불필요
    spec:
      containers:
        - name: coredns
          image: registry.k8s.io/coredns/coredns:v1.11.3   # 클러스터가 이미 보유한 태그면 pull 불필요
          args: ["-conf", "/etc/coredns/Corefile"]
          ports:
            - { containerPort: 53, protocol: UDP }
            - { containerPort: 53, protocol: TCP }
          volumeMounts:
            - { name: corefile, mountPath: /etc/coredns }
            - { name: hosts,    mountPath: /hosts }
          readinessProbe:
            tcpSocket: { port: 53 }
            initialDelaySeconds: 2
        # writer — busybox: shared /hosts/addn 를 재작성해 GSLB flip을 수행하는 통로.
        - name: writer
          image: busybox:1.36
          command: ["sh", "-c", "touch /hosts/addn; while true; do sleep 3600; done"]
          volumeMounts:
            - { name: hosts, mountPath: /hosts }
      volumes:
        - name: corefile
          configMap: { name: coredns-corefile }
        - name: hosts
          emptyDir: {}
---
apiVersion: v1
kind: Service
metadata:
  name: lab-dns
  namespace: dns-lab
spec:
  selector: { app: lab-dns }
  ports:
    - { name: dns-udp, port: 53, protocol: UDP, targetPort: 53 }
    - { name: dns-tcp, port: 53, protocol: TCP, targetPort: 53 }
