DNS in Kubernetes & Application Publication

Master Service Discovery and Exposure Methods

Lesson 1: DNS in Kubernetes - Service Discovery & Efficiency

DNS in Kubernetes is primarily a mechanism for service discovery, allowing applications (Pods) to find and communicate with each other using names instead of unstable IP addresses.

DNS Resolution Workflow

1. Client Pod Request
Pod makes a DNS query (e.g., for another Service)
2. NodeLocal DNSCache (Recommended)
Request hits caching agent on the node
Reduces latency and lowers load on central DNS
3. CoreDNS (if cache misses)
Query forwarded to CoreDNS cluster DNS server
Exposed via ClusterIP Service
4. TCP for Reliability
Connection upgraded to TCP on port 53
Ensures reliable communication through NAT
Why NodeLocal DNSCache?
The NodeLocal DNSCache serves cached responses directly from the node, significantly reducing latency and preventing unnecessary load on the central CoreDNS server.

The External Query Overhead Problem

Pods are automatically configured with DNS search domains (e.g., my-namespace.svc.cluster.local). This is beneficial for internal lookups, as a query for a short name like my-service is automatically appended with suffixes to resolve internally.

Problem: When a Pod queries an external domain (e.g., yandex.ru), the system first tries to resolve it with every internal search domain suffix (e.g., yandex.ru.default.svc.cluster.local) before finally trying the correct external name.

This results in multiple unnecessary DNS requests for a single external lookup, creating excessive network traffic and potential latency.
Solution: autopath Plugin
Configure the autopath plugin in the CoreDNS ConfigMap to handle external queries more efficiently without trying every search domain.
apiVersion: v1 kind: ConfigMap metadata: name: coredns namespace: kube-system data: Corefile: | .:53 { errors health kubernetes cluster.local in-addr.arpa ip6.arpa { pods insecure fallthrough in-addr.arpa ip6.arpa } autopath @kubernetes prometheus :9153 forward . /etc/resolv.conf cache 30 loop reload loadbalance }

Lesson 2: Application Publication - Services (Layer 4)

Kubernetes offers two primary categories for publishing applications: Layer 4 (Services) and Layer 7 (Ingress).

Service Types Overview

Services offer network-level exposure (TCP/UDP) but are generally less feature-rich for web traffic than Ingress:

Service Type Key Use Case External Access Details & Caveats
ClusterIP Default, Internal None (cluster-only) Ideal for inter-service communication and internal load balancing
NodePort Testing/Non-HTTP Apps Yes (NodeIP:NodePort) Exposes on static high port (e.g., 32000) on all cluster nodes
LoadBalancer Cloud Native Exposure Yes (External IP) Requires cloud provider (AWS, GCP, Azure). Creates external LB automatically
ExternalName External Redirection N/A Maps Service name to external DNS name (CNAME) instead of IP
Headless Direct Pod Addressing None (internal discovery) No ClusterIP. DNS returns individual Pod IPs. Critical for StatefulSets

ClusterIP - Internal Communication

apiVersion: v1 kind: Service metadata: name: backend-service spec: type: ClusterIP selector: app: backend ports: - protocol: TCP port: 80 targetPort: 8080
ClusterIP Use Case: Perfect for internal microservices that should only be accessible within the cluster. Other Pods can reach it using the Service name.

NodePort - Testing & Development

apiVersion: v1 kind: Service metadata: name: web-nodeport spec: type: NodePort selector: app: web ports: - protocol: TCP port: 80 targetPort: 8080 nodePort: 32000 # Static port on all nodes
NodePort Limitations: Requires knowing node IPs and opening firewall rules. Not recommended for production web traffic. Better for testing or non-HTTP protocols.

LoadBalancer - Cloud Production

apiVersion: v1 kind: Service metadata: name: web-loadbalancer spec: type: LoadBalancer selector: app: web ports: - protocol: TCP port: 80 targetPort: 8080
LoadBalancer Benefits: Cloud provider automatically provisions an external load balancer with a public IP. Traffic is automatically distributed to healthy nodes.

Headless Service - StatefulSets

