일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | |||||
3 | 4 | 5 | 6 | 7 | 8 | 9 |
10 | 11 | 12 | 13 | 14 | 15 | 16 |
17 | 18 | 19 | 20 | 21 | 22 | 23 |
24 | 25 | 26 | 27 | 28 | 29 | 30 |
- gitea
- gitops
- knative
- blue/green
- Model Serving
- Continuous Deployment
- Litmus
- kubernetes operator
- Kopf
- serving
- nginx ingress
- CI/CD
- argocd
- Kubernetes 인증
- Kubeflow
- opensearch
- Argo
- 카오스 엔지니어링
- keda
- Kubernetes
- 오퍼레이터
- mlops
- opentelemetry
- tekton
- MLflow
- operator
- Pulumi
- argo rollout
- CANARY
- seldon core
- Today
- Total
Kubernetes 이야기
Kubernetes에서 NodeLocal DNSCache 사용 본문
기본적으로 Pod는 kube-dns 서비스에 쿼리를 보냅니다 . Pod의 /etc/resolv.conf 에 nameserver가 자동으로 세팅된다.
# cat /etc/resolv.conf
search test.svc.cluster.local svc.cluster.local cluster.local
nameserver 10.96.0.10
options ndots:5
Kubernetes 클러스터에서 DNS를 구현하는 가장 일반적인 방법은 서비스 추상화를 사용하는 것이다. 기본적으로 서비스 추상화는 DNAT를 사용하여 Service ClusterIP로 들어오는 요청을 DNS Pod로 균형을 맞추는 iptables 규칙 집합이다. 이 메커니즘은 conntrack 모듈을 사용하여 커널에서 처리된다.
Linux 커널 conntrack 모듈은 동일한 소켓을 통해 동시에 다른 스레드에서 전송된 UDP 패킷은 영향을 받는다. 경쟁이 발생하면 UDP 패킷이 삭제되고 결과적으로 호스트 이름이 전혀 확인되지 않는다.
이러한 이유로 Kubernetes의 DNS 확인이 안정적으로 작동하지 않는 경우가 있다. 때때로 5초 후에 시간이 초과되는 경우이다. DNS 쿼리에 문제가 발생하면 올바른 애플리케이션 실행 시 시간 초과로 종료될 수 있다.
이러한 문제를 완화하려면 여러 가지 해결 방법이 존재하지만 이러한 문제와 기타 문제의 장기적인 완화로 Kubernetes DNS 아키텍처가 재설계되었으며 결과는 Nodelocal DNS 캐시 프로젝트 가 되었습니다.
NodeLocal DNSCache는 클러스터 노드에서 DaemonSet으로 DNS 캐싱 에이전트를 실행하여 클러스터 DNS 성능을 향상시킨다.
'ClusterFirst' DNS 모드의 Pod는 DNS 쿼리를 위해 kube-dns에 도달한다. 이것은 kube-proxy에 의해 추가된 iptables 규칙을 통해 kube-dns/CoreDNS 끝점으로 변환된다. DNSCache에서의 Pod는 동일한 노드에서 실행되는 DNS 캐싱 에이전트에 도달하므로 iptables DNAT 규칙 및 연결 추적을 피할 수 있다.
아키텍처
NodeLocal DNSCache가 활성화된 후 DNS 쿼리가 따라오는 경로는 다음과 같다.
이 기능은 다음 단계를 사용하여 활성화할 수 있습니다.
# wget https://github.com/kubernetes/kubernetes/raw/master/cluster/addons/dns/nodelocaldns/nodelocaldns.yaml
이 manifest 파일에는 여러 변수가 포함되어 있다.
- __PILLAR__LOCAL__DNS__ : NodeLocal DNSCache에 대해 선택된 로컬 수신 IP 주소
- __PILLAR__DNS__DOMAIN__ : 클러스터 도메인을 나타내며 기본값은 cluster.local
- __PILLAR__DNS__SERVER__ : kubectl get svc -n kube-system | grep kube-dns | awk '{ print $3 }'
다음과 같이 설정 한다.
# kubedns=`kubectl get svc kube-dns -n kube-system -o jsonpath={.spec.clusterIP}`
# domain=cluster.local
# localdns=169.254.20.10
IPTABELS 모드인 경우에는
# sed -i "s/__PILLAR__LOCAL__DNS__/$localdns/g; s/__PILLAR__DNS__DOMAIN__/$domain/g; s/__PILLAR__DNS__SERVER__/$kubedns/g" nodelocaldns.yaml
IPVS 모드인 경우에는
# sed -i "s/__PILLAR__LOCAL__DNS__/$localdns/g; s/__PILLAR__DNS__DOMAIN__/$domain/g; s/,__PILLAR__DNS__SERVER__//g; s/__PILLAR__CLUSTER__DNS__/$kubedns/g" nodelocaldns.yaml
IPVS 모드에서 kube-proxy를 사용하는 경우 NodeLocal DNSCache가 수신 대기 중인 <node-local-address>를 사용하도록 kubelet에 대한 --cluster-dns 플래그를 수정해야 한다. 그렇지 않으면 NodeLocal DNSCache가 kube-dns 서비스 IP와 <node-local-address>를 모두 수신하므로 --cluster-dns 플래그 값을 수정할 필요가 없다.
nodelocaldns.yaml 을 이제 클러스터에 배포하자.
# kubectl create -f nodelocaldns.yaml
설치가 완료되면 다음과 같은 pod가 생성된다.
# k get pods -n kube-system | grep node-local
node-local-dns-2fncz 1/1 Running 0 98s
node-local-dns-cb422 1/1 Running 0 98s
node-local-dns-f22bq 1/1 Running 0 98s
테스트
테스트 전에 local-dns 로그를 확인 전 log 를 남기도록 수정해보자. ( log 행을 추가한다. )
# kubectl -n kube-system edit configmap node-local-dns
...
apiVersion: v1
data:
Corefile: |
cluster.local:53 {
log
errors
cache {
success 9984 30
denial 9984 5
}
...
수정 후 daemonset을 다시 rollout한다.
# kubectl rollout restart daemonset -n kube-system node-local-dns
이제 다음의 Pod를 실행한다.
# kubectl apply -f https://k8s.io/examples/admin/dns/dnsutils.yaml
# kubectl get pods dnsutils
NAME READY STATUS RESTARTS AGE
dnsutils 1/1 Running 0 60s
Pod에 접속하여 쿼리를 실행하자.
# k exec -it dnsutils -- /bin/sh
# dig +short @169.254.20.10 www.com
96.126.123.244
45.33.18.44
45.56.79.23
72.14.178.174
198.58.118.167
45.33.23.183
45.33.30.197
45.33.20.235
72.14.185.43
45.33.2.79
173.255.194.134
45.79.19.196
# dig +short @10.96.0.10 example.com
93.184.216.34
# nslookup kubernetes.default
Server: 10.96.0.10
Address: 10.96.0.10#53
Name: kubernetes.default.svc.cluster.local
Address: 10.96.0.1
로그확인
# kubectl logs --namespace=kube-system -l k8s-app=node-local-dns -f
[INFO] 192.168.104.18:51908 - 32462 "A IN kubernetes.default.default.svc.cluster.local. udp 62 false 512" NXDOMAIN qr,aa,rd 155 0.001029601s
[INFO] 192.168.104.18:59100 - 39531 "A IN kubernetes.default.svc.cluster.local. udp 54 false 512" NOERROR qr,aa,rd 106 0.000509834s
LocalDNS 삭제
# kubectl delete -f nodelocaldns.yaml
참고
https://kubernetes.io/docs/tasks/administer-cluster/nodelocaldns/
https://www.sobyte.net/post/2021-11/use-nodelocal-dns-cache/
'Kubernetes > 일반' 카테고리의 다른 글
kubectl 활용 팁 (0) | 2022.09.11 |
---|---|
Kubernetes EndpointSlices (0) | 2022.09.06 |
Finalizers, ownerReferences (0) | 2022.08.30 |
Pod에서 tcpdump 패킷 캡처 (0) | 2022.08.28 |
Pod 생성 시 FailedMount : no space left on device 오류 (0) | 2022.08.23 |