IP-based Pod DNS resolution enables direct pod-to-pod communication patterns that are essential for advanced Kubernetes networking architectures, service mesh implementations, and enterprise applications requiring precise control over network connectivity. This comprehensive guide demonstrates production-ready configurations, security patterns, and operational strategies for implementing sophisticated pod networking solutions.

Executive Summary

Modern Kubernetes applications increasingly require direct pod communication capabilities that bypass traditional service abstractions. IP-based Pod DNS resolution provides the foundation for advanced networking patterns including service mesh integration, database clustering, distributed system coordination, and high-performance application architectures. This guide presents enterprise-grade configurations and security patterns for implementing IP-based pod resolution while maintaining operational excellence and security compliance.

IP-Based Pod DNS Architecture

CoreDNS Pod Resolution Configuration

CoreDNS supports multiple modes of Pod DNS resolution, each providing different levels of security and functionality:

# Advanced CoreDNS configuration for IP-based Pod DNS
apiVersion: v1
kind: ConfigMap
metadata:
  name: coredns-pod-dns-config
  namespace: kube-system
  labels:
    app: coredns
    component: pod-dns
data:
  Corefile: |
    # Core Kubernetes DNS configuration
    cluster.local:53 {
        errors {
            consolidate 5m ".*" warning
        }

        # Comprehensive health monitoring
        health {
            lameduck 5s
        }

        ready

        # Advanced Kubernetes plugin configuration
        kubernetes cluster.local in-addr.arpa ip6.arpa {
            # Pod DNS resolution modes:
            # - disabled: No pod DNS records (default)
            # - insecure: Pod DNS records without verification
            # - verified: Pod DNS records with existence verification
            pods verified

            # Enable endpoint resolution
            endpoint_pod_names

            # TTL for pod records
            ttl 30

            # Fallthrough for reverse DNS
            fallthrough in-addr.arpa ip6.arpa

            # Upstream for external queries
            upstream

            # Namespace selection for pod DNS
            namespaces default production staging monitoring

            # Ignore empty service endpoints
            ignore empty_service
        }

        # Enhanced caching for pod resolution
        cache 300 {
            success 10000 300
            denial 5000 60
            prefetch 50 60s 30%
        }

        # Loop detection and prevention
        loop

        # DNS forwarding for external domains
        forward . /etc/resolv.conf {
            max_concurrent 1000
            policy sequential
            health_check 30s
        }

        # Reload configuration automatically
        reload

        # Load balancing for multiple CoreDNS instances
        loadbalance

        # Prometheus metrics
        prometheus :9153 {
            path /metrics
        }

        # Query logging for debugging
        log {
            class error
        }
    }

    # Reverse DNS for pod IPs
    in-addr.arpa:53 {
        errors
        cache 300
        kubernetes cluster.local in-addr.arpa ip6.arpa {
            pods verified
            fallthrough
        }
        forward . /etc/resolv.conf
    }

    # IPv6 reverse DNS
    ip6.arpa:53 {
        errors
        cache 300
        kubernetes cluster.local in-addr.arpa ip6.arpa {
            pods verified
            fallthrough
        }
        forward . /etc/resolv.conf
    }

    # Wildcard for all other queries
    .:53 {
        errors
        health {
            lameduck 5s
        }
        ready
        kubernetes cluster.local in-addr.arpa ip6.arpa {
            pods disabled
            fallthrough in-addr.arpa ip6.arpa
        }
        forward . /etc/resolv.conf {
            max_concurrent 1000
        }
        cache 300
        loop
        reload
        loadbalance
    }

---
# Enhanced CoreDNS deployment for pod DNS
apiVersion: apps/v1
kind: Deployment
metadata:
  name: coredns
  namespace: kube-system
  labels:
    k8s-app: kube-dns
    app: coredns
spec:
  replicas: 3
  strategy:
    type: RollingUpdate
    rollingUpdate:
      maxUnavailable: 1
      maxSurge: 10%

  selector:
    matchLabels:
      k8s-app: kube-dns

  template:
    metadata:
      labels:
        k8s-app: kube-dns
        app: coredns
    spec:
      serviceAccountName: coredns

      # Priority class for DNS stability
      priorityClassName: system-cluster-critical

      # Node selection for DNS reliability
      nodeSelector:
        kubernetes.io/os: linux

      # Anti-affinity for high availability
      affinity:
        podAntiAffinity:
          preferredDuringSchedulingIgnoredDuringExecution:
          - weight: 100
            podAffinityTerm:
              labelSelector:
                matchLabels:
                  k8s-app: kube-dns
              topologyKey: kubernetes.io/hostname

      # Tolerations for critical system pods
      tolerations:
      - key: CriticalAddonsOnly
        operator: Exists
      - effect: NoSchedule
        key: node-role.kubernetes.io/control-plane

      # Security context
      securityContext:
        seccompProfile:
          type: RuntimeDefault

      containers:
      - name: coredns
        image: registry.k8s.io/coredns/coredns:v1.10.1
        imagePullPolicy: IfNotPresent

        # Resource allocation for pod DNS workloads
        resources:
          limits:
            memory: 1Gi
            cpu: 1000m
          requests:
            cpu: 100m
            memory: 128Mi

        # Security configuration
        securityContext:
          allowPrivilegeEscalation: false
          capabilities:
            add:
            - NET_BIND_SERVICE
            drop:
            - all
          readOnlyRootFilesystem: true
          runAsNonRoot: true
          runAsUser: 65534

        # Command line arguments
        args: [ "-conf", "/etc/coredns/Corefile" ]

        # Volume mounts
        volumeMounts:
        - name: config-volume
          mountPath: /etc/coredns
          readOnly: true

        # Network ports
        ports:
        - containerPort: 53
          name: dns
          protocol: UDP
        - containerPort: 53
          name: dns-tcp
          protocol: TCP
        - containerPort: 9153
          name: metrics
          protocol: TCP

        # Health checks optimized for pod DNS
        livenessProbe:
          httpGet:
            path: /health
            port: 8080
            scheme: HTTP
          initialDelaySeconds: 60
          timeoutSeconds: 5
          successThreshold: 1
          failureThreshold: 5

        readinessProbe:
          httpGet:
            path: /ready
            port: 8181
            scheme: HTTP
          initialDelaySeconds: 10
          timeoutSeconds: 5
          successThreshold: 1
          failureThreshold: 3

      # DNS policy configuration
      dnsPolicy: Default

      volumes:
      - name: config-volume
        configMap:
          name: coredns
          items:
          - key: Corefile
            path: Corefile

      # Restart policy for critical DNS service
      restartPolicy: Always

