HomeTutorialEssential Kubernetes Networking: Services, Ingress & Network Policies You Need to Know

Essential Kubernetes Networking: Services, Ingress & Network Policies You Need to Know

Any developer who works with containerized apps needs to know how Kubernetes networking works. Learning these three basic parts—Services, Ingress, and Network Policies—will make your development process much more efficient, whether you’re routing traffic between services, making apps available to outside users, or keeping communication between pods secure.

This detailed book will look at each part in depth, with real-world examples and important instructions that will make your daily development chores easier.

What Kubernetes Services Are?

In Kubernetes, services provide a reliable approach to make your apps available and accessible. Think of them as the network that links your pods to each other and to the rest of the world. Services give your apps a consistent endpoint, unlike pods, which are temporary and can be made or terminated at any time.

Types of Services

ClusterIP (Default) The most common service type, ClusterIP creates an internal IP address accessible only within the cluster. This is perfect for internal communication between your microservices.

# Create a ClusterIP service
kubectl create service clusterip my-app --tcp=80:8080

# Or using YAML
kubectl apply -f - <<EOF
apiVersion: v1
kind: Service
metadata:
  name: my-app-service
spec:
  selector:
    app: my-app
  ports:
    - protocol: TCP
      port: 80
      targetPort: 8080
  type: ClusterIP
EOF

NodePort NodePort exposes your service on a specific port across all cluster nodes. This is useful for development and testing scenarios.

# Create a NodePort service
kubectl create service nodeport my-app --tcp=80:8080 --node-port=30080

# Check the assigned port
kubectl get svc my-app -o jsonpath='{.spec.ports[0].nodePort}'

LoadBalancer LoadBalancer integrates with cloud providers to provision external load balancers. This is the go-to choice for production applications that need external access.

# Create a LoadBalancer service
kubectl create service loadbalancer my-app --tcp=80:8080

# Monitor the external IP assignment
kubectl get svc my-app --watch

Essential Service Commands

# List all services
kubectl get services

# Get detailed service information
kubectl describe service my-app

# View service endpoints
kubectl get endpoints my-app

# Test service connectivity from within the cluster
kubectl run test-pod --image=busybox --rm -it --restart=Never -- wget -qO- http://my-app-service

# Port forward for local testing
kubectl port-forward service/my-app 8080:80

# Delete a service
kubectl delete service my-app

Mastering Kubernetes Ingress

Ingress makes your HTTP (or HTTPS) network service available using a protocol-aware configuration mechanism, that understands web concepts like URIs, hostnames, paths, and more. It acts as the smart gateway that routes external traffic to your internal services based on rules you define.

Setting Up Ingress

Before creating Ingress resources, you need an Ingress Controller. In order for an Ingress to work in your cluster, there must be an ingress controller running. The most popular choice is NGINX Ingress Controller.

# Install NGINX Ingress Controller
kubectl apply -f https://raw.githubusercontent.com/kubernetes/ingress-nginx/controller-v1.10.0/deploy/static/provider/cloud/deploy.yaml

# For Minikube users
minikube addons enable ingress

# Verify installation
kubectl get pods -n ingress-nginx

Creating Ingress Resources

Basic Ingress Example

# Create a simple ingress using kubectl
kubectl create ingress simple --rule="foo.com/bar=svc1:8080,tls=my-cert"

# Or using YAML for more control
kubectl apply -f - <<EOF
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: my-app-ingress
  annotations:
    nginx.ingress.kubernetes.io/rewrite-target: /
spec:
  rules:
  - host: myapp.example.com
    http:
      paths:
      - path: /
        pathType: Prefix
        backend:
          service:
            name: my-app-service
            port:
              number: 80
EOF

Advanced Ingress with Multiple Paths

apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: multi-path-ingress
  annotations:
    nginx.ingress.kubernetes.io/ssl-redirect: "false"
    nginx.ingress.kubernetes.io/use-regex: "true"
