Page 2 of 2
Your app usually needs some settings - things like a log level, a feature flag, or a database password. You don't want to bake these into your container image, because then changing a setting means rebuilding the whole image.
Kubernetes gives you two places to store settings outside the container:
Both get handed to your app the same way - usually as environment variables, or as a file inside the container.
kubectl create configmap app-config --from-literal=LOG_LEVEL=info
kubectl create secret generic db-credentials --from-literal=DB_PASSWORD=s3cret
kubectl get configmaps
kubectl get secrets
Anything a container writes to its own filesystem disappears the moment that container is replaced. Most of the time that's fine - but sometimes you need data to actually survive, like a database's files.
kubectl get pvc # see what storage has been requested
kubectl get pv # see the actual storage available in the cluster
When you create a new Pod, something has to decide which machine it runs on. That's the scheduler's job, and by default it just picks a reasonable machine with enough free capacity.
Sometimes you want more control - say, "only run this on a machine with an SSD." You can label your machines and then tell a Pod to only run on machines with a matching label:
spec:
nodeSelector:
disktype: ssd
kubectl label node node-1 disktype=ssd # tag a machine
kubectl describe pod my-pod # if a Pod is stuck waiting, this tells you why
There are three kinds of "talking to each other" inside a cluster, and it helps to keep them separate in your head:
payments-service), the same way you'd type a website's name instead of memorizing its numeric address. Kubernetes handles the translation for you.kubectl exec -it my-pod -- wget -qO- my-service:80 # test that a Service actually responds
Two ideas matter here, and they answer two different questions.
A ServiceAccount answers "who is this Pod, as far as the cluster's own API is concerned?" Every Pod has one, whether you set it explicitly or not.
RBAC (Role-Based Access Control) answers "what is this identity actually allowed to do?" By default, nothing is allowed until you explicitly grant it - you create a Role describing a set of permissions (like "can view Pods"), then a RoleBinding to actually hand that Role to someone or something.
kubectl create serviceaccount my-app
kubectl auth can-i get pods --as=system:serviceaccount:production:my-app # check what an identity is actually allowed to do
Everything you create in Kubernetes - a Pod, a Deployment, a Service - is written the same way: as a text file describing what you want, in a format called YAML. You then hand that file to Kubernetes.
apiVersion: apps/v1
kind: Deployment
metadata:
name: web
spec:
replicas: 3
selector:
matchLabels:
app: web
template:
metadata:
labels:
app: web
spec:
containers:
- name: web
image: nginx:1.25
ports:
- containerPort: 80
Reading it top to bottom: kind says what you're creating, metadata gives it a name, and spec describes the state you want. That's the whole pattern - every Kubernetes object follows it.
One thing to watch out for: in YAML, spacing matters a lot, and it has to be spaces, never tab characters. Getting the indentation wrong is one of the most common reasons a file gets rejected or does something you didn't expect.
kubectl apply -f deployment.yaml # create it, or update it if it already exists - this is the command you'll use most
kubectl get -f deployment.yaml # check on what's described in this file
kubectl delete -f deployment.yaml # remove everything this file describes
Real scenario-based DevOps questions, hands-on practice, and clear explanations for every answer.