Service Mesh Integration Patterns

IP-based Pod DNS resolution is essential for service mesh implementations that require direct pod communication:

# Istio service mesh configuration with pod DNS
apiVersion: install.istio.io/v1alpha1
kind: IstioOperator
metadata:
  name: istio-control-plane
  namespace: istio-system
spec:
  # Global mesh configuration
  values:
    global:
      # Enable pod-level DNS resolution
      meshID: mesh1
      network: network1

      # Proxy configuration for direct pod communication
      proxy:
        # Enable DNS capture for service mesh
        dnsCapture: true
        # DNS refresh rate for pod resolution
        dnsRefreshRate: 300s

    # Pilot configuration for service discovery
    pilot:
      # Enable cross-cluster endpoint discovery
      enableCrossClusterWorkloadEntry: true
      # DNS resolution timeout
      dnsResolution: 30s

  # Component configurations
  components:
    pilot:
      k8s:
        # Resource allocation for service discovery
        resources:
          requests:
            cpu: 500m
            memory: 2048Mi
          limits:
            cpu: 2000m
            memory: 4096Mi

        # Environment variables for pod DNS
        env:
        - name: PILOT_ENABLE_IP_AUTOALLOCATE
          value: "true"
        - name: PILOT_ENABLE_CROSS_CLUSTER_WORKLOAD_ENTRY
          value: "true"
        - name: PILOT_DNS_LOOKUP_FAMILY
          value: "V4_PREFERRED"

    # Ingress gateway configuration
    ingressGateways:
    - name: istio-ingressgateway
      enabled: true
      k8s:
        service:
          type: LoadBalancer
        resources:
          requests:
            cpu: 1000m
            memory: 1024Mi

---
# Service mesh networking configuration
apiVersion: networking.istio.io/v1beta1
kind: Sidecar
metadata:
  name: default-sidecar
  namespace: production
spec:
  # Enable pod-level traffic interception
  workloadSelector:
    labels:
      app: microservice

  # Egress configuration for pod DNS
  egress:
  - port:
      number: 53
      name: dns-udp
      protocol: UDP
    hosts:
    - "./*"
    - "istio-system/*"

  - port:
      number: 53
      name: dns-tcp
      protocol: TCP
    hosts:
    - "./*"
    - "istio-system/*"

  # Enable pod IP discovery
  - hosts:
    - "./*"
    - "istio-system/*"
    port:
      number: 15090
      name: http-envoy-prom
      protocol: HTTP

---
# Virtual service for pod-level routing
apiVersion: networking.istio.io/v1beta1
kind: VirtualService
metadata:
  name: pod-direct-routing
  namespace: production
spec:
  hosts:
  - "*.pod.cluster.local"

  http:
  - match:
    - headers:
        pod-direct:
          exact: "true"
    route:
    - destination:
        host: "*.pod.cluster.local"
        # Enable pod-level load balancing
        subset: pod-direct

  - route:
    - destination:
        host: kubernetes.default.svc.cluster.local
        port:
          number: 443

---
# Destination rule for pod communication
apiVersion: networking.istio.io/v1beta1
kind: DestinationRule
metadata:
  name: pod-direct-destination
  namespace: production
spec:
  host: "*.pod.cluster.local"

  # Traffic policy for pod communication
  trafficPolicy:
    # Connection pool settings for pod-to-pod
    connectionPool:
      tcp:
        maxConnections: 100
        connectTimeout: 30s
      http:
        http1MaxPendingRequests: 50
        maxRequestsPerConnection: 2

    # Load balancer settings
    loadBalancer:
      simple: LEAST_CONN

    # Outlier detection for unhealthy pods
    outlierDetection:
      consecutiveGatewayErrors: 5
      interval: 30s
      baseEjectionTime: 30s
      maxEjectionPercent: 50

  # Subsets for different pod types
  subsets:
  - name: pod-direct
    labels:
      pod-direct: "enabled"
    trafficPolicy:
      connectionPool:
        tcp:
          maxConnections: 200

Database Clustering with Pod DNS

Database clusters require direct pod communication for replication and coordination:

