3. Google cloud DNS managed zone과 External DNS로 kubernetes service 연결하기


지난 2개의 글(https://bryan.wiki/305, https://bryan.wiki/306) 에 이어서, 이번에는 Google cloud DNS에 hosted-zone을 생성하여 Local kubernetes 의 external-dns를 통해 deploy 되는 service를 연결해 보자. 시리즈 처음 글에서 Google cloud DNS 측에 생성한 gcloud.kube.click 도메인을 사용한다.

 


 

 


Google cloud DNS project의 managed zone 확인

GCP console 좌측 메뉴에서 Network services > Cloud DNS > Zone details 을 통해서도 확인할 수 있다

Google cloud DNS의 managed zone은 프로젝트에 귀속되는 리소스이다

$ export PROJECT_NAME="dns-hosting-poc"
$ gcloud config set project $PROJECT_NAME

$ export CUSTOM_DOMAIN="gcloud.kube.click"
$ export DNS_ZONE_NAME="subdomain-route53"
$ export IAM_ACCOUNT="gcloud-dns-admin"

$ gcloud dns record-sets list --zone=$DNS_ZONE_NAME
----------
NAME                TYPE  TTL    DATA
gcloud.kube.click.  NS    21600  ns-cloud-e1.googledomains.com.,ns-cloud-e2.googledomains.com.,ns-cloud-e3.googledomains.com.,ns-cloud-e4.googledomains.com.
gcloud.kube.click.  SOA   21600  ns-cloud-e1.googledomains.com. cloud-dns-hostmaster.google.com. 1 21600 3600 259200 300

 

  • IAM service-account 생성, roles/dns.admin 과 바인딩하고 credential key 다운로드
$ gcloud --project $PROJECT_NAME iam service-accounts create $IAM_ACCOUNT --display-name "Service Account to support external-dns"

$ gcloud projects add-iam-policy-binding $PROJECT_NAME --member serviceAccount:$IAM_ACCOUNT@$PROJECT_NAME.iam.gserviceaccount.com --role roles/dns.admin

$ gcloud --project $PROJECT_NAME iam service-accounts list
----------
DISPLAY NAME                             EMAIL                                                     DISABLED
Service Account to support external-dns  gcloud-dns-admin@dns-hosting-poc.iam.gserviceaccount.com  False

$ gcloud iam service-accounts keys create key.json --iam-account=$IAM_ACCOUNT@$PROJECT_NAME.iam.gserviceaccount.com

 

다운로드 된 credential 로부터 Kubernetes secret 등록한다. 이 credential을 사용해서 external-dns가 Google cloud DNS에 접근하게 된다

Bitnami 버전의 external-dns 컨테이너는 Google cloud DNS 접근을 위한 인증 키 값을 credentials.json 에서 읽어 들인다

$ kubectl create secret generic gcloud-dns-key --from-file=credentials.json=./key.json

 


Kubernetes external-dns deploy

Helm을 통해 external-dns 를 deploy 한다.

txtOwnerId 로는 본 프로젝트의 목적과 연결되는 것이 확인 되도록 적당히 gcloudpoc를 사용한다

$ helm install external-dns bitnami/external-dns \
  --set provider=google \
  --set google.project=$PROJECT_NAME \
  --set google.serviceAccountSecret=gcloud-dns-key \
  --set txtOwnerId=gcloudpoc \
  --set domainFilters\[0\]=$CUSTOM_DOMAIN \
  --set policy=sync

$ kubectl logs external-dns-bfbcb5dc9-7djnz
----------
...
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 대역으로, 외부 접근 가능한 주소로 보면 된다(annotation의 도메인 부분을 제외하면 Route53 경우와 거의 유사함)

service-example.yaml

apiVersion: v1
kind: Service
metadata:
  name: svc1
  annotations:
    external-dns.alpha.kubernetes.io/hostname: svc1.gcloud.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:32221/TCP   1m

 

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

 


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를 삭제하면 Google cloud DNS의 gcloud.kube.click 호스팅 영역의 svc1.gcloud.kube.click 레코드도 자동으로 삭제된다

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

 

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

$ kubectl logs external-dns-bfbcb5dc9-7djnz
----------
...
time="2020-09-20T16:31:11Z" level=info msg="All records are already up to date"
time="2020-09-20T16:32:11Z" level=info msg="All records are already up to date"
time="2020-09-20T16:33:13Z" level=info msg="Change zone: subdomain-route53 batch #0"
time="2020-09-20T16:33:13Z" level=info msg="Del records: svc1.gcloud.kube.click. A [10.0.0.201] 10"
time="2020-09-20T16:33:13Z" level=info msg="Del records: svc1.gcloud.kube.click. TXT [\"heritage=external-dns,external-dns/owner=gcloudpoc,external-dns/resource=service/default/svc1\"] 300"
...

$ gcloud dns record-sets list --zone=$DNS_ZONE_NAME
----------
NAME                TYPE  TTL    DATA
gcloud.kube.click.  NS    21600  ns-cloud-e1.googledomains.com.,ns-cloud-e2.googledomains.com.,ns-cloud-e3.googledomains.com.,ns-cloud-e4.googledomains.com.
gcloud.kube.click.  SOA   21600  ns-cloud-e1.googledomains.com. cloud-dns-hostmaster.google.com. 1 21600 3600 259200 300

 

Barracuda

 

블로그 이미지

Barracuda

Bryan의 Tech-Log. 기록은 역사다. 나는 역사를 공유하고 그 안에서 배우며, 또 다른 역사를 써나간다

댓글을 달아 주세요

 

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

 

블로그 이미지

Barracuda

Bryan의 Tech-Log. 기록은 역사다. 나는 역사를 공유하고 그 안에서 배우며, 또 다른 역사를 써나간다

댓글을 달아 주세요

 

1. AWS Route53 도메인을 parent domain으로 Google cloud DNS sub-domain 등록 활용하기

 

 


이번에는 하나의 목표를 위한 3개의 글로 이루어진 시리즈물을 포스팅을 해 보려 한다.

최종 목표는 Public cloud의 managed DNS 서비스를 통해, 특정 도메인(FQDN, 여기서는 본인이 보유 중인 Route53 managed 도메인 중 kube.click 이라는 도메인의 subdomain 을 route53.kube.click 또는 gcloud.kube.click로 만들어서 사용)의 서브도메인이 자동으로 만들어지고, 해당 도메인을 통해 Kubernetes service로 외부에서 접속 가능하도록 구성해 보는 것이다. 즉, kubernetes service(또는 ingress host) 이름을 svc1 이라고 하면 svc1.route53.kube.click 으로 A record 가 생성되고 kubernetes 내에서 svc1 이 삭제되면 이 A record 도 삭제되도록 하면 상당히 간편하게 자동화 된 외부 노출 주소 관리가 가능해질 것이다.

이 기능은, 마치 OpenShift 로 app을 expose하면 app.openshift.base.domain 으로 그 app의 endpoint 가 자동으로 만들어지는 것과 유사한 사용자 경험을 제공하게 되는데, 그를 위해 현존 거의 대다수 잘 알려진 23개 Public DNS 들과 잘 연동되는 external-dns(CNCF incubation project; https://github.com/kubernetes-sigs/external-dns) 을 적용해 보고자 한다.

물론 Public cloud로는 제목에 언급된 Route53과 Google cloud DNS 각각에 대해 모두 다루어 볼 것이며, 이번 글은 다음의 2개의 글에 대한 준비 과정으로 보면 될 듯하다. 보너스로, Route53 에서 관리되는 하나의 도메인을 parent 로 해서, Google cloud DNS에 그 subdomain 을 hosted zone으로 등록하고 사용하는 과정과 방법을 같이 기록 정리해 두고자 한다.

 


  •  Pre-requisites
    • manageable FQDN(Route53 - kube.click)
    • aws sdk
    • gcloud sdk

Route53 domain 정보(parent domain)

$ aws route53 list-hosted-zones
----------
{
    "HostedZones": [
    ...
        {
            "Id": "/hostedzone/REDACTEDHOSTEDZONEID",
            "Name": "kube.click.",
            "CallerReference": "RISWorkflow-RD:REDACTEDUUID",
            "Config": {
                "Comment": "HostedZone created by Route53 Registrar",
                "PrivateZone": false
            },
            "ResourceRecordSetCount": 2
        }
    ]
}

 


Google cloud project 및 managed zone 생성

$ export PROJECT_NAME="dns-hosting-poc"
$ gcloud config set project $PROJECT_NAME

$ export CUSTOM_DOMAIN="gcloud.kube.click"
$ export DNS_ZONE_NAME="subdomain-route53"

$ gcloud dns managed-zones create $DNS_ZONE_NAME \
    --dns-name $CUSTOM_DOMAIN \
    --description "Automatically managed zone by kubernetes.io/external-dns"
----------
Created [https://dns.googleapis.com/dns/v1/projects/dns-hosting-poc/managedZones/subdomain-route53].

$ gcloud dns record-sets list \
    --zone=$DNS_ZONE_NAME \
    --name=$CUSTOM_DOMAIN
----------
NAME             TYPE  TTL    DATA
gcloud.kube.click.  NS    21600  ns-cloud-e1.googledomains.com.,ns-cloud-e2.googledomains.com.,ns-cloud-e3.googledomains.com.,ns-cloud-e4.googledomains.com.
gcloud.kube.click.  SOA   21600  ns-cloud-e1.googledomains.com. cloud-dns-hostmaster.google.com. 1 21600 3600 259200 300

 


Route53 parent domain에 NS record 추가

  • 변경 전 record-sets 확인

    $ export AWS_ZONE_ID=$(aws route53 list-hosted-zones-by-name --output json  --dns-name kube.click | jq -r '.HostedZones[0].Id' | cut -f3 -d'/')
    $ aws route53 list-resource-record-sets --hosted-zone-id $AWS_ZONE_ID

 

  • NS record 추가(단순 레코드 정의)

     

 

 

  • 변경 후 record-sets 확인

    $ export AWS_ZONE_ID=$(aws route53 list-hosted-zones-by-name --output json  --dns-name kube.click | jq -r '.HostedZones[0].Id' | cut -f3 -d'/')
    $ aws route53 list-resource-record-sets --hosted-zone-id $AWS_ZONE_ID

 

  • NS resolving 확인

    $ dig gcloud.kube.click ns
    ----------
    ; <<>> DiG 9.10.6 <<>> gcloud.kube.click ns
    ;; global options: +cmd
    ;; Got answer:
    ;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 20417
    ;; flags: qr rd ra; QUERY: 1, ANSWER: 4, AUTHORITY: 0, ADDITIONAL: 1
    
    ;; OPT PSEUDOSECTION:
    ; EDNS: version: 0, flags:; udp: 4096
    ;; QUESTION SECTION:
    ;gcloud.kube.click.		IN	NS
    
    ;; ANSWER SECTION:
    gcloud.kube.click.	300	IN	NS	ns-cloud-e2.googledomains.com.
    gcloud.kube.click.	300	IN	NS	ns-cloud-e4.googledomains.com.
    gcloud.kube.click.	300	IN	NS	ns-cloud-e3.googledomains.com.
    gcloud.kube.click.	300	IN	NS	ns-cloud-e1.googledomains.com.
    
    ;; Query time: 1007 msec
    ;; SERVER: 210.220.163.82#53(210.220.163.82)
    ;; WHEN: Mon Sep 14 03:10:31 KST 2020
    ;; MSG SIZE  rcvd: 167
    

 


Google cloud DNS에 A record 등록 후 resolving 확인

 

 

$ gcloud dns record-sets list --zone=subdomain-route53
----------
NAME                     TYPE  TTL    DATA
gcloud.kube.click.       NS    21600  ns-cloud-e1.googledomains.com.,ns-cloud-e2.googledomains.com.,ns-cloud-e3.googledomains.com.,ns-cloud-e4.googledomains.com.
gcloud.kube.click.       SOA   21600  ns-cloud-e1.googledomains.com. cloud-dns-hostmaster.google.com. 1 21600 3600 259200 300
test.gcloud.kube.click.  A     30     192.2.0.91

$ host test.gcloud.kube.click
----------
test.gcloud.kube.click has address 192.2.0.91

 

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

 

Barracuda

블로그 이미지

Barracuda

Bryan의 Tech-Log. 기록은 역사다. 나는 역사를 공유하고 그 안에서 배우며, 또 다른 역사를 써나간다

댓글을 달아 주세요


9월 6일자 티스토리 공지사항에 보면 아래의 내용이 올라와 있다. 밥벌이에 바쁘다 보니 뒤늦게 읽게 됐는데, 보다 보니 좀 심각한 내용이다. 티스토리의 서버가 이전함에 따라 IP가 바뀌게 되어 2차 도메인 사용자를 위한 배려(?)로 CNAME으로 host.tistory.io 만을 사용하고 도메인에 대한 A 레코드(티스토리의 IP주소로 등록한 부분)을 삭제 해 달라는 내용이다(10월6일 이후에 좀 더 상세하게 바뀐 내용으로 업데이트된 공지 참고).


그런데, DNS 표준 권고사항에서는 루트도메인(Root Domain=Naked Domain=Bare Domain=Zone Apex ... 다 같은 말이다. 즉 필자의 경우를 예로 들면, 보유 중인 2차 개인 도메인인 'bryan.wiki'가 바로 루트도메인)에 대한 CNAME 은 허용하지 않게 되어 있다(참고: RFC1034, Serverfault 포스팅).




다시 풀어서 예를 들어 보면, www.bryan.wiki 에 대해서는 CNAME 으로 host.tistory.io 를 등록할 수 있지만, bryan.wiki 에 대한 CNAME 으로 host.tistory.io 를 등록하지 못하게 되어 있다. 표준을 준수하는 메이저 DNS 제공 업체들(Ghandi, GoDaddy 등)은 이러한 등록을 시도하지 못하도록 오류를 뱉어내게 되어 있다. Amazon의 Route53(Ghandi 의 DNS 서비스사용) 의 관리 화면에서 @.bryan.wiki(또는 그냥 bryan.wiki) 에 대해 CNAME을 등록할 경우에 붉은 글씨의 오류 메시지를 볼 수 있다.


티스토리가 CNAME 만의 사용을 계속 강요한다면...?


만약 티스토리가 A 레코드를 삭제하고 bryan.wiki 에 대한 주소 등록을 CNAME 만으로 등록하도록 입장을 고수한다면, 다음의 우회적인 방법으로 구현은 가능하다. 필자가 사용중인 Amazon의 Route53과 S3 Redirection에 의한 방법을 예로 들어 보겠다.


우선 AWS 웹사이트에서 Route53 의 도메인 관리화면으로 들어간다. 일단, Create Record Set에서 다음과 같이 www.bryan.wiki 에 대한 CNAME은 host.tistory.io. 으로 등록은 가능하다. 이 부분은 표준에 어긋나지 않으므로...




다음으로, 티스토리가 요구하는 대로 현재 등록된 A 레코드를 삭제해 보자.


이제 "http://www.bryan.wiki 로는 블로그 접속이 되지만, http://bryan.wiki 로는 접속이 되지 않는다. 티스토리에서 원하는 대로 bryan.wiki 에 대한 CNAME 등록을 시도해 본다.


Create 를 눌러 보지만 등록 불가라고 붉은 글씨의 오류가 나며, 다음 단계로 진행되지 않는다. 빈칸 자리에 @ 를 넣으면 등록은 가능하지만 여전히 http://bryan.wiki 로 블로그 접속은 불가한 상태!



S3 의 Redirect request 를 써 보자


S3 는 Amazon의 스토리지 공간(Bucket)에 파일을 올려 두고 인터넷을 통해 다운로드 등의 서비스가 가능한 서비스로 알려져 있지만, 버킷 접속을 특정 주소로 전환해 주는 기능도 가지고 있다. 이 기능을 사용하면 되지만, 사용량에 따른 비용을 내야 하는 유료 서비스이다. 접속 형태와 지역에 따라 구분이 되기는 하지만 서울 Region 기준으로 1만 건당 0.37 센트(무려!!!)를 지불해야 한다.


AWS 메인 화면에서 S3를 클릭하여 해당 화면에 진입한다. Create Bucket을 선택해서 Bucket Name에 2차도메인을 입력하고 Create 클릭.

  

Bucket 접속에 대한 Redirection End Point를 설정해 보자. Bucket 왼쪽의 돋보기 아이콘이나 오른쪽 위의 Properties를 선택하고 Redirect all requests to .... 를 선택하고 Save.




이제 http://bryan.wiki 에 접속했을 때 리디렉션할 주소가 생성되었으니, Route53 에서 Create Record Set으로 루드도메인에 대한 A 레코드를 선택하고 Alias를 선택하면, 아래에 S3 endpoint가 목록에 나타난다. 이를 선택하고 Create!


여기까지 성공하였다면 다음 그림과 같은 등록 상태를 확인할 수 있을 것이다. SOA, NS, CNAME, A 타입의 레코드가 각각 하나씩이다. 이제 http://bryan.wiki 와 같은 2차 도메인으로 접속하면, CNAME으로 등록한 www 서브도메인(http://www.bryan.wiki)으로 리디렉션되고 티스토리 블로그로 접속할 수 있게 된다.



10월 6일 전후로 티스토리에서 해당 공지를 변경하여 발표했다. A 레코드에 의한 DNS 등록을 병행하기로 했다는 내용이다. 처음 발표된 9월 6일 이후로 수많은 2차도메인 사용자들에게 혼란을 초래해 왔고, 또 많은 이들의 지적과 불만에 찬 댓글에 대한 리액션인 듯 하다.


티스토리가 서버를 이전하는 일에는 인터넷 서비스회사의 특성상 그럴 수도 있다고 하지만 앞으로 IP 주소가 얼마나 자주 바뀔 예정이기에 표준 준수를 어겨가면서까지 A 레코드 방식을 버리라고 무리수를 두었는지는 도대체 지금도 알 길이 없다. 그냥 단순한 사용자 편의만을 위한 배려뿐이었을까?


- Barracuda -


블로그 이미지

Barracuda

Bryan의 Tech-Log. 기록은 역사다. 나는 역사를 공유하고 그 안에서 배우며, 또 다른 역사를 써나간다

댓글을 달아 주세요