Skip to content

Phase 5b — DNS Records (BIND)

Add all platform hostnames to the BIND DNS servers before applying TLS (Phase 6). DNS must be in place before ingress TLS is enabled — browsers and pods resolve hostnames at connection time.


Interim Fix — CoreDNS Hosts Block (use while BIND is being updated)

Temporary workaround — remove once BIND is updated

If ArgoCD or other pods cannot resolve cluster hostnames because BIND hasn't been updated yet, inject the records directly into CoreDNS via a hosts block. This unblocks pod DNS immediately without touching the BIND servers. Remove this block once BIND records are in place.

Step 1 — Edit the CoreDNS ConfigMap

kubectl edit configmap rke2-coredns-rke2-coredns -n kube-system

Add the hosts block before the forward line:

.:53 {
    errors
    health {
        lameduck 10s
    }
    ready
    kubernetes  cluster.local  cluster.local in-addr.arpa ip6.arpa {
        pods insecure
        fallthrough in-addr.arpa ip6.arpa
        ttl 30
    }
    prometheus  0.0.0.0:9153
    hosts {
      100.115.1.51 gitlab.cl1.sq4.aegis.internal
      100.115.1.51 registry.cl1.sq4.aegis.internal
      100.115.1.51 kas.cl1.sq4.aegis.internal
      100.115.1.51 argocd.cl1.sq4.aegis.internal
      100.115.1.51 vault.cl1.sq4.aegis.internal
      fallthrough
    }
    forward  . /etc/resolv.conf
    cache  30
    loop
    reload
    loadbalance
}

Save and quit (:wq).

Step 2 — Restart CoreDNS to pick up the change

The reload plugin should pick it up automatically but can take up to 30s. Force an immediate rollout:

kubectl rollout restart deployment rke2-coredns-rke2-coredns -n kube-system
kubectl rollout status deployment rke2-coredns-rke2-coredns -n kube-system

CoreDNS replica count vs schedulable nodes — read before restarting

This cluster has 9 CoreDNS replicas but only 7 schedulable worker nodes (3 masters have untolerated node-role.kubernetes.io/master taint; 7 GPU nodes have untolerated nvidia.com/gpu taint). Anti-affinity limits to 1 CoreDNS pod per node.

A rollout restart will deadlock — new pods can't schedule because old pods occupy all 7 nodes, and old pods won't terminate until new pods are Ready.

Scale to 7 first, then restart:

kubectl scale deployment rke2-coredns-rke2-coredns -n kube-system --replicas=7
kubectl rollout restart deployment rke2-coredns-rke2-coredns -n kube-system
kubectl rollout status deployment rke2-coredns-rke2-coredns -n kube-system

If the rollout deadlocks anyway (two replicasets fighting), break it with:

# 1. Scale the old replicaset to 0 (get name from kubectl get rs -n kube-system)
kubectl scale replicaset <old-rs-name> -n kube-system --replicas=0

# 2. Delete any stuck Pending pods
kubectl delete pods -n kube-system -l k8s-app=kube-dns --field-selector=status.phase=Pending --grace-period=0 --force

# 3. Re-apply replica count
kubectl scale deployment rke2-coredns-rke2-coredns -n kube-system --replicas=7

Root cause: The GPU operator added nvidia.com/gpu:NoSchedule to 7 GPU nodes after CoreDNS was originally deployed (when those nodes were schedulable). Permanently fix by keeping replicas at 7 to match the 7 dedicated worker nodes.

Watch progress:

kubectl get pods -n kube-system -l k8s-app=kube-dns -w

Step 3 — Verify

CoreDNS pod placement — verified 2026-06-10

7 pods running, one per worker node. The CoreDNS pod's own /etc/resolv.conf points directly to BIND (not itself — that would be circular). Do not test DNS from inside a CoreDNS pod — it bypasses CoreDNS and goes straight to BIND.

Pod suffix Node
556f4 k8s-worker7
57466 k8s-worker3
7rcqz k8s-worker5
85c97 k8s-worker4
pr57r k8s-worker2
ss2vn k8s-worker1
t2286 k8s-worker6

Check current placement:

kubectl get pods -n kube-system -l k8s-app=kube-dns -o wide

