CKA Prep: Part 4 – Services & Networking
On this page
Kubernetes Networking Fundamentals
Kubernetes networking can be complex, but understanding it is crucial for the CKA exam. This section covers essential Kubernetes networking concepts.
Kubernetes Network Model
The Kubernetes network model imposes the following requirements:
- Pod-to-Pod Communication: All pods can communicate with all other pods without NAT
- Node-to-Pod Communication: Nodes can communicate with all pods without NAT
- Pod-to-Node Communication: Pods can communicate with all nodes without NAT
These requirements are implemented by Container Network Interface (CNI) plugins like Calico, Cilium, Flannel, and others.
Pod Networking
Every pod in a Kubernetes cluster receives its own unique IP address. This IP address is ephemeral and will change if the pod is recreated.
Key Pod Networking Concepts:
- Each pod has its own IP address
- Containers within a pod share the same network namespace
- Containers within a pod can communicate via localhost
- The pod IP is visible to other pods in the cluster, regardless of the node
Kubernetes Services
Services provide a stable networking endpoint for a set of pods. They abstract away the ephemeral nature of pod IPs and provide load balancing.
Service Types
ClusterIP (Default)
Exposes the service on an internal IP within the cluster. Only accessible within the cluster.
apiVersion: v1
kind: Service
metadata:
name: nginx-service
spec:
selector:
app: nginx
ports:
- port: 80 # Service port
targetPort: 80 # Container port
type: ClusterIPCommon ClusterIP Commands:
# Create a ClusterIP service
kubectl expose deployment nginx --port=80 --target-port=80
# Get services
kubectl get services
# Describe a service
kubectl describe service nginx-serviceNodePort
Exposes the service on each node’s IP at a static port. Accessible from outside the cluster using <NodeIP>:<NodePort>.
apiVersion: v1
kind: Service
metadata:
name: nginx-nodeport
spec:
selector:
app: nginx
ports:
- port: 80 # Service port
targetPort: 80 # Container port
nodePort: 30080 # Node port (must be between 30000-32767)
type: NodePortCommon NodePort Commands:
# Create a NodePort service
kubectl expose deployment nginx --port=80 --target-port=80 --type=NodePort
# Get the assigned NodePort
kubectl get service nginx-nodeport -o jsonpath='{.spec.ports[0].nodePort}'LoadBalancer
Exposes the service externally using a cloud provider’s load balancer.
apiVersion: v1
kind: Service
metadata:
name: nginx-lb
spec:
selector:
app: nginx
ports:
- port: 80
targetPort: 80
type: LoadBalancerCommon LoadBalancer Commands:
# Create a LoadBalancer service
kubectl expose deployment nginx --port=80 --target-port=80 --type=LoadBalancer
# Check the external IP (may take a moment to provision)
kubectl get service nginx-lb -wExternalName
Maps the service to an external DNS name.
apiVersion: v1
kind: Service
metadata:
name: external-service
spec:
type: ExternalName
externalName: api.example.comHeadless Services
A headless service is created by setting the clusterIP field to None. This allows direct access to the pods behind the service.
apiVersion: v1
kind: Service
metadata:
name: headless-service
spec:
clusterIP: None
selector:
app: nginx
ports:
- port: 80
targetPort: 80Headless services are especially useful with StatefulSets to enable direct pod-to-pod communication.
Service Discovery and DNS
Kubernetes provides a built-in DNS service, typically implemented by CoreDNS, for service discovery.
DNS Resolution in Kubernetes
- Services are assigned a DNS name in the format:
<service-name>.<namespace>.svc.cluster.local - Pods can have DNS names in the format:
<pod-ip-with-dashes>.<namespace>.pod.cluster.local
Example DNS lookups from within a pod:
# Access a service in the same namespace
curl http://nginx-service/
# Access a service in a different namespace
curl http://nginx-service.production.svc.cluster.local/CoreDNS
CoreDNS is the default DNS service in Kubernetes. It runs as a deployment in the kube-system namespace.
# Check CoreDNS pods
kubectl get pods -n kube-system -l k8s-app=kube-dns
# Examine CoreDNS configuration
kubectl get configmap -n kube-system coredns -o yamlNetwork Policies
Network Policies are a Kubernetes resource that controls the traffic flow to and from pods. They act as a firewall within the cluster.
Note: Network Policies are namespace-specific, and you must have a CNI plugin that supports Network Policies (such as Calico, Cilium, or Antrea).
Example Network Policy
The following Network Policy allows inbound traffic to pods with the label app=nginx only from pods with the label role=frontend:
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: allow-frontend-to-nginx
spec:
podSelector:
matchLabels:
app: nginx
policyTypes:
- Ingress
ingress:
- from:
- podSelector:
matchLabels:
role: frontend
ports:
- protocol: TCP
port: 80Default Deny All Ingress Traffic
To create a default deny-all policy for a namespace:
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: default-deny-ingress
spec:
podSelector: {} # Selects all pods in the namespace
policyTypes:
- IngressAllow All Egress Traffic
To allow all outbound traffic from all pods:
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: allow-all-egress
spec:
podSelector: {}
egress:
- {}
policyTypes:
- EgressCommon Network Policy Commands
# Create a network policy
kubectl apply -f network-policy.yaml
# Get network policies
kubectl get networkpolicies
# Describe a network policy
kubectl describe networkpolicy allow-frontend-to-nginxIngress Resources and Controllers
Ingress exposes HTTP and HTTPS routes from outside the cluster to services within the cluster.
Ingress Controllers
Before you can use Ingress resources, you must have an Ingress controller running in your cluster. Some popular options include:
- NGINX Ingress Controller
- HAProxy Ingress
- Traefik
- Istio
- Contour
To install the NGINX Ingress Controller:
kubectl apply -f https://raw.githubusercontent.com/kubernetes/ingress-nginx/controller-v1.8.2/deploy/static/provider/cloud/deploy.yamlIngress Resource
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: minimal-ingress
annotations:
nginx.ingress.kubernetes.io/rewrite-target: /
spec:
ingressClassName: nginx
rules:
- host: myapp.example.com
http:
paths:
- path: /
pathType: Prefix
backend:
service:
name: myapp
port:
number: 80
- host: api.example.com
http:
paths:
- path: /
pathType: Prefix
backend:
service:
name: api-service
port:
number: 8080TLS with Ingress
To secure an Ingress with TLS:
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: tls-ingress
spec:
ingressClassName: nginx
tls:
- hosts:
- myapp.example.com
secretName: myapp-tls
rules:
- host: myapp.example.com
http:
paths:
- path: /
pathType: Prefix
backend:
service:
name: myapp
port:
number: 80The TLS secret must be created separately:
kubectl create secret tls myapp-tls --cert=path/to/cert.crt --key=path/to/key.keyCommon Ingress Commands
# Create an Ingress resource
kubectl apply -f ingress.yaml
# Get Ingress resources
kubectl get ingress
# Describe an Ingress
kubectl describe ingress minimal-ingressContainer Network Interface (CNI)
The Container Network Interface (CNI) is a standard for configuring network interfaces for Linux containers. Kubernetes uses CNI plugins to implement its networking model.
Common CNI Plugins
- Calico: Provides networking and network policy enforcement
- Cilium: Layer 7 (HTTP/gRPC) aware networking and security
- Flannel: Simple overlay network focused on traffic encapsulation
- Weave Net: Mesh overlay network with minimal configuration
- Antrea: Built on Open vSwitch to implement Kubernetes networking
Viewing CNI Configuration
The CNI configuration is typically stored on each node at /etc/cni/net.d/:
# Examine CNI configuration on a node (requires SSH access to the node)
ls -la /etc/cni/net.d/
cat /etc/cni/net.d/10-calico.conflistTroubleshooting Networking Issues
Networking issues are common in Kubernetes. Here are some tools and commands to help diagnose problems:
Pod Connectivity
# Run a temporary pod for testing network connectivity
kubectl run netshoot --rm -it --image=nicolaka/netshoot -- /bin/bash
# From inside the pod, test connectivity to a service
curl http://nginx-service
# Test DNS resolution
nslookup nginx-service
nslookup nginx-service.default.svc.cluster.localService Connectivity
# Describe the service to check endpoint connections
kubectl describe service nginx-service
# Check the endpoints for a service
kubectl get endpoints nginx-service
# Check if pods are selected correctly
kubectl get pods -l app=nginxDNS Troubleshooting
# Check CoreDNS pods
kubectl get pods -n kube-system -l k8s-app=kube-dns
# Check DNS configuration in a pod
kubectl exec -it nginx -- cat /etc/resolv.conf
# Deploy a DNS debugging pod
kubectl apply -f https://k8s.io/examples/admin/dns/dnsutils.yaml
kubectl exec -it dnsutils -- nslookup kubernetes.defaultNetwork Policy Testing
# Test connectivity from one pod to another with labels
kubectl run frontend --image=nginx -l role=frontend
kubectl run backend --image=nginx -l app=nginx
kubectl exec -it frontend -- curl backendSample Exam Questions
Question 1: Create a Service
Task: Create a ClusterIP service named ‘web-service’ that exposes port 80 for a deployment named ‘web-app’ which is running containers that use port 8080.
Solution:
kubectl expose deployment web-app --name=web-service --port=80 --target-port=8080Alternatively:
cat << EOF | kubectl apply -f -
apiVersion: v1
kind: Service
metadata:
name: web-service
spec:
selector:
app: web-app
ports:
- port: 80
targetPort: 8080
EOFQuestion 2: Network Policy Implementation
Task: Create a network policy named ‘db-policy’ that allows only pods with the label ‘app=web’ in the ‘app’ namespace to connect to pods with the label ‘app=db’ on port 3306.
Solution:
cat << EOF | kubectl apply -f -
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: db-policy
namespace: app
spec:
podSelector:
matchLabels:
app: db
policyTypes:
- Ingress
ingress:
- from:
- podSelector:
matchLabels:
app: web
ports:
- protocol: TCP
port: 3306
EOFQuestion 3: Debugging Service Connectivity
Task: A service named ‘frontend’ is not able to connect to a service named ‘backend’. Diagnose and fix the issue.
Solution:
# Step 1: Check if the backend service exists
kubectl get service backend
# Step 2: Check if the backend service has endpoints
kubectl get endpoints backend
# Step 3: Check if the selector matches any pods
kubectl describe service backend
kubectl get pods --show-labels | grep -E "$(kubectl get svc backend -o jsonpath='{.spec.selector}' | sed 's/[{},]/ /g' | sed 's/:/=/g')"
# Step 4: If no pods match the selector, check pod labels
kubectl get pods --show-labels
# Step 5: Fix the service selector or pod labels as needed
kubectl edit service backend
# Or
kubectl label pod <backend-pod-name> app=backendQuestion 4: Create an Ingress Resource
Task: Create an Ingress resource that routes traffic from ‘app.example.com’ to a service named ‘webapp’ on port 80, and traffic from ‘api.example.com’ to a service named ‘api’ on port 8080.
Solution:
cat << EOF | kubectl apply -f -
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: multi-ingress
spec:
ingressClassName: nginx
rules:
- host: app.example.com
http:
paths:
- path: /
pathType: Prefix
backend:
service:
name: webapp
port:
number: 80
- host: api.example.com
http:
paths:
- path: /
pathType: Prefix
backend:
service:
name: api
port:
number: 8080
EOFKey Tips for Services and Networking
Master service creation:
- Know the differences between service types
- Understand how selectors work to match pods
- Learn to create services imperatively and declaratively
Network Policy understanding:
- Be comfortable with both ingress and egress rules
- Know how to select specific pods using podSelector
- Understand namespace selection for cross-namespace policies
DNS resolution:
- Memorize the DNS naming format:
<service-name>.<namespace>.svc.cluster.local - Know how to troubleshoot DNS issues
- Memorize the DNS naming format:
Troubleshooting skills:
- Develop a systematic approach to debugging network issues
- Know how to check service-to-endpoint mappings
- Be comfortable using temporary pods for testing connectivity
Ingress configuration:
- Know how to route traffic based on hosts and paths
- Understand how to configure TLS
- Be familiar with common ingress annotations
Practice Exercises
To reinforce your understanding, try these exercises in your practice environment:
- Create a deployment and expose it using different service types (ClusterIP, NodePort)
- Create a network policy that restricts communication between namespaces
- Set up an Ingress resource with path-based routing
- Deploy a headless service for a StatefulSet
- Troubleshoot a service with no endpoints
- Configure TLS for an Ingress resource
- Deploy a multi-tier application with proper network isolation
What’s Next
In the next part, we’ll explore Kubernetes Storage concepts, covering:
- Volumes and Volume Types
- Persistent Volumes and Persistent Volume Claims
- Storage Classes
- Volume Snapshots
- Dynamic Provisioning
👉 Continue to Part 5: Storage