如何使用 Amazon EKS 設定 ExternalDNS?

4 分的閱讀內容
0

我要使用 Amazon Elastic Kubernetes Service (Amazon EKS) 來設定 ExternalDNS。

簡短描述

ExternalDNS 是在您的 Amazon EKS 叢集中執行的 Pod。若要以外掛程式形式搭配 Amazon EKS 使用 ExternalDNS,請設定 AWS Identity and Access Management (IAM) 許可。這些許可必須允許 Amazon EKS 存取 Amazon Route 53。

附註:在開始執行下列解決方案之前,請確認存在網域名稱和 Route 53 託管區域。

解決方案

設定 IAM 許可並部署 ExternalDNS

1.    設定 IAM 許可來提供 ExternalDNS Pod 許可,以便於您的 AWS 帳戶中建立、更新和刪除 Route 53 記錄。

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 政策的 ARN 來取代 IAM_POLICY_ARN

若要檢查服務帳戶的名稱,請執行下列命令:

kubectl get sa

範例輸出:

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

在前述的範例輸出中,external-dns 是建立服務帳戶時為其指定的名稱。

3.    部署 ExternalDNS。

檢查 RBAC 是否已在 Amazon EKS 叢集中開啟:

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

**附註:**套用下列清單檔案之前,請先檢查最新版 ExternalDNS (從 GitHub 網站)。

執行下列命令:

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 官方已更新 1 年前