Skip to content

Commit 30c4631

Browse files
authored
Merge pull request #53172 from kirti763/evergreen-blog
Add evergreen blog: Kubernetes Configuration Best Practices
2 parents 2fda3a1 + dd7bc23 commit 30c4631

File tree

1 file changed

+217
-0
lines changed
  • content/en/blog/_posts/2025-11-11-kubernetes-configuration-best-practices

1 file changed

+217
-0
lines changed
Lines changed: 217 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,217 @@
1+
---
2+
layout: blog
3+
title: "Kubernetes Configuration Good Practices"
4+
date: 2025-11-11
5+
slug: kubernetes-configuration-good-practices
6+
evergreen: true
7+
author: Kirti Goyal
8+
draft: true
9+
---
10+
11+
Configuration is one of those things in Kubernetes that seems small until it's not. Configuration is at the heart of every Kubernetes workload.
12+
A missing quote, a wrong API version or a misplaced YAML indent can ruin your entire deploy.
13+
14+
This blog brings together tried-and-tested configuration best practices. The small habits that make your Kubernetes setup clean, consistent and easier to manage.
15+
Whether you are just starting out or already deploying apps daily, these are the little things that keep your cluster stable and your future self sane.
16+
17+
## General Configuration Practices
18+
19+
### Use the latest stable API version
20+
Kubernetes evolves fast. Older APIs eventually get deprecated and stop working. So, whenever you are defining resources, make sure you are using the latest stable API version.
21+
You can always check with
22+
```bash
23+
kubectl api-resources
24+
```
25+
This simple step saves you from future compatibility issues.
26+
27+
### Store configuration in version control
28+
Never apply manifest files directly from your desktop. Always keep them in a version control system like Git, it's your safety net.
29+
If something breaks, you can instantly roll back to a previous commit, compare changes or recreate your cluster setup without panic.
30+
31+
### Write configs in YAML not JSON
32+
Write your configuration files using YAML rather than JSON. Both work technically, but YAML is just easier for humans. It's cleaner to read and less noisy and widely used in the community.
33+
34+
YAML has some sneaky gotchas with boolean values:
35+
Use only `true` or `false`.
36+
Don't write `yes`, `no`, `on` or `off`.
37+
They might work in one version of YAML but break in another. To be safe, quote anything that looks like a Boolean (for example `"yes"`).
38+
39+
### Keep configuration simple and minimal
40+
Avoid setting default values that are already handled by Kubernetes. Minimal manifests are easier to debug, cleaner to review and less likely to break things later.
41+
42+
### Group related objects together
43+
If your Deployment, Service and ConfigMap all belong to one app, put them in a single manifest file.
44+
It's easier to track changes and apply them as a unit.
45+
See the [Guestbook all-in-one.yaml](https://github.com/kubernetes/examples/blob/master/web/guestbook/all-in-one/guestbook-all-in-one.yaml) file for an example of this syntax.
46+
47+
You can even apply entire directories with:
48+
```bash
49+
kubectl apply -f configs/
50+
```
51+
One command and boom everything in that folder gets deployed.
52+
53+
### Add helpful annotations
54+
Manifest files are not just for machines, they are for humans too. Use annotations to describe why something exists or what it does. A quick one-liner can save hours when debugging later and also allows better collaboration.
55+
56+
The most helpful annotation to set is `kubernetes.io/description`. It's like using comment, except that it gets copied into the API so that everyone else can see it even after you deploy.
57+
58+
## Managing Workloads: Pods, Deployments, and Jobs
59+
60+
A common early mistake in Kubernetes is creating Pods directly. Pods work, but they don't reschedule themselves if something goes wrong.
61+
62+
_Naked Pods_ (Pods not managed by a controller, such as [Deployment](/docs/concepts/workloads/controllers/deployment/) or a [StatefulSet](/docs/concepts/workloads/controllers/statefulset/)) are fine for testing, but in real setups, they are risky.
63+
64+
Why?
65+
Because if the node hosting that Pod dies, the Pod dies with it and Kubernetes won't bring it back automatically.
66+
67+
### Use Deployments for apps that should always be running
68+
A Deployment, which both creates a ReplicaSet to ensure that the desired number of Pods is always available, and specifies a strategy to replace Pods (such as [RollingUpdate](/docs/concepts/workloads/controllers/deployment/#rolling-update-deployment)), is almost always preferable to creating Pods directly.
69+
You can roll out a new version, and if something breaks, roll back instantly.
70+
71+
### Use Jobs for tasks that should finish
72+
A [Job](/docs/concepts/workloads/controllers/job/) is perfect when you need something to run once and then stop like database migration or batch processing task.
73+
It will retry if the pods fails and report success when it's done.
74+
75+
## Service Configuration and Networking
76+
77+
Services are how your workloads talk to each other inside (and sometimes outside) your cluster. Without them, your pods exist but can't reach anyone. Let's make sure that doesn't happen.
78+
79+
### Create Services before workloads that use them
80+
When Kubernetes starts a Pod, it automatically injects environment variables for existing Services.
81+
So, if a Pod depends on a Service, create a [Service](/docs/concepts/services-networking/service/) **before** its corresponding backend workloads (Deployments or StatefulSets), and before any workloads that need to access it.
82+
83+
For example, if a Service named foo exists, all containers will get the following variables in their initial environment:
84+
```
85+
FOO_SERVICE_HOST=<the host the Service runs on>
86+
FOO_SERVICE_PORT=<the port the Service runs on>
87+
```
88+
DNS based discovery doesn't have this problem, but it's a good habit to follow anyway.
89+
90+
### Use DNS for Service discovery
91+
If your cluster has the DNS [add-on](/docs/concepts/cluster-administration/addons/) (most do), every Service automatically gets a DNS entry. That means you can access it by name instead of IP:
92+
```bash
93+
curl http://my-service.default.svc.cluster.local
94+
```
95+
It's one of those features that makes Kubernetes networking feel magical.
96+
97+
### Avoid `hostPort` and `hostNetwork` unless absolutely necessary
98+
You'll sometimes see these options in manifests:
99+
```yaml
100+
hostPort: 8080
101+
hostNetwork: true
102+
```
103+
But here's the thing:
104+
They tie your Pods to specific nodes, making them harder to schedule and scale. Because each <`hostIP`, `hostPort`, `protocol`> combination must be unique. If you don't specify the `hostIP` and `protocol` explicitly, Kubernetes will use `0.0.0.0` as the default `hostIP` and `TCP` as the default `protocol`.
105+
Unless you're debugging or building something like a network plugin, avoid them.
106+
107+
If you just need local access for testing, try [`kubectl port-forward`](/docs/reference/kubectl/generated/kubectl_port-forward/):
108+
109+
```bash
110+
kubectl port-forward deployment/web 8080:80
111+
```
112+
See [Use Port Forwarding to access applications in a cluster](/docs/tasks/access-application-cluster/port-forward-access-application-cluster/) to learn more.
113+
Or if you really need external access, use a [`type: NodePort` Service](/docs/concepts/services-networking/service/#type-nodeport). That's the safer, Kubernetes-native way.
114+
115+
### Use headless Services for internal discovery
116+
Sometimes, you don't want Kubernetes to load balance traffic. You want to talk directly to each Pod. That's where [headless Services](/docs/concepts/services-networking/service/#headless-services) come in.
117+
118+
You create one by setting `clusterIP: None`.
119+
Instead of a single IP, DNS gives you a list of all Pods IPs, perfect for apps that manage connections themselves.
120+
121+
122+
## Working with labels effectively
123+
124+
[Labels](/docs/concepts/overview/working-with-objects/labels/) are key/value pairs that are attached to objects such as Pods.
125+
Labels help you organize, query and group your resources.
126+
They don't do anything by themselves, but they make everything else from Services to Deployments work together smoothly.
127+
128+
### Use semantics labels
129+
Good labels help you understand what's what, even after months later.
130+
Define and use [labels](/docs/concepts/overview/working-with-objects/labels/) that identify semantic attributes of your application or Deployment.
131+
For example;
132+
```yaml
133+
labels:
134+
app.kubernetes.io/name: myapp
135+
app.kubernetes.io/component: web
136+
tier: frontend
137+
phase: test
138+
```
139+
- `app.kubernetes.io/name` : what the app is
140+
- `tier` : which layer it belongs to (frontend/backend)
141+
- `phase` : which stage it's in (test/prod)
142+
143+
You can then use these labels to make powerful selectors.
144+
For example:
145+
```bash
146+
kubectl get pods -l tier=frontend
147+
```
148+
This will list all frontend Pods across your cluster, no matter which Deployment they came from.
149+
Basically you are not manually listing Pod names; you are just describing what you want.
150+
See the [guestbook](https://github.com/kubernetes/examples/tree/master/web/guestbook/) app for examples of this approach.
151+
152+
### Use common Kubernetes labels
153+
Kubernetes actually recommends a set of [common labels](/docs/concepts/overview/working-with-objects/common-labels/). It's a standardized way to name things across your different workloads or projects.
154+
Following this convention makes your manifests cleaner, and it means that tools such as [Headlamp](https://headlamp.dev/), [dashboard](https://github.com/kubernetes/dashboard#introduction), or third-party monitoring systems can all
155+
automatically understand what's running.
156+
157+
### Manipulate labels for debugging
158+
Since controllers (like ReplicaSets or Deployments) use labels to manage Pods, you can remove a label to “detach” a Pod temporarily.
159+
160+
Example:
161+
```bash
162+
kubectl label pod mypod app-
163+
```
164+
The `app-` part removes the label key `app`.
165+
Once that happens, the controller won’t manage that Pod anymore.
166+
It’s like isolating it for inspection, a “quarantine mode” for debugging. To interactively remove or add labels, use [`kubectl label`](/docs/reference/kubectl/generated/kubectl_label/).
167+
168+
You can then check logs, exec into it and once done, delete it manually.
169+
That’s a super underrated trick every Kubernetes engineer should know.
170+
171+
## Handy kubectl tips
172+
173+
These small tips make life much easier when you are working with multiple manifest files or clusters.
174+
175+
### Apply entire directories
176+
Instead of applying one file at a time, apply the whole folder:
177+
178+
```bash
179+
# Using server-side apply is also a good practice
180+
kubectl apply -f configs/ --server-side
181+
```
182+
This command looks for `.yaml`, `.yml` and `.json` files in that folder and applies them all together.
183+
It's faster, cleaner and helps keep things grouped by app.
184+
185+
### Use label selectors to get or delete resources
186+
You don't always need to type out resource names one by one.
187+
Instead, use [selectors](/docs/concepts/overview/working-with-objects/labels/#label-selectors) to act on entire groups at once:
188+
189+
```bash
190+
kubectl get pods -l app=myapp
191+
kubectl delete pod -l phase=test
192+
```
193+
It's especially useful in CI/CD pipelines, where you want to clean up test resources dynamically.
194+
195+
### Quickly create Deployments and Services
196+
For quick experiments, you don't always need to write a manifest. You can spin up a Deployment right from the CLI:
197+
198+
```bash
199+
kubectl create deployment webapp --image=nginx
200+
```
201+
202+
Then expose it as a Service:
203+
```bash
204+
kubectl expose deployment webapp --port=80
205+
```
206+
This is great when you just want to test something before writing full manifests.
207+
Also, see [Use a Service to Access an Application in a cluster](/docs/tasks/access-application-cluster/service-access-application-cluster/) for an example.
208+
209+
## Conclusion
210+
211+
Cleaner configuration leads to calmer cluster administrators.
212+
If you stick to a few simple habits: keep configuration simple and minimal, version-control everything,
213+
use consistent labels, and avoid relying on naked Pods, you'll save yourself hours of debugging down the road.
214+
215+
The best part?
216+
Clean configurations stay readable. Even after months, you or anyone on your team can glance at them and know exactly what’s happening.
217+

0 commit comments

Comments
 (0)