|
| 1 | +--- |
| 2 | +title: Kubernetes Networking Explained |
| 3 | +--- |
| 4 | + |
| 5 | +## Objectives: |
| 6 | + |
| 7 | +1. How **networking works in Kubernetes** (flat networking and DNS). |
| 8 | +2. Types of Kubernetes **Service** resources and their usage. |
| 9 | +3. How **Ingress** works and integrates with your cluster. |
| 10 | +4. **Cross-namespace pod/service communication**. |
| 11 | +5. How to **restrict communication** with Network Policies. |
| 12 | +6. Bonus tips for optimizing and securing your cluster's networking. |
| 13 | + |
| 14 | +## The Basics of Kubernetes Networking |
| 15 | + |
| 16 | +Kubernetes networking is designed to be **simple and flat**: |
| 17 | +- Any pod can communicate with any other pod in the cluster, regardless of which namespace they're in. This communication works out of the box without additional configuration. |
| 18 | +- Pods and services use **DNS** for service discovery instead of hardcoding IP addresses. |
| 19 | + |
| 20 | +### Pod-to-Pod Networking |
| 21 | + |
| 22 | +Every pod is assigned a unique IP address. All pods share a single, flat address space, so there’s no [Network Address Translation (NAT)](https://www.youtube.com/watch?v=FTUV0t6JaDA) when pods communicate. However, pod IPs are [ephemeral](https://www.google.com/search?q=ephemeral&oq=ephemeral&gs_lcrp=EgZjaHJvbWUyBggAEEUYOdIBBzExOWowajeoAgCwAgA&sourceid=chrome&ie=UTF-8), they change if a pod is restarted. |
| 23 | + |
| 24 | +### Pod-to-Service Networking with DNS |
| 25 | + |
| 26 | +Kubernetes provides a built-in DNS service that allows pods to resolve services using their names. For example: |
| 27 | + |
| 28 | +- A service called `nodejs-service` in the `default` namespace can be resolved by other pods in the same namespace as: |
| 29 | +``` |
| 30 | +http://nodejs-service |
| 31 | +``` |
| 32 | + |
| 33 | +- From another namespace, it might look like: |
| 34 | + |
| 35 | +``` |
| 36 | +http://nodejs-service.default.svc.cluster.local |
| 37 | +``` |
| 38 | + |
| 39 | +This DNS-based service discovery simplifies communication between pods and services, especially in complex setups. |
| 40 | + |
| 41 | +## Key Networking Components in Kubernetes |
| 42 | + |
| 43 | +### **A. Services** |
| 44 | +Services are used to expose a group of pods (selected using labels) over the network and provide a stable address for accessing them. |
| 45 | + |
| 46 | +Three key types of services: |
| 47 | +1. **ClusterIP** (default) |
| 48 | + |
| 49 | +- Accessible **within the cluster only**. |
| 50 | +- Provides internal networking between pods. |
| 51 | +- Example: A backend service used by a frontend within the same application stack. |
| 52 | + |
| 53 | +2. **NodePort** |
| 54 | + |
| 55 | +- Exposes a service on a static port across all cluster nodes. |
| 56 | +- Mostly used for development purposes but not ideal for production due to limited network flexibility. |
| 57 | + |
| 58 | +3. **LoadBalancer** |
| 59 | + |
| 60 | +- Requests an external IP to expose the service outside your cluster. In K3s, this integrates with **MetalLB** to assign an IP from your private pool. |
| 61 | + |
| 62 | +> Tip: Minimize `LoadBalancer` usage by routing external traffic via an **Ingress Controller** for better efficiency. |
| 63 | +
|
| 64 | +## Ingress: The Gateway to Your Cluster |
| 65 | + |
| 66 | +Ingress is responsible for **routing external HTTP / HTTPS traffic** to services within your cluster. It integrates seamlessly with **Traefik**, your Ingress Controller in K3s. |
| 67 | + |
| 68 | +### How It Works: |
| 69 | + |
| 70 | +1. Create your services (e.g., `ClusterIP` services for Node.js, backends, etc.). |
| 71 | +2. Define an Ingress resource: |
| 72 | + - Map hostnames (e.g., `nodejs.example.com`) or path prefixes (e.g., `/api`) to specific services. |
| 73 | +3. Traefik manages incoming requests and routes them to the appropriate service. |
| 74 | + |
| 75 | +**Example Ingress Resource:** |
| 76 | + |
| 77 | +```yaml |
| 78 | +apiVersion: networking.k8s.io/v1 |
| 79 | +kind: Ingress |
| 80 | +metadata: |
| 81 | + name: my-ingress |
| 82 | + annotations: |
| 83 | + traefik.ingress.kubernetes.io/router.entrypoints: web |
| 84 | +spec: |
| 85 | + rules: |
| 86 | + - host: nodejs.example.com |
| 87 | + http: |
| 88 | + paths: |
| 89 | + - path: / |
| 90 | + pathType: Prefix |
| 91 | + backend: |
| 92 | + service: |
| 93 | + name: nodejs-service |
| 94 | + port: |
| 95 | + number: 80 |
| 96 | +``` |
| 97 | +
|
| 98 | +### Benefits of Ingress: |
| 99 | +- Reduces the need for multiple `LoadBalancer` services—only Traefik’s load balancer requires an external IP. |
| 100 | +- Simplifies DNS-based routing for multiple services. |
| 101 | + |
| 102 | +## Cross-Namespace Networking |
| 103 | + |
| 104 | +### **Default Behavior:** |
| 105 | + |
| 106 | +In K3s/Kubernetes, pods and services in one namespace can communicate with those in another **by default**. You can achieve this by: |
| 107 | +1. Using DNS: |
| 108 | + - `<service-name>.<namespace>.svc.cluster.local` |
| 109 | + - Example: `http://postgres-service.database.svc.cluster.local` |
| 110 | + |
| 111 | +2. Accessing services by IP/methods if service discovery is properly managed. |
| 112 | + |
| 113 | +### **Restricting Cross-Namespace Communication** |
| 114 | + |
| 115 | +To prevent unrestricted communication between namespaces, use **Network Policies** (see below). |
| 116 | + |
| 117 | +## Network Policies: Restricting Internal Communication |
| 118 | + |
| 119 | +By default, Kubernetes allows all traffic between pods and across namespaces. To secure your cluster, you can leverage **Network Policies** to restrict ingress (incoming) and/or egress (outgoing) traffic. |
| 120 | + |
| 121 | +### **How Network Policies Work** |
| 122 | + |
| 123 | +Network Policies let you: |
| 124 | + |
| 125 | +1. Define which pods are allowed to receive traffic (ingress). |
| 126 | +2. Define which pods are allowed to send traffic (egress). |
| 127 | +3. Use labels and selectors to control access between pods/services. |
| 128 | + |
| 129 | +### Examples: |
| 130 | + |
| 131 | +#### **Default-Deny All Traffic** |
| 132 | + |
| 133 | +The foundation of securing your cluster: |
| 134 | + |
| 135 | +```yaml |
| 136 | +apiVersion: networking.k8s.io/v1 |
| 137 | +kind: NetworkPolicy |
| 138 | +metadata: |
| 139 | + name: deny-all |
| 140 | + namespace: default |
| 141 | +spec: |
| 142 | + podSelector: {} |
| 143 | + policyTypes: |
| 144 | + - Ingress |
| 145 | + - Egress |
| 146 | +``` |
| 147 | + |
| 148 | +- Blocks all traffic to/from pods in the `default` namespace unless explicitly allowed. |
| 149 | + |
| 150 | +#### **Allow Specific Namespace Traffic** |
| 151 | + |
| 152 | +Allow only traffic originating from pods in a specific namespace (e.g., `frontend` namespace): |
| 153 | + |
| 154 | +```yaml |
| 155 | +apiVersion: networking.k8s.io/v1 |
| 156 | +kind: NetworkPolicy |
| 157 | +metadata: |
| 158 | + name: allow-namespace-frontend |
| 159 | + namespace: backend |
| 160 | +spec: |
| 161 | + podSelector: {} |
| 162 | + policyTypes: |
| 163 | + - Ingress |
| 164 | + ingress: |
| 165 | + - from: |
| 166 | + - namespaceSelector: |
| 167 | + matchLabels: |
| 168 | + role: frontend |
| 169 | +``` |
| 170 | + |
| 171 | +- In the `backend` namespace, only pods from the `frontend` namespace (labeled `role: frontend`) can communicate. |
| 172 | + |
| 173 | +#### **Allow Specific Pod Communication** |
| 174 | + |
| 175 | +Allow only a specific pod to communicate with another (e.g., frontend → backend): |
| 176 | + |
| 177 | +```yaml |
| 178 | +apiVersion: networking.k8s.io/v1 |
| 179 | +kind: NetworkPolicy |
| 180 | +metadata: |
| 181 | + name: allow-frontend-backend |
| 182 | + namespace: default |
| 183 | +spec: |
| 184 | + podSelector: |
| 185 | + matchLabels: |
| 186 | + app: backend |
| 187 | + ingress: |
| 188 | + - from: |
| 189 | + - podSelector: |
| 190 | + matchLabels: |
| 191 | + app: frontend |
| 192 | +``` |
| 193 | + |
| 194 | +- Backend pods (`app: backend`) can only receive traffic from frontend pods (`app: frontend`). |
| 195 | + |
| 196 | +## Useful Tools for Debugging Networking in K3s |
| 197 | + |
| 198 | +1. **DNS Resolution** |
| 199 | + |
| 200 | +- Verify service discovery with DNS: |
| 201 | +```bash |
| 202 | +kubectl exec -it <pod-name> -- nslookup <service-name> |
| 203 | +``` |
| 204 | + |
| 205 | +2. **Curl/HTTP Testing** |
| 206 | +- Use `curl` or similar tools to confirm connectivity between services: |
| 207 | +```bash |
| 208 | +kubectl exec -it <pod-name> -- curl <service-name> |
| 209 | +``` |
| 210 | + |
| 211 | +3. **Logs for Ingress** |
| 212 | +- Check Traefik logs to diagnose routing issues. |
| 213 | + |
| 214 | +4. **Network Policy Debugging** |
| 215 | +- Use tools like **Cilium** (if installed) or **NetworkPolicy Viewer** addons for better visualization of applied policies. |
| 216 | + |
| 217 | +## Best Practices for K3s Networking |
| 218 | + |
| 219 | +- Use **ClusterIP** for internal services and restrict `NodePort` services. |
| 220 | +- Depend on **Ingress** for external HTTP/S access—reduce the use of multiple `LoadBalancer` services. |
| 221 | +- Enforce a **default-deny policy** and gradually allow necessary traffic. |
| 222 | +- Use namespace labels and Network Policies to isolate and secure workloads. |
| 223 | +- Monitor and audit your networking policies and Traefik configurations regularly. |
0 commit comments