Target Audience: Backend developers who want to understand Kubernetes network structure Prerequisites: Service concepts, basic networking knowledge (IP, ports, DNS) After reading this: You will understand Kubernetes network model and Ingress

TL;DR
  • All Pods have unique IPs and can communicate directly with other Pods
  • Service provides stable access point for a set of Pods
  • Ingress routes HTTP/HTTPS traffic from outside the cluster

Kubernetes Network Model#

Kubernetes networking follows three basic principles.

PrincipleDescription
Pod-to-PodAll Pods can communicate with other Pods without NAT
Node-to-PodAll nodes can communicate with all Pods without NAT
Pod IPPod’s own IP and the IP other Pods see are identical
flowchart TB
    subgraph Node1[Node 1]
        P1[Pod A<br>10.244.1.5]
        P2[Pod B<br>10.244.1.6]
    end
    subgraph Node2[Node 2]
        P3[Pod C<br>10.244.2.3]
    end
    P1 <-->|direct communication| P2
    P1 <-->|cross-node communication| P3

Cluster Internal Communication#

Pod-to-Pod Communication#

Pods within the same cluster can communicate directly via IP.

# Direct communication from Pod A to Pod C
kubectl exec pod-a -- curl http://10.244.2.3:8080

However, since Pod IPs can change, we actually use Services.

Communication Through Service#

flowchart LR
    Client[Client Pod] -->|my-service:80| SVC[Service]
    SVC --> P1[Pod 1]
    SVC --> P2[Pod 2]
    SVC --> P3[Pod 3]

Using Service DNS prevents impact from Pod IP changes.

# Use Service name in application
spring:
  datasource:
    url: jdbc:postgresql://postgres-service:5432/mydb

External Exposure Methods Comparison#

Comparing methods to access applications from outside the cluster.

MethodUse CaseCharacteristics
NodePortDev/testSimple but port limited (30000-32767)
LoadBalancerSingle service external exposureUses cloud LB, incurs cost
IngressHTTP routing to multiple servicesDomain/path-based routing

Ingress#

Ingress manages HTTP/HTTPS traffic from outside the cluster to internal Services.

External Request Processing Flow#

Let’s examine step by step how HTTP requests from outside reach Pods.

flowchart TB
    subgraph External[External]
        User[User<br>api.example.com/users]
    end

    subgraph Cluster[Kubernetes Cluster]
        subgraph Ingress[Ingress Layer]
            LB[LoadBalancer<br>External IP]
            IC[Ingress Controller<br>NGINX]
            ING[Ingress Rules]
        end

        subgraph Services[Service Layer]
            SVC[user-service<br>ClusterIP]
        end

        subgraph Pods[Pod Layer]
            P1[Pod 1]
            P2[Pod 2]
        end
    end

    User -->|1. DNS lookup| LB
    LB -->|2. Forward traffic| IC
    IC -->|3. Match rules| ING
    ING -->|4. Route| SVC
    SVC -->|5. Load balance| P1
    SVC -->|5. Load balance| P2
StepComponentAction
1DNS/LBResolve domain to LoadBalancer IP
2LoadBalancerForward traffic to Ingress Controller
3Ingress ControllerMatch host/path in Ingress rules
4Ingress → ServiceRoute to matched Service
5Service → PodDistribute traffic to multiple Pods

Ingress vs LoadBalancer#

ItemLoadBalancerIngress
TargetSingle ServiceMultiple Services
ProtocolTCP/UDPHTTP/HTTPS
RoutingNoneHost/path based
TLSPer-Service configurationCentralized management
CostLB cost per ServiceOne LB for multiple services
flowchart LR
    Client[External client]
    subgraph Cluster
        ING[Ingress Controller]
        S1[Service A]
        S2[Service B]
        S3[Service C]
    end
    Client -->|api.example.com| ING
    Client -->|web.example.com| ING
    ING -->|/api/*| S1
    ING -->|/web/*| S2
    ING -->|/| S3

Ingress Controller#

Ingress resource alone doesn’t work. An Ingress Controller is needed.

ControllerCharacteristics
NGINX IngressMost widely used, community support
TraefikAuto-configuration, Let’s Encrypt integration
AWS ALB IngressIntegrates with AWS ALB
GKE IngressIntegrates with GCP HTTP(S) LB

Ingress Resource Definition#

apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: my-ingress
  annotations:
    nginx.ingress.kubernetes.io/rewrite-target: /
spec:
  ingressClassName: nginx
  rules:
  - host: api.example.com
    http:
      paths:
      - path: /users
        pathType: Prefix
        backend:
          service:
            name: user-service
            port:
              number: 80
      - path: /orders
        pathType: Prefix
        backend:
          service:
            name: order-service
            port:
              number: 80
  - host: web.example.com
    http:
      paths:
      - path: /
        pathType: Prefix
        backend:
          service:
            name: web-service
            port:
              number: 80

Key fields explained:

FieldDescription
ingressClassNameIngress Controller to use
rules[].hostDomain to route
rules[].http.paths[]Path-based routing rules
pathTypeExact (exact match) or Prefix
backend.serviceService to forward traffic to

TLS Configuration#

TLS configuration for HTTPS.

apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: tls-ingress
spec:
  ingressClassName: nginx
  tls:
  - hosts:
    - api.example.com
    secretName: api-tls-secret
  rules:
  - host: api.example.com
    http:
      paths:
      - path: /
        pathType: Prefix
        backend:
          service:
            name: api-service
            port:
              number: 80

Create TLS Secret as follows:

kubectl create secret tls api-tls-secret \
  --cert=path/to/cert.crt \
  --key=path/to/cert.key

NetworkPolicy#

NetworkPolicy controls traffic between Pods. By default, all Pods can communicate with each other, but NetworkPolicy can restrict this.

Default Isolation#

apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
  name: deny-all
spec:
  podSelector: {}  # Apply to all Pods
  policyTypes:
  - Ingress
  - Egress

When this policy is applied, all Pods in that namespace have their traffic blocked.

Allow Specific Traffic#

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

This policy only allows access from Pods with app: frontend label to port 8080 of app: backend Pods.

flowchart LR
    F[Frontend Pod] -->|allowed| B[Backend Pod:8080]
    O[Other Pod] -.-x|blocked| B

Practice: Ingress Configuration#

Enable Ingress in Minikube#

# Enable NGINX Ingress Controller
minikube addons enable ingress

# Check status
kubectl get pods -n ingress-nginx

Deploy Test Applications#

# Create two Deployments
kubectl create deployment web --image=nginx
kubectl create deployment api --image=httpd

# Create Services
kubectl expose deployment web --port=80
kubectl expose deployment api --port=80

Create Ingress Resource#

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

Test#

# Check Minikube IP
minikube ip

# Add to /etc/hosts (Linux/macOS)
echo "$(minikube ip) test.local" | sudo tee -a /etc/hosts

# Test
curl http://test.local/web
curl http://test.local/api

Next Steps#

Once you understand networking, proceed to the next steps:

GoalRecommended Doc
Resource configurationResource Management
Auto-scalingScaling
Actual deployment practiceSpring Boot Deployment