본문 바로가기

Technical/Cloud, Virtualization, Containers

Amazon Route53, Google cloud DNS 를 활용한 kubernetes service DNS 자동화 (2/3)

 

2. AWS Route53 hosted-zone(호스팅영역) 과 External DNS로 kubernetes service 연결하기

 


 

지난 글(https://bryan.wiki/305) 에 이어서, 이번에는 Route53에 hosted-zone을 생성하여 Local kubernetes 의 external-dns를 통해 deploy 되는 service를 연결해 보고자 한다

 

 


 

 

Route53 hosted-zone 만들기

Aws console UI에서 Route53 > 호스팅 영역 > 호스팅 영역 생성' 을 통해서도 동일한 결과를 볼 수 있다

$ aws route53 create-hosted-zone --name route53.kube.click --caller-reference this-hosted-zone-is-sub-domain-of-kube-click
----------
{
    "Location": "https://route53.amazonaws.com/2013-04-01/hostedzone/REDACTEDHOSTEDZONEID",
    "HostedZone": {
        "Id": "/hostedzone/REDACTEDHOSTEDZONEID",
        "Name": "route53.kube.click.",
        "CallerReference": "this-hosted-zone-is-sub-domain-of-kube-click",
        "Config": {
            "PrivateZone": false
        },
        "ResourceRecordSetCount": 2
    },
    "ChangeInfo": {
        "Id": "/change/REDACTEDCHANGEID",
        "Status": "PENDING",
        "SubmittedAt": "2020-09-13T09:22:25.551000+00:00"
    },
    "DelegationSet": {
        "NameServers": [
            "ns-1333.redactedawsdomain.org",
            "ns-556.redactedawsdomain.net",
            "ns-1574.redactedawsdomain.co.uk",
            "ns-240.redactedawsdomain.com"
        ]
    }
}

$ aws route53 list-hosted-zones
----------
{
    "HostedZones": [
    ...
        {
            "Id": "/hostedzone/REDACTEDHOSTEDZONEID",
            "Name": "route53.kube.click.",
            "CallerReference": "this-hosted-zone-is-sub-domain-of-kube-click",
            "Config": {
                "PrivateZone": false
            },
            "ResourceRecordSetCount": 2
        }
    ]
}

 

  • Kube.click(parent domain) 에 NS record 추가
$ export AWS_ZONE_ID=$(aws route53 list-hosted-zones-by-name --output json  --dns-name route53.kube.click | jq -r '.HostedZones[0].Id' | cut -f3 -d'/')

$ aws route53 get-hosted-zone --id $AWS_ZONE_ID
----------
{
    "HostedZone": {
        "Id": "/hostedzone/REDACTEDHOSTEDZONEID",
        "Name": "route53.kube.click.",
        "CallerReference": "this-hosted-zone-is-sub-domain-of-kube-click",
        "Config": {
            "PrivateZone": false
        },
        "ResourceRecordSetCount": 3
    },
    "DelegationSet": {
        "NameServers": [
            "ns-1333.redactedawsdomain.org",
            "ns-556.redactedawsdomain.net",
            "ns-1574.redactedawsdomain.co.uk",
            "ns-240.redactedawsdomain.com"
        ]
    }
}

 

Route53 > 호스팅 영역 > kube.click > 레코드 생성

 

  • NS resolving 확인
$ dig route53.kube.click ns
----------
; <<>> DiG 9.10.6 <<>> route53.kube.click ns
;; global options: +cmd
;; Got answer:
;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 64026
;; flags: qr rd ra; QUERY: 1, ANSWER: 4, AUTHORITY: 0, ADDITIONAL: 1

;; OPT PSEUDOSECTION:
; EDNS: version: 0, flags:; udp: 4096
;; QUESTION SECTION:
;route53.kube.click.        IN    NS

;; ANSWER SECTION:
route53.kube.click.    30    IN    NS    ns-1333.redactedawsdomain.org.
route53.kube.click.    30    IN    NS    ns-1574.redactedawsdomain.co.uk.
route53.kube.click.    30    IN    NS    ns-556.redactedawsdomain.net.
route53.kube.click.    30    IN    NS    ns-240.redactedawsdomain.com.

;; Query time: 186 msec
;; SERVER: 210.220.163.82#53(210.220.163.82)
;; WHEN: Sun Sep 13 20:04:09 KST 2020
;; MSG SIZE  rcvd: 187

 

 


Kubernetes external-dns deploy

Aws Route53 과 연결 가능한 external-dns 를 helm 을 통해서 deploy 해 보자.
txtOwnerId 로는 앞서 추출한 route53.kube.click 도메인의 ID를 사용한다

$ helm install external-dns bitnami/external-dns \
  --set provider=aws \
  --set aws.credentials.accessKey="AWSSDKACCESSKEY" \
  --set aws.credentials.secretKey="AWSSDKSECRETKEY" \
  --set txtOwnerId=$AWS_ZONE_ID \
  --set domainFilters\[0\]=route53.kube.click \
  --set policy=sync

$ kubectl logs external-dns-f44b659f8-vqc94
----------
...
time="2020-09-13T16:04:08Z" level=info msg="Instantiating new Kubernetes client"
time="2020-09-13T16:04:08Z" level=info msg="Using inCluster-config based on serviceaccount-token"
time="2020-09-13T16:04:08Z" level=info msg="Created Kubernetes client https://10.100.0.1:443"
time="2020-09-13T16:04:17Z" level=info msg="All records are already up to date"
time="2020-09-13T16:05:19Z" level=info msg="All records are already up to date"

 


접속 대상인 Kubernetes service deploy

Nginx 로 이루어진 kubernetes service 를 다음과 같이 정의하자. Type을 LoadBalancer 로 하고 svc1 서비스에 대해 Kubernetes cluster 에서 사용 가능한 주소 대역이 할당되도록 설정하면 되는데, 여기서 보이는 10.0.0.* 대역의 IP가 지금은 사설 IP 대역이지만 실제 운영시에는 공인 IP 대역으로, 외부 접근 가능한 주소로 보면 된다.

 

service-example.yaml

apiVersion: v1
kind: Service
metadata:
  name: svc1
  annotations:
    external-dns.alpha.kubernetes.io/hostname: svc1.route53.kube.click
  labels:
    app: nginx
spec:
  type: LoadBalancer
  ports:
  - port: 80
    name: http
    targetPort: 80
  selector:
    app: nginx

---

apiVersion: apps/v1
kind: Deployment
metadata:
  name: nginx
spec:
  selector:
    matchLabels:
      app: nginx
  template:
    metadata:
      labels:
        app: nginx
    spec:
      containers:
      - image: nginx
        name: nginx
        ports:
        - containerPort: 80
          name: http

 

$ kubectl apply -f service-example.yaml
----------
service/svc1 created
deployment.apps/nginx created

$ kubectl get service -l app=nginx
----------
NAME   TYPE           CLUSTER-IP      EXTERNAL-IP   PORT(S)        AGE
svc1   LoadBalancer   10.100.89.153   10.0.0.201    80:32114/TCP   29m

 

약간의 시간이 흐른 후 External-dns 의 log 를 살펴 보면 다음과 같은 내용과 함께, Route53 에 새로운 A 레코드와 TXT 레코드가 추가되 어 있는 것을 볼 수 있다.

$ kubectl logs external-dns-f44b659f8-vqc94
----------
...
time="2020-09-13T16:12:28Z" level=info msg="Desired change: CREATE svc1.route53.kube.click A [Id: /hostedzone/REDACTEDHOSTEDZONEID]"
time="2020-09-13T16:12:28Z" level=info msg="Desired change: CREATE svc1.route53.kube.click TXT [Id: /hostedzone/REDACTEDHOSTEDZONEID]"
time="2020-09-13T16:12:28Z" level=info msg="2 record(s) in zone route53.kube.click. [Id: /hostedzone/REDACTEDHOSTEDZONEID] were successfully updated"
...

$ aws route53 list-resource-record-sets --hosted-zone-id $AWS_ZONE_ID
----------
{
    "ResourceRecordSets": [
        ...
        {
            "Name": "svc1.route53.kube.click.",
            "Type": "A",
            "TTL": 300,
            "ResourceRecords": [
                {
                    "Value": "10.0.0.201"
                }
            ]
        },
        {
            "Name": "svc1.route53.kube.click.",
            "Type": "TXT",
            "TTL": 300,
            "ResourceRecords": [
                {
                    "Value": "\"heritage=external-dns,external-dns/owner=REDACTEDHOSTEDZONEID,external-dns/resource=service/default/svc1\""
                }
            ]
        }
    ]
}

 


Curl 또는 웹 브라우저로 도메인 접속

$ curl http://10.0.0.201
----------
<!DOCTYPE html>
<html>
<head>
<title>Welcome to nginx!</title>
<style>
    body {
        width: 35em;
        margin: 0 auto;
        font-family: Tahoma, Verdana, Arial, sans-serif;
    }
</style>
</head>
<body>
<h1>Welcome to nginx!</h1>
<p>If you see this page, the nginx web server is successfully installed and
working. Further configuration is required.</p>

<p>For online documentation and support please refer to
<a href="http://nginx.org/">nginx.org</a>.<br/>
Commercial support is available at
<a href="http://nginx.com/">nginx.com</a>.</p>

<p><em>Thank you for using nginx.</em></p>
</body>
</html>

 


Kubernetes service 삭제

 

External-dns deploy 옵션에서 policy=sync 로 설정했기 때문에, 접속 대상이 되는 service를 삭제하면 Route53의 route53.kube.click 호스팅 영역의 svc1.route53.kube.click 레코드도 자동으로 삭제된다

$ kubectl delete -f service-example.yaml
----------
service/svc1 deleted
deployment.apps/nginx deleted

 

약간의 시간이 흐른 후 External-dns 의 log 를 살펴 보면 다음과 같은 내용과 함께, Route53 의 svc1에 대한 A 레코드와 TXT 레코드가 삭제되어 있는 것을 볼 수 있다.

$ kubectl logs external-dns-f44b659f8-vqc94
----------
...
time="2020-09-13T17:46:16Z" level=info msg="Desired change: DELETE svc1.route53.kube.click A [Id: /hostedzone/REDACTEDHOSTEDZONEID]"
time="2020-09-13T17:46:16Z" level=info msg="Desired change: DELETE svc1.route53.kube.click TXT [Id: /hostedzone/REDACTEDHOSTEDZONEID]"
time="2020-09-13T17:46:16Z" level=info msg="2 record(s) in zone route53.kube.click. [Id: /hostedzone/REDACTEDHOSTEDZONEID] were successfully updated"
...

$ aws route53 list-resource-record-sets --hosted-zone-id $AWS_ZONE_ID

 

다음 포스팅(https://bryan.wiki/307)에서는 Google cloud DNS와 external-dns 를 이용해서 kubernetes service 와 domain 주소를 통한 연결을 구성해 보도록 하자.

 

Barracuda