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

5분 분량
0

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

간략한 설명

ExternalDNS를 설치하려면 AWS Identity and Access Management(IAM) 권한을 사용하여 Amazon EKS에 Amazon Route 53과 상호 작용하는 데 필요한 액세스 권한을 부여합니다.

참고: 다음 해결 방법을 시작하기 전에 도메인 이름과 Route 53 호스팅 영역이 있는지 확인합니다.

해결 방법

IAM 권한 설정 및 ExternalDNS 배포

다음 단계를 완료합니다.

  1. 다음 정책을 생성하여 AWS 계정에서 Route 53 레코드를 생성, 업데이트 및 삭제할 수 있는 권한을 ExternalDNS pod에 부여하는 IAM 권한을 설정합니다.

    {
      "Version": "2012-10-17",
      "Statement": [
        {
          "Effect": "Allow",
          "Action": [
            "route53:ChangeResourceRecordSets"
          ],
          "Resource": [
            "arn:aws:route53:::hostedzone/"
          ]
        },
        {
          "Effect": "Allow",
          "Action": [
            "route53:ListHostedZones",
            "route53:ListResourceRecordSets",
            "route53:ListTagsForResource"
          ],
          "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

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

    NAME           SECRETS   AGE
    default        1         23h
    external-dns   1         23h
  3. 다음 명령을 실행하여 Amazon EKS 클러스터에서 RBAC가 켜져 있는지 확인합니다.

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

    참고: 이전 명령의 경우 GitHub 프로젝트에서 사용할 수 있는 최신 버전의 ExternalDNS를 확인합니다.

  4. 다음 명령을 실행하여 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
      labels:
        app.kubernetes.io/name: external-dns
    rules:
      - apiGroups: [""]
        resources: ["services","endpoints","pods","nodes"]
        verbs: ["get","watch","list"]
      - apiGroups: ["extensions","networking.k8s.io"]
        resources: ["ingresses"]
        verbs: ["get","watch","list"]
    ---
    apiVersion: rbac.authorization.k8s.io/v1
    kind: ClusterRoleBinding
    metadata:
      name: external-dns-viewer
      labels:
        app.kubernetes.io/name: external-dns
    roleRef:
      apiGroup: rbac.authorization.k8s.io
      kind: ClusterRole
      name: external-dns
    subjects:
      - kind: ServiceAccount
        name: external-dns
        namespace: default # change to desired namespace: externaldns, kube-addons
    ---
    apiVersion: apps/v1
    kind: Deployment
    metadata:
      name: external-dns
      labels:
        app.kubernetes.io/name: external-dns
    spec:
      strategy:
        type: Recreate
      selector:
        matchLabels:
          app.kubernetes.io/name: external-dns
      template:
        metadata:
          labels:
            app.kubernetes.io/name: external-dns
        spec:
          serviceAccountName: external-dns
          containers:
            - name: external-dns
              image: registry.k8s.io/external-dns/external-dns:v0.14.0
              args:
                - --source=service
                - --source=ingress
                - --domain-filter=example.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=external-dns
              env:
                - name: AWS_DEFAULT_REGION
                  value: eu-west-1 # change to region where EKS is installed

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

    apiVersion: apps/v1
    kind: Deployment
    metadata:
      name: external-dns
      labels:
        app.kubernetes.io/name: external-dns
    spec:
      strategy:
        type: Recreate
      selector:
        matchLabels:
          app.kubernetes.io/name: external-dns
      template:
        metadata:
          labels:
            app.kubernetes.io/name: external-dns
        spec:
          containers:
            - name: external-dns
              image: registry.k8s.io/external-dns/external-dns:v0.14.0
              args:
                - --source=service
                - --source=ingress
                - --domain-filter=example.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
              env:
                - name: AWS_DEFAULT_REGION
                  value: eu-west-1 # change to region where EKS is installed
  5. 다음 명령을 실행하여 배포가 성공했는지 확인합니다.

    kubectl get deployments

    출력 예시:

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

    또는 로그를 확인하여 레코드가 업데이트되었는지 확인합니다.

    kubectl logs external-dns-9f85d8d5b-sx5f

    출력 예시:

    ....
    time="2023-12-14T17:16:16Z" level=info msg="Instantiating new Kubernetes client"
    time="2023-12-14T17:16:16Z" level=info msg="Using inCluster-config based on serviceaccount-token"
    time="2023-12-14T17:16:16Z" level=info msg="Created Kubernetes client https://10.100.0.1:443"
    time="2023-12-14T17:16:18Z" level=info msg="Applying provider record filter for domains: [xxxxx.people.aws.dev. .xxxxx.people.aws.dev. xxxxx.people.aws.dev. .xxxxx.people.aws.dev.]"
    time="2023-12-14T17:16:18Z" level=info msg="All records are already up to date"
    ....

ExternalDNS 확인

ExternalDNS가 올바르게 설정되었는지 확인하려면 다음 단계를 완료합니다.

  1. LoadBalancer로 노출되는 서비스를 만듭니다. 서비스는 Route 53에서 호스팅되는 도메인 이름을 통해 외부로 라우팅되어야 합니다.

    kubectl apply SERVICE_MANIFEST_FILE_NAME.yaml
    
    Note: Replace SERVICE_MANIFEST_FILE_NAME with your service manifest's file name.
    
    Manifest:
    
    apiVersion: v1
    kind: Service
    metadata:
      name: nginx
      annotations:
        external-dns.alpha.kubernetes.io/hostname: nginx.xxxxx.people.aws.dev
    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

    참고: ExternalDNS는 서비스에 external-dns.alpha.kubernetes.io/hostname 주석을 사용합니다. 또한 연결된 값도 사용합니다. 서비스에 여러 이름을 할당하려면 쉼표 구분 기호로 external-dns.alpha.kubernetes.io/hostname 주석을 구성합니다.

  2. NGINX 서비스가 LoadBalancer 유형으로 생성되었는지 확인합니다.

    kubectl get svc

    출력 예시:

    NAME         TYPE           CLUSTER-IP      EXTERNAL-IP                                                              PORT(S)        AGE
    kubernetes   ClusterIP      10.100.0.1      <none>                                                                   443/TCP        05h
    nginx        LoadBalancer   10.100.254.68   xxxxyyyyzzzz-123456789.eu-west-1.elb.amazonaws.com   80:30792/TCP   74m
    

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

  3. 다음 명령을 실행하여 로그를 보고 Route 53 레코드가 성공적으로 생성되었는지 확인합니다.

    kubectl logs external-dns-9f85d8d5b-sx5fg

    출력 예시:

    ...
    time="2023-12-14T17:19:19Z" level=info msg="Desired change: CREATE cname-nginx.xxxxx.people.aws.dev TXT [Id: /hostedzone/Z0786329GDVAZMXYZ]"
    time="2023-12-14T17:19:19Z" level=info msg="Desired change: CREATE nginx.xxxxx.people.aws.dev A [Id: /hostedzone/Z0786329GDVAZMXYZ]"
    time="2023-12-14T17:19:19Z" level=info msg="Desired change: CREATE nginx.xxxxx.people.aws.dev TXT [Id: /hostedzone/Z0786329GDVAZMXYZ]"
    time="2023-12-14T17:19:20Z" level=info msg="3 record(s) in zone xxxxx.people.aws.dev. [Id: /hostedzone/Z0786329GDVAZMXYZ] were successfully updated"
    ...
AWS 공식
AWS 공식업데이트됨 일 년 전