# PostgreSQL cluster with pod DNS resolution
apiVersion: postgresql.cnpg.io/v1
kind: Cluster
metadata:
  name: postgres-cluster
  namespace: database
spec:
  instances: 3

  # PostgreSQL configuration
  postgresql:
    parameters:
      # Enable pod-level communication
      listen_addresses: "*"
      # DNS-based discovery
      cluster_name: "postgres-cluster"

  # Pod template for cluster nodes
  template:
    metadata:
      labels:
        app: postgres
        cluster: postgres-cluster
        pod-dns-enabled: "true"

    spec:
      # Affinity rules for pod distribution
      affinity:
        podAntiAffinity:
          requiredDuringSchedulingIgnoredDuringExecution:
          - labelSelector:
              matchLabels:
                app: postgres
            topologyKey: kubernetes.io/hostname

      # Service account for pod discovery
      serviceAccountName: postgres-pod-discovery

      containers:
      - name: postgres
        image: postgres:15

        # Environment variables for pod DNS
        env:
        - name: POD_IP
          valueFrom:
            fieldRef:
              fieldPath: status.podIP
        - name: POD_NAME
          valueFrom:
            fieldRef:
              fieldPath: metadata.name
        - name: POD_NAMESPACE
          valueFrom:
            fieldRef:
              fieldPath: metadata.namespace

        # DNS configuration for cluster discovery
        - name: POSTGRES_CLUSTER_DISCOVERY
          value: "$(POD_NAME).postgres-cluster.$(POD_NAMESPACE).svc.cluster.local"

        # Resource allocation
        resources:
          requests:
            cpu: 1000m
            memory: 2Gi
          limits:
            cpu: 2000m
            memory: 4Gi

        # Volume mounts for data persistence
        volumeMounts:
        - name: postgres-data
          mountPath: /var/lib/postgresql/data

        # Health checks
        livenessProbe:
          exec:
            command:
            - sh
            - -c
            - pg_isready -h $(POD_IP) -p 5432 -U postgres
          initialDelaySeconds: 30
          periodSeconds: 10

        readinessProbe:
          exec:
            command:
            - sh
            - -c
            - pg_isready -h $(POD_IP) -p 5432 -U postgres
          initialDelaySeconds: 5
          periodSeconds: 5

  # Storage configuration
  storage:
    size: 100Gi
    storageClass: fast-ssd

  # Monitoring configuration
  monitoring:
    enabled: true

---
# Service for postgres cluster pod discovery
apiVersion: v1
kind: Service
metadata:
  name: postgres-cluster-pods
  namespace: database
  labels:
    app: postgres
    service-type: pod-discovery
spec:
  # Headless service for pod DNS resolution
  clusterIP: None

  # Expose postgres port
  ports:
  - name: postgres
    port: 5432
    targetPort: 5432

  # Select all postgres pods
  selector:
    app: postgres
    cluster: postgres-cluster

---
# Service account for pod discovery
apiVersion: v1
kind: ServiceAccount
metadata:
  name: postgres-pod-discovery
  namespace: database

---
# RBAC for pod discovery
apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
  name: postgres-pod-discovery
  namespace: database
rules:
- apiGroups: [""]
  resources: ["pods", "endpoints"]
  verbs: ["get", "list", "watch"]

---
apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata:
  name: postgres-pod-discovery
  namespace: database
subjects:
- kind: ServiceAccount
  name: postgres-pod-discovery
  namespace: database
roleRef:
  kind: Role
  name: postgres-pod-discovery
  apiGroup: rbac.authorization.k8s.io

Advanced Pod Discovery Patterns

Custom Pod Discovery Controller

#!/usr/bin/env python3
"""
Advanced Pod Discovery Controller for IP-based DNS resolution
"""

import asyncio
import json
import logging
import time
from typing import Dict, List, Set, Optional, Any
from dataclasses import dataclass, field
from datetime import datetime, timedelta

from kubernetes import client, config, watch
import aiohttp
import aiodns

logging.basicConfig(level=logging.INFO)
logger = logging.getLogger(__name__)

@dataclass
class PodInfo:
    name: str
    namespace: str
    ip: str
    labels: Dict[str, str]
    annotations: Dict[str, str]
    phase: str
    node_name: str
    creation_timestamp: datetime
    dns_names: List[str] = field(default_factory=list)
    health_status: str = "unknown"
    last_health_check: Optional[datetime] = None

