> For the complete documentation index, see [llms.txt](https://kubernetes.youngwjung.com/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://kubernetes.youngwjung.com/advanced-topics/dns/lab.md).

# 실습

### Custom DNS Entry

1. NGINX 서비스 생성

   ```
   cat <<EOF | kubectl apply -f -
   apiVersion: apps/v1
   kind: Deployment
   metadata:
     labels:
       app: nginx
     name: nginx
   spec:
     replicas: 1
     selector:
       matchLabels:
         app: nginx
     template:
       metadata:
         labels:
           app: nginx
       spec:
         containers:
         - image: nginx
           name: nginx
   ---
   apiVersion: v1
   kind: Service
   metadata:
     name: nginx
   spec:
     selector:
       app: nginx
     ports:
       - protocol: TCP
         port: 80
         targetPort: 80
   EOF
   ```
2. Pod 생성&#x20;

   ```
   cat <<EOF | kubectl apply -f -
   apiVersion: v1
   kind: Pod
   metadata:
     name: alpine
   spec:
     containers:
     - name: alpine
       image: praqma/network-multitool
       command: [ "sleep" ]
       args: [ "infinity" ]
   EOF
   ```
3. 위에서 생성한 Pod가 사용하는 DNS 서버 정보 확인

   ```
   kubectl exec alpine -- dig
   ```
4. 로컬 DNS 설정 정보 확인&#x20;

   ```
   kubectl exec alpine -- cat /etc/resolv.conf
   ```
5. DNS 서버 상세 정보 확인&#x20;

   ```
   kubectl exec alpine -- \
   bash -c 'DNS_SERVER=$(cat /etc/resolv.conf | grep nameserver | awk "{print \$2}");dig @$DNS_SERVER -x $DNS_SERVER'
   ```
6. CURL 명령어로 위에서 생성한 Service의 FQDN로 접근&#x20;

   ```
   kubectl exec alpine -- \
   curl -s nginx.default.svc.cluster.local
   ```
7. CURL 명령어로 에서 생성한 Service의 이름으로 접근&#x20;

   ```
   kubectl exec alpine -- \
   curl -s nginx
   ```
8. CURL 명령어로 에서 생성한 Service의 이름로 Namespace 이름을 추가하고 접근&#x20;

   ```
   kubectl exec alpine -- \
   curl -s nginx.default
   ```
9. *kube-system* Namespace 안에 있는 *kube-dns* Service 확인&#x20;

   ```
   kubectl -n kube-system get svc kube-dns
   ```
10. 위에서 확인한 Service의 Selector 조건 확인 &#x20;

    ```
    kubectl -n kube-system get svc kube-dns \
    -o=jsonpath='{.spec.selector}' | jq
    ```
11. *k8s-app* Label을 가진 Pod 확인&#x20;

    ```
    kubectl get pod -l k8s-app --all-namespaces
    ```
12. *k8s-app=kube-dns* Label을 가진 Pod 확인&#x20;

    ```
    kubectl get pod -l k8s-app=kube-dns --all-namespaces
    ```
13. `coredns` Pod 상세 내용 확인&#x20;

    ```
    kubectl -n kube-system get pod \
    $(kubectl get pod -l k8s-app=kube-dns -o=jsonpath='{.items[0].metadata.name}' -n kube-system) -o yaml
    ```
14. *kube-system* Namespace 안에 있는 ConfigMap 확인&#x20;

    ```
    kubectl -n kube-system get configmap
    ```
15. *coredns* ConfigMap 상세 내용 확인&#x20;

    ```
    kubectl -n kube-system get configmaps coredns -o yaml
    ```
16. CoreDNS 설정파일 수정 &#x20;

    ```
    cat <<EOF | kubectl apply -f -
    apiVersion: v1
    kind: ConfigMap
    metadata:
      name: coredns
      namespace: kube-system
      labels:
        eks.amazonaws.com/component: coredns
        k8s-app: kube-dns
    data:
      Corefile: |
        .:53 {
            rewrite stop {
                name regex (.*)\.test\.io {1}.default.svc.cluster.local
                answer name (.*)\.default\.svc\.cluster\.local {1}.test.io
            }
            errors
            health
            kubernetes cluster.local in-addr.arpa ip6.arpa {
              pods insecure
              fallthrough in-addr.arpa ip6.arpa
            }
            prometheus :9153
            forward . /etc/resolv.conf
            cache 30
            loop
            reload
            loadbalance
        }
    EOF
    ```
17. CoreDNS Pod 재생성&#x20;

    ```
    {
        kubectl -n kube-system scale deployment coredns --replicas=0
        kubectl -n kube-system scale deployment coredns --replicas=2
    }
    ```
18. CoreDNS에 추가한 Rewrite 규칙 확인&#x20;

    ```
    kubectl exec alpine -- dig nginx.test.io
    ```
19. *nginx* Service의 주소 확인

    ```
    kubectl get svc nginx
    ```
20. CoreDNS에 추가한 Rewrite 규칙 테스트&#x20;

    ```
    kubectl exec alpine -- curl -s nginx.test.io
    ```
21. 새로운 데모 웹서버 배포&#x20;

    ```
    {
        kubectl create deploy web --image=httpd 
        kubectl expose deploy web --port 80
    }
    ```
22. CoreDNS에 추가한 Rewrite 규칙 테스트&#x20;

    ```
    kubectl exec alpine -- curl -s web.test.io
    ```
23. 생성한 리소스 삭제&#x20;

    ```
    {
        kubectl delete deploy nginx web
        kubectl delete svc nginx web
        kubectl delete pod alpine
    }
    ```
24. CoreDNS 설정파일 원복

    ```
    cat <<EOF | kubectl apply -f -
    apiVersion: v1
    kind: ConfigMap
    metadata:
      name: coredns
      namespace: kube-system
      labels:
        eks.amazonaws.com/component: coredns
        k8s-app: kube-dns
    data:
      Corefile: |
        .:53 {
            errors
            health
            kubernetes cluster.local in-addr.arpa ip6.arpa {
              pods insecure
              fallthrough in-addr.arpa ip6.arpa
            }
            prometheus :9153
            forward . /etc/resolv.conf
            cache 30
            loop
            reload
            loadbalance
        }
    EOF
    ```
25. CoreDNS Pod 재생성&#x20;

    ```
    {
        kubectl -n kube-system scale deployment coredns --replicas=0
        kubectl -n kube-system scale deployment coredns --replicas=2
    }
    ```

### ExternalDNS

1. Node에 부여된 Label을 통해서 EKS 클러스터 이름 확인하고 환경변수로 저장

   ```
   {
       export CLUSTER_NAME=$(kubectl get node \
       -o=jsonpath='{.items[0].metadata.labels.alpha\.eksctl\.io\/cluster-name}')
       echo $CLUSTER_NAME
   }
   ```
2. ServiceAccount 생성&#x20;

   ```
   eksctl create iamserviceaccount \
   --cluster $CLUSTER_NAME \
   --namespace=kube-system \
   --name=external-dns \
   --attach-policy-arn=arn:aws:iam::aws:policy/AmazonRoute53FullAccess \
   --override-existing-serviceaccounts \
   --approve
   ```
3. Helm 차트 리포지토리 추가&#x20;

   ```
   {
       helm repo add external-dns https://kubernetes-sigs.github.io/external-dns/
       helm repo update
   }
   ```
4. ExternalDNS 설치&#x20;

   ```
   helm install external-dns external-dns/external-dns -n kube-system \
   --set serviceAccount.create=false \
   --set serviceAccount.name=external-dns
   ```
5. 배포된 구성요소 확인&#x20;

   ```
   kubectl -n kube-system get all -l app.kubernetes.io/name=external-dns
   ```
6. ExternalDNS 로그 확인

   ```
   kubectl -n kube-system logs deploy/external-dns
   ```
