Helm, kubectl Cheat Sheet & Best Practices

Package apps with Helm, deploy with GitOps, secure clusters with RBAC, and keep a kubectl cheat sheet at hand. Plus a production checklist for every workload.

Intermediate⏱ 5 min readLesson 8 of 8#kubernetes#helm#kubectl#gitops#rbac#best-practices

Part 1: Helm, the package manager

The big idea

Installing an app by hand means writing a Deployment, a Service, an Ingress, a ConfigMap, a Secret, an HPA… and copying them all for each environment with small changes. Helm is like npm for Kubernetes: it packages those YAML files into a chart with templates and values, so you can install, upgrade and roll back with one command.

Helm: a chart plus values renders into Kubernetes manifestsHelm: a chart plus values renders into Kubernetes manifests

Helm termMeaningnpm analogy
ChartA package of templated Kubernetes YAMLA package
ValuesSettings that fill the templates (values.yaml)Config options
ReleaseOne installed instance of a chartAn installed dependency
RepositoryWhere charts are publishedThe npm registry

Using existing charts

helm repo add bitnami https://charts.bitnami.com/bitnami
helm install my-redis bitnami/redis --namespace cache --create-namespace --set auth.enabled=true
helm list -A
helm upgrade my-redis bitnami/redis -f my-redis-values.yaml
helm rollback my-redis 1
helm uninstall my-redis -n cache

Your own chart

shop-api/
β”œβ”€β”€ Chart.yaml          # name, version
β”œβ”€β”€ values.yaml         # defaults
β”œβ”€β”€ values-prod.yaml    # production overrides
└── templates/
    β”œβ”€β”€ deployment.yaml
    β”œβ”€β”€ service.yaml
    β”œβ”€β”€ ingress.yaml
    └── hpa.yaml
# templates/deployment.yaml (excerpt)
apiVersion: apps/v1
kind: Deployment
metadata:
  name: {{ .Release.Name }}
spec:
  replicas: {{ .Values.replicaCount }}
  template:
    spec:
      containers:
        - name: api
          image: "{{ .Values.image.repository }}:{{ .Values.image.tag }}"
          resources:
            {{- toYaml .Values.resources | nindent 12 }}
# values.yaml                         # values-prod.yaml
replicaCount: 1                       # replicaCount: 5
image:                                # image:
  repository: registry.example.com/shop-api
  tag: "1.9.0"                        #   tag: "1.9.0"
resources:                            # resources:
  requests: { cpu: 100m, memory: 128Mi }  #   requests: { cpu: 500m, memory: 512Mi }
helm upgrade --install shop-api ./shop-api -f values-prod.yaml -n prod
helm template ./shop-api -f values-prod.yaml   # render locally to inspect the YAML

Alternative: Kustomize (built into kubectl apply -k) layers plain-YAML patches per environment instead of templates. Simpler for small differences; Helm is better for distributing reusable packages.

Part 2: GitOps

Instead of running kubectl apply from laptops, the desired state lives in git, and an operator in the cluster (Argo CD or Flux) continuously syncs the cluster to match.

Drawing diagram…

βœ… Every change is reviewed and versioned; rollback = git revert; the cluster self-corrects manual drift; and nobody needs production credentials on their laptop.

Part 3: Security basics

RBAC: who can do what

apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata: { name: read-pods, namespace: team-shop }
rules:
  - apiGroups: [""]
    resources: ["pods", "pods/log"]
    verbs: ["get", "list", "watch"]
---
apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata: { name: devs-read-pods, namespace: team-shop }
subjects: [{ kind: Group, name: shop-developers }]
roleRef: { kind: Role, name: read-pods, apiGroup: rbac.authorization.k8s.io }
Drawing diagram…

Role + RoleBinding apply within a namespace; ClusterRole + ClusterRoleBinding apply cluster-wide. Follow least privilege.

Pod security essentials

securityContext:
  runAsNonRoot: true
  runAsUser: 10001
  allowPrivilegeEscalation: false
  readOnlyRootFilesystem: true
  capabilities: { drop: ["ALL"] }

Plus: scan images, pull only from trusted registries, use NetworkPolicies, keep Secrets in a vault, and enforce the Pod Security Standards (restricted profile) per namespace.

Part 4: kubectl cheat sheet

TaskCommand
Apply YAMLkubectl apply -f app.yaml / -f dir/ / -k overlay/
List thingskubectl get pods,svc,deploy -n team-shop -o wide
Watch livekubectl get pods -w
Details + eventskubectl describe pod <name>
Logskubectl logs <pod> [-c container] [-f] [--previous]
Logs of all pods of an appkubectl logs -l app=shop-api --tail=50
Shell into a containerkubectl exec -it <pod> -- sh
Port-forwardkubectl port-forward svc/shop-api 8080:80
Scalekubectl scale deploy/shop-api --replicas=5
Update imagekubectl set image deploy/shop-api api=repo/shop-api:1.9.1
Rollout status / undokubectl rollout status deploy/shop-api / kubectl rollout undo deploy/shop-api
Restart podskubectl rollout restart deploy/shop-api
Resource usagekubectl top pods / kubectl top nodes
Recent eventskubectl get events --sort-by=.lastTimestamp
Dry run + diffkubectl diff -f app.yaml
Generate YAMLkubectl create deploy web --image=nginx --dry-run=client -o yaml
Explain a fieldkubectl explain deployment.spec.strategy
Switch namespacekubectl config set-context --current --namespace=team-shop
Drain a nodekubectl drain <node> --ignore-daemonsets

πŸ’‘ Handy tools: k9s (a terminal UI), kubectx/kubens (fast context and namespace switching), stern (tail logs from many pods), Lens (a desktop UI).

Part 5: Production checklist for every workload

Drawing diagram…
  • At least 2 replicas, spread across nodes and zones
  • Readiness and liveness probes (and startup, if boot is slow)
  • Resource requests on every container, memory limits set
  • HPA configured, and a PodDisruptionBudget
  • Graceful SIGTERM handling
  • Image pinned by version (or digest), scanned, pulled from a trusted registry
  • Runs as non-root with a restrictive securityContext
  • Config in ConfigMaps, secrets from a secret manager
  • NetworkPolicy limiting who can reach it
  • Logs to stdout in JSON, metrics exposed, alerts defined
  • Manifests in git, deployed through GitOps

Key takeaways

  • Helm packages Kubernetes YAML as reusable, configurable charts (install, upgrade, rollback); Kustomize patches plain YAML.
  • GitOps (Argo CD, Flux) keeps the cluster in sync with git: reviewed, versioned, self-healing deploys.
  • Secure with RBAC (least privilege), a restrictive securityContext, NetworkPolicies and a secret manager.
  • Keep the kubectl cheat sheet close; describe, logs --previous and get events solve most problems.
  • Run through the production checklist for every workload.