class PodDiscoveryController:
    def __init__(self, namespaces: List[str] = None):
        # Initialize Kubernetes client
        try:
            config.load_incluster_config()
        except:
            config.load_kube_config()

        self.v1 = client.CoreV1Api()
        self.namespaces = namespaces or ["default", "production", "staging"]

        # Pod tracking
        self.pods: Dict[str, PodInfo] = {}
        self.pod_dns_cache: Dict[str, str] = {}

        # DNS resolver for validation
        self.resolver = aiodns.DNSResolver()

        # Configuration
        self.health_check_interval = 60  # seconds
        self.dns_validation_interval = 300  # seconds

    async def start_monitoring(self):
        """Start monitoring pods for DNS resolution"""
        logger.info("Starting pod discovery controller")

        # Start concurrent tasks
        tasks = [
            asyncio.create_task(self.watch_pods()),
            asyncio.create_task(self.health_check_loop()),
            asyncio.create_task(self.dns_validation_loop()),
            asyncio.create_task(self.cleanup_stale_pods())
        ]

        await asyncio.gather(*tasks)

    async def watch_pods(self):
        """Watch for pod changes"""
        logger.info("Starting pod watcher")

        w = watch.Watch()
        while True:
            try:
                for event in w.stream(
                    self.v1.list_pod_for_all_namespaces,
                    timeout_seconds=300
                ):
                    await self.handle_pod_event(event)

            except Exception as e:
                logger.error(f"Error watching pods: {e}")
                await asyncio.sleep(10)

    async def handle_pod_event(self, event):
        """Handle pod lifecycle events"""
        event_type = event['type']
        pod = event['object']

        # Filter by namespace
        if pod.metadata.namespace not in self.namespaces:
            return

        pod_key = f"{pod.metadata.namespace}/{pod.metadata.name}"

        if event_type == 'ADDED' or event_type == 'MODIFIED':
            await self.process_pod(pod)

        elif event_type == 'DELETED':
            if pod_key in self.pods:
                logger.info(f"Pod deleted: {pod_key}")
                del self.pods[pod_key]
                await self.update_dns_records(pod_key, [])

    async def process_pod(self, pod):
        """Process pod for DNS registration"""
        pod_key = f"{pod.metadata.namespace}/{pod.metadata.name}"

        # Skip pods without IP
        if not pod.status.pod_ip:
            return

        # Skip pods not in running state
        if pod.status.phase != 'Running':
            return

        # Extract pod information
        pod_info = PodInfo(
            name=pod.metadata.name,
            namespace=pod.metadata.namespace,
            ip=pod.status.pod_ip,
            labels=pod.metadata.labels or {},
            annotations=pod.metadata.annotations or {},
            phase=pod.status.phase,
            node_name=pod.spec.node_name,
            creation_timestamp=pod.metadata.creation_timestamp
        )

        # Generate DNS names for pod
        dns_names = self.generate_pod_dns_names(pod_info)
        pod_info.dns_names = dns_names

        # Store pod information
        self.pods[pod_key] = pod_info

        # Update DNS records
        await self.update_dns_records(pod_key, dns_names)

        logger.info(f"Processed pod: {pod_key} with IP {pod_info.ip}")

    def generate_pod_dns_names(self, pod_info: PodInfo) -> List[str]:
        """Generate DNS names for pod"""
        dns_names = []

        # Standard pod DNS name (IP-based)
        ip_parts = pod_info.ip.replace('.', '-')
        dns_names.append(f"{ip_parts}.{pod_info.namespace}.pod.cluster.local")

        # Service-based DNS names if pod belongs to services
        service_dns_names = self.get_service_dns_names(pod_info)
        dns_names.extend(service_dns_names)

        # Label-based DNS names
        if 'app' in pod_info.labels:
            app_name = pod_info.labels['app']
            dns_names.append(f"{pod_info.name}.{app_name}.{pod_info.namespace}.pod.cluster.local")

        # Custom DNS names from annotations
        if 'pod-dns.kubernetes.io/names' in pod_info.annotations:
            custom_names = pod_info.annotations['pod-dns.kubernetes.io/names'].split(',')
            dns_names.extend([name.strip() for name in custom_names])

        return dns_names

    def get_service_dns_names(self, pod_info: PodInfo) -> List[str]:
        """Get service-based DNS names for pod"""
        dns_names = []

        try:
            # Get services in the namespace
            services = self.v1.list_namespaced_service(namespace=pod_info.namespace)

            for service in services.items:
                if self.pod_matches_service_selector(pod_info, service):
                    service_name = service.metadata.name
                    dns_names.append(f"{pod_info.name}.{service_name}.{pod_info.namespace}.svc.cluster.local")

        except Exception as e:
            logger.warning(f"Error getting service DNS names: {e}")

        return dns_names

    def pod_matches_service_selector(self, pod_info: PodInfo, service) -> bool:
        """Check if pod matches service selector"""
        if not service.spec.selector:
            return False

        for key, value in service.spec.selector.items():
            if key not in pod_info.labels or pod_info.labels[key] != value:
                return False

        return True

    async def update_dns_records(self, pod_key: str, dns_names: List[str]):
        """Update DNS records for pod"""
        try:
            # Implementation would update CoreDNS or external DNS
            # This is a placeholder for the actual DNS update logic
            logger.debug(f"Updating DNS records for {pod_key}: {dns_names}")

            # Update local cache
            for dns_name in dns_names:
                self.pod_dns_cache[dns_name] = self.pods[pod_key].ip

        except Exception as e:
            logger.error(f"Error updating DNS records for {pod_key}: {e}")

    async def health_check_loop(self):
        """Continuously check pod health"""
        while True:
            await asyncio.sleep(self.health_check_interval)

            tasks = []
            for pod_key, pod_info in self.pods.items():
                task = asyncio.create_task(self.check_pod_health(pod_info))
                tasks.append(task)

            if tasks:
                await asyncio.gather(*tasks, return_exceptions=True)

    async def check_pod_health(self, pod_info: PodInfo):
        """Check health of a specific pod"""
        try:
            # HTTP health check
            async with aiohttp.ClientSession(timeout=aiohttp.ClientTimeout(total=5)) as session:
                health_url = f"http://{pod_info.ip}:8080/health"

                async with session.get(health_url) as response:
                    if response.status == 200:
                        pod_info.health_status = "healthy"
                    else:
                        pod_info.health_status = "unhealthy"

        except Exception:
            pod_info.health_status = "unhealthy"

        pod_info.last_health_check = datetime.now()

    async def dns_validation_loop(self):
        """Validate DNS resolution for pods"""
        while True:
            await asyncio.sleep(self.dns_validation_interval)

            for pod_key, pod_info in self.pods.items():
                for dns_name in pod_info.dns_names:
                    try:
                        result = await self.resolver.query(dns_name, 'A')
                        expected_ip = pod_info.ip

                        if result and str(result[0].host) == expected_ip:
                            logger.debug(f"DNS validation passed for {dns_name}")
                        else:
                            logger.warning(f"DNS validation failed for {dns_name}")

                    except Exception as e:
                        logger.warning(f"DNS validation error for {dns_name}: {e}")

    async def cleanup_stale_pods(self):
        """Clean up stale pod entries"""
        while True:
            await asyncio.sleep(300)  # 5 minutes

            current_time = datetime.now()
            stale_pods = []

            for pod_key, pod_info in self.pods.items():
                # Check if pod hasn't been health checked recently
                if (pod_info.last_health_check and
                    current_time - pod_info.last_health_check > timedelta(minutes=10)):

                    # Verify pod still exists in Kubernetes
                    try:
                        self.v1.read_namespaced_pod(
                            name=pod_info.name,
                            namespace=pod_info.namespace
                        )
                    except client.exceptions.ApiException as e:
                        if e.status == 404:
                            stale_pods.append(pod_key)

            # Remove stale pods
            for pod_key in stale_pods:
                logger.info(f"Removing stale pod: {pod_key}")
                del self.pods[pod_key]

    def get_pod_discovery_report(self) -> Dict[str, Any]:
        """Generate pod discovery report"""
        total_pods = len(self.pods)
        healthy_pods = sum(1 for pod in self.pods.values() if pod.health_status == "healthy")
        unhealthy_pods = sum(1 for pod in self.pods.values() if pod.health_status == "unhealthy")

        namespace_stats = {}
        for pod in self.pods.values():
            if pod.namespace not in namespace_stats:
                namespace_stats[pod.namespace] = 0
            namespace_stats[pod.namespace] += 1

        return {
            "timestamp": datetime.now().isoformat(),
            "total_pods": total_pods,
            "healthy_pods": healthy_pods,
            "unhealthy_pods": unhealthy_pods,
            "namespace_distribution": namespace_stats,
            "dns_cache_entries": len(self.pod_dns_cache),
            "monitored_namespaces": self.namespaces
        }

