如何使用 Amazon EKS 设置 ExternalDNS?
我想使用我的 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 官方已更新 2 年前
- AWS 官方已更新 2 年前
- AWS 官方已更新 1 年前
- AWS 官方已更新 2 年前