DevOps

Chapter 8
Containers, Kubernetes, and Cloud-Native Architecture

Bachelors Program in Computer Applications
DevOps   •   Bachelor

Containers, Kubernetes, and Cloud-Native Architecture

Introduction

Modern software is expected to be released rapidly, operate reliably under changing demand, and run consistently across development, testing, and production environments. Traditional deployment methods often fail to provide this consistency because applications depend on operating-system libraries, configuration files, network services, and particular runtime versions. Containers address this problem by packaging an application with its dependencies into a portable execution unit. Kubernetes extends this idea by coordinating many containers across a cluster of machines.

Containers and Kubernetes are important foundations of cloud-native computing, but they are not synonymous with cloud computing. A cloud-native system uses automation, service decomposition, elastic infrastructure, observability, resilience engineering, and loosely coupled interfaces to exploit the characteristics of cloud platforms. Containers may support such systems, but good architecture also requires appropriate data management, security, governance, and operational discipline.

Learning Objectives

After completing this chapter, a student should be able to:

  • explain the difference between virtualization, containers, and serverless computing;
  • build secure and efficient container images using a Dockerfile;
  • describe image registries, tags, digests, and supply-chain controls;
  • explain Kubernetes architecture and common resources;
  • configure service discovery, scaling, health checking, and resilience;
  • evaluate microservices and serverless architectures;
  • identify cloud-native design trade-offs and governance concerns; and
  • apply these concepts to a realistic application deployment.

1. Containers as an Operating-System Abstraction

A container is an isolated process, or group of processes, that shares the host operating system kernel while having an apparently separate filesystem, process space, network environment, and resource limits. Linux containers commonly rely on namespaces for isolation and control groups (cgroups) for resource accounting and limitation. A container is therefore not a lightweight virtual machine: it does not normally include a complete guest kernel.

A virtual machine (VM) includes a guest operating system running on virtualized hardware supplied by a hypervisor. This provides stronger operating-system isolation but usually consumes more memory and has a longer startup time. Containers generally start faster and use fewer resources, while VMs can run different kernels and operating systems on the same physical host.

CharacteristicVirtual machineContainer
Isolation boundaryGuest operating system and virtual hardwareProcess and kernel isolation
KernelSeparate guest kernelShared host kernel
StartupUsually slowerUsually faster
Typical unitComplete machine environmentApplication process and dependencies
Main riskVM escape or guest compromiseContainer or kernel escape

Isolation is not identical to security. A container that runs as root, requests excessive privileges, mounts sensitive host paths, or uses an untrusted image can create serious risks. Containers should therefore be combined with least privilege, image scanning, network controls, secrets management, and host hardening.

2. Images, Layers, and Registries

A container image is an immutable package containing application code, runtime libraries, metadata, and a filesystem description. Images are commonly built as layers. Each instruction in a Dockerfile may create a layer, and layers can be reused between images. Layer reuse reduces transfer and build time, although it does not eliminate the need for security scanning.

A simplified Dockerfile for a Python web service is:

FROM python:3.12-slim
WORKDIR /app
COPY requirements.txt .
RUN pip install --no-cache-dir -r requirements.txt
COPY . .
USER 10001
EXPOSE 8080
CMD ["python", "app.py"]

The FROM instruction selects a base image. WORKDIR sets the working directory. Copying dependency declarations before application source can improve build-cache reuse. USER avoids running the application as root. EXPOSE documents the intended port; it does not itself publish that port. CMD supplies the default process command.

A production Dockerfile should be designed carefully:

  1. Select a maintained and appropriately small base image.
  2. Pin dependencies or use a lock file where reproducibility is required.
  3. Use a .dockerignore file to exclude credentials, build output, and unnecessary files.
  4. Avoid embedding secrets in image layers because deleted secrets may remain in image history.
  5. Run one primary foreground process per container unless a deliberate supervisor design is used.
  6. Use a non-root user and remove unnecessary packages.
  7. Add a health endpoint or health-check mechanism where appropriate.
  8. Scan the image and its dependencies before release.
  9. Generate a software bill of materials (SBOM) for traceability.
  10. Prefer multi-stage builds when a compiler or build tool is not needed at runtime.

