ECS(RKE2) 기반 Cloudera AI 에서 모델을 배포하면 빌드 파드가 베이스 런타임 이미지를 내부 레지스트리(<registry-host>:58443)에서 받아온다. 빌드가 두 단계에서 연달아 막혔다. 첫째, 파드 안에서 레지스트리 호스트명이 해석되지 않았다(lookup <registry-host> ... no such host). 둘째, 해석된 뒤에는 x509: certificate signed by unknown authority 로 TLS 검증이 실패했다. 노드에서는 /etc/hosts 와 OS 신뢰 저장소 덕에 잘 되지만, 파드는 CoreDNS 를 타고 빌더(s2i-builder)는 별도 신뢰 경로를 본다.
CoreDNS Corefile 의 forward . /etc/resolv.conf 는 CoreDNS 파드 안의 resolv.conf 를 뜻하며 상위 사내 DNS 로 질의가 닿지 않는다. kube-system 의 coredns ConfigMap 은 Helm 이 관리하므로 kubectl edit 으로 고쳐도 재동기화 때 덮어써진다. 마스터 노드에 HelmChartConfig 를 두면 RKE2 가 자동 재배포한다.
# /var/lib/rancher/rke2/server/manifests/rke2-coredns-config.yaml
apiVersion: helm.cattle.io/v1
kind: HelmChartConfig
metadata:
name: rke2-coredns
namespace: kube-system
spec:
valuesContent: |-
servers:
- zones:
- zone: .
port: 53
plugins:
- name: errors
- name: health
configBlock: |-
lameduck 5s
- name: ready
- name: kubernetes
parameters: cluster.local cluster.local in-addr.arpa ip6.arpa
configBlock: |-
pods insecure
fallthrough in-addr.arpa ip6.arpa
ttl 30
- name: prometheus
parameters: 0.0.0.0:9153
- name: forward
parameters: . <내부DNS-IP1> <내부DNS-IP2>
- name: cache
parameters: 30
- name: loop
- name: reload
- name: loadbalance
특정 호스트만 필요하면 forward 앞에 hosts 플러그인(<IP> <fqdn> + fallthrough)을 넣는 우회도 된다. 확인은 kubectl run dnstest --rm -it --image=busybox --restart=Never -- nslookup <registry-host> 로 한다.
/etc/docker/certs.d/<registry-host>:<port>/ca.crt 에 넣어 둔 파일이 실제로는 서버(리프) 인증서였다. basicConstraints 가 CA:FALSE 면 신뢰 앵커로 쓸 수 없다.
openssl s_client -connect <registry-host>:58443 -showcerts </dev/null 2>/dev/null | openssl x509 -noout -issuer -subject
openssl x509 -in /etc/docker/certs.d/<registry-host>:58443/ca.crt -noout -subject -issuer -ext basicConstraints
# 체인에서 루트 CA 추출 (체인에 포함된 경우)
openssl s_client -connect <registry-host>:58443 -showcerts </dev/null 2>/dev/null \
| awk '/-----BEGIN CERTIFICATE-----/{i++} i>1{print}' > /tmp/rootca.crt
openssl x509 -in /tmp/rootca.crt -noout -subject -ext basicConstraints # CA:TRUE 여야 함
# 노드 신뢰 저장소에 이미 있을 때
trust list | grep -i "<CA 이름>" -A2 -B2
올바른 루트 CA 를 확보하면 두 층에 적용한다.
/etc/docker/certs.d/<registry-host>:58443/ca.crt 교체.kubectl -n <workspace-ns> create configmap registry-ca --from-file=registry.crt=/tmp/rootca.crt
kubectl -n <workspace-ns> get deploy | grep -iE 's2i|build'
kubectl -n <workspace-ns> edit deploy <s2i-builder-deploy>
volumes:
- name: registry-ca
configMap:
name: registry-ca
containers:
- volumeMounts:
- name: registry-ca
mountPath: /etc/ssl/certs/registry-ca.crt # 버전별 경로 확인
subPath: registry.crt
fs.inotify.max_user_instances=256 은 낮다. fs.inotify.max_user_instances=8192, fs.inotify.max_user_watches=1048576 로 올리고 sysctl -p 한다. net.bridge.bridge-nf-call-iptables=1 은 필수다.