![[Kubernetes] Service - Service Discovery (2)](https://img1.daumcdn.net/thumb/R750x0/?scode=mtistory2&fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdna%2FerSsay%2FbtrCJTphRld%2FAAAAAAAAAAAAAAAAAAAAAEXltWsf-LC6D2jexTsgcAp5xfbBA1WmWg9Bh535Y4MX%2Fimg.png%3Fcredential%3DyqXZFxpELC7KVnFOS48ylbz2pIh7yKj8%26expires%3D1761922799%26allow_ip%3D%26allow_referer%3D%26signature%3DfQ23tIfPT0%252BQtzpKDkejWE1jXH0%253D)
✔️ Challenge
default NS에 myweb-svc 서비스를 만드시오
dev 라는 NS를 만들어서 nettool 파드를 띄우시오
그렇다면 nettool Pod(dev NS) ↔ myweb-svc SVC(default NS) 어떻게 통신할 것인가 ?
 vagrant@k8s-node1  kubectl create ns dev
namespace/dev created
 vagrant@k8s-node1  ~/kubespray/inventory/mycluster/group_vars/k8s_cluster  ➦ e7508d7d  kubectl get ns                                                         
NAME              STATUS   AGE
default           Active   4d6h
dev               Active   3d4h
kube-node-lease   Active   4d6h
kube-public       Active   4d6h
kube-system       Active   4d6h우선 dev NS를 생성한다.
 vagrant@k8s-node1  ~/kubespray/inventory/mycluster/group_vars/k8s_cluster  ➦ e7508d7d  kubectl run nettool -it --image ghcr.io/c1t1d0s7/network-multitool -n dev --rmdev NS에 nettool 파드를 띄운다.
 vagrant@k8s-node1  ~  kubectl get svc
NAME              TYPE        CLUSTER-IP      EXTERNAL-IP   PORT(S)   AGE
kubernetes        ClusterIP   10.233.0.1      <none>        443/TCP   70m
myweb-svc         ClusterIP   10.233.13.143   <none>        80/TCP    69m
myweb-svc-named   ClusterIP   10.233.21.79    <none>        80/TCP    61m
 vagrant@k8s-node1  ~  kubectl get po -n dev        
NAME      READY   STATUS    RESTARTS   AGE
nettool   1/1     Running   0          43sdefault NS에 myweb-svc가 존재하며 dev NS에 nettool 파드가 존재하는 것을 확인할 수 있다.
/ # cat /etc/resolv.conf
search dev.svc.cluster.local svc.cluster.local cluster.local default.svc.cluster.local kornet
nameserver 169.254.25.10
options ndots:5dev NS에 존재하는 nettool에서 /etc/resolv.conf 파일을 확인하면 아까와 달리 dev가 붙어있는 것을 확인할 수 있다.
이를 가지고 DNS에 질의하면 NXDOMAIN 응답을 받게될 것이다.
/ # host myweb-svc.dev.svc.cluster.local
Host myweb-svc.dev.svc.cluster.local not found: 3(NXDOMAIN)실제로 NXDOMAIN 를 응답한다.
/ # host myweb-svc.svc.cluster.local 
Host myweb-svc.svc.cluster.local not found: 3(NXDOMAIN)
/ # host myweb-svc.cluster.local
Host myweb-svc.cluster.local not found: 3(NXDOMAIN)2번째 3번째 도메인 역시 존재하지 않는다.
/ # host myweb-svc.default.svc.cluster.local
myweb-svc.default.svc.cluster.local has address 10.233.13.143마지막 도메인만이 ip를 응답한다.
이는 k8s의 개선된 사항으로 1.20 버전까지는 nettool이라는 파드를 dev NS에 만들면 /etc/resolv.conf 파일에 마지막 default.svc.cluster.local 도메인은 등록이 안돼있었다.
따라서 이름만 가지고 검색하는 것이 불가능했다.
버전에 따라 다르므로 권장하는 바는 최소한 NS를 붙이는 것이다.
/ # host myweb-svc.default
myweb-svc.default.svc.cluster.local has address 10.233.13.143서비스가 실제로 어떤 NS에 있는지 따라서 이름과 NS를 꼭 지정해줘야 한다.
이것을 안붙이면 잘못된 결과를 낳을 수 있기 때문이다.
리소스의 이름은 NS에서만 유일하면 되기 때문에 default NS에도 myweb-svc가 있고 dev NS에도 myweb-svc가 있는 것은 가능하다.
/ # host myweb-svc
myweb-svc.default.svc.cluster.local has address 10.233.13.143다음과 같이 질의했을 때
/ # cat /etc/resolv.conf
search dev.svc.cluster.local svc.cluster.local cluster.local default.svc.cluster.local kornet
nameserver 169.254.25.10
options ndots:5/etc/resolv.conf의 내용대로 첫번째 질의는 첫번째 도메인인 dev.svc.cluster.local을 붙여 질의할 것이다.
내가 접속하기를 원했던 ip는 myweb-svc.default.svc.cluster.local 이지만 실제로 myweb-svc.dev.svc.cluster.local가 존재한다면 이 ip로 접속하게 된다. 
이름이 같아서 생기는 문제가 발생한다. 같은 NS에서 먼저 찾기 때문이다.
따라서 가장 추천하는 것은 풀네임을 다 쓰는 것이며 최소한 NS를 붙여 질의하는 하는 것이 문제 발생 확률을 줄인다.
📌 ndots:5 - 우리가 질의할 FQDN에 .이 5개 있어야 한다는 의미이다.myweb-svc.default.svc.cluster.local. 마지막은 원래 .이 존재한다.
그래서 실제 DNS 서버에 셋팅할 때는 항상 .을 붙여줘야 한다.
마지막의 이 .은 Root Hint 라고 한다.
도메인은 Hierarchical Domain을 가진다. 최상단에 .이 있으며 이를 Root Hint라고 한다. 
그 하위로 com, net, org 등이 있으며 그 하위에 naver.com, daum.net 이런 것들이 존재한다. 
그리고 가장 하위에 도메인인 www가 존재한다.
✔️ nodelocal DNS
모든 파드는 DNS 서버로 169.254.25.10을 바라본다.
 vagrant@k8s-node1  ~/kubespray/inventory/mycluster/group_vars/k8s_cluster  ➦ e7508d7d  ip a s
4: nodelocaldns: <BROADCAST,NOARP> mtu 1500 qdisc noop state DOWN group default 
    link/ether fa:9b:ee:b9:01:9f brd ff:ff:ff:ff:ff:ff
    inet 169.254.25.10/32 scope global nodelocaldns
       valid_lft forever preferred_lft forevernodelocaldns의 ip가 nodelocaldns이다.
node가 3대가 있고 각 노드마다 가상의 nodelocaldns 인터페이스가 있다.
파드가 어떤 노드에 뜨는지 상관없이 기본적으로 169.254.25.10 여기에 질의한다.
중요한 것은 이 인터페이스에 실제 DNS 서버가 있는 것이 아니다.
 vagrant@k8s-node1  ~/kubespray/inventory/mycluster/group_vars/k8s_cluster  ➦ e7508d7d  sudo ss -tnlp                                 
State      Recv-Q     Send-Q             Local Address:Port            Peer Address:Port     Process                                                                                      
LISTEN     0          4096                   127.0.0.1:41471                0.0.0.0:*         users:(("containerd",pid=645,fd=15))                                                        
LISTEN     0          4096               169.254.25.10:9254                 0.0.0.0:*         users:(("node-cache",pid=2269,fd=7))169.254.25.10:9254 node-cache라고 된 것이 있다.node-cache는 프로세스이다. 169.254.25.10:9254로 질의하면 node-cache라는 프로세스가 받는다.
이것을 DNS Cache Server라고 한다.
파드가169.254.25.10(DNS Cache Server)으로 질의를 한다.
이 DNS Cache Server는 실제 해당되는 레코드를 가지지 않는다.
DNS Forwarder 라고 해서 자체적으로 알고 있는 정보는 없으나 질의를 받아서 실제 coredns 서버에게 재질의를 한다.
그러면 coredns 서버는 요청에 대한 응답을 해주고 이 응답을 DNS Cache Server의 로컬에 기록한다. 그리고 파드로 응답을 돌려준다.
DNS Cache Server는 coredns의 응답을 임시로 저장하고 있기 때문에 다른 파드가 똑같은 정보를 요청하면 딜레이없이 바로 응답한다.
물론 DNS Cache Server가 모르는 것은 coredns에게 질의하고 알고 있는 정보는 바로 응답해주게 된다.
https://kubernetes.io/docs/tasks/administer-cluster/nodelocaldns/

client 파드는 Local DNS Cache에 요청을 한다. 알고 있는 내용이면(Cache Hit) 응답을 바로 해주면 되고 모르는 내용이면 (Cache Miss) 실제 kubeDNS 서버에게 물어본다. 그리고 캐시에 저장한다.
영구적인 저장은 아니며 TTL 만큼의 시간만 저장할 수 있다.
Cache DNS Server가 모르는 정보를 물어보는 대상은 coredns이다.
 vagrant@k8s-node1  ~  kubectl get po -A -o wide
NAMESPACE     NAME                                      READY   STATUS    RESTARTS         AGE    IP                NODE    NOMINATED NODE   READINESS GATES
kube-system   nodelocaldns-hbm44                        1/1     Running   3 (178m ago)     34h    192.168.100.102   node3   <none>           <none>
kube-system   nodelocaldns-mq9nm                        1/1     Running   150 (178m ago)   4d7h   192.168.100.101   node2   <none>           <none>
kube-system   nodelocaldns-qc6vf                        1/1     Running   153 (179m ago)   4d7h   192.168.100.100   node1   <none>           <none>nodelocaldns 파드가 있고 파드의 ip 정보는 다음과 같다.
각 호스트에 nodelocaldns 가 떠있는 것이다.
 vagrant@k8s-node1  ~  kubectl get po -A  
kube-system   coredns-8474476ff8-4bmms                  1/1     Running   8 (3h1m ago)     4d7h
kube-system   coredns-8474476ff8-q7svm                  1/1     Running   9 (3h1m ago)     4d7h                    
 vagrant@k8s-node1  ~  kubectl get ep -n kube-system 
NAME      ENDPOINTS                                                     AGE
coredns   10.233.90.36:53,10.233.96.56:53,10.233.90.36:53 + 3 more...   4d7hkube-system NS에 있는 coredns 서비스로 접근하면 실제 coredns서버 파드로 접근한다.
nodelocal DNS 캐시 사용할 때
Pod --dns → 169.254.25.10(node-cache): DNS Cache Server → coredns SVC(kube-system NS) → coredns POD

AWS EKS에서는 nodelocalDNS는 add-on이다. 기본 구성이 아니다.nodelocalDNS add-on이 설치되지 않은 시스템은 파드들이 있으면 파드들의 /etc/resolv.conf파일을 보면 DNS 서버의 주소가 coredns의 ip가 부여되어있다. coredns로 바로 질의하는 것이다.
nodelocalDNS가 있다는 것은 각 노드마다 캐시 서버가 있다는 뜻이고nodelocalDNS를 설치하지 않으면 바로 coredns(DNS server)로 질의하는 것이다.
⭐️ 무슨 차이일까 ? ⭐️
노드와 파드가 굉장히 많은 상태라고 가정해보자coredns라는 파드가 컨트롤 플레인에만 있고 몇개 없는 상태이다.
그럼 무수히 많은 파드의 요청을 컨트롤 플레인이 Direct로 받게 된다. 컨트롤 플레인에 엄청난 부하가 생긴다.
그래서 DNS Server에 Direct로 질의하지 말고 로컬에 Cache Server를 두자고 하는 것이다.
모르는 정보에 대해서는 어쩔 수 없이 DNS Server로 질의해야 하겠지만 최소한 파드가 로컬의 Cache Server에서 1차로 답을 얻을 수 있다.
nodelocal DNS 캐시 사용을 하지 않을 때
파드 → dns → coredns SVC(kube-system NS) → coredns 파드
모든 파드는 바로 coredns SVC에 요청하고 그 뒤에 바로 파드가 있다. 너무 많아지면 부하가 너무 많이 걸린다.
DNS 이용한 Service Discovery는 나중에 서비스가 들어오더라도 그 서비스는 coredns Server한테 자동으로 생성되기 때문에 나중에 들어온 서비스도 얼마든지 질의할 수 있다.
'DevOps > Kubernetes' 카테고리의 다른 글
| [Kubernetes] Service - LoadBalancer ( + METALLB : on-prem 환경의 LB) (0) | 2022.05.23 | 
|---|---|
| [Kubernetes] Service - NodePort (1) | 2022.05.23 | 
| [Kubernetes] Service - Service Discovery (1) (0) | 2022.05.21 | 
| [Kubernetes] Service - ClusterIP (0) | 2022.05.20 | 
| [Kubernetes] Service & DNS (서비스와 DNS) (0) | 2022.05.20 | 
영차영차 성장 블로그
포스팅이 좋았다면 "좋아요❤️" 또는 "구독👍🏻" 해주세요!
![[Kubernetes] Service - LoadBalancer ( + METALLB : on-prem 환경의 LB)](https://img1.daumcdn.net/thumb/R750x0/?scode=mtistory2&fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdna%2FdXwIWC%2FbtrCMLx70uW%2FAAAAAAAAAAAAAAAAAAAAAHbv1XqPx6zI_diMso9d4QFq_xwC1FXgBmy2CY0OFGdb%2Fimg.png%3Fcredential%3DyqXZFxpELC7KVnFOS48ylbz2pIh7yKj8%26expires%3D1761922799%26allow_ip%3D%26allow_referer%3D%26signature%3DfKoa8d9JxBR%252BGJ958mjKt8QY92s%253D) 
                  ![[Kubernetes] Service - NodePort](https://img1.daumcdn.net/thumb/R750x0/?scode=mtistory2&fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdna%2FbRgWaF%2FbtrCRRkwYx4%2FAAAAAAAAAAAAAAAAAAAAALUyf6rmQJ8V61hmvGnPDUfeIppnkECkgAhabISv5oa7%2Fimg.png%3Fcredential%3DyqXZFxpELC7KVnFOS48ylbz2pIh7yKj8%26expires%3D1761922799%26allow_ip%3D%26allow_referer%3D%26signature%3DJQ0uVpZtQm1nbOzTfkrfZZBTYRo%253D) 
                  ![[Kubernetes] Service - ClusterIP](https://img1.daumcdn.net/thumb/R750x0/?scode=mtistory2&fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdna%2Fb7qWEZ%2FbtrCRRLAk7B%2FAAAAAAAAAAAAAAAAAAAAAJObgGaeSyISqoX3fip8TbUlQJMIjakItU893jKhKNs0%2Fimg.png%3Fcredential%3DyqXZFxpELC7KVnFOS48ylbz2pIh7yKj8%26expires%3D1761922799%26allow_ip%3D%26allow_referer%3D%26signature%3DUI5e0sttqbW3%252BeZpal5IMdimpjg%253D)