Chapter 5: Services & Networking
Authored by syscook.dev
What are Services and Networking in Kubernetes?
Services in Kubernetes provide stable network access to a set of pods, while networking enables communication between different components within the cluster and external systems. Services act as an abstraction layer that decouples the frontend from the backend, providing load balancing, service discovery, and network policies.
Key Concepts:
- Services: Stable network endpoints for pod groups
- Service Types: ClusterIP, NodePort, LoadBalancer, ExternalName
- Ingress: HTTP/HTTPS routing and load balancing
- Network Policies: Security rules for pod communication
- DNS: Service discovery through DNS names
- Load Balancing: Traffic distribution across multiple pods
Why Use Services and Networking?
1. Service Discovery and Load Balancing
Services provide stable network access and automatic load balancing across pod replicas.
# Example: ClusterIP service for internal communication
apiVersion: v1
kind: Service
metadata:
name: web-app-service
namespace: production
labels:
app: web-app
tier: frontend
spec:
type: ClusterIP
selector:
app: web-app
ports:
- name: http
protocol: TCP
port: 80
targetPort: 8080
- name: https
protocol: TCP
port: 443
targetPort: 8443
sessionAffinity: None
sessionAffinityConfig:
clientIP:
timeoutSeconds: 10800
Service Configuration Explanation:
type
: Service type (ClusterIP, NodePort, LoadBalancer, ExternalName)selector
: Label selector to identify target podsports
: Array of port configurationsname
: Port name for identificationprotocol
: Transport protocol (TCP, UDP)port
: Service porttargetPort
: Pod port to forward traffic to
sessionAffinity
: Session affinity type (None, ClientIP)sessionAffinityConfig
: Configuration for session affinity
2. External Access and Load Balancing
LoadBalancer services provide external access with cloud provider load balancing.
# Example: LoadBalancer service for external access
apiVersion: v1
kind: Service
metadata:
name: web-app-loadbalancer
namespace: production
labels:
app: web-app
tier: frontend
annotations:
service.beta.kubernetes.io/aws-load-balancer-type: "nlb"
service.beta.kubernetes.io/aws-load-balancer-cross-zone-load-balancing-enabled: "true"
service.beta.kubernetes.io/aws-load-balancer-ssl-cert: "arn:aws:acm:us-west-2:123456789012:certificate/12345678-1234-1234-1234-123456789012"
service.beta.kubernetes.io/aws-load-balancer-ssl-ports: "https"
service.beta.kubernetes.io/aws-load-balancer-backend-protocol: "http"
spec:
type: LoadBalancer
selector:
app: web-app
ports:
- name: http
protocol: TCP
port: 80
targetPort: 8080
- name: https
protocol: TCP
port: 443
targetPort: 8443
loadBalancerSourceRanges:
- 10.0.0.0/8
- 172.16.0.0/12
- 192.168.0.0/16
externalTrafficPolicy: Local
LoadBalancer Configuration Explanation:
annotations
: Cloud provider specific configurationsaws-load-balancer-type
: AWS load balancer type (nlb, alb)aws-load-balancer-cross-zone-load-balancing-enabled
: Enable cross-zone load balancingaws-load-balancer-ssl-cert
: SSL certificate ARNaws-load-balancer-ssl-ports
: Ports that use SSLaws-load-balancer-backend-protocol
: Backend protocol
loadBalancerSourceRanges
: Allowed source IP rangesexternalTrafficPolicy
: Traffic policy (Cluster, Local)
3. Ingress for HTTP/HTTPS Routing
Ingress provides HTTP and HTTPS routing with advanced features like SSL termination and path-based routing.
# Example: Ingress with SSL termination and path-based routing
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: web-app-ingress
namespace: production
labels:
app: web-app
annotations:
kubernetes.io/ingress.class: "nginx"
nginx.ingress.kubernetes.io/ssl-redirect: "true"
nginx.ingress.kubernetes.io/force-ssl-redirect: "true"
nginx.ingress.kubernetes.io/ssl-protocols: "TLSv1.2 TLSv1.3"
nginx.ingress.kubernetes.io/ssl-ciphers: "ECDHE-RSA-AES128-GCM-SHA256:ECDHE-RSA-AES256-GCM-SHA384"
nginx.ingress.kubernetes.io/proxy-body-size: "50m"
nginx.ingress.kubernetes.io/proxy-connect-timeout: "60"
nginx.ingress.kubernetes.io/proxy-send-timeout: "60"
nginx.ingress.kubernetes.io/proxy-read-timeout: "60"
nginx.ingress.kubernetes.io/rate-limit: "100"
nginx.ingress.kubernetes.io/rate-limit-window: "1m"
spec:
tls:
- hosts:
- webapp.example.com
- api.example.com
secretName: webapp-tls-secret
rules:
- host: webapp.example.com
http:
paths:
- path: /
pathType: Prefix
backend:
service:
name: web-app-service
port:
number: 80
- path: /api
pathType: Prefix
backend:
service:
name: api-service
port:
number: 8080
- host: api.example.com
http:
paths:
- path: /
pathType: Prefix
backend:
service:
name: api-service
port:
number: 8080
Ingress Configuration Explanation:
tls
: SSL/TLS configurationhosts
: Hostnames for SSL certificatessecretName
: Secret containing SSL certificates
rules
: Routing ruleshost
: Hostname to matchhttp.paths
: Path-based routing rulespath
: URL path patternpathType
: Path matching type (Exact, Prefix, ImplementationSpecific)backend
: Target service and port
annotations
: Ingress controller specific configurations
How to Use Services and Networking?
1. Service Types and Configuration
ClusterIP Service (Internal)
# Example: ClusterIP service for internal communication
apiVersion: v1
kind: Service
metadata:
name: database-service
namespace: production
labels:
app: database
tier: backend
spec:
type: ClusterIP
clusterIP: None # Headless service
selector:
app: postgres
ports:
- name: postgres
protocol: TCP
port: 5432
targetPort: 5432
- name: metrics
protocol: TCP
port: 9187
targetPort: 9187
NodePort Service (External Access)
# Example: NodePort service for external access
apiVersion: v1
kind: Service
metadata:
name: web-app-nodeport
namespace: production
labels:
app: web-app
tier: frontend
spec:
type: NodePort
selector:
app: web-app
ports:
- name: http
protocol: TCP
port: 80
targetPort: 8080
nodePort: 30080
- name: https
protocol: TCP
port: 443
targetPort: 8443
nodePort: 30443
ExternalName Service (External Service)
# Example: ExternalName service for external services
apiVersion: v1
kind: Service
metadata:
name: external-api-service
namespace: production
labels:
app: external-api
spec:
type: ExternalName
externalName: api.external-provider.com
ports:
- name: https
protocol: TCP
port: 443
targetPort: 443
2. Advanced Service Configuration
Service with Multiple Ports
# Example: Service with multiple ports and protocols
apiVersion: v1
kind: Service
metadata:
name: multi-port-service
namespace: production
labels:
app: multi-port-app
spec:
type: ClusterIP
selector:
app: multi-port-app
ports:
- name: http
protocol: TCP
port: 80
targetPort: 8080
- name: https
protocol: TCP
port: 443
targetPort: 8443
- name: grpc
protocol: TCP
port: 9090
targetPort: 9090
- name: metrics
protocol: TCP
port: 9091
targetPort: 9091
- name: udp-logging
protocol: UDP
port: 514
targetPort: 514
sessionAffinity: ClientIP
sessionAffinityConfig:
clientIP:
timeoutSeconds: 3600
Headless Service for StatefulSets
# Example: Headless service for StatefulSet
apiVersion: v1
kind: Service
metadata:
name: postgres-headless
namespace: production
labels:
app: postgres
tier: database
spec:
type: ClusterIP
clusterIP: None
selector:
app: postgres
ports:
- name: postgres
protocol: TCP
port: 5432
targetPort: 5432
- name: replication
protocol: TCP
port: 5433
targetPort: 5433
- name: metrics
protocol: TCP
port: 9187
targetPort: 9187
3. Ingress Configuration
Basic Ingress
# Example: Basic Ingress configuration
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: basic-ingress
namespace: production
labels:
app: web-app
spec:
rules:
- host: webapp.example.com
http:
paths:
- path: /
pathType: Prefix
backend:
service:
name: web-app-service
port:
number: 80
- host: api.example.com
http:
paths:
- path: /
pathType: Prefix
backend:
service:
name: api-service
port:
number: 8080
Ingress with SSL Termination
# Example: Ingress with SSL termination
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: ssl-ingress
namespace: production
labels:
app: web-app
annotations:
kubernetes.io/ingress.class: "nginx"
nginx.ingress.kubernetes.io/ssl-redirect: "true"
nginx.ingress.kubernetes.io/force-ssl-redirect: "true"
cert-manager.io/cluster-issuer: "letsencrypt-prod"
spec:
tls:
- hosts:
- webapp.example.com
- api.example.com
secretName: webapp-tls-secret
rules:
- host: webapp.example.com
http:
paths:
- path: /
pathType: Prefix
backend:
service:
name: web-app-service
port:
number: 80
- host: api.example.com
http:
paths:
- path: /
pathType: Prefix
backend:
service:
name: api-service
port:
number: 8080
Ingress with Advanced Routing
# Example: Ingress with advanced routing and rate limiting
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: advanced-ingress
namespace: production
labels:
app: web-app
annotations:
kubernetes.io/ingress.class: "nginx"
nginx.ingress.kubernetes.io/ssl-redirect: "true"
nginx.ingress.kubernetes.io/force-ssl-redirect: "true"
nginx.ingress.kubernetes.io/rate-limit: "100"
nginx.ingress.kubernetes.io/rate-limit-window: "1m"
nginx.ingress.kubernetes.io/rate-limit-connections: "10"
nginx.ingress.kubernetes.io/rate-limit-requests: "100"
nginx.ingress.kubernetes.io/proxy-body-size: "50m"
nginx.ingress.kubernetes.io/proxy-connect-timeout: "60"
nginx.ingress.kubernetes.io/proxy-send-timeout: "60"
nginx.ingress.kubernetes.io/proxy-read-timeout: "60"
nginx.ingress.kubernetes.io/configuration-snippet: |
more_set_headers "X-Frame-Options: DENY";
more_set_headers "X-Content-Type-Options: nosniff";
more_set_headers "X-XSS-Protection: 1; mode=block";
more_set_headers "Strict-Transport-Security: max-age=31536000; includeSubDomains";
spec:
tls:
- hosts:
- webapp.example.com
- api.example.com
- admin.example.com
secretName: webapp-tls-secret
rules:
- host: webapp.example.com
http:
paths:
- path: /
pathType: Prefix
backend:
service:
name: web-app-service
port:
number: 80
- path: /static
pathType: Prefix
backend:
service:
name: static-service
port:
number: 80
- host: api.example.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
- host: admin.example.com
http:
paths:
- path: /
pathType: Prefix
backend:
service:
name: admin-service
port:
number: 8080
4. Network Policies
Basic Network Policy
# Example: Basic network policy
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: basic-network-policy
namespace: production
labels:
app: web-app
spec:
podSelector:
matchLabels:
app: web-app
policyTypes:
- Ingress
- Egress
ingress:
- from:
- namespaceSelector:
matchLabels:
name: ingress-nginx
- podSelector:
matchLabels:
app: load-balancer
ports:
- protocol: TCP
port: 8080
egress:
- to:
- podSelector:
matchLabels:
app: database
ports:
- protocol: TCP
port: 5432
- to: []
ports:
- protocol: UDP
port: 53
- protocol: TCP
port: 53
Advanced Network Policy
# Example: Advanced network policy with multiple rules
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: advanced-network-policy
namespace: production
labels:
app: web-app
spec:
podSelector:
matchLabels:
app: web-app
policyTypes:
- Ingress
- Egress
ingress:
- from:
- namespaceSelector:
matchLabels:
name: ingress-nginx
- podSelector:
matchLabels:
app: load-balancer
ports:
- protocol: TCP
port: 8080
- from:
- podSelector:
matchLabels:
app: monitoring
ports:
- protocol: TCP
port: 9090
- from:
- ipBlock:
cidr: 10.0.0.0/8
except:
- 10.0.1.0/24
ports:
- protocol: TCP
port: 8080
egress:
- to:
- podSelector:
matchLabels:
app: database
ports:
- protocol: TCP
port: 5432
- to:
- podSelector:
matchLabels:
app: redis
ports:
- protocol: TCP
port: 6379
- to:
- podSelector:
matchLabels:
app: api
ports:
- protocol: TCP
port: 8080
- to: []
ports:
- protocol: UDP
port: 53
- protocol: TCP
port: 53
- to:
- ipBlock:
cidr: 0.0.0.0/0
ports:
- protocol: TCP
port: 443
- protocol: TCP
port: 80
5. DNS and Service Discovery
Service DNS Resolution
# Service DNS resolution examples
# Internal service: <service-name>.<namespace>.svc.cluster.local
# External service: <service-name>.<namespace>.svc.cluster.local
# Examples:
# web-app-service.production.svc.cluster.local
# database-service.production.svc.cluster.local
# api-service.production.svc.cluster.local
# Short names (within same namespace):
# web-app-service
# database-service
# api-service
Headless Service DNS
# Example: Headless service for DNS-based service discovery
apiVersion: v1
kind: Service
metadata:
name: postgres-headless
namespace: production
labels:
app: postgres
spec:
type: ClusterIP
clusterIP: None
selector:
app: postgres
ports:
- name: postgres
protocol: TCP
port: 5432
targetPort: 5432
# DNS resolution for headless service
# Returns A records for all pod IPs
# postgres-headless.production.svc.cluster.local
# postgres-0.postgres-headless.production.svc.cluster.local
# postgres-1.postgres-headless.production.svc.cluster.local
# postgres-2.postgres-headless.production.svc.cluster.local
Practical Examples
1. Complete Web Application Networking
Step 1: Create Services
#!/bin/bash
# create-services.sh
# Create web app service
kubectl apply -f - <<EOF
apiVersion: v1
kind: Service
metadata:
name: web-app-service
namespace: production
labels:
app: web-app
tier: frontend
spec:
type: ClusterIP
selector:
app: web-app
ports:
- name: http
protocol: TCP
port: 80
targetPort: 8080
EOF
# Create API service
kubectl apply -f - <<EOF
apiVersion: v1
kind: Service
metadata:
name: api-service
namespace: production
labels:
app: api
tier: backend
spec:
type: ClusterIP
selector:
app: api
ports:
- name: http
protocol: TCP
port: 8080
targetPort: 8080
EOF
# Create database service
kubectl apply -f - <<EOF
apiVersion: v1
kind: Service
metadata:
name: database-service
namespace: production
labels:
app: postgres
tier: database
spec:
type: ClusterIP
selector:
app: postgres
ports:
- name: postgres
protocol: TCP
port: 5432
targetPort: 5432
EOF
echo "Services created successfully!"
Step 2: Create Ingress
#!/bin/bash
# create-ingress.sh
kubectl apply -f - <<EOF
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: web-app-ingress
namespace: production
labels:
app: web-app
annotations:
kubernetes.io/ingress.class: "nginx"
nginx.ingress.kubernetes.io/ssl-redirect: "true"
nginx.ingress.kubernetes.io/force-ssl-redirect: "true"
nginx.ingress.kubernetes.io/rate-limit: "100"
nginx.ingress.kubernetes.io/rate-limit-window: "1m"
spec:
tls:
- hosts:
- webapp.example.com
- api.example.com
secretName: webapp-tls-secret
rules:
- host: webapp.example.com
http:
paths:
- path: /
pathType: Prefix
backend:
service:
name: web-app-service
port:
number: 80
- host: api.example.com
http:
paths:
- path: /
pathType: Prefix
backend:
service:
name: api-service
port:
number: 8080
EOF
echo "Ingress created successfully!"
Step 3: Create Network Policies
#!/bin/bash
# create-network-policies.sh
kubectl apply -f - <<EOF
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: web-app-network-policy
namespace: production
labels:
app: web-app
spec:
podSelector:
matchLabels:
app: web-app
policyTypes:
- Ingress
- Egress
ingress:
- from:
- namespaceSelector:
matchLabels:
name: ingress-nginx
- podSelector:
matchLabels:
app: load-balancer
ports:
- protocol: TCP
port: 8080
egress:
- to:
- podSelector:
matchLabels:
app: api
ports:
- protocol: TCP
port: 8080
- to: []
ports:
- protocol: UDP
port: 53
- protocol: TCP
port: 53
---
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: api-network-policy
namespace: production
labels:
app: api
spec:
podSelector:
matchLabels:
app: api
policyTypes:
- Ingress
- Egress
ingress:
- from:
- podSelector:
matchLabels:
app: web-app
ports:
- protocol: TCP
port: 8080
egress:
- to:
- podSelector:
matchLabels:
app: postgres
ports:
- protocol: TCP
port: 5432
- to:
- podSelector:
matchLabels:
app: redis
ports:
- protocol: TCP
port: 6379
- to: []
ports:
- protocol: UDP
port: 53
- protocol: TCP
port: 53
---
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: database-network-policy
namespace: production
labels:
app: postgres
spec:
podSelector:
matchLabels:
app: postgres
policyTypes:
- Ingress
- Egress
ingress:
- from:
- podSelector:
matchLabels:
app: api
ports:
- protocol: TCP
port: 5432
egress:
- to: []
ports:
- protocol: UDP
port: 53
- protocol: TCP
port: 53
EOF
echo "Network policies created successfully!"
2. LoadBalancer Service with Cloud Provider
Step 1: Create LoadBalancer Service
#!/bin/bash
# create-loadbalancer.sh
kubectl apply -f - <<EOF
apiVersion: v1
kind: Service
metadata:
name: web-app-loadbalancer
namespace: production
labels:
app: web-app
tier: frontend
annotations:
service.beta.kubernetes.io/aws-load-balancer-type: "nlb"
service.beta.kubernetes.io/aws-load-balancer-cross-zone-load-balancing-enabled: "true"
service.beta.kubernetes.io/aws-load-balancer-ssl-cert: "arn:aws:acm:us-west-2:123456789012:certificate/12345678-1234-1234-1234-123456789012"
service.beta.kubernetes.io/aws-load-balancer-ssl-ports: "https"
service.beta.kubernetes.io/aws-load-balancer-backend-protocol: "http"
spec:
type: LoadBalancer
selector:
app: web-app
ports:
- name: http
protocol: TCP
port: 80
targetPort: 8080
- name: https
protocol: TCP
port: 443
targetPort: 8443
loadBalancerSourceRanges:
- 10.0.0.0/8
- 172.16.0.0/12
- 192.168.0.0/16
externalTrafficPolicy: Local
EOF
echo "LoadBalancer service created successfully!"
Step 2: Monitor LoadBalancer
#!/bin/bash
# monitor-loadbalancer.sh
# Check service status
kubectl get service web-app-loadbalancer -n production
# Check external IP
kubectl get service web-app-loadbalancer -n production -o jsonpath='{.status.loadBalancer.ingress[0].hostname}'
# Check endpoints
kubectl get endpoints web-app-loadbalancer -n production
echo "LoadBalancer monitoring completed!"
3. Service Mesh Integration
Step 1: Install Istio
#!/bin/bash
# install-istio.sh
# Download Istio
curl -L https://istio.io/downloadIstio | sh -
cd istio-*
export PATH=$PWD/bin:$PATH
# Install Istio
istioctl install --set values.defaultRevision=default
# Enable sidecar injection for namespace
kubectl label namespace production istio-injection=enabled
echo "Istio installed successfully!"
Step 2: Configure Istio Gateway
#!/bin/bash
# configure-istio-gateway.sh
kubectl apply -f - <<EOF
apiVersion: networking.istio.io/v1alpha3
kind: Gateway
metadata:
name: web-app-gateway
namespace: production
spec:
selector:
istio: ingressgateway
servers:
- port:
number: 80
name: http
protocol: HTTP
hosts:
- webapp.example.com
- api.example.com
tls:
httpsRedirect: true
- port:
number: 443
name: https
protocol: HTTPS
hosts:
- webapp.example.com
- api.example.com
tls:
mode: SIMPLE
credentialName: webapp-tls-secret
---
apiVersion: networking.istio.io/v1alpha3
kind: VirtualService
metadata:
name: web-app-virtual-service
namespace: production
spec:
hosts:
- webapp.example.com
- api.example.com
gateways:
- web-app-gateway
http:
- match:
- uri:
prefix: /api
route:
- destination:
host: api-service
port:
number: 8080
- match:
- uri:
prefix: /
route:
- destination:
host: web-app-service
port:
number: 80
EOF
echo "Istio Gateway configured successfully!"
Best Practices
1. Service Naming and Organization
# Good: Consistent naming convention
apiVersion: v1
kind: Service
metadata:
name: web-app-service
namespace: production
labels:
app: web-app
tier: frontend
version: v1.0
2. Security Configuration
# Good: Network policies for security
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: secure-network-policy
namespace: production
spec:
podSelector:
matchLabels:
app: web-app
policyTypes:
- Ingress
- Egress
ingress:
- from:
- namespaceSelector:
matchLabels:
name: ingress-nginx
ports:
- protocol: TCP
port: 8080
egress:
- to:
- podSelector:
matchLabels:
app: api
ports:
- protocol: TCP
port: 8080
3. Load Balancing Configuration
# Good: Proper load balancing configuration
apiVersion: v1
kind: Service
metadata:
name: web-app-service
namespace: production
spec:
type: ClusterIP
selector:
app: web-app
ports:
- name: http
protocol: TCP
port: 80
targetPort: 8080
sessionAffinity: None
sessionAffinityConfig:
clientIP:
timeoutSeconds: 10800
Common Pitfalls and Solutions
1. Service Discovery Issues
# ❌ Problem: Service not accessible
# Error: connection refused
# ✅ Solution: Check service selector and pod labels
kubectl get service web-app-service -n production
kubectl get pods -n production -l app=web-app
kubectl describe service web-app-service -n production
2. Ingress Configuration Issues
# ❌ Problem: Ingress not routing traffic
# Error: 404 Not Found
# ✅ Solution: Check ingress configuration and backend services
kubectl get ingress web-app-ingress -n production
kubectl describe ingress web-app-ingress -n production
kubectl get service web-app-service -n production
3. Network Policy Issues
# ❌ Problem: Pods cannot communicate
# Error: network is unreachable
# ✅ Solution: Check network policies and allow necessary traffic
kubectl get networkpolicy -n production
kubectl describe networkpolicy web-app-network-policy -n production
Conclusion
Services and networking are essential for enabling communication between different components in Kubernetes. By understanding:
- What services and networking are and their purposes
- Why they're crucial for application communication and load balancing
- How to configure services, ingress, and network policies properly
You can create a robust networking infrastructure that enables secure, scalable, and maintainable applications. Proper configuration ensures that your applications can communicate effectively while maintaining security and performance.
Next Steps
- Practice with different service types and configurations
- Learn about ConfigMaps and Secrets
- Move on to Chapter 6: ConfigMaps & Secrets
This tutorial is part of the Kubernetes Mastery series by syscook.dev