if __name__ == "__main__":
    controller = PodDiscoveryController(["default", "production", "staging", "database"])

    # Start the controller
    asyncio.run(controller.start_monitoring())

Enhanced DNS Security for Pod Resolution

# Security-enhanced CoreDNS configuration for pod DNS
apiVersion: v1
kind: ConfigMap
metadata:
  name: coredns-secure-pod-dns
  namespace: kube-system
data:
  Corefile: |
    # Secure pod DNS configuration
    (pod-dns-security) {
        errors {
            consolidate 5m ".*" warning
        }

        log {
            class all
            format "[POD-DNS] {type} {name} {rcode} {remote} {size} {duration}"
        }

        # Health checks
        health {
            lameduck 5s
        }
        ready

        # Rate limiting for pod DNS queries
        ratelimit {
            per_second 100
            per_client 20
            window 60s
            ipv4_mask 24
            whitelist 10.0.0.0/8 172.16.0.0/12 192.168.0.0/16
        }

        # Caching with security considerations
        cache 300 {
            success 5000 300
            denial 1000 60
            prefetch 20 60s 25%
        }

        prometheus :9153 {
            path /metrics
        }
    }

    # Production namespace - verified pod DNS
    cluster.local:53 {
        import pod-dns-security

        kubernetes cluster.local in-addr.arpa ip6.arpa {
            # Verified pod DNS - checks pod existence
            pods verified

            # Enable endpoint names
            endpoint_pod_names

            # TTL for pod records
            ttl 30

            # Namespace restrictions for pod DNS
            namespaces production database monitoring

            # Security: ignore empty services
            ignore empty_service

            # Upstream fallback
            upstream /etc/resolv.conf

            # Fallthrough for reverse DNS
            fallthrough in-addr.arpa ip6.arpa
        }

        # Access control for pod DNS queries
        acl {
            # Allow pod-to-pod communication within cluster
            allow 10.0.0.0/8
            allow 172.16.0.0/12
            allow 192.168.0.0/16
            # Deny external access to pod DNS
            deny all
        }

        # Forward non-cluster queries
        forward . /etc/resolv.conf {
            max_concurrent 1000
        }

        # Standard configurations
        loop
        reload
        loadbalance
    }

    # Staging environment - insecure pod DNS for development
    staging.cluster.local:53 {
        import pod-dns-security

        kubernetes staging.cluster.local {
            # Insecure pod DNS for development flexibility
            pods insecure

            # Limited to staging namespace
            namespaces staging

            # Reduced TTL for development
            ttl 10

            upstream /etc/resolv.conf
        }

        # More relaxed access control for staging
        acl {
            allow 192.168.100.0/24  # Staging network
            allow 10.100.0.0/16     # Developer network
            deny all
        }

        forward . /etc/resolv.conf
        loop
        reload
        loadbalance
    }

    # Reverse DNS with security
    in-addr.arpa:53 {
        import pod-dns-security

        kubernetes cluster.local in-addr.arpa ip6.arpa {
            pods verified
            namespaces production database monitoring
            fallthrough
        }

        forward . /etc/resolv.conf
    }

    # Default secure configuration
    .:53 {
        import pod-dns-security

        # Disable pod DNS for external queries
        kubernetes cluster.local in-addr.arpa ip6.arpa {
            pods disabled
            fallthrough in-addr.arpa ip6.arpa
        }

        forward . /etc/resolv.conf {
            max_concurrent 1000
        }

        loop
        reload
        loadbalance
    }

