For AI agents: a documentation index is available at https://www.mongodb.com/docs/llms.txt — markdown versions of all pages are available by appending .md to any URL path.

Configure External DNS

This page walks you through the process of deploying and validating external DNS for your Kubernetes Operator components deployed across multiple Kubernetes clusters without a service mesh.

Before you begin, perform the following tasks:

  • Install kubectl.

  • Update as needed and set the environment variables defined in the following env_variables.sh file.

    # This script builds on top of the environment configured in the setup guides.# It depends (uses) the following env variables defined there to work correctly.# If you don't use the setup guide to bootstrap the environment, then define them here.# ${K8S_CLUSTER_0}# ${K8S_CLUSTER_1}# ${K8S_CLUSTER_2}# ${K8S_CLUSTER_0_ZONE}# ${K8S_CLUSTER_1_ZONE}# ${K8S_CLUSTER_2_ZONE}# ${K8S_CLUSTER_0_CONTEXT_NAME}# ${K8S_CLUSTER_1_CONTEXT_NAME}# ${K8S_CLUSTER_2_CONTEXT_NAME}# ${MDB_GKE_PROJECT} export DNS_SA_NAME="ext-dns-sa${K8S_CLUSTER_SUFFIX:-}"export DNS_SA_EMAIL="${DNS_SA_NAME}@${MDB_GKE_PROJECT}.iam.gserviceaccount.com" export CUSTOM_DOMAIN="mongodb.custom"export DNS_ZONE="mongodb${K8S_CLUSTER_SUFFIX:-}"

You can find all included source code in the MongoDB Kubernetes Operator repository.

1
gcloud iam service-accounts create "${DNS_SA_NAME}" --display-name "${DNS_SA_NAME}"
2
gcloud projects add-iam-policy-binding "${MDB_GKE_PROJECT}" --member serviceAccount:"${DNS_SA_EMAIL}" --role roles/dns.admin
3
mkdir -p secrets gcloud iam service-accounts keys create secrets/external-dns-sa-key.json --iam-account="${DNS_SA_EMAIL}"
4
kubectl --context "${K8S_CLUSTER_0_CONTEXT_NAME}" create ns external-dnskubectl --context "${K8S_CLUSTER_1_CONTEXT_NAME}" create ns external-dnskubectl --context "${K8S_CLUSTER_2_CONTEXT_NAME}" create ns external-dns
5
# create secret with service account keykubectl --context "${K8S_CLUSTER_0_CONTEXT_NAME}" -n external-dns create secret generic external-dns-sa-secret --from-file credentials.json=secrets/external-dns-sa-key.jsonkubectl --context "${K8S_CLUSTER_1_CONTEXT_NAME}" -n external-dns create secret generic external-dns-sa-secret --from-file credentials.json=secrets/external-dns-sa-key.jsonkubectl --context "${K8S_CLUSTER_2_CONTEXT_NAME}" -n external-dns create secret generic external-dns-sa-secret --from-file credentials.json=secrets/external-dns-sa-key.json
6

ExternalDNS makes Kubernetes resources discoverable via public DNS servers. Deploy the eternal-dns Kubernetes deployment and related permissions objects to the namespace you just created.

# Render the manifest once so ${DNS_ZONE}/${CUSTOM_DOMAIN} are substituted.rendered_manifest=$(eval "cat <<EOF$(cat yamls/externaldns.yaml)EOF") echo "${rendered_manifest}" | kubectl --context "${K8S_CLUSTER_0_CONTEXT_NAME}" -n external-dns apply -f -echo "${rendered_manifest}" | kubectl --context "${K8S_CLUSTER_1_CONTEXT_NAME}" -n external-dns apply -f -echo "${rendered_manifest}" | kubectl --context "${K8S_CLUSTER_2_CONTEXT_NAME}" -n external-dns apply -f -
apiVersion: v1kind: ServiceAccountmetadata: name: external-dns labels: app.kubernetes.io/name: external-dns---apiVersion: rbac.authorization.k8s.io/v1kind: ClusterRolemetadata: name: external-dns labels: app.kubernetes.io/name: external-dnsrules: - 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/v1kind: ClusterRoleBindingmetadata: name: external-dns-viewer labels: app.kubernetes.io/name: external-dnsroleRef: apiGroup: rbac.authorization.k8s.io kind: ClusterRole name: external-dnssubjects: - kind: ServiceAccount name: external-dns namespace: external-dns---apiVersion: apps/v1kind: Deploymentmetadata: name: external-dns labels: app.kubernetes.io/name: external-dnsspec: 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.16.1 args: - --source=service - --source=ingress - --provider=google - --google-zone-visibility=private - --zone-id-filter=${DNS_ZONE} - --domain-filter=${CUSTOM_DOMAIN} - --log-format=json # google cloud logs parses severity of the "text" log format incorrectly - --interval=10s - --policy=upsert-only # would prevent ExternalDNS from deleting any records, omit to enable full synchronization - --registry=txt # # uncomment below if static credentials are used env: - name: GOOGLE_APPLICATION_CREDENTIALS value: /etc/secrets/service-account/credentials.json volumeMounts: - name: google-service-account mountPath: /etc/secrets/service-account/ volumes: - name: google-service-account secret: secretName: external-dns-sa-secret
7

This example includes a private DNS zone. This means that you can only access the resources deployed in the DNS zone from the GKE clusters we created. If you are planning to access your resources from outside your GKE clusters, use a public DNS zone. To do so, you must have a registered domain.

FQ_CLUSTER_0="projects/${MDB_GKE_PROJECT}/locations/${K8S_CLUSTER_0_ZONE}/clusters/${K8S_CLUSTER_0}"FQ_CLUSTER_1="projects/${MDB_GKE_PROJECT}/locations/${K8S_CLUSTER_1_ZONE}/clusters/${K8S_CLUSTER_1}"FQ_CLUSTER_2="projects/${MDB_GKE_PROJECT}/locations/${K8S_CLUSTER_2_ZONE}/clusters/${K8S_CLUSTER_2}" gcloud dns managed-zones create "${DNS_ZONE}" \ --description="" \ --dns-name="${CUSTOM_DOMAIN}" \ --visibility="private" \ --gkeclusters="${FQ_CLUSTER_0}","${FQ_CLUSTER_1}","${FQ_CLUSTER_2}"