spec:
  rules:
  - host: api.example.com
    http:
      paths:
      - path: /v1/users
        pathType: Prefix
        backend:
          service:
            name: user-service
            port:
              number: 8080
      - path: /v1/orders
        pathType: Prefix
        backend:
          service:
            name: order-service
            port:
              number: 8080
  - host: admin.example.com
    http:
      paths:
      - path: /
        pathType: Prefix
        backend:
          service:
            name: admin-service
            port:
              number: 3000

Ingress with TLS/SSL

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

Essential Ingress Commands

# List all ingress resources
kubectl get ingress

# Get detailed ingress information
kubectl describe ingress my-app-ingress

# Edit ingress resource
kubectl edit ingress my-app-ingress

# Check ingress controller logs
kubectl logs -n ingress-nginx -l app.kubernetes.io/name=ingress-nginx

# Test ingress connectivity
curl -H "Host: myapp.example.com" http://$(kubectl get ingress my-app-ingress -o jsonpath='{.status.loadBalancer.ingress[0].ip}')

# Port forward to ingress controller for local testing
kubectl port-forward -n ingress-nginx service/ingress-nginx-controller 8080:80

Implementing Network Policies for Security

NetworkPolicies allow you to specify rules for traffic flow within your cluster, and also between Pods and the outside world. They’re essential for implementing zero-trust networking and microservice security.

Prerequisites

Your cluster must use a network plugin that supports NetworkPolicy enforcement. Popular options include:

  • Calico
  • Cilium
  • Weave Net
# Check if your cluster supports NetworkPolicy
kubectl api-versions | grep networking.k8s.io

# For Calico installation
kubectl apply -f https://docs.projectcalico.org/manifests/calico.yaml

Network Policy Best Practices

Start with a deny-all policy: Start by denying all network traffic and gradually allow only the necessary traffic as you identify it. This approach, known as “zero-trust” networking, significantly reduces your attack surface.

Default Deny-All Policy

apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
  name: default-deny-all
  namespace: production
spec:
  podSelector: {}
  policyTypes:
  - Ingress
  - Egress

Allow Internal Communication

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

Allow External Access

apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
  name: allow-external
  namespace: production
spec:
  podSelector:
    matchLabels:
      app: api-gateway
  policyTypes:
  - Ingress
  - Egress
  ingress:
  - from: []  # Allow from anywhere
    ports:
    - protocol: TCP
      port: 80
    - protocol: TCP
      port: 443
  egress:
  - to: []  # Allow to anywhere
    ports:
    - protocol: TCP
      port: 443  # HTTPS
    - protocol: TCP
      port: 53   # DNS
    - protocol: UDP
      port: 53   # DNS

Advanced Network Policy Examples

Namespace-Based Access Control

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

Time-Based Access (Using Annotations)

apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
  name: business-hours-only
  annotations:
    scheduler.alpha.kubernetes.io/critical-pod: ""
spec:
  podSelector:
    matchLabels:
      app: business-app
  policyTypes:
  - Ingress
  ingress:
  - from:
    - podSelector:
        matchLabels:
          role: business-user
    ports:
    - protocol: TCP
      port: 8080

Essential Network Policy Commands

# List all network policies
kubectl get networkpolicies

# Get detailed policy information
kubectl describe networkpolicy default-deny-all

# Test network connectivity
kubectl run test-pod --image=busybox --rm -it --restart=Never -- wget -qO- --timeout=2 http://target-service:8080

# Debug network policy issues
kubectl get pods -o wide
kubectl exec -it source-pod -- nslookup target-service

# Check policy effectiveness
kubectl get networkpolicy -o yaml

# Delete network policy
kubectl delete networkpolicy policy-name

Putting It All Together: Complete Example

Let’s create a complete example that demonstrates Services, Ingress, and Network Policies working together:

# Application Deployment
apiVersion: apps/v1
kind: Deployment
metadata:
  name: web-app
  namespace: production
spec:
  replicas: 3
  selector:
    matchLabels:
      app: web-app
      tier: frontend
  template:
    metadata:
      labels:
        app: web-app
        tier: frontend
    spec:
      containers:
      - name: web-app
        image: nginx:1.21
        ports:
        - containerPort: 80