---
# Network policy for pod DNS security
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
  name: pod-dns-security
  namespace: production
spec:
  podSelector:
    matchLabels:
      pod-dns-enabled: "true"

  policyTypes:
  - Ingress
  - Egress

  ingress:
  # Allow DNS queries from other pods in namespace
  - from:
    - namespaceSelector:
        matchLabels:
          name: production
    ports:
    - protocol: UDP
      port: 53
    - protocol: TCP
      port: 53

  # Allow service mesh communication
  - from:
    - namespaceSelector:
        matchLabels:
          name: istio-system
    ports:
    - protocol: TCP
      port: 15090

  egress:
  # Allow DNS resolution
  - to: []
    ports:
    - protocol: UDP
      port: 53
    - protocol: TCP
      port: 53

  # Allow pod-to-pod communication
  - to:
    - namespaceSelector:
        matchLabels:
          name: production
    ports:
    - protocol: TCP
      port: 8080
    - protocol: TCP
      port: 8443

---
# Pod DNS monitoring service
apiVersion: v1
kind: Service
metadata:
  name: pod-dns-monitor
  namespace: monitoring
  labels:
    app: pod-dns-monitor
spec:
  selector:
    app: pod-dns-monitor
  ports:
  - name: metrics
    port: 9090
    targetPort: 9090
  - name: health
    port: 8080
    targetPort: 8080

---
# Pod DNS monitoring deployment
apiVersion: apps/v1
kind: Deployment
metadata:
  name: pod-dns-monitor
  namespace: monitoring
spec:
  replicas: 1
  selector:
    matchLabels:
      app: pod-dns-monitor
  template:
    metadata:
      labels:
        app: pod-dns-monitor
    spec:
      serviceAccountName: pod-dns-monitor

      containers:
      - name: monitor
        image: company/pod-dns-monitor:v1.0.0

        # Environment configuration
        env:
        - name: NAMESPACES
          value: "production,database,monitoring"
        - name: DNS_SERVER
          value: "kube-dns.kube-system.svc.cluster.local"
        - name: CHECK_INTERVAL
          value: "60"

        # Resource allocation
        resources:
          requests:
            cpu: 100m
            memory: 128Mi
          limits:
            cpu: 500m
            memory: 512Mi

        # Health checks
        livenessProbe:
          httpGet:
            path: /health
            port: 8080
          initialDelaySeconds: 30
          periodSeconds: 30

        readinessProbe:
          httpGet:
            path: /ready
            port: 8080
          initialDelaySeconds: 5
          periodSeconds: 10

        # Metrics port
        ports:
        - containerPort: 9090
          name: metrics
        - containerPort: 8080
          name: health

      # Service account for monitoring
      serviceAccountName: pod-dns-monitor

---
# RBAC for pod DNS monitoring
apiVersion: v1
kind: ServiceAccount
metadata:
  name: pod-dns-monitor
  namespace: monitoring

---
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:
  name: pod-dns-monitor
rules:
- apiGroups: [""]
  resources: ["pods", "services", "endpoints"]
  verbs: ["get", "list", "watch"]
- apiGroups: ["networking.k8s.io"]
  resources: ["networkpolicies"]
  verbs: ["get", "list"]

---
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRoleBinding
metadata:
  name: pod-dns-monitor
roleRef:
  apiGroup: rbac.authorization.k8s.io
  kind: ClusterRole
  name: pod-dns-monitor
subjects:
- kind: ServiceAccount
  name: pod-dns-monitor
  namespace: monitoring

Performance Testing and Validation

Comprehensive DNS Resolution Testing

#!/bin/bash
# Comprehensive Pod DNS resolution testing script

set -euo pipefail

# Configuration
NAMESPACE="production"
TEST_ITERATIONS=100
DNS_SERVER="kube-dns.kube-system.svc.cluster.local"
RESULTS_DIR="/tmp/pod-dns-tests"

# Create results directory
mkdir -p "$RESULTS_DIR"

# Test functions
test_pod_ip_resolution() {
    local pod_name=$1
    local pod_namespace=$2
    local pod_ip=$3

    echo "Testing IP-based DNS resolution for pod: $pod_name"

    # Generate IP-based DNS name
    local ip_dns_name="${pod_ip//./-}.$pod_namespace.pod.cluster.local"

    # Test DNS resolution
    local resolved_ip
    resolved_ip=$(dig +short @$DNS_SERVER "$ip_dns_name" A 2>/dev/null | head -n1)

    if [[ "$resolved_ip" == "$pod_ip" ]]; then
        echo "✅ SUCCESS: $ip_dns_name resolves to $pod_ip"
        return 0
    else
        echo "❌ FAILED: $ip_dns_name resolves to '$resolved_ip', expected '$pod_ip'"
        return 1
    fi
}

