두개의 포드와 서비스가 있다고 해보자. 각 포드의 이름은 test와 web이고, 가상 IP를 하나씩 할당받았다.
/-----\ /--------- /-----\ | pod | 《 service | pod | \-----/ \--------- \-----/ 10.244.1.5 10.107.37.188 10.244.1.5 test web-service web
서비스가 생성되면, k8s DNS sevice(CoreDNS)는 해당 서비스를 위한 레코드를 저장한다. 즉, ip를 직접 명시하지 않고 사용할 수 있는 대체 이름을 지정해준다는 것이다. 우선 클러스터 내부에서 포드는 해당 서비스의 이름으로 접근하여 그 서비스의 위치로 요청을 보낼 수 있다.
curl http://web-service > Welcome to NGINX!
하지만 만약에 두 포드가 다른 네임스페이스에 있다고 해보자. 그런 경우에도 해당 네임스페이스명을 같이 적어주기만 하면 요청을 보낼 수 있다.
curl http://web-service.{namespace name} > Welcome to NGINX!
그리고 모든 서비스는 svc라는 서브 도메인 안에 묶여있다. 그렇기 때문에 아래와 같이 접근하는 것 또한 가능하다.
curl http://web-service.{namespace name}.svc > Welcome to NGINX!
그리고 모든 서비스와 포드는 cluster.local이라는 root 도메인 안에 묶여있다. 이 url이 바로, 10.107.37.188 IP를 가진 web-service 서비스에 대해서 k8s 내부에서 쓸 수 있는 완전한 도메인명이다.
curl http://web-service.{namespace name}.svc.cluster.local > Welcome to NGINX!
CoreDNS
위에서 서비스를 레코드에 등록하고, 쿼리할 수 있는 기능을 지원하기 위해 k8s에 내장되어있는 CoreDNS라는 프로그램이 동작한다. 기존에는 KubeDNS라는 별도의 프로그램이 사용되었었는데, 메모리나 CPU 점유율 문제로 1.12 버전부터 기본 설정이 변경됐다.
CoreDNS는 일반적으로 Kubernetes Cluster 내부에서 이용되는 DNS Server이다. Kubernetes Cluster 내부에서 Domain을 통해서 Service나 Pod의 IP를 찾기 위한 용도로 많이 이용된다.
CoreDNS는 일반적으로 Worker Node에서 Deployment로 배포되어 다수의 Pod으로 구동된다. 그리고 다수의 CoreDNS Pod들은 CoreDNS Service를 통해서 VIP (ClusterIP)로 묶이게 된다. Kubernetes Cluster의 Pod들은 CoreDNS Service의 VIP를 통해서 CoreDNS에 접근하게 된다. 다수의 CoreDNS Pod와 CoreDNS Service를 이용하는 이유는 HA(High Availability) 때문이다.
$ kubectl -n kube-system get deployment corednsNAME READY UP-TO-DATE AVAILABLE AGEcoredns 2/2 2 2 13d
$ kubectl -n kube-system get service kube-dnsNAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGEkube-dns ClusterIP 10.96.0.10 <none> 53/UDP,53/TCP,9153/TCP 13d[Shell 1] CoreDNS Deployment, Pod
$ kubectl run my-shell --rm -i --tty --image nicolaka/netshoot -- bash(container)# cat /etc/resolv.confnameserver 10.96.0.10search default.svc.cluster.local svc.cluster.local cluster.localoptions ndots:5
임의의 Shell Pod을 만들고 Shell Pod안에서 /etc/resolv.conf 파일에 설정된 DNS Server를 확인하는 과정이다. CoreDNS Service의 VIP (ClusterIP)가 설정되어 있는걸 확인할 수 있다.
Corefile
.:53 { log errors health { lameduck 5s } ready kubernetes cluster.local in-addr.arpa ip6.arpa { pods insecure fallthrough in-addr.arpa ip6.arpa ttl 30 } prometheus :9153 forward . /etc/resolv.conf cache 30 loop reload loadbalance}
CoreDNS는 Kubernetes API 서버로부터 Service와 Pod를 Watch하여 Service와 Pod의 Event를 수신한다.
Kubernetes API 서버로부터 Service 생성/삭제 Event를 받은 CoreDNS는 Service, Pod의 Domain을 생성/삭제한다. 이러한 CoreDNS의 Kubernetes 관련 동작은 CoreDNS의 Config 파일을 통해서 설정할 수 있다. 위의 코드는 CoreDNS의 Config 파일을 나타내고 있다. kubernetes 설정 부분이 있는걸 확인할 수 있다.
CoreDNS의 설정파일에서 한가지 더 주목해야하는 설정은 forward 설정이다. forward 설정은 CoreDNS의 Upstream DNS Server를 지정하는 역할을 수행한다. forward 설정에 /etc/resolv.conf
파일이 지정되어 있는것을 알 수 있다. CoreDNS Pod의 dnsPolicy는 “Default”이다. “Default”는 Pod가 떠있는 Node의 /etc/resolv.conf
파일의 내용을 상속받아 Pod의 /etc/resolv.conf
파일을 생성하는 설정이다. 따라서 CoreDNS Pod의 /etc/resolve.conf
는 Node의 DNS Server 정보가 저장되어 있다. 즉 CoreDNS는 Node의 DNS Server를 Upstream으로 설정한다.
참고