Test from a non-CoreDNS pod (e.g. any running pod in default namespace):

POD=$(kubectl get pods -n kube-system -l k8s-app=kube-dns --no-headers | grep Running | head -1 | awk '{print $1}')
COREDNS_SVC=$(kubectl get svc -n kube-system | grep -i dns | grep -v pushprox | awk '{print $3}' | head -1)
kubectl exec -n kube-system $POD -- nslookup gitlab.cl1.sq4.aegis.internal $COREDNS_SVC

Expected:

Server:    100.115.1.21
Address 1: 100.115.1.21

Name:      gitlab.cl1.sq4.aegis.internal
Address 1: 100.115.1.51

Test all 5 hostnames at once:

POD=$(kubectl get pods -n kube-system -l k8s-app=kube-dns --no-headers | head -1 | awk '{print $1}')
for host in gitlab registry kas argocd vault; do
  echo -n "${host}.cl1.sq4.aegis.internal → "
  kubectl exec -n kube-system $POD -- nslookup ${host}.cl1.sq4.aegis.internal 2>/dev/null \
    | grep "Address 1:" | grep -v "100.115.1.21" | awk '{print $3}'
done

Expected:

gitlab.cl1.sq4.aegis.internal   → 100.115.1.51
registry.cl1.sq4.aegis.internal → 100.115.1.51
kas.cl1.sq4.aegis.internal      → 100.115.1.51
argocd.cl1.sq4.aegis.internal   → 100.115.1.51
vault.cl1.sq4.aegis.internal    → 100.115.1.51

Step 4 — Remove hosts block once BIND is updated

Once the BIND records are confirmed (Step 5b.5), remove the hosts block:

kubectl edit configmap rke2-coredns-rke2-coredns -n kube-system
# Delete the entire hosts { ... } block
# Save and quit

kubectl rollout restart deployment rke2-coredns-rke2-coredns -n kube-system
kubectl rollout status deployment rke2-coredns-rke2-coredns -n kube-system

Verify BIND is now answering:

POD=$(kubectl get pods -n kube-system -l k8s-app=kube-dns --no-headers | head -1 | awk '{print $1}')
kubectl exec -n kube-system $POD -- nslookup gitlab.cl1.sq4.aegis.internal
# Should still resolve — now via BIND instead of hosts block


Overview

Item Value
Primary DNS 100.115.1.21
Secondary DNS 100.115.1.22
Zone (existing) cl1.sq4.aegis.internal
Zone (new) mod.auh1.dev.dir
Ingress Controller IPs 100.115.1.51, 100.115.1.52, 100.115.1.53 (master nodes)
RGW S3 VIP 100.115.1.130

Why 3 A records per hostname (not 1)?

The RKE2 Ingress Controller is a DaemonSet running on all 17 nodes. The kubectl get ingress ADDRESS field shows all 17 node IPs as valid endpoints. For DNS we use only the 3 master node IPs — they are the most stable (workers can be drained or replaced without affecting DNS resolution). DNS round-robins across the 3 masters; any one of them can accept the request.

Node IP
k8s-master1 100.115.1.51
k8s-master2 100.115.1.52
k8s-master3 100.115.1.53

Bastion /etc/hosts — current state (informational only)

The bastion /etc/hosts has several entries pointing to 100.115.1.14 (a worker node IP). These are not authoritative and use the wrong IP. Once BIND is updated, remove these and rely on DNS. After BIND is updated and verified, clean up the bastion hosts file:

sudo sed -i '/cl1.sq4.aegis.internal/d' /etc/hosts

CoreDNS forwards to BIND automatically

RKE2 CoreDNS is configured with forward . /etc/resolv.conf. The nodes' /etc/resolv.conf points to 100.115.1.21 and 100.115.1.22. This means all K8s pods automatically inherit DNS from BIND — no CoreDNS changes needed.

Update both BIND servers

100.115.1.21 and 100.115.1.22 must have identical zone data. Add records to .21 first, then replicate to .22 (or use zone transfer if configured).


DNS Records Required

Zone: cl1.sq4.aegis.internal — Add these records

All ingress hostnames need 3 A records — one per master node

BIND supports multiple A records per name (round-robin). Add all three for each hostname.