apiVersion: v1 kind: Service metadata: name: database-headless spec: clusterIP: None # Makes it headless selector: app: database ports: - protocol: TCP port: 5432 targetPort: 5432
Headless Service Purpose: DNS returns the individual Pod IPs instead of a single ClusterIP. Essential for databases and StatefulSets where you need direct Pod-to-Pod communication.

Lesson 3: Ingress for Web Applications (Layer 7)

Ingress is the preferred method for publishing standard HTTP/HTTPS web services as it offers advanced routing capabilities and is easily managed via configuration.

Ingress Components

Ingress Controller: The actual application (e.g., Nginx, Envoy, Traefik) running inside a Pod. It watches the Kubernetes API for Ingress objects and dynamically configures itself to handle incoming traffic.
Ingress Object: A declarative configuration that defines the routing rules, such as mapping specific hostnames (foo.mydomain.com) and URL paths (/bar) to the appropriate backend Services.
Annotations: Used to pass controller-specific parameters that are not available in the standard Ingress spec. Examples include specifying HTTPS for the backend connection or passing raw Nginx configuration snippets.

Basic Ingress Example

apiVersion: networking.k8s.io/v1 kind: Ingress metadata: name: web-ingress annotations: nginx.ingress.kubernetes.io/rewrite-target: / spec: rules: - host: foo.mydomain.com http: paths: - path: /bar pathType: Prefix backend: service: name: backend-service port: number: 80

This configuration routes all traffic from foo.mydomain.com/bar to the backend-service on port 80.

Advanced Routing with Multiple Paths

apiVersion: networking.k8s.io/v1 kind: Ingress metadata: name: multi-path-ingress spec: rules: - host: api.mydomain.com http: paths: - path: /v1 pathType: Prefix backend: service: name: api-v1-service port: number: 8080 - path: /v2 pathType: Prefix backend: service: name: api-v2-service port: number: 8080
Path-Based Routing: Single hostname can route to different backend services based on URL paths. Perfect for API versioning or microservice architectures.

Host-Based Routing

apiVersion: networking.k8s.io/v1 kind: Ingress metadata: name: multi-host-ingress spec: rules: - host: app1.mydomain.com http: paths: - path: / pathType: Prefix backend: service: name: app1-service port: number: 80 - host: app2.mydomain.com http: paths: - path: / pathType: Prefix backend: service: name: app2-service port: number: 80
Host-Based Routing: Different hostnames route to different backend services. Enables hosting multiple applications on a single cluster with a single external IP.

Using Annotations for Advanced Features

apiVersion: networking.k8s.io/v1 kind: Ingress metadata: name: advanced-ingress annotations: nginx.ingress.kubernetes.io/backend-protocol: "HTTPS" nginx.ingress.kubernetes.io/ssl-redirect: "true" nginx.ingress.kubernetes.io/configuration-snippet: | more_set_headers "X-Custom-Header: CustomValue"; spec: rules: - host: secure.mydomain.com http: paths: - path: / pathType: Prefix backend: service: name: secure-backend port: number: 443
Controller-Specific Annotations: Annotations are specific to the Ingress Controller implementation (Nginx, Traefik, etc.). Always check your controller's documentation for supported annotations.

Lesson 4: Automated TLS with cert-manager

Securely exposing a website requires HTTPS/TLS. The best practice is to automate certificate management using cert-manager.

Manual TLS (Not Recommended)

Manual Process: Involves manually creating a Secret containing the key and certificate files and referencing it in the Ingress manifest's tls section. This is cumbersome and prone to error when certificates expire.
apiVersion: v1 kind: Secret metadata: name: tls-secret type: kubernetes.io/tls data: tls.crt: <base64-encoded-cert> tls.key: <base64-encoded-key> --- apiVersion: networking.k8s.io/v1 kind: Ingress metadata: name: tls-ingress spec: tls: - hosts: - secure.mydomain.com secretName: tls-secret rules: - host: secure.mydomain.com http: paths: - path: / pathType: Prefix backend: service: name: web-service port: number: 80

cert-manager Automation (Recommended)

cert-manager automates the entire certificate lifecycle: issuance, renewal, and storage.

