Skip to main content

Typical actions in Kubernetes

Kubernetes Header

There's a handful of operations that show up over and over when running a cluster: running scheduled tasks, controlling where pods land and granting permissions to a ServiceAccount. This guide collects the patterns we use day to day, with copy-pasteable syntax.

Running CronJobs

A CronJob runs a Job on a cron-style schedule. It's useful for backups, cleanup, reports, syncs, etc.

apiVersion: batch/v1
kind: CronJob
metadata:
name: daily-backup
spec:
schedule: "0 2 * * *" # 02:00 every day
successfulJobsHistoryLimit: 3
failedJobsHistoryLimit: 1
jobTemplate:
spec:
template:
spec:
restartPolicy: OnFailure
containers:
- name: backup
image: yourcompany/backup:1.2
args: ["/scripts/backup.sh"]

Sidecar pattern

If your pod's main application already ships with the dependencies you need for the task (database CLI, credentials, VPN connection…), you can reuse that same image as a sidecar inside the CronJob:

containers:
- name: app
image: yourcompany/app:1.2
- name: cron-runner
image: yourcompany/app:1.2 # same image, different command
command: ["/bin/sh", "-c", "/app/run-maintenance.sh"]

This avoids maintaining two images with redundant configuration.

Topology Keys and pod placement

Nodes carry labels (kubernetes.io/hostname, topology.kubernetes.io/zone, node-role.kubernetes.io/worker, etc.). Those keys are the topology keys the scheduler uses to decide where to place pods.

Three typical uses:

  • Spread across zones with topologySpreadConstraints:

    topologySpreadConstraints:
    - maxSkew: 1
    topologyKey: topology.kubernetes.io/zone
    whenUnsatisfiable: ScheduleAnyway
    labelSelector:
    matchLabels:
    app: api
  • Prevent two replicas from landing on the same node with anti-affinity:

    affinity:
    podAntiAffinity:
    requiredDuringSchedulingIgnoredDuringExecution:
    - labelSelector:
    matchLabels: { app: api }
    topologyKey: kubernetes.io/hostname
  • Force a pod to run next to another with affinity, using the same topologyKey (same node, same zone, etc.).

Mental rule: topologyKey defines the grouping unit (node, zone, rack). The label selector defines who the rule applies to.

RoleBinding from the command line

To bind an existing Role to a ServiceAccount without writing YAML:

kubectl -n <ns> create rolebinding <binding-name> \
--role=<role-name> \
--serviceaccount=<ns>:<sa-name>

Real example: grant process-sa the permissions of the processor Role inside the data namespace:

kubectl -n data create rolebinding process \
--role=processor \
--serviceaccount=data:process-sa

Useful variants:

# Bind a ClusterRole to a user inside a namespace
kubectl -n app create rolebinding admin-binding \
--clusterrole=admin \
--user=[email protected]

# Bind a ClusterRole to a group cluster-wide
kubectl create clusterrolebinding view-all \
--clusterrole=view \
--group=auditors

Remember to add --dry-run=client -o yaml to save the manifest instead of applying it directly; that way you can version it in git.

Final cheatsheet

I want to…Command
Schedule periodic taskskubectl create cronjob name --image=img --schedule="..."
See node labelskubectl get nodes --show-labels
Top resources per nodekubectl top nodes
Top resources per podkubectl top pods -A
Sort by CPUkubectl top pods -A --sort-by=cpu
Validate permissionskubectl auth can-i <verb> <res> --as=...

Mastering these actions covers maybe 80% of the day-to-day work on a cluster.