For example, a compiled application can be built in one stage and copied into a smaller runtime stage:

FROM golang:1.22 AS build
WORKDIR /src
COPY . .
RUN go build -o /out/service ./cmd/service

FROM gcr.io/distroless/static-debian12
COPY --from=build /out/service /service
USER nonroot:nonroot
ENTRYPOINT ["/service"]

An image reference may contain a registry, repository, tag, and digest. For example, registry.example.com/payments/api:2.4.1 identifies a tagged image. Tags are human-friendly but mutable unless a registry policy prevents overwriting. A digest, such as a cryptographic content identifier, refers to exact image content. Production deployments should often use signed images and digest pinning, while tags remain useful for human workflow and release channels.

A registry stores and distributes images. Public registries are convenient but require trust evaluation. Private registries support access control, audit records, retention policies, vulnerability scanning, and organizational ownership. A secure delivery pipeline normally builds an image, tests it, scans it, signs it, stores it in a registry, and deploys an approved immutable reference.

3. Orchestration and Kubernetes Architecture

Running one container manually is simple. Operating hundreds of replicas across machines requires scheduling, networking, health management, rollout control, and reconciliation. Container orchestration automates these activities.

Kubernetes is a declarative orchestration platform. A user specifies a desired state, such as “run three replicas of this application,” and controllers repeatedly compare actual state with desired state and take corrective action. This reconciliation model is central to Kubernetes.

A Kubernetes cluster contains a control plane and worker nodes. The control plane commonly includes:

  • the API server, which exposes the Kubernetes API;
  • a persistent key-value store, commonly etcd, containing cluster state;
  • the scheduler, which selects suitable nodes for unscheduled Pods;
  • controller managers, which implement control loops; and
  • optional cloud-controller components for cloud-provider integration.

Worker nodes run the container runtime, a node agent called kubelet, and networking components. A Pod is the smallest deployable Kubernetes unit. It may contain one or more tightly coupled containers that share network identity and selected storage. Most application Pods contain one main container, while sidecar containers may provide supporting functions such as proxying or log transformation.

A Deployment is a higher-level resource for managing replicated, stateless Pods. It creates ReplicaSets and supports rolling updates and rollback. A StatefulSet is designed for applications requiring stable identities or ordered behavior, although stateful systems still require careful storage and recovery design. A DaemonSet places a Pod on selected nodes, often for monitoring or log collection. A Job runs work to completion, and a CronJob creates Jobs on a schedule.

The following conceptual relationship is important:

Deployment → ReplicaSet → Pods → Containers
       ↓
   controlled by Kubernetes controllers
       ↓
 Service → stable virtual endpoint → selected Pods

4. Kubernetes Resources and Configuration

Kubernetes resources are commonly described in YAML. A simplified Deployment is:

apiVersion: apps/v1
kind: Deployment
metadata:
  name: catalog
spec:
  replicas: 3
  selector:
    matchLabels:
      app: catalog
  template:
    metadata:
      labels:
        app: catalog
    spec:
      containers:
        - name: catalog
          image: registry.example.com/catalog:2.1.0
          ports:
            - containerPort: 8080
          resources:
            requests:
              cpu: "250m"
              memory: "256Mi"
            limits:
              cpu: "1"
              memory: "512Mi"

The selector connects a Deployment to its Pods through labels. A CPU request of 250m means one-quarter of a CPU core as a scheduling quantity; it is not a guaranteed constant processing rate. A limit constrains resource use according to platform behavior. Requests help the scheduler place Pods, while limits help prevent one workload from consuming unlimited resources. Poorly chosen requests can cause inefficient packing or scheduling failures.

Configuration should be separated from the image. ConfigMaps hold non-confidential configuration, while Secrets are intended for confidential values. However, a Secret is not automatically safe merely because it has that name; access permissions, encryption at rest, rotation, and external secret-management systems remain important.

