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¶
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:
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:
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:
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.internal → 100.115.1.101 and s3.cl1.sq4.aegis.internal → 100.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):
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:
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:
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:
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 cloud-user@100.115.1.22 "sudo rndc retransfer cl1.sq4.aegis.internal"
ssh cloud-user@100.115.1.22 "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 cloud-user@100.115.1.22:/tmp/
scp /var/named/mod.auh1.dev.dir.zone cloud-user@100.115.1.22:/tmp/
ssh cloud-user@100.115.1.22 "
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
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,s3A records added - [ ] Serial number bumped
- [ ]
named-checkzone cl1.sq4.aegis.internal→ OK - [ ]
systemctl reload namedon100.115.1.21
mod.auh1.dev.dir zone (new)¶
- [ ] Zone file created at
/var/named/mod.auh1.dev.dir.zone - [ ]
*.askwildcard 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 namedon100.115.1.21
Secondary DNS (100.115.1.22)¶
- [ ] Zone files replicated (transfer or manual copy)
- [ ]
named-checkconf→ OK on.22 - [ ]
systemctl reload namedon100.115.1.22
Verification¶
- [ ]
*.askwildcard 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