본문 바로가기

Cloud/Kubernetes

Kube DNS에 대해 알아보기

 아침부터 DNS의 작동이 원활하지 않아 장애가 발생했다는 전화를 받았다. KubeDNS를 공부하고 장애도 찾을 겸 포스팅 해본다. Kubernetes DNS는 Kubernetes 공식 문서에 다음과 같이 정의되어 있다.

 클러스터의 서비스와 DNS 파드를 관리하며, 개별 컨테이너들이 DNS 네임을 해석할 때 DNS 서비스의 IP를 사용하도록 kubelets를 구성한다.

 KubeDNS는 Kubernetes 1.12v부터 CoreDNS가 권장되고 있으며 자동으로 구성되어진다. KubeDNS도 설치할 수 있긴한데 이왕이면 권장되는 CoreDNS를 사용하자. kubernetes ns인 kube-system을 검색하면 조회할 수 있다. 이 CoreDNS를 한 번 알아본다.

[root@c1 ~]# kg pods -n kube-system
NAME                                      READY   STATUS    RESTARTS   AGE
calico-kube-controllers-59fc8847c-n8ts6   1/1     Running   2          7d21h
calico-node-4q6qh                         1/1     Running   2          7d21h
calico-node-xmvn9                         1/1     Running   0          7d21h
calicoctl                                 1/1     Running   0          4d2h
coredns-5c98db65d4-bgwnz                  1/1     Running   4          7d21h
coredns-5c98db65d4-mqdjp                  1/1     Running   4          7d21h
etcd-c1                                   1/1     Running   2          7d21h
fluentd-elasticsearch-n7b7x               1/1     Running   0          20h
fluentd-elasticsearch-vfnxm               1/1     Running   0          20h
hostpath-provisioner-5d4f4497c4-fcvgn     1/1     Running   0          3d21h
kube-apiserver-c1                         1/1     Running   2          6d22h
kube-controller-manager-c1                1/1     Running   4          7d21h
kube-proxy-dnjdd                          1/1     Running   2          7d21h
kube-proxy-g22dc                          1/1     Running   0          7d21h
kube-scheduler-c1                         1/1     Running   3          7d21h

 

[root@c1 ~]# kubectl get configmap -n kube-system coredns
NAME      DATA   AGE
coredns   1      7d22h

1. DNS

 DNS를 모르는 불행은 없으리라 믿지만 나도 개념이 헷갈려서 오랜만에 다시 찾아보았다. 이 쪽 글을 보면 쉽게 이해가 가능하다. 주소 <-> IP를 처리해주는 시스템이라고 생각하면 된다.

 K8S에서 왜 DNS를 사용할까? K8S의 특성을 생각해보면, 오브젝트들은 emphemeral한 존재들이다. Object들 중 하나인 Pod는 생애주기를 가지며 여러 이유로 재생성된다. 새로 생성된 Pod는 새 IP를 가지며 외부에서 새로운 Pod IP를 알아내는 일은 쉽지 않다. 이러한 수고로움을 덜기 위해, 불필요한 연산을 막기 위해 DNS 서버가 사용된다.

2. Config File 보기

apiVersion: v1
data:
  Corefile: |
    .:53 {
        errors
        health
        kubernetes cluster.local in-addr.arpa ip6.arpa {
           pods insecure
           upstream
           fallthrough in-addr.arpa ip6.arpa
           ttl 30
        }
        prometheus :9153
        forward . /etc/resolv.conf
        cache 30
        loop
        reload
        loadbalance
    }
kind: ConfigMap
metadata:
  creationTimestamp: "2020-04-13T07:03:47Z"
  name: coredns
  namespace: kube-system
  resourceVersion: "193"
  selfLink: /api/v1/namespaces/kube-system/configmaps/coredns
  uid: 60de6af4-ac5d-4a49-975e-9509b203932e

 CoreDNS가 배포된 이후에 검색해보면 coredns라는 configmap이 생성된 것을 볼 수 있으며 얘는 Corefile을 가지고 있다. Corefile은 CoreDNS의 구성 파일이며 어떤 서버가 어떤 포트와 어떤 프로토콜을 수신하는지, 각 서버가 어느 영역에 권한이 있는지 정의한다.  Pod가 DNS에게 이거 어디있어요? 하고 물어볼 때 pod insecure에게 먼저 물어보고, 그 다음 upstream으로 나가게 된다.  상세히 적어보면 이렇다.

errors stdout에 에러를 기록
health CoreDNS의 상태를 health에 보고
ready ready 상태가 되면 8181 포트에서 200 응답(OK) 리턴
kubernetes 서비스 및 파드의 IP를 기반으로 DNS에 응답하며 TTL(데이터 유효 기간)을 설정할 수 있음

3. Pod 안에서 살펴보기

 이건 어떻게 확인할까? Pod exec로 들어간 다음 /etc/resolv.conf를 보자.

nameserver 10.96.0.10
search [app-name].svc.cluster.local svc.cluster.local cluster.local
options ndots:5

이 옵션은 pod의 dns 정책을 통해 결정된다. 이 친구는 이런 옵션을 가지고 있다.

[root@c1 ~]# k get pods virt-launcher-7a634907-zq4cc -o yaml | grep dns
dnsPolicy: ClusterFirst

다른 옵션도 물론 존재한다. 이 중 ClusterFirst는 클러스터와 일치하지 않는 DNS 쿼리는 upstream으로 보내는 옵션이다.