새소식

AWS/EKS

[PKOS Study 1주차] Kubernetes External DNS

  • -

CloudNet@ 팀의 가시다님께서 Leading 하시는 PKOS 2기 Study 내용 요약

해당 Kubernetes Study 는 '24단계 실습으로 정복하는 쿠버네티스' 책을 기반으로 진행 중입니다.

 

 

이전 포스팅은 kops 를 통해 k8s 실습 환경을 마련하는 목적이었습니다.

지금부터는 본격적으로 k8s 기능 과 활용에 대해 포스팅해보겠습니다.



 

1. k8s External DNS ??


Public Domain 과 Kubernetes Resource 를 연결시켜주는 솔루션

 

GitHub - kubernetes-sigs/external-dns: Configure external DNS servers (AWS Route53, Google CloudDNS and others) for Kubernetes I

Configure external DNS servers (AWS Route53, Google CloudDNS and others) for Kubernetes Ingresses and Services - GitHub - kubernetes-sigs/external-dns: Configure external DNS servers (AWS Route53, ...

github.com

 

 

쿠버네티스는 기본적으로 Service, Deployment 등의 오브젝트를 내부 DNS 로 관리합니다.
이 때 사용되는 것이 바로 CoreDNS 입니다.

[root@kops-ec2 ~]# kubectl get pods -o wide -n kube-system | grep -i -e coredns -e name
NAME                                          READY   STATUS    RESTARTS      AGE   IP              NODE                  NOMINATED NODE   READINESS GATES
coredns-68cd66b8cc-k6ndg                      1/1     Running   0             64m   172.30.94.15    i-0a771d5232e826cc5   <none>           <none>
coredns-68cd66b8cc-kqt7m                      1/1     Running   0             82m   172.30.40.125   i-03589b6c5b00e4609   <none>           <none>
coredns-autoscaler-66fbc7dd48-v5w55           1/1     Running   0             82m   172.30.63.77    i-03589b6c5b00e4609   <none>           <none>

 

 

 

그런데 만약 내가 test.com 이라는 도메인 주소를 가지고 있고, 이 도메인 주소를 통해 외부에 서비스를 하고 싶다면 어떻게 해야될까요??

단순하게 생각하면 NodePort 타입으로 Service 오브젝트를 배포하고 해당 노드와 test.com 을 연결시켜주면 된다고 생각할 수 있습니다.


하지만, 서비스가 계속 생성되고 삭제되는 와중에 이런 작업을 반복하는 것은 굉장히 번거로운 일입니다.

 

 

이 때 External DNS 를 사용하면 내가 가진 test.com 를 통해 쿠버네티스 오브젝트 등을 관리할 수 있게 됩니다.


즉, 쿠버네티스 오브젝트가 생성되고 삭제되면 자동으로 test.com 에 서브도메인이 생성되고 삭제되게 할 수 있는 것입니다.
- Route 53 자동 업데이트

 

 

1.1. IAM Policy 생성 - Route53 편집 권한

 

현재 AWS 에서 kops 를 배포했고, Route53 을 사용하고 있습니다.
External DNS 를 사용하려면 쿠버네티스에 Route53 도메인 편집 권한이 필요합니다.

 

 

  • Route53
  1. Record 편집 허용
  2. Hostzone , Record 조회 허용
cat << EOF > externaldns.json
{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Effect": "Allow",
      "Action": [
        "route53:ChangeResourceRecordSets"
      ],
      "Resource": [
        "arn:aws:route53:::hostedzone/*"
      ]
    },
    {
      "Effect": "Allow",
      "Action": [
        "route53:ListHostedZones",
        "route53:ListResourceRecordSets"
      ],
      "Resource": [
        "*"
      ]
    }
  ]
}
EOF

 

해당 json 파일을 이용하여 AWS IAM Policy 를 생성해줍니다.

aws iam create-policy --policy-name AllowExternalDNSUpdates --policy-document file://externaldns.json

 



 

1.2. Kubernetes 에 권한 부여

 

생성한 IAM Policy 를 쿠버네티스가 사용할 수 있도록 Control Plane 과 Worker Node 인스턴스의 IAM Role 에 해당 정책을 부여해줍니다.
현재 k8s IRSA 가 없는 상태라 EC2 Role 에 해당 권한을 부여해줍니다.

export ACCOUNT_ID=$(aws sts get-caller-identity --query 'Account' --output text)
export KOPS_CLUSTER_NAME=클러스터이름

aws iam attach-role-policy --policy-arn arn:aws:iam::$ACCOUNT_ID:policy/AllowExternalDNSUpdates --role-name masters.$KOPS_CLUSTER_NAME
aws iam attach-role-policy --policy-arn arn:aws:iam::$ACCOUNT_ID:policy/AllowExternalDNSUpdates --role-name nodes.$KOPS_CLUSTER_NAME



1.3. External DNS 설치

 

기본적으로 Helm 이나 yaml 로 External DNS 에 대한 부분을 정의해줘야 하나, kops 는 간편하게 생성할 수 있습니다.
spec 부분에 아래 내용을 추가합니다.

[root@kops-ec2 ~]# kops edit cluster

spec:
  externalDns:
    provider: external-dns

 

이후 kops cluster 를 업데이트한 후, ExternalDNS 를 확인해봅니다.

[root@kops-ec2 ~]# kops update cluster --yes && echo && sleep 3 && kops rolling-update cluster

[root@kops-ec2 ~]# kubectl get pod -n kube-system -l k8s-app=external-dns
NAME                           READY   STATUS    RESTARTS   AGE
external-dns-764b5c498-5nlr6   1/1     Running   0          61s

 

1.4. External DNS 실행

 

이전에 배포해보았던 mario 게임에 External DNS 를 연결해봅시다.

[root@kops-ec2 ~]# curl -s -O https://raw.githubusercontent.com/gasida/PKOS/main/1/mario.yaml
[root@kops-ec2 ~]# kubectl apply -f mario.yaml
deployment.apps/mario created
service/mario created

[root@kops-ec2 ~]# kubectl get svc mario
NAME    TYPE           CLUSTER-IP       EXTERNAL-IP                                                                    PORT(S)        AGE
mario   LoadBalancer   100.67.170.124   a3c16bdd356ce4bd1a0c0a9f5c6a9429-1019613296.ap-northeast-2.elb.amazonaws.com   80:31219/TCP   4m30s

 

현재 mario 게임이 배포되어 있는 상태입니다.
하지만 route53 에는 아직 해당 LoadBalancer 가 연결되지 않았습니다.

 

 

Mario 게임의 Service 오브젝트를 External DNS 와 연결시켜줍니다.

[root@kops-ec2 ~]# kubectl annotate service mario "external-dns.alpha.kubernetes.io/hostname=mario.$KOPS_CLUSTER_NAME"
service/mario annotated

[root@kops-ec2 ~]# kubectl logs -n kube-system -l k8s-app=external-dns

 

 

 

Route 53 확인 및 도메인으로 접속

 

  • External DNS 제거
[root@kops-ec2 ~]# kubectl delete deploy,svc mario
deployment.apps "mario" deleted
service "mario" deleted

[root@kops-ec2 ~]# kubectl logs -n kube-system -l k8s-app=external-dns

 

 

 

Route 53 확인 및 도메인으로 접속

 

 

 


이번에는 External DNS 를 통해 쿠버네티스 오브젝트를 외부 서비스로 배포하는 방법을 알아보았습니다.

다음에는 쿠버네티스 네트워크 중 AWS CNI스토리지에 관해 공부해보겠습니다.

Contents

포스팅 주소를 복사했습니다