Namespaces provide a logical partition for names, access control, quotas, and operational ownership. They are not always a strong security boundary by themselves. Role-Based Access Control (RBAC) should grant the minimum permissions required by users and service accounts.

5. Service Discovery and Networking

Pod IP addresses are ephemeral. A Kubernetes Service provides a stable virtual endpoint and selects Pods using labels. Common service types include:

  • ClusterIP, for access inside the cluster;
  • NodePort, which exposes a port on cluster nodes;
  • LoadBalancer, which requests an external load balancer where supported; and
  • headless Services, which can expose individual Pod addresses for client-side discovery.

Cluster DNS allows applications to locate Services by names such as catalog.default.svc.cluster.local. This avoids hard-coding changing Pod addresses.

An Ingress or Gateway resource can route external HTTP(S) traffic to internal Services. It may perform host-based routing, path-based routing, TLS termination, and traffic policy. The precise features depend on the chosen controller or gateway implementation.

NetworkPolicies can restrict which Pods may communicate. A default-deny approach followed by explicit allow rules is generally safer than allowing unrestricted east-west traffic. Policies must be tested because a syntactically valid policy can still block required operations or fail to protect traffic if the network implementation does not enforce it as expected.

6. Health, Scaling, and Resilience

Kubernetes distinguishes several health concepts. A startup probe gives a slow-starting application time to initialize. A readiness probe indicates whether a Pod should receive traffic. A liveness probe indicates whether the process is unhealthy enough to restart. Confusing liveness and readiness can create cascading failures: if a temporary dependency failure causes liveness to fail, Kubernetes may repeatedly restart otherwise recoverable applications.

Horizontal Pod Autoscaling (HPA) changes the number of replicas according to observed metrics such as CPU utilization or application-level demand. If average observed CPU utilization is 70%, the target is 50%, and the current replica count is 4, a simplified proportional estimate is:

Nnew = ceil(Ncurrent × Ucurrent ÷ Utarget)

Here, Ncurrent is the current replica count, Ucurrent is measured utilization, Utarget is target utilization, and ceil rounds upward. Thus, Nnew = ceil(4 × 0.70 ÷ 0.50) = ceil(5.6) = 6. This is an explanatory proportional model, not a complete description of the Kubernetes HPA algorithm. Actual behavior includes stabilization windows, metric delays, readiness, tolerance, and policy limits. The ratio is dimensionless because both utilization values represent the same unit, such as a fraction of requested CPU.

Vertical scaling changes resource requests and limits. Cluster autoscaling adds or removes worker nodes when Pods cannot be scheduled or capacity is underused. Autoscaling cannot solve every performance problem: a database bottleneck, lock contention, external API limit, or inefficient algorithm may remain unchanged when replicas increase.

Resilience requires more than replica counts. Important techniques include:

  • multiple availability zones where appropriate;
  • graceful shutdown and connection draining;
  • timeouts on network calls;
  • bounded retries with exponential backoff and jitter;
  • circuit breakers for failing dependencies;
  • idempotent operations for safe retries;
  • queue-based load leveling;
  • Pod disruption budgets for planned maintenance; and
  • backups, restoration tests, and disaster-recovery procedures.

A retry must be designed carefully. Retrying a non-idempotent payment request without an idempotency key could charge a customer twice. Conversely, failing to retry a transient network error could unnecessarily reduce availability. Reliability is therefore a property of the complete interaction, not merely of an individual Pod.

Observability combines logs, metrics, and traces. Logs explain events, metrics reveal trends and saturation, and distributed traces show a request across services. Correlation identifiers help connect these signals. Monitoring should measure user-facing service-level indicators such as latency, error rate, and availability rather than only infrastructure utilization.

7. Microservices and Cloud-Native Architecture

