TechLead
Lesson 7 of 25
5 min read
Cloud & Kubernetes

Services and Networking

Master Kubernetes Services (ClusterIP, NodePort, LoadBalancer), DNS, network policies, and inter-pod communication

Kubernetes Networking Model

Kubernetes implements a flat network model with several fundamental requirements: every Pod gets its own IP address, Pods on any node can communicate with all Pods on all nodes without NAT, and agents on a node can communicate with all Pods on that node. This model simplifies networking and makes it easier to port applications from VMs to containers.

Networking Fundamentals

  • Pod-to-Pod: All Pods can communicate with each other directly using their IP addresses
  • Pod-to-Service: Services provide stable endpoints for a set of Pods
  • External-to-Service: Services can be exposed externally via NodePort, LoadBalancer, or Ingress
  • DNS: CoreDNS provides cluster-internal DNS for service discovery

Service Types

ClusterIP (Default)

Exposes the Service on a cluster-internal IP. Only reachable from within the cluster. This is the default Service type and is used for internal communication between microservices.

# clusterip-service.yaml
apiVersion: v1
kind: Service
metadata:
  name: api-service
  labels:
    app: api
spec:
  type: ClusterIP
  selector:
    app: api-server
  ports:
  - name: http
    protocol: TCP
    port: 80          # Port the service listens on
    targetPort: 8080  # Port on the container
  - name: grpc
    protocol: TCP
    port: 9090
    targetPort: 9090

NodePort

Exposes the Service on each node's IP at a static port (30000-32767). A ClusterIP Service is automatically created. You can reach the service externally via <NodeIP>:<NodePort>.

# nodeport-service.yaml
apiVersion: v1
kind: Service
metadata:
  name: web-service-nodeport
spec:
  type: NodePort
  selector:
    app: web
  ports:
  - port: 80
    targetPort: 3000
    nodePort: 30080   # Optional: auto-assigned if omitted (30000-32767)

LoadBalancer

Exposes the Service externally using the cloud provider's load balancer. This creates a NodePort and ClusterIP Service automatically, and then configures a cloud load balancer to forward traffic to the NodePort.

# loadbalancer-service.yaml
apiVersion: v1
kind: Service
metadata:
  name: web-service-lb
  annotations:
    # AWS-specific annotations
    service.beta.kubernetes.io/aws-load-balancer-type: "nlb"
    service.beta.kubernetes.io/aws-load-balancer-scheme: "internet-facing"
spec:
  type: LoadBalancer
  selector:
    app: web
  ports:
  - name: http
    port: 80
    targetPort: 3000
  - name: https
    port: 443
    targetPort: 3000

Headless Service

A headless Service (ClusterIP: None) does not allocate a cluster IP. Instead, DNS returns the Pod IPs directly. This is useful for stateful applications where clients need to connect to specific Pods.

# headless-service.yaml
apiVersion: v1
kind: Service
metadata:
  name: postgres-headless
spec:
  clusterIP: None
  selector:
    app: postgres
  ports:
  - port: 5432
    targetPort: 5432

DNS in Kubernetes

CoreDNS provides DNS resolution inside the cluster. Every Service gets a DNS entry in the format: <service-name>.<namespace>.svc.cluster.local.

# Service DNS examples:
# Same namespace: api-service
# Cross-namespace: api-service.production.svc.cluster.local

# Test DNS resolution from inside a pod
kubectl run dns-test --image=busybox:1.36 --rm -it -- nslookup api-service

# Full DNS output:
# Server:    10.96.0.10
# Address:   10.96.0.10:53
# Name:      api-service.default.svc.cluster.local
# Address:   10.100.200.50

Network Policies

Network Policies are Kubernetes resources that control traffic flow between Pods. By default, all Pods can communicate with all other Pods. Network Policies let you restrict this communication for security.

# network-policy.yaml
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
  name: api-network-policy
  namespace: production
spec:
  podSelector:
    matchLabels:
      app: api-server
  policyTypes:
  - Ingress
  - Egress
  ingress:
  # Allow traffic from web frontend pods
  - from:
    - podSelector:
        matchLabels:
          app: web-frontend
    ports:
    - protocol: TCP
      port: 8080
  # Allow traffic from monitoring namespace
  - from:
    - namespaceSelector:
        matchLabels:
          name: monitoring
    ports:
    - protocol: TCP
      port: 9090
  egress:
  # Allow DNS
  - to: []
    ports:
    - protocol: UDP
      port: 53
    - protocol: TCP
      port: 53
  # Allow traffic to database
  - to:
    - podSelector:
        matchLabels:
          app: postgres
    ports:
    - protocol: TCP
      port: 5432

Key Takeaways

  • ClusterIP provides internal-only access, NodePort exposes on a static port, LoadBalancer integrates with cloud LBs
  • CoreDNS enables service discovery via DNS names like service.namespace.svc.cluster.local
  • Network Policies implement firewall rules between Pods for zero-trust networking
  • Headless Services return Pod IPs directly, useful for stateful workloads
  • Always define Network Policies in production to restrict unauthorized pod-to-pod traffic

Continue Learning