如何使用 Amazon EKS 设置 ExternalDNS?

4 分钟阅读
0

我想使用我的 Amazon Elastic Kubernetes Service(Amazon EKS)设置 ExternalDNS。

简短描述

ExternalDNS 是在您的 Amazon EKS 集群中运行的容器组。要将 ExternalDNS 用作 Amazon EKS 的插件,请设置 AWS Identity and Access Management(IAM)权限。这些权限必须允许 Amazon EKS 访问 Amazon Route 53。

注意: 在开始以下解决方法之前,请确保存在域名和 Route 53 托管区。

解决方法

设置 IAM 权限并部署 ExternalDNS

1.    设置 IAM 权限,授予 ExternalDNS 容器组在您的 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_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

**注意:**在应用以下清单之前,请检查最新版本的 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 年前
没有评论