Hostname Type Value Service
gitlab.cl1.sq4.aegis.internal A 100.115.1.51 GitLab
gitlab.cl1.sq4.aegis.internal A 100.115.1.52 GitLab
gitlab.cl1.sq4.aegis.internal A 100.115.1.53 GitLab
registry.cl1.sq4.aegis.internal A 100.115.1.51 GitLab Container Registry
registry.cl1.sq4.aegis.internal A 100.115.1.52 GitLab Container Registry
registry.cl1.sq4.aegis.internal A 100.115.1.53 GitLab Container Registry
kas.cl1.sq4.aegis.internal A 100.115.1.51 GitLab KAS
kas.cl1.sq4.aegis.internal A 100.115.1.52 GitLab KAS
kas.cl1.sq4.aegis.internal A 100.115.1.53 GitLab KAS
argocd.cl1.sq4.aegis.internal A 100.115.1.51 ArgoCD UI
argocd.cl1.sq4.aegis.internal A 100.115.1.52 ArgoCD UI
argocd.cl1.sq4.aegis.internal A 100.115.1.53 ArgoCD UI
vault.cl1.sq4.aegis.internal A 100.115.1.51 HashiCorp Vault
vault.cl1.sq4.aegis.internal A 100.115.1.52 HashiCorp Vault
vault.cl1.sq4.aegis.internal A 100.115.1.53 HashiCorp Vault
harbor.cl1.sq4.aegis.internal A 100.115.1.101 Harbor Registry ✅ already in BIND
s3.cl1.sq4.aegis.internal A 100.115.1.130 Ceph RGW S3 endpoint ✅ already in BIND

Already in BIND — do not add again

harbor.cl1.sq4.aegis.internal100.115.1.101 and s3.cl1.sq4.aegis.internal100.115.1.130 already exist. Add only the 5 new hostnames above (gitlab, registry, kas, argocd, vault).


Zone: mod.auh1.dev.dir — New zone, create all records

Hostname Type Value Service
ask.mod.auh1.dev.dir A 100.115.1.51 ASK Frontend
ask.mod.auh1.dev.dir A 100.115.1.52 ASK Frontend
ask.mod.auh1.dev.dir A 100.115.1.53 ASK Frontend
api.mod.auh1.dev.dir A 100.115.1.51 ASK Core Service API
api.mod.auh1.dev.dir A 100.115.1.52 ASK Core Service API
api.mod.auh1.dev.dir A 100.115.1.53 ASK Core Service API
argocd.mod.auh1.dev.dir A 100.115.1.51 ArgoCD UI
argocd.mod.auh1.dev.dir A 100.115.1.52 ArgoCD UI
argocd.mod.auh1.dev.dir A 100.115.1.53 ArgoCD UI
gitlab.mod.auh1.dev.dir A 100.115.1.51 GitLab
gitlab.mod.auh1.dev.dir A 100.115.1.52 GitLab
gitlab.mod.auh1.dev.dir A 100.115.1.53 GitLab
vault.mod.auh1.dev.dir A 100.115.1.51 HashiCorp Vault
vault.mod.auh1.dev.dir A 100.115.1.52 HashiCorp Vault
vault.mod.auh1.dev.dir A 100.115.1.53 HashiCorp Vault
harbor.mod.auh1.dev.dir A 100.115.1.51 Harbor Registry
harbor.mod.auh1.dev.dir A 100.115.1.52 Harbor Registry
harbor.mod.auh1.dev.dir A 100.115.1.53 Harbor Registry
s3.mod.auh1.dev.dir A 100.115.1.130 Ceph RGW S3 (alias)
*.ask.mod.auh1.dev.dir A 100.115.2.210 ASK application subdomains (wildcard via app HAProxy VIP)

ASK application subdomains — one wildcard covers them all

The ASK apps use two-level hostnames under ask.mod.auh1.dev.dir, which the *.mod.auh1.dev.dir wildcard does not match (a wildcard matches only one label). So they get their own wildcard record pointing at the app HAProxy VIP (100.115.2.210, TCP/SNI passthrough → worker-node nginx ingress — see App HAProxy):

*.ask.mod.auh1.dev.dir.   IN  A   100.115.2.210

