Skip to main content

FAQ

What is the difference between a container and a virtual machine?

A virtual machine virtualises hardware and runs a full guest operating system with its own kernel on top of a hypervisor, while a container virtualises the operating system and shares the host kernel, isolating only the userspace process. This makes containers far lighter: they start in milliseconds, use a fraction of the memory, and pack more densely on a host. The trade-off is weaker isolation than a VM, since a kernel vulnerability is a shared boundary; for stronger isolation you can combine containers with VMs (for example using gVisor or a microVM runtime like Kata Containers).

How do I make my Docker images smaller?

Start from a minimal base image (a distroless or slim variant, or build from scratch for static binaries), and use a multi-stage build so compilers and SDKs never reach the final image. Order Dockerfile instructions from least to most frequently changing to maximise layer cache reuse, copy only what you need (use a .dockerignore), and combine related RUN steps to avoid leftover intermediate files. Smaller images pull faster, start faster, and reduce attack surface.

When should I use Docker Compose versus Kubernetes?

Use Docker Compose for local development and simple single-host deployments where you just need to run a few services together with one command. Reach for Kubernetes when you need multi-node scheduling, self-healing, horizontal autoscaling, rolling updates, declarative reconciliation, and rich networking and storage abstractions across a cluster. Compose and Kubernetes solve different scales of problem; many teams develop with Compose and ship to Kubernetes.

Why was Docker "removed" from Kubernetes, and does my image still work?

Kubernetes removed the in-tree "dockershim" adapter in version 1.24, so the kubelet no longer talks to Docker Engine directly; it talks to CRI-compliant runtimes such as containerd or CRI-O. Your images are unaffected because they are OCI images, which containerd runs natively, and Docker itself uses containerd under the hood. The change concerns the node runtime, not the image format, so you keep building images with Docker as before.

What is a Pod and why not just run a single container?

A Pod is the smallest schedulable unit in Kubernetes and wraps one or more containers that share a network namespace and can share volumes, always co-located on one node. Most Pods run a single application container, but the model exists so tightly coupled helpers (a sidecar proxy, a log shipper) can share the same network and storage as the main container. Kubernetes schedules, scales, and networks Pods rather than bare containers, which is why even a single container runs inside one.

How do I expose my application running in Kubernetes to the outside world?

Inside the cluster, a ClusterIP Service gives Pods a stable virtual IP and DNS name. To reach it from outside you can use a NodePort (opens a port on every node), a LoadBalancer Service (provisions an external load balancer, typically in a cloud), or, for HTTP/HTTPS, an Ingress with an Ingress controller that provides host- and path-based routing and TLS termination. For richer L4/L7 routing the newer Gateway API is the evolving successor to Ingress.

What is the difference between a liveness probe and a readiness probe?

A liveness probe tells Kubernetes whether a container is still healthy; when it fails, the kubelet restarts the container, which recovers it from deadlocks or hung states. A readiness probe tells Kubernetes whether the container is ready to serve traffic; when it fails, the Pod is removed from Service endpoints but is not restarted, so it stops receiving requests until it recovers. Use readiness for "don't send traffic yet" and liveness for "this is broken, restart it"; misconfiguring liveness as readiness can cause needless restart loops.

How do resource requests and limits actually affect my Pods?

A request is what the scheduler reserves when placing the Pod, so it determines where the Pod can fit and contributes to its Quality of Service class. A limit is the hard ceiling at run time: exceeding the memory limit gets the container OOM-killed, and exceeding the CPU limit gets it throttled rather than killed. Setting requests equal to limits gives the Guaranteed QoS class and the most predictable behaviour; omitting requests lets Pods be scheduled onto overcommitted nodes and evicted first under pressure.

How should I store configuration and secrets in Kubernetes?

Put non-sensitive configuration in ConfigMaps and inject it as environment variables or mounted files, keeping configuration out of the image so the same image runs in every environment. Put sensitive values in Secrets, but be aware that by default Secrets are only base64-encoded in etcd, not encrypted, so enable encryption at rest, restrict access with RBAC, and consider an external secrets manager. Never bake credentials into the image or commit them to Git.

What is the difference between a Deployment and a StatefulSet?

A Deployment manages stateless, interchangeable replicas and is the default for web apps and APIs; Pods are fungible and can be replaced in any order. A StatefulSet gives each Pod a stable, ordered identity and its own persistent storage that follows it across rescheduling, which is what databases and clustered systems need. Choose a Deployment unless your workload requires stable network identity, ordered startup, or per-replica persistent volumes.

How do rolling updates achieve zero downtime?

A Deployment's rolling update creates a new ReplicaSet and shifts Pods from old to new gradually, governed by maxSurge (how many extra Pods may be created) and maxUnavailable (how many may be down at once). Readiness probes are essential: new Pods only receive traffic once they report ready, and old Pods are removed only as new ones become available. Combined with a PodDisruptionBudget, this lets you deploy and tolerate node maintenance without dropping requests, and you can roll back to a previous ReplicaSet if the new version misbehaves.

How do I persist data for a container or Pod?

In Docker, use a named volume rather than writing to the container's writable layer, since the writable layer is discarded when the container is removed; bind mounts are convenient for development but tie data to a host path. In Kubernetes, a Pod requests storage with a PersistentVolumeClaim, which binds to a PersistentVolume; a StorageClass can provision the underlying disk dynamically. For workloads that need per-replica durable storage with stable identity, use a StatefulSet with a volumeClaimTemplate.

Why is my Pod stuck in Pending, CrashLoopBackOff, or ImagePullBackOff?

Pending usually means the scheduler cannot place the Pod: insufficient CPU/memory on any node, an unsatisfiable affinity or taint rule, or an unbound PersistentVolumeClaim. CrashLoopBackOff means the container starts and exits repeatedly, so check the logs and the exit code (137 indicates an OOM kill), and review liveness probe settings. ImagePullBackOff means the node cannot fetch the image, typically a wrong image name or tag, a missing imagePullSecret, or registry connectivity; kubectl describe pod shows the precise event in each case.

How do containers in a cluster talk to each other securely?

Kubernetes gives every Pod its own IP on a flat network so any Pod can reach any other by default, with in-cluster DNS resolving Service names. To restrict that, apply NetworkPolicies (enforced by a capable CNI such as Calico or Cilium) that allow only the ingress and egress you intend, following least privilege. For authenticated, encrypted service-to-service traffic and fine-grained policy, a service mesh (Istio, Linkerd) adds mutual TLS and L7 controls on top.

What is Helm and when do I need it?

Helm is the de facto package manager for Kubernetes: it bundles a set of templated manifests into a versioned chart, parameterised by a values file, so one chart deploys to many environments and can be upgraded or rolled back as a release. You need it when you install third-party applications (most ship a chart) or when you want to template and version your own manifests across dev, staging, and production. Alternatives for templating include Kustomize, which patches plain YAML without a templating language.

What are some essential Docker image security practices?

Run the container as a non-root user, pin base images by digest rather than a mutable tag, and keep images minimal so there is less to exploit and patch. Scan images for known vulnerabilities in CI, never embed secrets in layers (use BuildKit secret mounts or runtime injection), and set a read-only root filesystem with dropped Linux capabilities where possible. In Kubernetes, enforce these with a securityContext (runAsNonRoot, readOnlyRootFilesystem, drop ALL capabilities) and admission policies such as Pod Security Standards.