Amazon EKS로 ExternalDNS를 설정하려면 어떻게 해야 하나요?

5분 분량
0

Amazon Elastic Kubernetes Service(Amazon EKS)를 사용하여 ExternalDNS를 설정하고 싶습니다.

간략한 설명

ExternalDNS는 Amazon EKS 클러스터에서 실행되는 포드입니다. Amazon EKS로 ExternalDNS를 플러그 인으로 사용하려면 AWS Identity and Access Management(IAM) 권한을 설정하세요. 이러한 권한은 Amazon EKS에서 Amazon Route 53에 액세스할 수 있도록 허용해야 합니다.

참고: 다음 해결 방법을 시작하기 전에, 도메인 이름 및 Route 53 호스팅 영역이 존재하는지 확인하세요.

해결 방법

IAM 권한 설정 및 ExternalDNS 배포

1.    AWS 계정에서 Route 53 레코드를 생성, 업데이트 및 삭제할 수 있는 권한을 ExternalDNS 포드에 부여하도록 IAM 권한을 설정하세요.

IAM 정책:

{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Effect": "Allow",
      "Action": [
        "route53:ChangeResourceRecordSets"
      ],
      "Resource": [
        "arn:aws:route53:::hostedzone/*"
      ]
    },
    {
      "Effect": "Allow",
      "Action": [
        "route53:ListHostedZones",
        "route53:ListResourceRecordSets"
      ],
      "Resource": [
        "*"
      ]
    }
  ]
}

참고: 또한 명시적인 호스팅 영역 ID에 대한 업데이트를 허용하도록 이전 정책을 조정할 수 있습니다.

2.    이전 정책을 사용하여 다음과 같이 서비스 계정에 대한 IAM 역할을 생성하세요.

eksctl create iamserviceaccount --name SERVICE_ACCOUNT_NAME --namespace NAMESPACE --cluster CLUSTER_NAME --attach-policy-arn IAM_POLICY_ARN --approve

참고:SERVICE_ACCOUNT_NAME을 귀하의 서비스 계정 이름으로, NAMESPACE를 네임스페이스로, CLUSTER_NAME을 클러스터 이름으로, IAM_POLICY_ARN을 귀하의 IAM 정책 ARN으로 바꾸세요.

서비스 계정의 이름을 확인하려면 다음 명령을 실행합니다.

kubectl get sa

출력 예시:

NAME           SECRETS   AGE
default        1         23h
external-dns   1         23h

위 출력 예시에서 external-dns는 서비스 계정을 만들 때 서비스 계정에 지정된 이름입니다.

3.    ExternalDNS 배포.

Amazon EKS 클러스터에서 RBAC가 켜져 있는지 확인하세요.

kubectl api-versions | grep rbac.authorization.k8s.io

**참고:**다음 매니페스트를 적용하기 전에 (GitHub 웹 사이트에서) ExternalDNS의 최신 버전을 확인하세요.

다음 명령을 실행합니다.

kubectl apply DEPLOYMENT_MANIFEST_FILE_NAME.yaml

**참고:DEPLOYMENT_MANIFEST_FILE_NAME을 귀하의 배포 매니페스트 파일 이름으로 **바꾸세요.

RBAC가 켜져 있는 경우, 다음 매니페스트를 사용하여 ExternalDNS를 배포하세요.

apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:
  name: external-dns
rules:
- apiGroups: [""]
  resources: ["services","endpoints","pods"]
  verbs: ["get","watch","list"]
- apiGroups: ["extensions","networking.k8s.io"]
  resources: ["ingresses"]
  verbs: ["get","watch","list"]
- apiGroups: [""]
  resources: ["nodes"]
  verbs: ["list","watch"]
---
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRoleBinding
metadata:
  name: external-dns-viewer
roleRef:
  apiGroup: rbac.authorization.k8s.io
  kind: ClusterRole
  name: external-dns
subjects:
- kind: ServiceAccount
  name: external-dns
  namespace: default
---
apiVersion: apps/v1
kind: Deployment
metadata:
  name: external-dns
spec:
  strategy:
    type: Recreate
  selector:
    matchLabels:
      app: external-dns
  template:
    metadata:
      labels:
        app: external-dns
    spec:
      serviceAccountName: external-dns
      containers:
      - name: external-dns
        image: k8s.gcr.io/external-dns/external-dns:v0.10.2
        args:
        - --source=service
        - --source=ingress
        - --domain-filter=external-dns-test.my-org.com # will make ExternalDNS see only the hosted zones matching provided domain, omit to process all available hosted zones
        - --provider=aws
        - --policy=upsert-only # would prevent ExternalDNS from deleting any records, omit to enable full synchronization
        - --aws-zone-type=public # only look at public hosted zones (valid values are public, private or no value for both)
        - --registry=txt
        - --txt-owner-id=my-hostedzone-identifier
      securityContext:
        fsGroup: 65534 # For ExternalDNS to be able to read Kubernetes and AWS token files