This single record serves every current and future ASK app subdomain — no per-host A records are needed, just the one wildcard:

Hostname Service Notes
sso.ask.mod.auh1.dev.dir Zitadel (IAM) core-service chart ingress; browser hits it during login
core-service.ask.mod.auh1.dev.dir ASK Core Service API (path /) its own ingress host (verified kubectl get ingress -n ask); browser calls it for org discovery
api.ask.mod.auh1.dev.dir assistant-service API (path /ask71/v2/astsvc) (PP also routes core-service /ask71/v2/svc here, but in this env core-service has its own host above)
hatchet.ask.mod.auh1.dev.dir Hatchet dashboard + the engine's external gRPC broadcast address in-cluster clients use hatchet-engine.ask.svc:7070 instead (see below)
admin.ask.mod.auh1.dev.dir ASK Frontend — Super-Admin tenant the frontend redirects to <tenant_subdomain>.<base> after login; ask-default org tenant_subdomain=admin → this host. Requires the air-gap frontend image (see note below)
chat.ask.mod.auh1.dev.dir ASK Frontend — chat tenant only if a chat tenant org is used (PP pattern); covered by the wildcard regardless

ask.mod.auh1.dev.dir (the frontend root) is single-level, so it's covered by the existing *.mod.auh1.dev.dir wildcard — not this *.ask one.

Frontend tenant subdomains (admin./chat.) — DNS is ready, image is the blocker

The *.ask.mod.auh1.dev.dir wildcard already resolves admin.ask.mod.auh1.dev.dir, so no new DNS record is needed for the frontend tenant redirect. But the frontend currently ships the staging image which bakes NEXT_PUBLIC_APP_BASE_URL=ask.stg.ai71.ai → it redirects to admin.ask.stg.ai71.ai (un-resolvable here). DNS alone can't fix this; the frontend must be rebuilt with NEXT_PUBLIC_APP_BASE_URL=https://ask.mod.auh1.dev.dir. See Troubleshooting → frontend redirects to admin.ask.stg.ai71.ai. Once the correct image is deployed, also add admin.ask.mod.auh1.dev.dir (and chat. if used) to the frontend ingress hosts + the frontend-tls cert SANs.

Until the *.ask wildcard is in BIND, these resolve only via manual /etc/hosts entries (100.115.2.210 <host>) — add the wildcard to retire those workarounds.

Client browser (Mac) — interim /etc/hosts until the *.ask wildcard is in BIND

The Mac browser resolves these hosts itself. /etc/hosts does not support wildcards, so each ASK host must be listed explicitly → the app HAProxy VIP 100.115.2.210:

100.115.2.210  ask.mod.auh1.dev.dir core-service.ask.mod.auh1.dev.dir api.ask.mod.auh1.dev.dir sso.ask.mod.auh1.dev.dir hatchet.ask.mod.auh1.dev.dir admin.ask.mod.auh1.dev.dir
admin.ask.mod.auh1.dev.dir is included for the frontend tenant redirect (needed once the air-gap frontend image is deployed). Apply, then flush DNS:
sudo dscacheutil -flushcache; sudo killall -HUP mDNSResponder
Once the BIND *.ask wildcard is live, remove these lines and rely on DNS.

hatchet.ask... is the token's gRPC broadcast address — don't use it in-cluster

The Hatchet engine is deployed with SERVER_GRPC_BROADCAST_ADDRESS = hatchet.ask.mod.auh1.dev.dir:443, so client tokens embed that external address. In-cluster consumers (core-service, assistant-service workers) must override it to the internal service — HATCHET_CLIENT_HOST_PORT = hatchet-engine.ask.svc.cluster.local:7070 (plaintext gRPC) — because pods can't resolve the external host and :443 is TLS (conflicts with tls_strategy=none). The *.ask record is only for external Hatchet access (dashboard).


Step 5b.1 — Confirm Zone File Location

Run on both BIND servers:

sudo grep -A5 'cl1.sq4.aegis' /etc/named.conf

Expected output:

zone "cl1.sq4.aegis.internal" IN {
    type master;
    file "/var/named/cl1.sq4.aegis.internal.zone";
    allow-update { none; };
};

