CoreDNS
EdgeCDN-X uses CoreDNS as a Global Server Load Balancer (GSLB). The DNS controller routes requests based on client location, IP prefix, and service health, directing traffic to the most appropriate edge location.
DNS Routing Engine
The EdgeCDN-X DNS controller (edgecdnx plugin) routes DNS queries through the following decision logic:
- Direct Node Resolution (optional): For queries matching the pattern
nodename.location.node.service., return the IP address of the specified node directly. - DNSEndpoint Lookup: Match the query name and type to a
DNSEndpointCRD resource.Simple: return configured target addresses directly.Weighted: choose among matching locations using weight metadata.Failover: prefer the first configured primary location and move to healthier fallbacks when needed.Geolocation: determine the best location using prefix routing and geolookup.RoundRobin: rotate deterministically across matching locations.
- Location Selection:
- Prefix Routing: Match the client's source IP (or EDNS client subnet) to a
PrefixListCRD for direct location assignment. - Geolocation Routing: If prefix routing doesn't apply, use geolocation data to select a location based on configured geo attributes and weights.
- Prefix Routing: Match the client's source IP (or EDNS client subnet) to a
- Candidate Node Pool: Within the selected location, build a pool of healthy nodes:
- Include nodes from node groups whose labels (merged with location labels) match the endpoint's
routeSelector. - Exclude nodes and node groups in maintenance mode.
- Include nodes from child locations (locations with
spec.parentpointing to the chosen location) if the child location is healthy (not in maintenance mode, no active alerts). - Use deterministic hashing on the query name to select a specific node from the pool (maximizing cache affinity and minimizing cache misses).
- Enforce health checks: only include nodes with successful IPv4/IPv6 health status matching the query type (
Afor IPv4,AAAAfor IPv6). - Filter out nodes with active Prometheus alerts.
- Include nodes from node groups whose labels (merged with location labels) match the endpoint's
- Health-Aware Fallback:
- If no healthy node exists in the chosen location, try the parent location (if configured via
spec.parent). - If the parent location also has no healthy nodes, try each location in the parent's
spec.fallbackLocationsin order. - If there is no parent, try locations in the chosen location's
spec.fallbackLocationsdirectly. - Skip any location that is in maintenance mode (
spec.maintenanceMode: true) or has active alerts (status.alertsis non-empty). - Continue until a location with a healthy node is found, or exhausts all fallback options.
- If no healthy node exists in the chosen location, try the parent location (if configured via
- Response Generation:
- A/AAAA Response: Return the IP address of the selected node.
- CNAME Response: Return a CNAME pointing to the node using the format
node_name.location.node.original-request. - Response Type Selection: Use the configured
dnsresponsetypefor normal DNS queries, orgrpcresponsetypeif the request originated from gRPC.
- Zone Authority (if no DNSEndpoint matched): Fall back to zone-authoritative behavior using
ZoneCRDs to return SOA, NS, or NXDOMAIN responses.
Deploy this engine to each location where edgecdnx.com/routing label is set in metadata.
Prefix-Based Routing
The PrefixList CRD defines IP address ranges (CIDR blocks) and their destination locations. The DNS controller matches incoming client source IPs (or EDNS client subnet values) against these prefixes to determine the target location.
Capabilities: - IPv4 and IPv6 CIDR routing - EDNS0 client subnet extension support for fine-grained client location detection - Non-overlapping prefix consolidation (managed by the EdgeCDN-X controller)
Example PrefixList:
apiVersion: infrastructure.edgecdnx.com/v1alpha1
kind: PrefixList
metadata:
name: prefixlist-us-west-1
spec:
destination: us-west-1 # Target location
prefix:
v4:
- address: 192.168.100.128
size: 27
- address: 192.168.100.0
size: 27
v6: []
Geolocation-Based Routing
When prefix routing does not match (or is not applicable), the DNS controller falls back to geolocation routing. Each Location CRD defines geolocation attributes and weights for scoring requests by geographic proximity.
Example Location:
apiVersion: infrastructure.edgecdnx.com/v1alpha1
kind: Location
metadata:
name: nyc1-c1
labels:
tier: primary
region: us-east
spec:
# (Optional) Parent location for hierarchical fallback and shared configuration
parent: us-east-1
# Fallback targets when this location has no healthy nodes
fallbackLocations:
- fra1-c1
- lax1-c1
# Maintenance mode: when true, this location is skipped in routing decisions
maintenanceMode: false
# Geolocation-based routing configuration
geoLookup:
weight: 100 # Weight relative to other locations
attributes:
geoip/continent/code:
weight: 1000
values:
- value: NA # North America
- value: SA # South America
# Node groups organize nodes by cache profile and configuration
nodeGroups:
- name: ssd
flavor: "" # Optional flavor to distinguish variants of the same cache type
# Kubernetes label selector for discovering nodes via DaemonSet
nodeSelector:
kubernetes.civo.com/civo-node-pool: nyc1-c1
# Labels merged with Location labels for route selector matching
labels:
cache-tier: primary
# Generic metadata for cache configuration (replaces deprecated cacheConfig)
metadata:
path: /var/cache/ssd
maxSize: 4096m
keysZone: 100m
inactive: 10080m # Inactivity timeout
# Individual nodes in this group
nodes:
- name: n1
ipv4: 74.220.30.216
ipv6: "2001:db8::1"
# Maintenance mode: when true, this node is excluded from routing
maintenanceMode: false
Route Selector Matching: When a DNSEndpoint specifies a routeSelector, the DNS controller matches it against the combined labels of each location and its node groups. For example:
# In DNSEndpoint
routeSelector:
tier: primary # Must match a label from Location or NodeGroup
# Matches this Location because it has tier: primary at the metadata level
# OR if a NodeGroup has labels: {tier: primary}
Node groups can be configured with different cache profiles for services requiring varied caching performance. Multiple node groups with the same name but different flavors can coexist within a location for redundancy or specialized caching needs.
DNSEndpoint Configuration
DNSEndpoint CRDs define which domains are served and how requests should be routed. The plugin supports these routing policies on spec.routingPolicy:
| Policy | When to use it | Primary fields |
|---|---|---|
Simple |
Static answers, often for origin addresses or explicit records | targets, recordType, recordTTL |
Weighted |
Prefer some matching locations over others using weights and labels | routeSelector, recordType, recordTTL |
Failover |
Prefer a primary location and then fall back to healthy alternatives | targets, routeSelector, recordType, recordTTL |
Geolocation |
Route by prefix match or geographic metadata | routeSelector, recordType, recordTTL |
RoundRobin |
Spread queries across multiple candidate locations in sequence | routeSelector, recordType, recordTTL |
The plugin matches the value case-insensitively, but the canonical CRD examples use title case such as Simple, Weighted, Failover, Geolocation, and RoundRobin.
Simple
Use Simple for explicit static targets. The plugin returns the spec.targets values directly for the requested record type.
apiVersion: infrastructure.edgecdnx.com/v1alpha1
kind: DNSEndpoint
metadata:
name: static-origin
spec:
dnsName: static.example.com
routingPolicy: Simple
recordType: A
targets: ["203.0.113.10", "203.0.113.11"]
recordTTL: 300
Weighted
Use Weighted when multiple matching locations should be considered and some should win more often based on their configured weight metadata.
apiVersion: infrastructure.edgecdnx.com/v1alpha1
kind: DNSEndpoint
metadata:
name: weighted-service
spec:
dnsName: cdn.example.com
routingPolicy: Weighted
recordType: A
recordTTL: 60
routeSelector:
matchLabels:
edgecdnx.com/tenant: tbotech
edgecdnx.com/region: us-east
Failover
Use Failover to prefer one location first and then fail over to additional healthy alternatives. In the current implementation, the first entry in spec.targets is treated as a Location name, not a literal DNS hostname.
apiVersion: infrastructure.edgecdnx.com/v1alpha1
kind: DNSEndpoint
metadata:
name: failover-service
spec:
dnsName: api.example.com
routingPolicy: Failover
recordType: A
recordTTL: 60
targets:
- us-east
routeSelector:
matchLabels:
edgecdnx.com/tenant: tbotech
Geolocation
Use Geolocation to route by location labels, prefix match, or geo metadata. The plugin first checks prefix routing and then uses geolocation lookup when needed.
apiVersion: infrastructure.edgecdnx.com/v1alpha1
kind: DNSEndpoint
metadata:
name: geo-service
spec:
dnsName: cdn.example.com
routingPolicy: Geolocation
recordType: A
recordTTL: 60
routeSelector:
matchLabels:
edgecdnx.com/tenant: tbotech
edgecdnx.com/region: us-east
RoundRobin
Use RoundRobin to rotate target locations in a deterministic sequence across repeated queries to the same endpoint.
apiVersion: infrastructure.edgecdnx.com/v1alpha1
kind: DNSEndpoint
metadata:
name: rr-service
spec:
dnsName: app.example.com
routingPolicy: RoundRobin
recordType: A
recordTTL: 60
routeSelector:
matchLabels:
edgecdnx.com/tenant: tbotech
edgecdnx.com/site: edge
Zone Configuration
Zone CRDs enable you to serve DNS zones with authoritative SOA and NS records, useful for hosting your own domain apex or delegating subdomains.
Example Zone:
apiVersion: infrastructure.edgecdnx.com/v1alpha1
kind: Zone
metadata:
name: example.com
spec:
zone: example.com
email: noc@example.com
DNS Controller Configuration
The DNS controller is configured in the CoreDNS Corefile via the edgecdnx plugin directive:
.:53 {
errors
health
ready
edgecdnx . {
namespace edgecdnx # K8S namespace containing EdgeCDN-X CRDs
soa ns1 # SOA MNAME label prefix
ns ns1.edge.example.com. 203.0.113.10 # NS records (repeatable)
ns ns2.edge.example.com. 203.0.113.11
recordttl 60 # Default TTL for generated answers
dnsresponsetype A_AAAA # Response type for DNS queries (A_AAAA or CNAME)
grpcresponsetype CNAME # Response type for gRPC-originated requests
}
prometheus :9153
forward . 1.1.1.1 8.8.8.8 # Upstream resolvers for fallthrough
cache 30
reload
}
Configuration Directives:
| Directive | Required | Default | Description |
|---|---|---|---|
namespace |
Yes | none | Kubernetes namespace to watch for CRDs |
soa |
Yes | none | SOA MNAME label prefix (e.g., ns1 → ns1.zone.) |
ns |
Recommended | empty | NS record entries (repeatable); format: ns <hostname> <ipv4> |
recordttl |
No | 60 | Default TTL for generated answers (in seconds) |
dnsresponsetype |
No | A_AAAA | Response type for normal DNS queries: A_AAAA or CNAME |
grpcresponsetype |
No | CNAME | Response type for gRPC requests: A_AAAA or CNAME |
Operational Considerations
Maintenance and Health Checks
- Maintenance Mode: Set
spec.maintenanceMode: trueon a Location or Node to temporarily exclude it from routing without deleting the resource. - Health Conditions: Nodes have health conditions tracked for IPv4 and IPv6 separately (
IPV4HealthCheckSuccessful,IPV6HealthCheckSuccessful). The DNS controller respects these when selecting nodes forAorAAAAqueries. - Prometheus Alerts: Active alerts on locations or nodes (via
status.alertsor nodestatus.nodeStatus[name].alerts) cause them to be skipped in routing. Configurespec.alertswithAlertNameand optional label matchers to watch external Prometheus alerts.
Plugin Readiness
- The DNS controller plugin readiness is tied to Kubernetes informer synchronization for
Zone,DNSEndpoint, andPrefixListwatchers. - If informers have not synced yet, the CoreDNS
readyprobe integration will report the plugin as not ready. - Location informers are watched independently and do not block plugin readiness.
Fallthrough Behavior
- If the DNS controller cannot find a matching DNSEndpoint, location, or healthy node, the query is passed to the next plugin in the CoreDNS chain (typically
forwardto upstream resolvers). - Direct node requests that reference a non-existent service, location, or node also fall through.