RBAC가 켜져 있지 않은 경우 다음 매니페스트를 사용하여 ExternalDNS를 배포하세요.

apiVersion: apps/v1
kind: Deployment
metadata:
  name: external-dns
spec:
  strategy:
    type: Recreate
  selector:
    matchLabels:
      app: external-dns
  template:
    metadata:
      labels:
        app: external-dns
    spec:
      containers:
      - name: external-dns
        image: k8s.gcr.io/external-dns/external-dns:v0.10.2
        args:
        - --source=service
        - --source=ingress
        - --domain-filter= <Your_R53_Domain_Name>  # will make ExternalDNS see only the hosted zones matching provided domain, omit to process all available hosted zones
        - --provider=aws
        - --policy=upsert-only # would prevent ExternalDNS from deleting any records, omit to enable full synchronization
        - --aws-zone-type=public # only look at public hosted zones (valid values are public, private or no value for both)
        - --registry=txt
        - --txt-owner-id=<Your_R53_HostedZone_Id>

4.    배포가 성공했는지 다음과 같이 확인하세요.

kubectl get deployments

출력 예시:

NAME           READY   UP-TO-DATE   AVAILABLE   AGE
external-dns   1/1     1            1           85m

다음과 같이 로그를 확인하여 레코드가 최신 상태인지 확인할 수도 있습니다.

kubectl logs external-dns-9f85d8d5b-sx5fg

출력 예시:

....
....
time="2022-02-10T20:22:02Z" level=info msg="Instantiating new Kubernetes client"
time="2022-02-10T20:22:02Z" level=info msg="Using inCluster-config based on serviceaccount-token"
time="2022-02-10T20:22:02Z" level=info msg="Created Kubernetes client https://10.100.0.1:443"
time="2022-02-10T20:22:09Z" level=info msg="Applying provider record filter for domains: [<yourdomainname>.com. .<yourdomainname>.com.]"
time="2022-02-10T20:22:09Z" level=info msg="All records are already up to date"
....
....

ExternalDNS가 작동하는지 확인

1.    다음과 같이 LoadBalancer 노출되고 Route 53에서 호스팅되는 도메인 이름을 통해 외부로 라우팅될 수 있는 서비스를 생성하세요.

kubectl apply SERVICE_MANIFEST_FILE_NAME.yaml

**참고:SERVICE_MANIFEST_FILE_NAME을 귀하의 서비스 매니페스트 파일 이름으로 **바꿉니다.

매니페스트:

apiVersion: v1
kind: Service
metadata:
  name: nginx
  annotations:
    external-dns.alpha.kubernetes.io/hostname: DOMAIN_NAME
spec:
  ports:
    - port: 80
      targetPort: 80
      protocol: TCP
  type: LoadBalancer
  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

**참고:DOMAIN_NAME을 귀하의 도메인 이름으로 **바꿉니다.

2.    다음과 같이 NGINX 서비스가 LoadBalancer유형으로 생성되었는지 확인하세요.

kubectl get svc

출력 예시:

NAME         TYPE           CLUSTER-IP      EXTERNAL-IP                                                              PORT(S)        AGE
kubernetes   ClusterIP      10.100.0.1      <none>                                                                   443/TCP        26h
nginx        LoadBalancer   10.100.234.77   a1ef09255d52049f487e05b4f74faea6-954147917.us-west-1.elb.amazonaws.com   80:30792/TCP   74m

참고: 이 서비스는 해당 호스팅 영역에 대한 Route 53 레코드를 자동으로 생성합니다.

다음과 같이 로그를 확인하여 Route 53 레코드가 생성되었는지 확인하세요.

kubectl logs external-dns-9f85d8d5b-sx5fg

출력 예시:

...
...
...
time="2022-02-10T21:22:43Z" level=info msg="Applying provider record filter for domains: [<domainname>.com. .<domainname>.com.]"
time="2022-02-10T21:22:43Z" level=info msg="Desired change: CREATE <domainname>.com A [Id: /hostedzone/Z01155763Q6AN7CEI3AP6]"
time="2022-02-10T21:22:43Z" level=info msg="Desired change: CREATE <domainname>.com TXT [Id: /hostedzone/Z01155763Q6AN7CEI3AP6]"
time="2022-02-10T21:22:43Z" level=info msg="2 record(s) in zone xxx.com. [Id: /hostedzone/Z01155763Q6AN7CEI3AP6] were successfully updated"
time="2022-02-10T21:23:43Z" level=info msg="Applying provider record filter for domains: [<domainname>.com. .<domainname>.com.]"
time="2022-02-10T21:23:43Z" level=info msg="All records are already up to date"
...
...
...

ExternalDNS에 대한 더 자세한 정보 및 예시는 AWS에서의 서비스를 위한 ExternalDNS 설정(GitHub 웹 사이트) 및 ExternalDNS 설정(Kubernetes 웹 사이트)를 참조하세요.


AWS 공식
AWS 공식업데이트됨 일 년 전