A microservice is a relatively small service organized around a business capability and communicating through a network contract. Microservices can enable independent deployment, team autonomy, and technology flexibility. They also introduce distributed-systems costs: network latency, partial failure, data consistency challenges, versioned APIs, operational complexity, and increased observability requirements.

A modular monolith may be a better starting point when the domain is not understood, the team is small, or independent scaling is unnecessary. Decomposition should follow business boundaries and ownership rather than arbitrary technical layers. Each service should have a clear responsibility, stable interface, and explicit data ownership.

Common communication styles include synchronous REST or gRPC calls and asynchronous messaging through queues or event streams. Synchronous calls are straightforward but couple availability and latency. Asynchronous communication can improve decoupling and load handling, but it introduces eventual consistency, duplicate delivery, ordering questions, and more complex monitoring.

Cloud-native architecture often includes:

  • immutable, automated builds;
  • infrastructure as code;
  • continuous integration and delivery;
  • declarative deployment;
  • automated observability;
  • elastic resource management;
  • managed platform services; and
  • failure-aware design.

The twelve-factor principles, including configuration through the environment, stateless processes, disposable instances, and logs treated as event streams, remain useful guidance, though they must be adapted for stateful and security-sensitive systems.

8. Serverless Computing

Serverless computing is a cloud execution model in which the provider manages much of the infrastructure and charges according to execution, requests, or allocated resources. Function-as-a-Service (FaaS) platforms run event-triggered functions. Serverless containers provide a similar operational model for containerized workloads.

Advantages include rapid deployment, automatic scaling, reduced server administration, and potentially efficient cost for sporadic workloads. Limitations include cold-start latency, execution-duration limits, provider-specific interfaces, observability challenges, concurrency controls, and possible vendor lock-in. A serverless function should generally be stateless, small enough to test, and explicit about external state such as databases or object stores.

Serverless is not automatically cheaper. Cost depends on invocation frequency, execution duration, memory allocation, networking, storage, observability, and related managed services. A continuously busy workload may be more economical on reserved or dedicated capacity. Architecture decisions should use measured workload characteristics rather than fashion.

9. Applied Case: A Containerized University Registration Platform

Background

This illustrative case concerns a university registration platform used by students, faculty, and administrators. It contains a web interface, course catalogue, registration service, payment integration, notification service, and relational database.

Problem

The original application runs on two manually configured servers. Releases require downtime, traffic increases sharply at semester registration, and inconsistent server libraries produce deployment failures. A server failure can interrupt registration for many users.

Analysis

The team first identifies service boundaries and dependencies. The web interface and catalogue are largely stateless and can be replicated. Registration requires transactional data and must protect against duplicate requests. The database is stateful and cannot be treated as disposable. Payment and email providers are external dependencies with rate limits and possible outages.

Approach and Solution

The team creates reproducible images using multi-stage builds, non-root execution, dependency locking, and vulnerability scanning. Images are stored in a private registry and deployed by digest. Kubernetes Deployments manage the web and catalogue services. Services provide stable discovery, while an Ingress exposes the web endpoint.

Readiness probes prevent traffic from reaching an instance before it has loaded configuration. Liveness probes detect genuine deadlocks rather than temporary dependency failures. Horizontal scaling is based on CPU and request latency, with minimum and maximum replica limits. A queue absorbs bursts of notification work.

The registration service uses idempotency keys for client retries and database transactions for seat allocation. Database backups are automated and restoration is tested. RBAC limits deployment permissions, NetworkPolicies restrict service communication, and secrets are supplied through an external secret-management mechanism. Dashboards show registration latency, rejected requests, queue depth, database saturation, and error rates.

Outcome

The platform can release application changes with rolling updates and can add stateless replicas during registration periods. Failures in notification processing no longer block the primary registration transaction. The database remains a carefully managed stateful dependency rather than being incorrectly assumed to scale like a web Pod.

Learning Points

The case demonstrates that Kubernetes improves deployment and operational consistency but does not automatically solve data integrity, capacity planning, or domain design. Successful cloud-native architecture combines containers, automation, security, observability, and appropriate treatment of state.