Note the file path — use it in the steps below.


Step 5b.2 — Add Records to cl1.sq4.aegis.internal

Run on 100.115.1.21 first:

# Set your zone file path from Step 5b.1
ZONE_FILE="/var/named/cl1.sq4.aegis.internal.zone"

# Backup first
sudo cp $ZONE_FILE ${ZONE_FILE}.bak.$(date +%Y%m%d)

# Add A records
sudo tee -a $ZONE_FILE > /dev/null << 'EOF'

; --- core42 deployment records added $(date +%Y-%m-%d) ---
; 3 A records per ingress hostname = round-robin across master nodes
gitlab          IN  A  100.115.1.51
gitlab          IN  A  100.115.1.52
gitlab          IN  A  100.115.1.53
registry        IN  A  100.115.1.51
registry        IN  A  100.115.1.52
registry        IN  A  100.115.1.53
kas             IN  A  100.115.1.51
kas             IN  A  100.115.1.52
kas             IN  A  100.115.1.53
argocd          IN  A  100.115.1.51
argocd          IN  A  100.115.1.52
argocd          IN  A  100.115.1.53
vault           IN  A  100.115.1.51
vault           IN  A  100.115.1.52
vault           IN  A  100.115.1.53
; harbor (100.115.1.101) and s3 (100.115.1.130) already exist — do not re-add
EOF

# Bump serial number (must be higher than current)
# Find current serial first
sudo grep -i serial $ZONE_FILE

Update the serial manually to today's date + increment (e.g. 2026060901):

# Edit the zone file and update the serial line
sudo vi $ZONE_FILE
# Change: 2026052003  →  2026060901

Verify syntax:

sudo named-checkzone cl1.sq4.aegis.internal $ZONE_FILE
# Expected: zone cl1.sq4.aegis.internal/IN: loaded serial XXXXXXXXXX
#           OK

Reload BIND:

sudo systemctl reload named
echo "✅ BIND reloaded on 100.115.1.21"


Step 5b.3 — Create New Zone mod.auh1.dev.dir

Run on 100.115.1.21:

Step 5b.3a — Create zone file

sudo tee /var/named/mod.auh1.dev.dir.zone > /dev/null << 'EOF'
$TTL 3600
@   IN  SOA  ns1.mod.auh1.dev.dir. admin.mod.auh1.dev.dir. (
        2026060901  ; Serial (YYYYMMDDNN)
        3600        ; Refresh
        600         ; Retry
        1209600     ; Expire
        3600 )      ; Minimum TTL

; Name servers
@       IN  NS   ns1.mod.auh1.dev.dir.
ns1     IN  A    100.115.1.21

; --- ASK Platform services (3 A records per name = round-robin across masters) ---
ask         IN  A  100.115.1.51
ask         IN  A  100.115.1.52
ask         IN  A  100.115.1.53
api         IN  A  100.115.1.51
api         IN  A  100.115.1.52
api         IN  A  100.115.1.53
argocd      IN  A  100.115.1.51
argocd      IN  A  100.115.1.52
argocd      IN  A  100.115.1.53
gitlab      IN  A  100.115.1.51
gitlab      IN  A  100.115.1.52
gitlab      IN  A  100.115.1.53
vault       IN  A  100.115.1.51
vault       IN  A  100.115.1.52
vault       IN  A  100.115.1.53
harbor      IN  A  100.115.1.51
harbor      IN  A  100.115.1.52
harbor      IN  A  100.115.1.53
s3          IN  A  100.115.1.130

; --- ASK application subdomains (two-level *.ask) → app HAProxy VIP (SNI passthrough) ---
; one wildcard serves sso, core-service, api, hatchet, admin (frontend tenant), chat, etc.
*.ask       IN  A  100.115.2.210
EOF

The *.ask wildcard is the record that makes login work

Without *.ask IN A 100.115.2.210, the browser can't resolve sso.ask…, core-service.ask…, or the frontend's admin.ask… tenant redirect — and login fails even though the backend is healthy. This one line replaces the per-host /etc/hosts workarounds.

Step 5b.3b — Register zone in named.conf

sudo tee -a /etc/named.conf > /dev/null << 'EOF'

