27.7 Structured Logging Best Practices for Kubernetes Apps

Look, let’s be honest: your application’s logs are a firehose of misery. In the old days, you’d SSH into a server, tail -f a file, and hope for the best. In Kubernetes, that single server is now a teeming swarm of ephemeral, constantly rescheduled pods. Your logs are scattered across nodes, stored in containers that vanish the moment you need them most. Grepping a thousand text files isn’t just impractical; it’s a form of career self-sabotage.

27.6 Log Retention, Rotation, and Storage Costs

Right, let’s talk about the part of logging everyone loves to ignore until they get a frantic 3 AM call from finance asking why the cloud bill has a line item the size of a used hatchback: storage. In Kubernetes, your logs don’t just magically disappear. If you’re not careful, they’ll pile up like junk mail in a digital hallway, cluttering your nodes and vacuuming your wallet. The default setup is, frankly, a trap for the unwary.

27.5 Grafana Loki: Log Aggregation Without Full-Text Indexing

Alright, let’s talk about Loki. If you’ve ever run a kubectl logs command for a pod that’s since been deleted and gotten that sinking feeling of “where did my logs go?”, you understand the why of log aggregation. Loki is Grafana’s answer to this, but it takes a fundamentally different, and frankly, more cost-effective approach than the elephants in the room (I’m looking at you, Elasticsearch). The core premise is brilliantly simple and a bit contrarian: don’t index the content of the log lines. Index only the labels associated with them (like namespace, pod_name, container_name). When you want to search your logs, you first use those labels to narrow down the set of logs you’re dealing with to a manageable chunk, and then you do a brute-force grep-style search on that subset. This is the opposite of full-text indexing, where you pay a massive upfront cost in CPU, memory, and storage to index every word so you can find it instantly later. Loki makes the query a bit slower so the ingest is cheaper, faster, and simpler. For the vast majority of debugging use cases, this is a trade-off you absolutely want to make.

27.4 The EFK Stack: Elasticsearch, Fluent Bit, Kibana

Right, so you’ve got a Kubernetes cluster, and it’s spewing out logs from a dozen different pods like a firehose into a bucket. You can’t just kubectl logs your way out of this mess. You need a proper logging stack. Enter the old guard: the EFK Stack (Elasticsearch, Fluent Bit, Kibana). It’s the industry-standard workhorse for a reason, but let’s be clear: it’s a bit like adopting a pet elephant. Powerful, impressive, but it needs a lot of room and you will, at some point, be cleaning up after it.

27.3 Fluent Bit: Lightweight Log Collector as DaemonSet

Right, so you’ve got a Kubernetes cluster, and it’s spewing logs from its various Pods like a firehose into a void. Your job is to catch that stream, make sense of it, and send it somewhere useful. That’s where Fluent Bit comes in. It’s the lean, mean, log-processing machine we all turn to because it’s written in C, uses a fraction of the memory of its bigger sibling (Fluentd), and is ruthlessly efficient. We’re going to run it as a DaemonSet, which is a fancy way of saying “one copy of this Pod on every single node in our cluster.” This is non-negotiable; you need an agent on each node to read the logs from /var/log/containers, which is where the kubelet helpfully symlinks all your container logs.

27.2 kubectl logs and Multi-Container Log Access

Right, so you’ve got a pod running. Maybe it’s a beautiful, elegant piece of software. Or maybe it’s a burning dumpster fire of 500 errors. Either way, your first move is almost always kubectl logs. It’s the debugging equivalent of a trusty flashlight. But like any good tool, it has its quirks, and if your pod has more than one container, it gets a little… opinionated. Let’s say you run a simple:

27.1 Kubernetes Logging Architecture: stdout/stderr and Node-Level Logging

Right, let’s talk about logging. It’s the duct tape of our industry, and in Kubernetes, it feels like you need a whole lot more of it. You’re not just debugging your application anymore; you’re debugging your application’s entire reality. The first and most crucial thing to burn into your brain is this core Kubernetes design choice: it expects your applications to log to standard output (stdout) and standard error (stderr).

— joke —

...