Skip to content

Kubernetes Networking

Overview

Kubernetes networking in the cluster is handled by Flannel CNI with VXLAN backend, providing pod-to-pod communication across nodes.

Network Architecture

graph TB
    subgraph External
        CF[Cloudflare]
    end

    subgraph Cluster Networking
        subgraph Node 1
            P1[Pod A]
            P2[Pod B]
            F1[Flannel]
        end

        subgraph Node 2
            P3[Pod C]
            P4[Pod D]
            F2[Flannel]
        end

        SVC[Service]
        DNS[CoreDNS]
    end

    CF -->|Tunnel| SVC
    SVC --> P1
    SVC --> P3
    P1 --> DNS
    F1 <-->|VXLAN| F2

CNI: Flannel

Configuration

K3s includes Flannel by default with VXLAN backend:

  • Pod CIDR: 10.42.0.0/16
  • Service CIDR: 10.43.0.0/16
  • Backend: VXLAN

How It Works

  1. Each node gets a /24 subnet from Pod CIDR
  2. Pods on same node communicate directly
  3. Cross-node traffic encapsulated in VXLAN
  4. Flannel manages routing tables

Services

Service Types

Type Description Use Case
ClusterIP Internal-only IP Default, internal services
NodePort Node IP + port Debugging only
LoadBalancer External LB N/A (no cloud provider)
ExternalName DNS alias External service reference

Service Example

apiVersion: v1
kind: Service
metadata:
  name: my-app
  namespace: my-namespace
spec:
  type: ClusterIP
  selector:
    app: my-app
  ports:
  - port: 80
    targetPort: 8080

DNS Resolution

CoreDNS

CoreDNS provides cluster DNS with the following zones:

  • cluster.local - Default cluster domain
  • svc.cluster.local - Services
  • pod.cluster.local - Pods (optional)

DNS Records

Record Type Format Example
Service A <svc>.<ns>.svc.cluster.local grafana.monitoring.svc.cluster.local
Pod A <pod-ip>.<ns>.pod.cluster.local 10-42-0-5.default.pod.cluster.local
Headless <pod>.<svc>.<ns>.svc.cluster.local pod-0.mysql.databases.svc.cluster.local

DNS Debugging

# Test DNS resolution
kubectl run dnsutils --image=tutum/dnsutils -it --rm -- nslookup grafana.monitoring

# Check CoreDNS logs
kubectl logs -n kube-system -l k8s-app=kube-dns

Ingress

Cloudflare Tunnel (cloudflared)

Instead of traditional ingress controllers, external traffic routes through Cloudflare Tunnel:

apiVersion: v1
kind: ConfigMap
metadata:
  name: cloudflared
  namespace: cloudflared
data:
  config.yaml: |
    tunnel: <tunnel-id>
    credentials-file: /etc/cloudflared/credentials.json
    ingress:
      - hostname: grafana.ajandrews.pro
        service: http://grafana.monitoring.svc:3000
      - hostname: kibana.ajandrews.pro
        service: http://kibana.monitoring.svc:5601
      - service: http_status:404

Benefits

  • No exposed ports
  • DDoS protection
  • Automatic SSL
  • Zero-trust access

Network Policies

Default Deny

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

Allow Specific Traffic

apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
  name: allow-monitoring
  namespace: my-app
spec:
  podSelector:
    matchLabels:
      app: my-app
  ingress:
  - from:
    - namespaceSelector:
        matchLabels:
          name: monitoring
    ports:
    - protocol: TCP
      port: 8080

Troubleshooting

Connectivity Issues

# Test pod-to-pod
kubectl exec -it pod-a -- ping <pod-b-ip>

# Test service
kubectl exec -it pod-a -- curl http://service-name:port

# Check endpoints
kubectl get endpoints <service-name>

Common Problems

Issue Symptom Resolution
No endpoints Service has no backends Check pod labels match selector
DNS failure Cannot resolve service Check CoreDNS pods are running
Cross-node timeout Pods can't reach other nodes Check Flannel, firewall rules

Performance Tuning

MTU Settings

Flannel VXLAN has 50-byte overhead:

Physical MTU: 1500
VXLAN overhead: 50
Effective pod MTU: 1450

Connection Tracking

For high-traffic services, increase conntrack limits:

# Check current limits
sysctl net.netfilter.nf_conntrack_max

# Increase if needed
sysctl -w net.netfilter.nf_conntrack_max=131072