본문 바로가기

Technical/Cloud, Virtualization, Containers

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

 

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