zone "mod.auh1.dev.dir" IN {
    type master;
    file "/var/named/mod.auh1.dev.dir.zone";
    allow-update { none; };
};
EOF

Step 5b.3c — Verify and reload

# Check named.conf syntax
sudo named-checkconf
# Expected: no output = OK

# Check zone file syntax
sudo named-checkzone mod.auh1.dev.dir /var/named/mod.auh1.dev.dir.zone
# Expected: OK

# Reload BIND
sudo systemctl reload named
echo "✅ BIND reloaded — mod.auh1.dev.dir zone active"

Step 5b.4 — Replicate to Secondary DNS (100.115.1.22)

If 100.115.1.22 is a BIND slave with zone transfer from .21:

# Force zone transfer on secondary
ssh [email protected] "sudo rndc retransfer cl1.sq4.aegis.internal"
ssh [email protected] "sudo rndc retransfer mod.auh1.dev.dir"

If 100.115.1.22 is a standalone master (no zone transfer):

# Copy zone files manually
scp /var/named/cl1.sq4.aegis.internal.zone [email protected]:/tmp/
scp /var/named/mod.auh1.dev.dir.zone [email protected]:/tmp/

ssh [email protected] "
  sudo cp /tmp/cl1.sq4.aegis.internal.zone /var/named/
  sudo cp /tmp/mod.auh1.dev.dir.zone /var/named/

  # Add mod.auh1.dev.dir zone to named.conf if not already there
  sudo grep -q 'mod.auh1.dev.dir' /etc/named.conf || sudo tee -a /etc/named.conf > /dev/null << 'EOF'

zone \"mod.auh1.dev.dir\" IN {
    type master;
    file \"/var/named/mod.auh1.dev.dir.zone\";
    allow-update { none; };
};
EOF

  sudo named-checkconf &&
  sudo named-checkzone mod.auh1.dev.dir /var/named/mod.auh1.dev.dir.zone &&
  sudo systemctl reload named &&
  echo '✅ 100.115.1.22 updated'
"


Step 5b.5 — Verify All Records

Run from bastion against both DNS servers:

echo "=== Checking 100.115.1.21 ==="
for host in \
  argocd.cl1.sq4.aegis.internal \
  vault.cl1.sq4.aegis.internal \
  harbor.cl1.sq4.aegis.internal \
  s3.cl1.sq4.aegis.internal \
  ask.mod.auh1.dev.dir \
  api.mod.auh1.dev.dir \
  argocd.mod.auh1.dev.dir \
  gitlab.mod.auh1.dev.dir \
  vault.mod.auh1.dev.dir \
  harbor.mod.auh1.dev.dir \
  s3.mod.auh1.dev.dir; do
  result=$(dig $host @100.115.1.21 +short)
  echo "$host$result"
done

echo ""
echo "=== Checking 100.115.1.22 ==="
for host in \
  argocd.cl1.sq4.aegis.internal \
  vault.cl1.sq4.aegis.internal \
  harbor.cl1.sq4.aegis.internal \
  s3.cl1.sq4.aegis.internal \
  ask.mod.auh1.dev.dir \
  api.mod.auh1.dev.dir \
  argocd.mod.auh1.dev.dir \
  gitlab.mod.auh1.dev.dir \
  vault.mod.auh1.dev.dir \
  harbor.mod.auh1.dev.dir \
  s3.mod.auh1.dev.dir; do
  result=$(dig $host @100.115.1.22 +short)
  echo "$host$result"
done

Expected output (3 IPs per ingress hostname — round-robin across masters):