cert-manager Benefits:
  • Automatic certificate issuance from Let's Encrypt or other CAs
  • Automatic renewal before expiration
  • Domain validation via HTTP-01 or DNS-01 challenges
  • Kubernetes-native integration

Step 1: Install cert-manager

kubectl apply -f https://github.com/cert-manager/cert-manager/releases/download/v1.13.0/cert-manager.yaml

Step 2: Create ClusterIssuer

apiVersion: cert-manager.io/v1 kind: ClusterIssuer metadata: name: letsencrypt-prod spec: acme: server: https://acme-v02.api.letsencrypt.org/directory email: admin@mydomain.com privateKeySecretRef: name: letsencrypt-prod-key solvers: - http01: ingress: class: nginx
ClusterIssuer vs Issuer: ClusterIssuer is cluster-wide and can be used by any namespace. Issuer is namespace-scoped. Use ClusterIssuer for shared certificate authorities.

Step 3: Annotate Your Ingress

apiVersion: networking.k8s.io/v1 kind: Ingress metadata: name: auto-tls-ingress annotations: cert-manager.io/cluster-issuer: "letsencrypt-prod" spec: tls: - hosts: - app.mydomain.com secretName: app-tls-cert # cert-manager will create this rules: - host: app.mydomain.com http: paths: - path: / pathType: Prefix backend: service: name: web-service port: number: 80
Automatic Process:
  1. cert-manager detects the Ingress with the annotation
  2. Creates a Certificate resource automatically
  3. Contacts Let's Encrypt to validate domain ownership
  4. Creates temporary resources for HTTP-01 challenge
  5. Obtains the certificate and stores it in the specified Secret
  6. Automatically renews the certificate before expiration

DNS-01 Challenge for Wildcard Certificates

apiVersion: cert-manager.io/v1 kind: ClusterIssuer metadata: name: letsencrypt-dns spec: acme: server: https://acme-v02.api.letsencrypt.org/directory email: admin@mydomain.com privateKeySecretRef: name: letsencrypt-dns-key solvers: - dns01: cloudflare: email: admin@mydomain.com apiKeySecretRef: name: cloudflare-api-key key: api-key
DNS-01 Challenge: Required for wildcard certificates (*.mydomain.com). Validates domain ownership by creating a DNS TXT record. Requires API access to your DNS provider.
Best Practice Summary:
  • Always use cert-manager for TLS automation
  • Use HTTP-01 for single domain certificates
  • Use DNS-01 for wildcard certificates
  • Monitor certificate expiration with cert-manager metrics
  • Use production Let's Encrypt only after testing with staging

Final Quiz

Test your knowledge of DNS in Kubernetes and Application Publication!

Question 1: What is the primary purpose of DNS in Kubernetes?

a) To provide external internet access
b) Service discovery and Pod-to-Pod communication using names
c) To encrypt network traffic
d) To manage storage volumes

Question 2: What is the benefit of NodeLocal DNSCache?

a) It encrypts DNS queries
b) It reduces latency and lowers load on central CoreDNS server
c) It provides external DNS resolution
d) It replaces CoreDNS entirely

Question 3: Which Service type requires a cloud provider to function?

a) ClusterIP
b) LoadBalancer
c) NodePort
d) Headless

Question 4: What makes a Service "headless"?

a) It has no selector
b) Setting clusterIP to None so DNS returns individual Pod IPs
c) It uses NodePort
d) It has no ports defined

Question 5: What layer does Ingress operate at?

a) Layer 4 (Transport)
b) Layer 7 (Application/HTTP)
c) Layer 2 (Data Link)
d) Layer 3 (Network)

Question 6: What is the purpose of Ingress annotations?

a) To define routing rules
b) To pass controller-specific parameters not in standard spec
c) To create TLS secrets
d) To specify the Service backend

Question 7: What does cert-manager automate?

a) DNS configuration
b) TLS certificate issuance, renewal, and storage
c) Pod deployment
d) Service creation

Question 8: Which challenge type is required for wildcard certificates?

a) HTTP-01
b) DNS-01
c) TLS-ALPN-01
d) EMAIL-01
Quiz Complete!
All correct answers are option 'b'. Review the lessons above to understand why these are the best answers.