Înapoi la Blog
KubernetesNetworkingCNIDevOps

Kubernetes Networking Deep Dive: Services, Ingress and Network Policies

V
Vadym
10 iulie 20264 min citire
Kubernetes Networking Deep Dive: Services, Ingress and Network Policies

Kubernetes networking confuses many engineers because it abstracts several layers of complexity. Once you understand the mental model, it becomes straightforward. Let's break it down.

The Core Rule

Every pod gets its own IP address. Every pod can communicate with every other pod without NAT — regardless of which node they're on. This is the Kubernetes networking model.

The implementation of this model is handled by the CNI (Container Network Interface) plugin. Common choices: Cilium, Calico, Flannel, Weave. They each implement the same model differently.

Service Types

Services are stable network endpoints in front of pods. Pods are ephemeral — they come and go, their IPs change. Services give you a stable IP and DNS name.

ClusterIP (default)

Internal only. Gets a virtual IP reachable only within the cluster.

apiVersion: v1
kind: Service
metadata:
  name: backend
spec:
  selector:
    app: backend
  ports:
    - port: 80
      targetPort: 8080
  type: ClusterIP

DNS: backend.default.svc.cluster.local resolves to the ClusterIP. Traffic is load-balanced across matching pods by kube-proxy (iptables or IPVS rules).

NodePort

Exposes the service on a static port (30000–32767) on every node. Traffic to <NodeIP>:<NodePort> is forwarded to the service.

Useful for development and direct access without a cloud load balancer. Not recommended for production — it exposes ports on all nodes and bypasses cloud load balancer features.

LoadBalancer

Creates an external load balancer (AWS ALB/NLB, GCP LB, etc.) pointing to the service. The standard way to expose services externally in cloud environments.

spec:
  type: LoadBalancer
  # AWS-specific annotations
  annotations:
    service.beta.kubernetes.io/aws-load-balancer-type: "nlb"
    service.beta.kubernetes.io/aws-load-balancer-scheme: "internet-facing"

The downside: each LoadBalancer service creates a separate cloud load balancer, which gets expensive fast. Use Ingress for HTTP/HTTPS instead.

ExternalName

Maps a service to an external DNS name. Useful for referencing services outside the cluster.

Ingress

Ingress is an HTTP/HTTPS router sitting in front of multiple services. One load balancer, many services — routing by hostname or path.

apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: main-ingress
  annotations:
    nginx.ingress.kubernetes.io/rewrite-target: /
spec:
  ingressClassName: nginx
  tls:
    - hosts:
        - cloudopsmaster.win
      secretName: tls-secret
  rules:
    - host: cloudopsmaster.win
      http:
        paths:
          - path: /api
            pathType: Prefix
            backend:
              service:
                name: api-service
                port:
                  number: 80
          - path: /
            pathType: Prefix
            backend:
              service:
                name: frontend-service
                port:
                  number: 80

The Ingress controller (nginx, Traefik, Kong, AWS ALB controller) watches Ingress resources and configures the actual load balancer. The Ingress resource itself does nothing without a controller.

TLS with cert-manager

Install cert-manager and use Let's Encrypt for automatic certificate management:

apiVersion: cert-manager.io/v1
kind: ClusterIssuer
metadata:
  name: letsencrypt-prod
spec:
  acme:
    server: https://acme-v02.api.letsencrypt.org/directory
    email: [email protected]
    privateKeySecretRef:
      name: letsencrypt-prod
    solvers:
      - http01:
          ingress:
            class: nginx

Annotate your Ingress and cert-manager handles renewal automatically.

Network Policies

By default, all pods can talk to all other pods. This is a significant security risk. Network Policies let you define what traffic is allowed.

Default deny all ingress:

apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
  name: default-deny-ingress
  namespace: production
spec:
  podSelector: {}  # Applies to all pods in namespace
  policyTypes:
    - Ingress

Allow specific traffic only:

apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
  name: allow-frontend-to-api
  namespace: production
spec:
  podSelector:
    matchLabels:
      app: api
  policyTypes:
    - Ingress
  ingress:
    - from:
        - podSelector:
            matchLabels:
              app: frontend
      ports:
        - protocol: TCP
          port: 8080

Important: Network Policies require your CNI plugin to support them. Flannel does NOT. Cilium and Calico do.

DNS in Kubernetes

CoreDNS handles DNS resolution inside the cluster. Every service gets a DNS name:

<service>.<namespace>.svc.cluster.local

Pods can also be reached by:

<pod-ip-with-dashes>.<namespace>.pod.cluster.local

CoreDNS configuration is a ConfigMap — you can customize it to forward specific domains to external resolvers, which is useful when your cluster needs to resolve internal company domains.

Common Networking Problems

Pod can't reach external internet — check NAT gateway configuration, node security groups, and whether the subnet has a route to the internet.

Service discovery not working — verify CoreDNS pods are running and that the service namespace matches. Try kubectl exec -it <pod> -- nslookup <service>.

Intermittent connection drops — often caused by conntrack table overflow on nodes handling high traffic. Increase net.netfilter.nf_conntrack_max.

High latency between pods on different nodes — check CNI plugin health and MTU settings. Misconfigured MTU causes packet fragmentation.

Understanding the networking model makes troubleshooting much faster. When something doesn't work, you can reason through the path a packet takes and find where it breaks.

Ai nevoie de ajutor cu infrastructura?

Să lucrăm împreună

Disponibil pentru proiecte B2B remote la nivel global.

Ia Legătura