ExternalDNS for Route53¶
func create hosted zone¶
- refer: ../../CLI/awscli/route53-cmd
- refer: ../../CLI/awscli/route53-cmd
- refer: route53-subdomian
- you also could create private hosted zone and associate to your vpc. plugin will insert/update record in your private hosted zone. (link)
install¶
install-with-eksdemo-¶
install-¶
- https://github.com/kubernetes-sigs/external-dns/blob/master/docs/tutorials/aws.md
- 创建所需要的服务账号 (create service account)
- 确保 EKS 集群名称正确 (ensure eks cluster name is correct)
- 确保使用正确的 Region (ensure region is correct)
- 确保域名匹配所需 (ensure domain name is correct)
CLUSTER_NAME=ekscluster1 AWS_REGION=us-west-2 DOMAIN_NAME=poc1207.xxx.xxx.xxx EXTERNALDNS_NS=externaldns export AWS_PAGER="" # create namespace if it does not yet exist kubectl get namespaces | grep -q $EXTERNALDNS_NS || \ kubectl create namespace $EXTERNALDNS_NS cat >externaldns-policy.json <<-EOF { "Version": "2012-10-17", "Statement": [ { "Effect": "Allow", "Action": [ "route53:ChangeResourceRecordSets" ], "Resource": [ "arn:aws:route53:::hostedzone/*" ] }, { "Effect": "Allow", "Action": [ "route53:ListHostedZones", "route53:ListResourceRecordSets" ], "Resource": [ "*" ] } ] } EOF POLICY_NAME=AllowExternalDNSUpdates-${RANDOM} aws iam create-policy --policy-name ${POLICY_NAME} --policy-document file://externaldns-policy.json # example: arn:aws:iam::XXXXXXXXXXXX:policy/AllowExternalDNSUpdates export POLICY_ARN=$(aws iam list-policies \ --query 'Policies[?PolicyName==`'"${POLICY_NAME}"'`].Arn' --output text) eksctl create iamserviceaccount \ --cluster ${CLUSTER_NAME} \ --name "external-dns" \ --namespace ${EXTERNALDNS_NS:-"default"} \ --override-existing-serviceaccounts \ --attach-policy-arn $POLICY_ARN \ --approve
HELM INSTALL¶
echo ${EXTERNALDNS_NS}
helm repo add --force-update external-dns https://kubernetes-sigs.github.io/external-dns/
# support gateway api
cat >externaldns-values.yaml <<-EOF
sources:
- service
- ingress
- gateway-httproute
- gateway-tcproute
EOF
helm upgrade --install external-dns external-dns/external-dns \
--namespace ${EXTERNALDNS_NS:-"default"} \
--set serviceAccount.create=false \
--set serviceAccount.name=external-dns \
-f externaldns-values.yaml
MANUAL INSTALL – 使用上述服务账号安装 ExternalDNS (install ExternalDNS with existed SA)¶
echo ${EXTERNALDNS_NS}
echo ${DOMAIN_NAME}
echo ${AWS_REGION}
envsubst >externaldns-with-rbac.yaml <<-EOF
# comment out sa if it was previously created
# apiVersion: v1
# kind: ServiceAccount
# metadata:
# name: external-dns
# labels:
# app.kubernetes.io/name: external-dns
---
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: ${EXTERNALDNS_NS} # 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.13.2
args:
- --source=service
- --source=ingress
- --domain-filter=${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=external-dns
env:
- name: AWS_DEFAULT_REGION
value: ${AWS_REGION} # change to region where EKS is installed
# # Uncommend below if using static credentials
# - name: AWS_SHARED_CREDENTIALS_FILE
# value: /.aws/credentials
# volumeMounts:
# - name: aws-credentials
# mountPath: /.aws
# readOnly: true
# volumes:
# - name: aws-credentials
# secret:
# secretName: external-dns
EOF
kubectl create --filename externaldns-with-rbac.yaml \
--namespace ${EXTERNALDNS_NS:-"default"}
sample¶
verify-¶
- create namespace
service sample
-
create nlb (no more clb, 20230423) with service definition
echo ${DOMAIN_NAME} envsubst >verify-nginx.yaml <<-EOF apiVersion: v1 kind: Service metadata: name: nginx annotations: external-dns.alpha.kubernetes.io/hostname: nginx.${DOMAIN_NAME} service.beta.kubernetes.io/aws-load-balancer-scheme: "internet-facing" spec: type: LoadBalancer ports: - port: 80 name: http targetPort: 80 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 EOF kubectl create --filename verify-nginx.yaml -n ${NS:-default} -
wait nlb available and execute
aws route53 list-resource-record-sets --output json --hosted-zone-id $ZONE_ID \ --query "ResourceRecordSets[?Name == 'nginx.${DOMAIN_NAME}.']|[?Type == 'A']" aws route53 list-resource-record-sets --output json --hosted-zone-id $ZONE_ID \ --query "ResourceRecordSets[?Name == 'nginx.${DOMAIN_NAME}.']|[?Type == 'TXT']" dig +short nginx.${DOMAIN_NAME}. A curl http://nginx.${DOMAIN_NAME}
ingress sample
-
ensure certificate is existed and create alb
echo ${CERTIFICATE_ARN} envsubst >verify-nginx-ingress.yaml <<-EOF --- apiVersion: networking.k8s.io/v1 kind: Ingress metadata: name: nginx annotations: alb.ingress.kubernetes.io/scheme: internet-facing alb.ingress.kubernetes.io/tags: Environment=dev,Team=test,Application=nginx alb.ingress.kubernetes.io/target-type: ip alb.ingress.kubernetes.io/listen-ports: '[{"HTTP": 80}, {"HTTPS": 443}]' alb.ingress.kubernetes.io/ssl-redirect: '443' alb.ingress.kubernetes.io/certificate-arn: ${CERTIFICATE_ARN} spec: ingressClassName: alb rules: - host: server.${DOMAIN_NAME} http: paths: - backend: service: name: nginx port: number: 80 path: / pathType: Prefix EOF kubectl create --filename verify-nginx-ingress.yaml -n ${NS:-default} -
wait alb available and execute