gitlab.cl1.sq4.aegis.internal    → 100.115.1.51 100.115.1.52 100.115.1.53
registry.cl1.sq4.aegis.internal  → 100.115.1.51 100.115.1.52 100.115.1.53
kas.cl1.sq4.aegis.internal       → 100.115.1.51 100.115.1.52 100.115.1.53
argocd.cl1.sq4.aegis.internal    → 100.115.1.51 100.115.1.52 100.115.1.53
vault.cl1.sq4.aegis.internal     → 100.115.1.51 100.115.1.52 100.115.1.53
harbor.cl1.sq4.aegis.internal    → 100.115.1.101
s3.cl1.sq4.aegis.internal        → 100.115.1.130
ask.mod.auh1.dev.dir             → 100.115.1.51 100.115.1.52 100.115.1.53
api.mod.auh1.dev.dir             → 100.115.1.51 100.115.1.52 100.115.1.53
argocd.mod.auh1.dev.dir          → 100.115.1.51 100.115.1.52 100.115.1.53
gitlab.mod.auh1.dev.dir          → 100.115.1.51 100.115.1.52 100.115.1.53
vault.mod.auh1.dev.dir           → 100.115.1.51 100.115.1.52 100.115.1.53
harbor.mod.auh1.dev.dir          → 100.115.1.51 100.115.1.52 100.115.1.53
s3.mod.auh1.dev.dir              → 100.115.1.130

Then confirm the *.ask wildcard answers for the ASK app subdomains (all → the HAProxy VIP):

for host in sso core-service api hatchet admin chat; do
  echo -n "${host}.ask.mod.auh1.dev.dir → "
  dig ${host}.ask.mod.auh1.dev.dir @100.115.1.21 +short
done
Expected — every one resolves to 100.115.2.210 (the wildcard matches any single *.ask label):
sso.ask.mod.auh1.dev.dir          → 100.115.2.210
core-service.ask.mod.auh1.dev.dir → 100.115.2.210
api.ask.mod.auh1.dev.dir          → 100.115.2.210
hatchet.ask.mod.auh1.dev.dir      → 100.115.2.210
admin.ask.mod.auh1.dev.dir        → 100.115.2.210
chat.ask.mod.auh1.dev.dir         → 100.115.2.210


Step 5b.6 — Verify from K8s Pod

Confirm CoreDNS is forwarding correctly:

kubectl run dnsverify --rm -it --restart=Never -n default \
  --image=harbor.cl1.sq4.aegis.internal/dockerhub/amazon/aws-cli:2.22.0 \
  --overrides='{
    "spec":{
      "securityContext":{"runAsNonRoot":true,"runAsUser":1000,"seccompProfile":{"type":"RuntimeDefault"}},
      "containers":[{
        "name":"dnsverify",
        "image":"harbor.cl1.sq4.aegis.internal/dockerhub/amazon/aws-cli:2.22.0",
        "command":["/bin/sh","-c","for h in argocd.cl1.sq4.aegis.internal ask.mod.auh1.dev.dir s3.cl1.sq4.aegis.internal; do echo -n \"$h → \"; getent hosts $h | awk \"{print \\$1}\"; done"],
        "securityContext":{"allowPrivilegeEscalation":false,"capabilities":{"drop":["ALL"]}}
      }]
    }
  }'

Summary Checklist

cl1.sq4.aegis.internal zone

  • [ ] Zone file path confirmed
  • [ ] Backup taken (cp zone.file zone.file.bak.YYYYMMDD)
  • [ ] argocd, vault, harbor, s3 A records added
  • [ ] Serial number bumped
  • [ ] named-checkzone cl1.sq4.aegis.internal → OK
  • [ ] systemctl reload named on 100.115.1.21

mod.auh1.dev.dir zone (new)

  • [ ] Zone file created at /var/named/mod.auh1.dev.dir.zone
  • [ ] *.ask wildcard A record added (*.ask IN A 100.115.2.210) — serves sso/core-service/api/hatchet/admin/chat
  • [ ] Zone registered in /etc/named.conf
  • [ ] named-checkconf → OK
  • [ ] named-checkzone mod.auh1.dev.dir → OK
  • [ ] systemctl reload named on 100.115.1.21

Secondary DNS (100.115.1.22)

  • [ ] Zone files replicated (transfer or manual copy)
  • [ ] named-checkconf → OK on .22
  • [ ] systemctl reload named on 100.115.1.22

Verification

  • [ ] *.ask wildcard resolves (sso/core-service/admin.ask… → 100.115.2.210)
  • [ ] All 10 hostnames resolve correctly via dig @100.115.1.21
  • [ ] All 10 hostnames resolve correctly via dig @100.115.1.22
  • [ ] Pod DNS test passes (Step 5b.6)
  • [ ] Proceed to Phase 6 — TLS & cert-manager