---
# ClusterIP Service
apiVersion: v1
kind: Service
metadata:
  name: web-app-service
  namespace: production
spec:
  selector:
    app: web-app
  ports:
    - protocol: TCP
      port: 80
      targetPort: 80

---
# Ingress Resource
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: web-app-ingress
  namespace: production
  annotations:
    nginx.ingress.kubernetes.io/rewrite-target: /
spec:
  rules:
  - host: webapp.example.com
    http:
      paths:
      - path: /
        pathType: Prefix
        backend:
          service:
            name: web-app-service
            port:
              number: 80

---
# Network Policy
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
  name: web-app-netpol
  namespace: production
spec:
  podSelector:
    matchLabels:
      app: web-app
  policyTypes:
  - Ingress
  - Egress
  ingress:
  - from:
    - namespaceSelector:
        matchLabels:
          name: ingress-nginx
    ports:
    - protocol: TCP
      port: 80
  egress:
  - to: []
    ports:
    - protocol: TCP
      port: 443
    - protocol: TCP
      port: 53
    - protocol: UDP
      port: 53

Troubleshooting Common Issues

Service Discovery Problems

# Check service endpoints
kubectl get endpoints service-name

# Verify pod labels match service selector
kubectl get pods --show-labels
kubectl get service service-name -o yaml

# Test DNS resolution
kubectl run debug --image=busybox --rm -it --restart=Never -- nslookup service-name

Ingress Not Working

# Check ingress controller status
kubectl get pods -n ingress-nginx

# Verify ingress resource
kubectl get ingress -o wide

# Check ingress controller logs
kubectl logs -n ingress-nginx deployment/ingress-nginx-controller

# Test with curl
curl -H "Host: your-domain.com" http://ingress-ip

Network Policy Blocking Traffic

# List all policies affecting a pod
kubectl get networkpolicy -o wide

# Check policy selectors
kubectl describe networkpolicy policy-name

# Test connectivity step by step
kubectl exec -it source-pod -- telnet target-service port

Performance Optimization Tips

Service Optimization

# Use headless services for direct pod communication
kubectl create service clusterip my-service --clusterip="None"

# Enable session affinity for stateful applications
kubectl patch service my-service -p '{"spec":{"sessionAffinity":"ClientIP"}}'

Ingress Optimization

# Use appropriate annotations for better performance
metadata:
  annotations:
    nginx.ingress.kubernetes.io/proxy-buffer-size: "8k"
    nginx.ingress.kubernetes.io/proxy-connect-timeout: "600"
    nginx.ingress.kubernetes.io/proxy-send-timeout: "600"
    nginx.ingress.kubernetes.io/proxy-read-timeout: "600"

Network Policy Optimization

Use specific pod selectors to avoid unintentionally including new pods and leverage monitoring tools to evaluate how your ingress and egress policies perform.

Monitoring and Observability

# Monitor service health
kubectl get services --watch

# Check ingress metrics
kubectl top pods -n ingress-nginx

# View network policy logs (if supported by CNI)
kubectl logs -n kube-system -l k8s-app=calico-node

# Use kubectl events for troubleshooting
kubectl get events --sort-by='.lastTimestamp'

Conclusion

To develop strong, safe, and scalable apps, you need to know how to use Services, Ingress, and Network Policies to manage Kubernetes networking. Services are the building blocks of internal communication, Ingress manages exterior traffic routing in a smart way, and Network Policies make sure your apps follow security best practices.

Keep these important points in mind:

  • Always use ClusterIP services for internal communication and only let others outside of your network see them when you need to.
  • When you can, use Ingress instead of LoadBalancer services to route HTTP and HTTPS traffic.
  • Use a deny-all strategy for network policies and only let in traffic that is needed over time.
  • Check the performance of your network setup and test it often.

You should be able to handle most Kubernetes networking situations well with these commands and examples in your toolkit. The most important thing is to start with simple things, test them well, and then add more complicated things as your apps expand.

If you keep using these commands, you’ll quickly discover that Kubernetes networking becomes second nature in your development process.

RELATED ARTICLES

LEAVE A REPLY

Please enter your comment!
Please enter your name here

Most Popular