Kubernetes Networking
Service Types
ClusterIP (Default)
apiVersion: v1
kind: Service
metadata:
name: web-app-service
namespace: production
labels:
app: web-app
spec:
type: ClusterIP
selector:
app: web-app
tier: frontend
ports:
- name: http
port: 80
targetPort: 8080
protocol: TCP
- name: metrics
port: 9090
targetPort: metrics
protocol: TCP
sessionAffinity: ClientIP
sessionAffinityConfig:
clientIP:
timeoutSeconds: 3600
Headless Service (StatefulSet)
apiVersion: v1
kind: Service
metadata:
name: postgres-headless
namespace: database
spec:
clusterIP: None # Headless
selector:
app: postgres
ports:
- name: postgres
port: 5432
targetPort: 5432
NodePort
apiVersion: v1
kind: Service
metadata:
name: external-app
namespace: production
spec:
type: NodePort
selector:
app: external-app
ports:
- name: http
port: 80
targetPort: 8080
nodePort: 30080 # Range: 30000-32767
protocol: TCP
LoadBalancer
apiVersion: v1
kind: Service
metadata:
name: public-web
namespace: production
annotations:
service.beta.kubernetes.io/aws-load-balancer-type: "nlb"
service.beta.kubernetes.io/aws-load-balancer-internal: "false"
spec:
type: LoadBalancer
selector:
app: web-app
ports:
- name: http
port: 80
targetPort: 8080
- name: https
port: 443
targetPort: 8443
loadBalancerSourceRanges:
- 203.0.113.0/24 # Restrict source IPs
Ingress Resources
NGINX Ingress
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: web-ingress
namespace: production
annotations:
nginx.ingress.kubernetes.io/rewrite-target: /
nginx.ingress.kubernetes.io/ssl-redirect: "true"
nginx.ingress.kubernetes.io/force-ssl-redirect: "true"
nginx.ingress.kubernetes.io/proxy-body-size: "10m"
nginx.ingress.kubernetes.io/rate-limit: "100"
cert-manager.io/cluster-issuer: "letsencrypt-prod"
spec:
ingressClassName: nginx
tls:
- hosts:
- www.example.com
- api.example.com
secretName: example-tls
rules:
- host: www.example.com
http:
paths:
- path: /
pathType: Prefix
backend:
service:
name: frontend-service
port:
number: 80
- host: api.example.com
http:
paths:
- path: /v1
pathType: Prefix
backend:
service:
name: api-service
port:
number: 8080
- path: /v2
pathType: Prefix
backend:
service:
name: api-v2-service
port:
number: 8080
Path-Based Routing
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: app-ingress
namespace: production
spec:
ingressClassName: nginx
rules:
- host: app.example.com
http:
paths:
- path: /api
pathType: Prefix
backend:
service:
name: backend-api
port:
number: 8080
- path: /
pathType: Prefix
backend:
service:
name: frontend
port:
number: 80
NetworkPolicy (Zero Trust)
Default Deny All
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: default-deny-all
namespace: production
spec:
podSelector: {}
policyTypes:
- Ingress
- Egress
Allow Frontend to Backend
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: frontend-to-backend
namespace: production
spec:
podSelector:
matchLabels:
tier: backend
policyTypes:
- Ingress
ingress:
- from:
- podSelector:
matchLabels:
tier: frontend
ports:
- protocol: TCP
port: 8080
Backend to Database
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: backend-to-database
namespace: production
spec:
podSelector:
matchLabels:
app: postgres
policyTypes:
- Ingress
ingress:
- from:
- podSelector:
matchLabels:
tier: backend
- namespaceSelector:
matchLabels:
name: production
ports:
- protocol: TCP
port: 5432
Allow DNS and External HTTPS
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: allow-dns-and-https
namespace: production
spec:
podSelector:
matchLabels:
tier: backend
policyTypes:
- Egress
egress:
- to:
- namespaceSelector:
matchLabels:
name: kube-system
ports:
- protocol: UDP
port: 53
- to:
- namespaceSelector: {}
ports:
- protocol: TCP
port: 443
Cross-Namespace Communication
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: allow-monitoring
namespace: production
spec:
podSelector:
matchLabels:
app: web-app
policyTypes:
- Ingress
ingress:
- from:
- namespaceSelector:
matchLabels:
name: monitoring
podSelector:
matchLabels:
app: prometheus
ports:
- protocol: TCP
port: 8080
DNS Configuration
Service DNS Names
# Within same namespace
http://web-app-service
# Cross-namespace
http://web-app-service.production.svc.cluster.local
# Headless service (StatefulSet)
postgres-0.postgres-headless.database.svc.cluster.local
postgres-1.postgres-headless.database.svc.cluster.local
postgres-2.postgres-headless.database.svc.cluster.local
Custom DNS Policy
apiVersion: v1
kind: Pod
metadata:
name: custom-dns
spec:
dnsPolicy: None
dnsConfig:
nameservers:
- 8.8.8.8
- 8.8.4.4
searches:
- production.svc.cluster.local
- svc.cluster.local
- cluster.local
options:
- name: ndots
value: "2"
containers:
- name: app
image: myapp:latest
Service Mesh (Istio Example)
VirtualService
apiVersion: networking.istio.io/v1beta1
kind: VirtualService
metadata:
name: web-app-routes
namespace: production
spec:
hosts:
- web-app-service
http:
- match:
- headers:
canary:
exact: "true"
route:
- destination:
host: web-app-service
subset: v2
- route:
- destination:
host: web-app-service
subset: v1
weight: 90
- destination:
host: web-app-service
subset: v2
weight: 10
DestinationRule
apiVersion: networking.istio.io/v1beta1
kind: DestinationRule
metadata:
name: web-app-destination
namespace: production
spec:
host: web-app-service
trafficPolicy:
connectionPool:
tcp:
maxConnections: 100
http:
http1MaxPendingRequests: 50
http2MaxRequests: 100
loadBalancer:
simple: LEAST_REQUEST
subsets:
- name: v1
labels:
version: v1.0.0
- name: v2
labels:
version: v2.0.0
EndpointSlice (Modern Alternative to Endpoints)
apiVersion: discovery.k8s.io/v1
kind: EndpointSlice
metadata:
name: web-app-abc123
namespace: production
labels:
kubernetes.io/service-name: web-app-service
addressType: IPv4
ports:
- name: http
protocol: TCP
port: 8080
endpoints:
- addresses:
- "10.244.1.5"
conditions:
ready: true
nodeName: node-1
- addresses:
- "10.244.2.7"
conditions:
ready: true
nodeName: node-2
Best Practices
- Default Deny: Start with deny-all NetworkPolicy, then allow specific traffic
- Least Privilege: Only open required ports and protocols
- Service Selection: Use ClusterIP by default, LoadBalancer sparingly
- DNS Names: Use service DNS names, avoid hardcoded IPs
- TLS Termination: Terminate TLS at Ingress when possible
- Health Checks: Configure proper health check paths
- Rate Limiting: Apply rate limits at Ingress level
- Monitoring: Expose metrics endpoints for Prometheus