Engineering/Kubernetes (K8S)

[Kubernetes] 쿠버네티스 서비스(Service) Deep Dive - (3) Cluster DNS

[앙금빵] 2022. 5. 18.

 

리마인드

(1) Pod는 고유한 IP주소가 존재하며 일시적인(ephemeral) 특성을 지니며 불안정한 리소스이다.

(2) 클라이언트 관점에서 서비스를 지원하는 Pod의 수와 IP에 상관하지 않아야 하며 모든 Pod는 단일 IP주소로 Access할 수 있어야 한다.

(3) 쿠버네티스는 이러한 문제점을 해결하기 위해 "Service" 리소스 유형을 제공한다.

(4) Service는 어떤 파드가 어디에서 존재하는지 (어떤 IP를 가지는지)에 관계없이 Pod 앞단에서 Pod 중 하나로 연결하여 요청을 처리하도록 한다.

(5) 서비스를 지원하는 Pod는 여러개일 수 있으며, 레이블 셀렉터(Label Selector)를 통해 서비스와 연결된 Pod를 정의한다.


 

DNS를 통한 서비스 검색

Service 이름을 도메인 주소로도 사용이 가능하다. 이는 바로 쿠버네티스에서 제공하는 DNS 서버가 있기 때문이다.

 

  1. kube-system 네임스페이스 내에 kube-dns 라는 파드가 존재한다.
  2. kube-dns 파드는 DNS 서버를 실행하며, 클러스터에서 실행 중인 다른 모든 파드는 자동으로 이를 사용하도록 구성한다. (쿠버네티스는 각 컨테이너의 /etc/resolv.conf 파일을 수정하여 이를 수행한다.) 
  3. 파드에서 실행 중인 프로세스에서 수행된 모든 DNS 쿼리는 시스템에서 실행 중인 모든 서비스를 알고 있는 쿠버네티스의 자체 DNS 서버로 처리된다.

 

리눅스 시스템에서 DNS 서버 설정을 담당하는 /etc/resolv.conf 파일을 확인해보자.

/ # cat /etc/resolv.conf
nameserver 10.96.0.10
search john.svc.cluster.local svc.cluster.local cluster.local
options ndots:5

 

네임서버에 10.96.0.10 이라는 IP를 확인할 수 있다. 쿠버네티스의 모든 Pod들은 바로 이 IP로 DNS를 조회한다. 

그리고 이 IP의 주인은 바로 kube-dns IP 주소이다.

root@k8s-m:~# kubectl get svc kube-dns -n kube-system --show-labels
NAME       TYPE        CLUSTER-IP   EXTERNAL-IP   PORT(S)                  AGE   LABELS
kube-dns   ClusterIP   10.96.0.10   <none>        53/UDP,53/TCP,9153/TCP   64d   k8s-app=kube-dns,kubernetes.io/cluster-service=true,kubernetes.io/name=CoreDNS

 

이제, kube-app=kube-dns 라벨 정보를 이용하여 어떤 Pod가 매핑되는지 확인해보면 CoreDNS인 것을 확인할 수 있다.

root@k8s-m:~# kubectl get pod -n kube-system -l k8s-app=kube-dns
NAME                       READY   STATUS    RESTARTS   AGE
coredns-558bd4d5db-d78qm   1/1     Running   0          64d
coredns-558bd4d5db-kzpkt   1/1     Running   0          64d

 

모든 Pod들은 클러스터의 내·외부 질의를 CoreDNS를 통해 수행한다. 그렇기에 쿠버네티스 클러스터 환경 안에서 자체적인 도메인 네임 시스템을 가질 수 있다.

CoreDNS


 

URL을 통한 서비스 접근

요청(curl) URL에서 호스트 이름으로 서비스 이름을 사용하여 서비스에 접근할 수 있다.

Case1. 서비스가 DNS 조사하는 pod와 같은 네임스페이스인 경우

  • <service-name>
/ # curl http://quiz
This is the quiz service running in pod quiz

/ # curl http://quiz.john
This is the quiz service running in pod quiz

 

Case 2. 서비스가 서로 다른 네임스페이스인 경우

  • <service-name>.<service-namespace>
  • <service-name>.<service-namespace>.svc
  • <service-name>.<service-namespace>.svc.cluster.local
#default 네임스페이스 내 my-service 서비스
/ # curl http://my-service.default
<!DOCTYPE html>
<html>
<head>
<title>Welcome to nginx!</title>
<style>

# 아래 명령어도 같은 출력을 나타냄
/ # curl http://my-service.default.svc
/ # curl http://my-service.default.svc.cluster.local

 

서비스 IP에 핑을 할 수 없는 이유

앞에서 어떻게 서비스가 파드로 포워딩하는지 보았다. 그러나 만약 정상적으로 포워딩하지 않는다면 어떻게 할까? 아마 일반적으로 서비스 IP로 ping을 시도할 것이며 작동 여부를 확인할 것이다. 지금 한번 해보자.

root@k8s-m:~# kubectl exec -it quote-001 -c nginx -- ping quiz
PING quiz (10.104.206.158): 56 data bytes
^C
--- quiz ping statistics ---
7 packets transmitted, 0 packets received, 100% packet loss
command terminated with exit code 1

 

결과와 같이 서비스로 curl은 동작하지만 핑은 응답이 없다. 이는 서비스의 Cluster IP가 가상 IP이기에 서비스 포트와 결합된 경우에만 의미가 있기 때문이다. 서비스가 어떻게 구현되는지는 추후 추가할 예정이다. 지금으로서는 서비스 IP에 Ping은 할 수 없다는 점만 알아두자.


참고

  • kubernetes-in-action-2nd-Edition

댓글