test_pod_dns_performance() {
    local dns_name=$1
    local iterations=${2:-$TEST_ITERATIONS}

    echo "Testing DNS resolution performance for: $dns_name ($iterations iterations)"

    local total_time=0
    local successful_queries=0
    local failed_queries=0

    for ((i=1; i<=iterations; i++)); do
        local start_time
        start_time=$(date +%s.%N)

        if dig +short @$DNS_SERVER "$dns_name" A >/dev/null 2>&1; then
            ((successful_queries++))
        else
            ((failed_queries++))
        fi

        local end_time
        end_time=$(date +%s.%N)
        local query_time
        query_time=$(echo "$end_time - $start_time" | bc)
        total_time=$(echo "$total_time + $query_time" | bc)
    done

    # Calculate statistics
    local avg_time
    avg_time=$(echo "scale=4; $total_time / $iterations" | bc)
    local success_rate
    success_rate=$(echo "scale=2; $successful_queries * 100 / $iterations" | bc)

    echo "Performance Results:"
    echo "  Average query time: ${avg_time}s"
    echo "  Success rate: ${success_rate}%"
    echo "  Successful queries: $successful_queries"
    echo "  Failed queries: $failed_queries"

    # Save results
    cat > "$RESULTS_DIR/performance_${dns_name//[\/\.]/_}.json" <<EOF
{
  "dns_name": "$dns_name",
  "total_iterations": $iterations,
  "successful_queries": $successful_queries,
  "failed_queries": $failed_queries,
  "success_rate": $success_rate,
  "average_query_time": $avg_time,
  "total_time": $total_time
}
EOF
}

test_pod_dns_cache_behavior() {
    local dns_name=$1

    echo "Testing DNS cache behavior for: $dns_name"

    # Clear DNS cache (if possible)
    kubectl exec -n kube-system deployment/coredns -- \
        pkill -SIGUSR1 coredns 2>/dev/null || true
    sleep 2

    # First query (should be uncached)
    echo "Testing uncached query..."
    local uncached_start
    uncached_start=$(date +%s.%N)
    dig +short @$DNS_SERVER "$dns_name" A >/dev/null
    local uncached_end
    uncached_end=$(date +%s.%N)
    local uncached_time
    uncached_time=$(echo "$uncached_end - $uncached_start" | bc)

    # Second query (should be cached)
    echo "Testing cached query..."
    local cached_start
    cached_start=$(date +%s.%N)
    dig +short @$DNS_SERVER "$dns_name" A >/dev/null
    local cached_end
    cached_end=$(date +%s.%N)
    local cached_time
    cached_time=$(echo "$cached_end - $cached_start" | bc)

    # Calculate performance improvement
    local improvement
    improvement=$(echo "scale=2; $uncached_time / $cached_time" | bc)

    echo "Cache Performance:"
    echo "  Uncached query time: ${uncached_time}s"
    echo "  Cached query time: ${cached_time}s"
    echo "  Performance improvement: ${improvement}x"
}

test_cross_namespace_pod_dns() {
    echo "Testing cross-namespace pod DNS resolution"

    # Get pods from different namespaces
    local source_namespace="production"
    local target_namespace="database"

    # Test from production pod to database pod
    local production_pods
    production_pods=$(kubectl get pods -n $source_namespace -o json | \
        jq -r '.items[] | select(.status.phase=="Running") | .metadata.name' | head -1)

    local database_pods
    database_pods=$(kubectl get pods -n $target_namespace -o json | \
        jq -r '.items[] | select(.status.phase=="Running") | .metadata.name' | head -1)

    if [[ -n "$production_pods" && -n "$database_pods" ]]; then
        # Get database pod IP
        local db_pod_ip
        db_pod_ip=$(kubectl get pod "$database_pods" -n $target_namespace -o jsonpath='{.status.podIP}')

        # Generate DNS name
        local db_dns_name="${db_pod_ip//./-}.$target_namespace.pod.cluster.local"

        echo "Testing resolution of $db_dns_name from $source_namespace"

        # Test DNS resolution from production pod
        local result
        result=$(kubectl exec -n $source_namespace "$production_pods" -- \
            dig +short "$db_dns_name" A 2>/dev/null | head -n1)

        if [[ "$result" == "$db_pod_ip" ]]; then
            echo "✅ SUCCESS: Cross-namespace pod DNS resolution works"
        else
            echo "❌ FAILED: Cross-namespace pod DNS resolution failed"
        fi
    else
        echo "⚠️  SKIPPED: No suitable pods found for cross-namespace test"
    fi
}

validate_pod_dns_security() {
    echo "Validating Pod DNS security configuration"

    # Check if pod DNS is properly configured
    local coredns_config
    coredns_config=$(kubectl get configmap coredns -n kube-system -o jsonpath='{.data.Corefile}')

    if echo "$coredns_config" | grep -q "pods verified"; then
        echo "✅ SUCCESS: Pod DNS is configured with 'verified' mode"
    elif echo "$coredns_config" | grep -q "pods insecure"; then
        echo "⚠️  WARNING: Pod DNS is configured with 'insecure' mode"
    else
        echo "❌ FAILED: Pod DNS configuration not found or disabled"
    fi

    # Check for rate limiting
    if echo "$coredns_config" | grep -q "ratelimit"; then
        echo "✅ SUCCESS: Rate limiting is configured"
    else
        echo "⚠️  WARNING: Rate limiting not configured"
    fi

    # Check for access control
    if echo "$coredns_config" | grep -q "acl"; then
        echo "✅ SUCCESS: Access control is configured"
    else
        echo "⚠️  WARNING: Access control not configured"
    fi
}