10. Trade-offs, Governance, and Best Practices

Cloud-native systems create a trade-off between agility and complexity. More services may allow independent releases but increase network calls and operational overhead. More replicas may improve availability but increase cost and database pressure. Managed services reduce maintenance but may introduce contractual dependency and portability concerns.

Security should be continuous across the software supply chain. Organizations should control who can build and deploy images, verify provenance, scan dependencies, sign artifacts, rotate credentials, and record audit events. Admission policies can reject images with forbidden registries, missing signatures, excessive privileges, or absent resource specifications.

Compliance may require data residency, retention controls, encryption, access reviews, and evidence of change management. Containers do not remove these responsibilities. Personally identifiable information should be minimized, access should be logged appropriately, and test environments should not receive production data without approved protection and masking.

A practical operating checklist includes:

  • define ownership for every service and resource;
  • version application code, infrastructure, and deployment configuration;
  • use automated tests and progressive delivery;
  • pin and verify production image versions;
  • set requests, limits, and quotas based on measurements;
  • use least-privilege RBAC and network segmentation;
  • design explicit health, timeout, retry, and shutdown behavior;
  • test backup restoration and failure scenarios;
  • monitor user-facing indicators and set actionable alerts; and
  • document recovery objectives and operational runbooks.

Contemporary developments include platform engineering, internal developer platforms, policy as code, confidential computing, software supply-chain frameworks, service meshes, and workload scheduling for AI accelerators. These tools can be valuable, but each introduces operational and learning costs. A service mesh, for example, may standardize traffic security and telemetry while also adding proxies, configuration complexity, and new failure modes. Technology should therefore be selected to address a demonstrated problem.

Chapter Summary

Containers package applications and dependencies into portable, isolated execution units, while sharing the host kernel. Images are built from layers, stored in registries, and should be reproducible, scanned, signed, and deployed using trustworthy immutable references. Kubernetes provides declarative orchestration through a control plane, worker nodes, Pods, controllers, Deployments, Services, and related resources.

Services provide stable discovery for ephemeral Pods. Probes, resource requests, autoscaling, rolling updates, and disruption controls support reliable operation, but resilience also requires timeouts, idempotency, observability, backups, and failure testing. Microservices can improve independent ownership and deployment, yet they introduce distributed-systems complexity; a modular monolith may be preferable in some contexts. Serverless computing reduces infrastructure administration but has constraints involving latency, cost, limits, portability, and provider dependence.

Cloud-native design is therefore not a checklist of products. It is a disciplined approach that combines automation, declarative infrastructure, security, observability, elastic capacity, and careful analysis of state, failure, cost, and organizational capability.

Key Terms

Container: An isolated process environment that shares the host operating-system kernel.

Container image: An immutable package containing application code, dependencies, and filesystem metadata.

Dockerfile: A declarative file containing instructions for building a container image.

Layer: A reusable filesystem change within an image.

Registry: A repository used to store and distribute container images.

Digest: A content-derived identifier referring to exact image content.

Kubernetes: A platform for declarative container orchestration.

Pod: Kubernetes’ smallest deployable unit, containing one or more containers.

Deployment: A Kubernetes resource that manages replicated, usually stateless, Pods.

Service: A stable virtual network endpoint selecting Kubernetes Pods.

Namespace: A logical Kubernetes partition used for organization, access control, and quotas.

ConfigMap: A Kubernetes resource for non-confidential configuration.

Secret: A Kubernetes resource intended for confidential values, requiring additional protection.

Readiness probe: A health check indicating whether a Pod should receive traffic.

Liveness probe: A health check indicating whether a container should be restarted.

Horizontal Pod Autoscaler: A controller that adjusts replica count using observed metrics.

Microservice: A service organized around a focused business capability and network contract.

Serverless computing: A model in which the provider manages much of the execution infrastructure.

Observability: The ability to understand system behavior through logs, metrics, and traces.

Infrastructure as code: The management of infrastructure through versioned, machine-readable definitions.

