ECS 용 와일드카드 DNS(*.apps.<host>) 를 잘못 등록한 상태에서 agent 를 재기동했더니, 서버가 그 호스트를 console-cdp.apps.ip-10-14-51-21... 로 기억하게 됐다. DNS 는 이후 바로잡았는데 heartbeat 가 계속 끊긴다. 서버 로그는 이렇게 나온다.
Hostname validation failed: Certificate for <console-cdp.apps.ip-10-14-51-21.ap-northeast-2.compute.internal>
doesn't match any of the subject alternative names: [ip-10-14-51-21.ap-northeast-2.compute.internal]
이 메시지는 "에이전트가 옛 이름 인증서를 내밀고 있다" 가 아니다. 서버가 아직 그 호스트를 console-cdp.apps... 로 알고 있어서 그 이름으로 검증을 시도하는데, 에이전트 인증서의 SAN 은 이미 올바른 ip-10-14-51-21... 하나뿐이라 안 맞는 것이다. 인증서는 정상이고 서버 DB 에 남은 옛 이름이 문제다.
그런데 서버 DB 를 직접 UPDATE 하면 안 된다. 호스트 식별은 hostname 이 아니라 /var/lib/cloudera-scm-agent/uuid 로 하고 hostname 은 heartbeat 가 들어올 때 자동 갱신되기 때문이다. 지금은 TLS 검증이 heartbeat 자체를 막고 있어 그 갱신이 못 일어나는 교착일 뿐이다. 검증만 통과시키면 이름은 알아서 바뀐다.
openssl x509 -in /var/lib/cloudera-scm-agent/agent-cert/cm-auto-host_cert_chain.pem \
-noout -subject -ext subjectAltName
python -c 'import socket; print(socket.getfqdn())'
hostname -f
getent hosts <IP>
grep -iE 'hostname|fqdn' /var/log/cloudera-scm-agent/cloudera-scm-agent.log | tail
세 이름이 모두 올바른 FQDN 으로 나와야 한다. 하나라도 옛 이름이 나오면 /etc/hosts 잔존 항목이나 PTR, nscd · sssd 캐시를 먼저 정리한다.
이름이 깨끗하면 supervisord 까지 내렸다 올린다. 일반 restart 는 supervisord 를 재시작하지 않아 프로세스가 옛 상태를 그대로 물고 있을 수 있다.
service cloudera-scm-agent hard_restart
hard_restart 는 그 호스트에서 돌던 role 프로세스(DataNode 등) 도 같이 내리므로, 복구 후 CM 에서 role 을 다시 시작해야 한다.
Auto-TLS 라면 인증서 자체를 다시 발급해야 할 때 generateHostCerts API 를 쓴다. SSH 경유라 heartbeat 없이도 배포된다. 수동 TLS 면 같은 경로 · 같은 파일명으로 교체한 뒤 재시작한다.
환경 생성 잡이 console-cdp.apps.<host> 를 못 푼다. 여기서 흔한 오해가 호스트의 /etc/resolv.conf 를 고치는 것이다. 환경 생성 잡은 파드 안에서 돈다. 파드는 호스트 resolv.conf 가 아니라 CoreDNS(10.43.0.10) 를 보고, CoreDNS 가 모르는 도메인은 자기 upstream 으로 넘긴다. 그 upstream 이 와일드카드를 모르는 DNS 면 호스트 설정을 아무리 고쳐도 똑같이 실패한다.
이 사례에서는 와일드카드가 10.14.51.10 에만 있고 회사 공용 DNS 10.14.0.2 에는 없었다. 각 nameserver 에 직접 물어 확인한다.
grep nameserver /etc/resolv.conf
dig +short console-cdp.apps.ip-10-14-51-21.ap-northeast-2.compute.internal @10.14.51.10
dig +short console-cdp.apps.ip-10-14-51-21.ap-northeast-2.compute.internal @10.14.0.2
정공법은 두 DNS 모두에 같은 레코드를 넣는 것이다.
*.apps.ip-10-14-51-21.ap-northeast-2.compute.internal. IN A 10.14.51.21
관리 주체가 달라 공용 DNS 를 못 건드리면, 호스트 resolv.conf 에서 그 nameserver 를 빼는 대신 CoreDNS 에 해당 존만 포워딩하는 블록을 추가한다. 호스트 네트워크를 건드리지 않아 다른 도메인 해석에 영향이 없고, configmap 에 저장되므로 재부팅에도 남고, 노드가 다섯 대여도 한 군데만 고치면 된다. resolv.conf 를 손으로 고치는 방식은 NetworkManager · cloud-init 이 재부팅 때 덮어써서 원복되고, 노드 하나라도 빠지면 "됐다 안 됐다" 가 재발한다.
export KUBECONFIG=/etc/rancher/rke2/rke2.yaml
export PATH=$PATH:/var/lib/rancher/rke2/bin
kubectl get configmap -n kube-system rke2-coredns-rke2-coredns -o yaml > /root/coredns-backup.yaml
kubectl edit configmap -n kube-system rke2-coredns-rke2-coredns
기존 .:53 { ... } 블록은 그대로 두고 아래 블록을 덧붙인다.
ap-northeast-2.compute.internal:53 {
errors
cache 30
forward . 10.14.51.10
}
kubectl rollout restart deployment -n kube-system rke2-coredns-rke2-coredns
kubectl rollout status deployment -n kube-system rke2-coredns-rke2-coredns
노드 다섯 대 중 두 대만 이상해 보였지만 실제로는 정상이었고, getent hosts <IP> 가 처음엔 비었다가 두 번째에 나오는 현상도 있었다. 캐시가 채워지는 과정이라 시간이 지나면 풀리므로, 한 번의 실패로 노드별 설정 차이를 단정하면 안 된다. 화면에 보이는 nameserver 10.14.0.2 같은 줄이 방금 연 파일의 내용인지 직전 명령의 잔상인지도 구분해야 한다. vi 는 내용을 표준출력으로 내보내지 않는다.
파드 안에서 python3 -c 로 gethostbyname 을 돌리다 syntax error near unexpected token 이 나오면 DNS 가 아니라 셸 따옴표 중첩 문제다.