Cross-namespace DNS management with ExternalDNS DNS Endpoint resources
TypeScriptCross-namespace DNS management is a powerful feature that allows you to create and manage DNS records across different namespaces. It is especially handy when you have services that span multiple Kubernetes namespaces but you want to control the DNS records from a single point.
The typical way to manage cross-namespace DNS records in Kubernetes is with the ExternalDNS tool. ExternalDNS synchronizes exposed Kubernetes Services and Ingresses with DNS providers like AWS Route53, Google Cloud DNS, Azure DNS, and others.
Before we start writing code, you'll need to deploy ExternalDNS to your Kubernetes cluster. The configuration of ExternalDNS can get involved, as it includes setting the right permissions with your DNS provider and configuring the ExternalDNS deployment to access those services.
For managing DNS Endpoint resources across namespaces, you typically need to:
- Configure RBAC (Role-Based Access Control) that allows the ExternalDNS service account to access resources across all needed namespaces.
- Deploy ExternalDNS with a configuration that watches over services and ingresses in all those namespaces and creates DNS records accordingly.
Let's take a look at a simplified example of a Pulumi program that sets up a DNS Endpoint resource in Kubernetes, which could be used by ExternalDNS to create DNS records. This example is abstract and intended to demonstrate the typical resources you would use; you would need to adjust it for your specific setup.
Note: This example assumes ExternalDNS is already configured and running in your cluster, and your Pulumi stack is configured to deploy to your Kubernetes cluster.
import * as k8s from "@pulumi/kubernetes"; // Assume there is a namespace "my-app-namespace" where you want to manage a DNS Endpoint. const appNamespace = new k8s.core.v1.Namespace("my-app-namespace", { metadata: { name: "my-app-namespace" } }); // Create a Service in the "my-app-namespace". const myService = new k8s.core.v1.Service("myService", { metadata: { namespace: appNamespace.metadata.name, // Annotations specify the desired DNS name on your actual DNS provider // which ExternalDNS watches and acts upon. annotations: { "external-dns.alpha.kubernetes.io/hostname": "myapp.example.com.", }, }, spec: { ports: [{ port: 80 }], selector: { app: "myapp" // This assumes a selector for pods with the label "app: myapp". } }, }, { dependsOn: appNamespace }); // Create a DNS Endpoint resource. This is not a native Kubernetes resource but rather a CRD that ExternalDNS might understand. // For this example, we're assuming that the CRD has already been registered in your cluster. const dnsEndpoint = new k8s.apiextensions.CustomResource("dnsEndpoint", { apiVersion: "externaldns.k8s.io/v1alpha1", kind: "DNSEndpoint", metadata: { namespace: appNamespace.metadata.name, // Cross-namespace relevant setting. }, spec: { endpoints: [ { dnsName: "myapp.example.com.", recordTTL: 300, recordType: "A", targets: [ "192.0.2.1" // The supposed external IP which should be the address of the Service above. ] }, ] } }, { dependsOn: myService }); // Exporting the DNS name for reference export const dnsName = dnsEndpoint.metadata.apply(m => m.annotations["external-dns.alpha.kubernetes.io/hostname"]);
This code does the following:
- It creates a new Kubernetes namespace
my-app-namespace
, which reflects a typical scenario where you have different namespaces for different parts of your application. - A service
myService
is created which would be the service you want to expose through DNS. - Annotations on the service indicate what DNS name
external-dns
should manage.external-dns
looks for services and ingresses with special annotations and creates or updates DNS records for them. - A
DNSEndpoint
custom resource is defined, whichexternal-dns
can pick up.external-dns
looks forDNSEndpoint
resources if it's configured to do so. - Finally, the DNS name that would be managed by
external-dns
is exported for reference.
Ensure you have the correct access permissions, ExternalDNS deployment, and DNS provider configurations in place. Adjust the
targets
field in theDNSEndpoint
resource to match the external address of your Service. Also, double-check the official ExternalDNS documentation for specific setup details for your DNS provider and cluster.