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