generate_test_report() {
    echo "Generating comprehensive test report"

    local report_file="$RESULTS_DIR/pod_dns_test_report.html"

    cat > "$report_file" <<EOF
<!DOCTYPE html>
<html>
<head>
    <title>Pod DNS Test Report</title>
    <style>
        body { font-family: Arial, sans-serif; margin: 20px; }
        .success { color: green; }
        .warning { color: orange; }
        .failure { color: red; }
        .test-section { margin: 20px 0; padding: 10px; border: 1px solid #ccc; }
        pre { background: #f5f5f5; padding: 10px; overflow-x: auto; }
    </style>
</head>
<body>
    <h1>Pod DNS Resolution Test Report</h1>
    <p>Generated on: $(date)</p>

    <div class="test-section">
        <h2>Test Configuration</h2>
        <ul>
            <li>Namespace: $NAMESPACE</li>
            <li>DNS Server: $DNS_SERVER</li>
            <li>Test Iterations: $TEST_ITERATIONS</li>
        </ul>
    </div>

    <div class="test-section">
        <h2>Performance Test Results</h2>
        <p>Performance test results are available in JSON format:</p>
        <ul>
EOF

    # Add performance test results to report
    for result_file in "$RESULTS_DIR"/performance_*.json; do
        if [[ -f "$result_file" ]]; then
            local dns_name
            dns_name=$(jq -r '.dns_name' "$result_file")
            local success_rate
            success_rate=$(jq -r '.success_rate' "$result_file")
            local avg_time
            avg_time=$(jq -r '.average_query_time' "$result_file")

            echo "            <li>$dns_name - Success: ${success_rate}%, Avg Time: ${avg_time}s</li>" >> "$report_file"
        fi
    done

    cat >> "$report_file" <<EOF
        </ul>
    </div>

    <div class="test-section">
        <h2>Test Summary</h2>
        <p>All performance data and detailed results are available in: $RESULTS_DIR</p>
    </div>
</body>
</html>
EOF

    echo "Test report generated: $report_file"
}

# Main test execution
main() {
    echo "=== Pod DNS Resolution Testing Suite ==="
    echo "Start time: $(date)"
    echo

    # Get test pods from namespace
    local test_pods
    test_pods=$(kubectl get pods -n $NAMESPACE -o json | \
        jq -r '.items[] | select(.status.phase=="Running") | "\(.metadata.name) \(.status.podIP)"')

    if [[ -z "$test_pods" ]]; then
        echo "No running pods found in namespace: $NAMESPACE"
        exit 1
    fi

    # Test individual pods
    echo "=== Individual Pod DNS Tests ==="
    local failed_tests=0

    while IFS= read -r pod_line; do
        if [[ -n "$pod_line" ]]; then
            local pod_name
            pod_name=$(echo "$pod_line" | cut -d' ' -f1)
            local pod_ip
            pod_ip=$(echo "$pod_line" | cut -d' ' -f2)

            test_pod_ip_resolution "$pod_name" "$NAMESPACE" "$pod_ip" || ((failed_tests++))

            # Performance test
            local ip_dns_name="${pod_ip//./-}.$NAMESPACE.pod.cluster.local"
            test_pod_dns_performance "$ip_dns_name" 50

            # Cache behavior test
            test_pod_dns_cache_behavior "$ip_dns_name"
        fi
    done <<< "$test_pods"

    echo
    echo "=== Cross-Namespace Tests ==="
    test_cross_namespace_pod_dns

    echo
    echo "=== Security Validation ==="
    validate_pod_dns_security

    echo
    echo "=== Test Report Generation ==="
    generate_test_report

    echo
    echo "=== Test Summary ==="
    echo "Failed individual tests: $failed_tests"
    echo "Results directory: $RESULTS_DIR"

    if [[ $failed_tests -eq 0 ]]; then
        echo "✅ All Pod DNS tests completed successfully!"
        exit 0
    else
        echo "❌ Some Pod DNS tests failed!"
        exit 1
    fi
}

# Execute main function
main "$@"

Conclusion

IP-based Pod DNS resolution provides the foundation for advanced Kubernetes networking patterns that enable direct pod communication, service mesh integration, and sophisticated distributed system architectures. The configurations and patterns presented in this guide demonstrate how organizations can implement secure, performant pod-to-pod networking while maintaining operational excellence and security compliance.

Key success factors include proper CoreDNS configuration with appropriate security modes, comprehensive network policies, effective service mesh integration, and proactive monitoring of DNS resolution performance. Organizations implementing these patterns can expect improved application performance, enhanced networking flexibility, and better support for complex distributed system requirements.

The combination of verified pod DNS resolution, advanced service discovery patterns, and comprehensive security controls provides a robust foundation for modern Kubernetes networking infrastructure capable of supporting enterprise-grade applications and evolving architectural requirements.