Review Questions

Short Answer Questions

  1. How does a container differ from a virtual machine?
  2. What is the purpose of a container registry?
  3. Why are Kubernetes Services needed when Pod IP addresses exist?
  4. Distinguish readiness probes from liveness probes.
  5. State two advantages and two limitations of microservices.

Long Answer Questions

  1. Explain the main components of a Kubernetes cluster and their responsibilities.
  2. Describe best practices for building and securing production container images.
  3. Explain how Deployments, ReplicaSets, Pods, and Services work together.
  4. Discuss the resilience techniques required for a distributed cloud-native application.
  5. Compare containers, virtual machines, and serverless computing in terms of control, portability, scalability, and operational responsibility.

Analytical / Application Questions

  1. A web service has four replicas and average CPU utilization of 70%, while its target is 50%. Using the simplified proportional model Nnew = ceil(Ncurrent × Ucurrent ÷ Utarget), estimate the new replica count and explain why the actual autoscaler may behave differently.
  2. Design a Kubernetes deployment approach for a university registration service that must survive traffic spikes, avoid duplicate seat allocation, and protect student data. Identify at least four resources or controls you would use.
  3. A team proposes splitting a small monolithic application into fifteen microservices immediately. Evaluate the proposal and recommend criteria for deciding whether decomposition is justified.

Multiple Choice Questions with Answers

Question 1

Which statement best describes a container?

A. A complete guest operating system running on virtual hardware

B. An isolated process environment that normally shares the host kernel

C. A physical server dedicated to one application

D. A database backup format

Correct Answer: B. An isolated process environment that normally shares the host kernel

Question 2

What is the primary purpose of a container registry?

A. To schedule Pods onto Kubernetes nodes

B. To provide DNS for application requests

C. To store and distribute container images

D. To replace application source control

Correct Answer: C. To store and distribute container images

Question 3

Which Kubernetes resource provides a stable endpoint for a changing set of Pods?

A. Service

B. ConfigMap

C. Job

D. Namespace

Correct Answer: A. Service

Question 4

What does a readiness probe primarily determine?

A. Whether an image has vulnerabilities

B. Whether a Pod should receive traffic

C. Whether a node needs more memory

D. Whether a container image should be rebuilt

Correct Answer: B. Whether a Pod should receive traffic

Question 5

Why should production deployments often use image digests rather than only tags?

A. Digests identify exact image content

B. Digests automatically reduce CPU usage

C. Digests create Kubernetes namespaces

D. Digests eliminate the need for testing

Correct Answer: A. Digests identify exact image content

Question 6

A Deployment manages which lower-level resource to maintain replicated Pods?

A. Ingress

B. ReplicaSet

C. Secret

D. NetworkPolicy

Correct Answer: B. ReplicaSet

Question 7

If current replicas are 4, utilization is 70%, and the target is 50%, what is the simplified proportional estimate using Nnew = ceil(Ncurrent × Ucurrent ÷ Utarget)?

A. 3 replicas

B. 4 replicas

C. 5 replicas

D. 6 replicas

Correct Answer: D. 6 replicas

Question 8

Which practice helps prevent duplicate effects when a distributed request is retried?

A. Removing all timeouts

B. Using idempotency keys where appropriate

C. Running every container as root

D. Disabling observability

Correct Answer: B. Using idempotency keys where appropriate

Question 9

Which statement about Kubernetes Secrets is most accurate?

A. They are automatically secure in every deployment

B. They are intended for confidential values but still require access control and protection

C. They can only store public configuration

D. They permanently encrypt all application traffic

Correct Answer: B. They are intended for confidential values but still require access control and protection

Question 10

Which is a common trade-off of microservices?

A. They eliminate network failures

B. They always reduce total operational complexity

C. They can enable independent deployment but introduce distributed-systems complexity

D. They require every service to use the same programming language

Correct Answer: C. They can enable independent deployment but introduce distributed-systems complexity

DevOps
Chapter 8 of 15