Chapters

10 Edge Container Orchestration: Images and Kubernetes

design-patterns
soa
container
orchestration

10.1 Start With the Decision

A Dockerfile should build the same service each time. Pin the base, copy only what runs, and state the startup command.

10.2 Route Overview

This is part 2 of 2. Review Edge Container Orchestration: Workload Contracts for the preceding evidence.

10.3 Learning Objectives

  • Test dockerfile baseline with a concrete scenario and pass criteria.
  • Validate references with a concrete scenario and pass criteria.

10.4 Chapter Roadmap

  • Dockerfile Baseline
  • Kubernetes Workload Pattern
  • Scaling Rule of Thumb
  • Knowledge Check: HPA and Readiness
  • Rollout and Rollback Behavior
  • Edge Orchestration Choices
  • K3s and KubeEdge in Context
  • Knowledge Check: Edge Autonomy
  • Service Mesh for IoT
  • Knowledge Check: Mesh Tradeoff
  • Checkpoint: Runtime Choice
  • Event-Driven Workloads
  • Deployment Review Checklist
  • Try It: Build a Rollout Review Note
  • Common Pitfalls
  • 1. Treating Kubernetes as a substitute for service design
  • 2. Making every health check return success
  • 3. Using CPU as the only scaling signal
  • 4. Running stateful services as if they were stateless
  • 5. Adding service mesh before the team can operate it
  • Label the Diagram
  • Code Challenge
  • Summary
  • Key Takeaway
  • Knowledge Check
  • Quiz: Container Orchestration Review
  • Interactive Quiz: Match Orchestration Concepts
  • Interactive Quiz: Sequence the Deployment Review
  • Try It Yourself
  • Exercise: Review an IoT Deployment Manifest
  • References
  • What’s Next
  • Navigation

10.5 Dockerfile Baseline

The container image should be boring, repeatable, and environment-neutral.

FROM python:3.12-slim

WORKDIR /app
COPY requirements.txt .
RUN pip install --no-cache-dir -r requirements.txt

COPY src/ ./src/

RUN useradd --create-home appuser
USER appuser

EXPOSE 8080
CMD ["python", "-m", "src.telemetry_ingest"]

10.5.1 Good Image Signals

  • Dependencies are pinned and rebuilt by CI.
  • The process does not run as root.
  • The image has no deployment secrets.
  • Runtime configuration is supplied by the platform.
  • Logs go to standard output for collection.

10.5.2 Image Smells

  • latest is used for production.
  • Credentials appear in build arguments or source files.
  • The image changes behavior based on hidden local files.
  • Health checks are missing or only check the process ID.
  • One image contains unrelated services.

10.6 Kubernetes Workload Pattern

Kubernetes commonly represents a stateless IoT service as a Deployment, a Service, and optional autoscaling policy.

Inspect Figure 10.1 before reading the manifest so each object has an operational purpose. The picture shows the request path and the scaling loop together, helping distinguish stable service access from the replaceable pods that implement it.

Kubernetes IoT orchestration diagram showing ingress controller routing traffic to pods with horizontal pod autoscaler scaling based on load
Figure 10.1: Kubernetes orchestration for IoT: Ingress routes traffic, HPA scales pods based on load

Follow Figure 10.1 from ingress to the stable Service and then to the pod replicas. Next trace the metric signal back through the horizontal autoscaler, which changes replica count rather than changing the client contract. This connects the YAML to the running operations narrative: routing, health, resources, and scaling need explicit objects and observable evidence.

10.6.1 Deployment and Service

This example keeps the manifest compact so the important contract is visible.

apiVersion: apps/v1
kind: Deployment
metadata:
  name: telemetry-ingest
  labels:
    app.kubernetes.io/name: telemetry-ingest
spec:
  replicas: 3
  selector:
    matchLabels:
      app.kubernetes.io/name: telemetry-ingest
  template:
    metadata:
      labels:
        app.kubernetes.io/name: telemetry-ingest
    spec:
      containers:
        - name: service
          image: ghcr.io/acme/telemetry-ingest:1.4.0
          ports:
            - containerPort: 8080
          envFrom:
            - configMapRef:
                name: telemetry-ingest-config
          volumeMounts:
            - name: device-ca
              mountPath: /var/run/iot-ca
              readOnly: true
          resources:
            requests:
              cpu: 250m
              memory: 256Mi
            limits:
              memory: 512Mi
          startupProbe:
            httpGet:
              path: /startup
              port: 8080
            failureThreshold: 12
            periodSeconds: 5
          readinessProbe:
            httpGet:
              path: /ready
              port: 8080
            periodSeconds: 5
          livenessProbe:
            httpGet:
              path: /live
              port: 8080
            periodSeconds: 20
      volumes:
        - name: device-ca
          secret:
            secretName: telemetry-device-ca
---
apiVersion: v1
kind: Service
metadata:
  name: telemetry-ingest
spec:
  selector:
    app.kubernetes.io/name: telemetry-ingest
  ports:
    - port: 80
      targetPort: 8080

10.6.2 Deployment

Keeps the desired number of replicas available and performs controlled updates through ReplicaSets.

10.6.3 Service

Gives clients a stable virtual address while pods are created, replaced, and rescheduled.

10.6.4 Probes

Separate startup, readiness, and liveness so Kubernetes does not send traffic too early or restart a slow-starting service unnecessarily.

10.6.5 Autoscaling

The Horizontal Pod Autoscaler can scale a Deployment based on resource metrics or custom metrics. In IoT systems, CPU is often a late signal; queue depth, broker lag, request latency, or dropped-message rate may be better leading indicators.

apiVersion: autoscaling/v2
kind: HorizontalPodAutoscaler
metadata:
  name: telemetry-ingest
spec:
  scaleTargetRef:
    apiVersion: apps/v1
    kind: Deployment
    name: telemetry-ingest
  minReplicas: 3
  maxReplicas: 12
  metrics:
    - type: Resource
      resource:
        name: cpu
        target:
          type: Utilization
          averageUtilization: 65
Scaling Rule of Thumb

Use resource metrics when they actually track demand. Use queue or broker metrics when the service can be overwhelmed before CPU rises. In either case, test the full path: metric collection, autoscaler reaction, image pull, startup, readiness, and load balancer update.

10.7 Rollout and Rollback Behavior

Rolling updates are useful only when the new version is observable and reversible.

Build CI creates an immutable image and attaches provenance, security scan results, and a changelog.

Deploy The Deployment updates pods gradually while readiness gates protect the Service endpoint set.

Observe Operators watch errors, latency, restarts, broker lag, and device command success rate.

Decide The release continues, pauses, rolls back, or shifts only a small percentage of traffic.

10.7.1 Rollout Signals

  • Error rate stays within the service objective.
  • Device reconnects do not spike.
  • Broker lag clears after a burst.
  • New pods do not restart repeatedly.
  • The old version remains available during the transition.

10.7.2 Rollout Smells

  • A database migration must finish before old pods can work.
  • Readiness is always true.
  • The only rollback plan is rebuilding an older image.
  • Operators cannot tell which version handled a failing request.
  • Long-running device sessions are dropped during each update.

10.8 Edge Orchestration Choices

Edge deployments add constraints that cloud clusters usually hide: power cycles, weak links, local storage, limited maintenance windows, and hardware that may be shared with gateways, brokers, or local analytics.

Inspect Figure 10.2 to see where central release control ends and site autonomy begins. That boundary matters before selecting an edge orchestrator because images, desired state, cached artifacts, and local recovery do not share the same connectivity assumptions.

Edge container deployment diagram showing a central registry publishing images to several edge nodes that run gateway, analytics, and local service containers
Figure 10.2: Edge container deployment across a registry and site nodes

Read Figure 10.2 from the central registry outward to each site, then inspect the gateway, analytics, and local-service workloads within a node. Distribution is centrally coordinated, but execution and recovery must continue locally when the link fails. This brings the chapter back to its governing choice: the platform must match real power, storage, connectivity, and field-support constraints.

10.8.1 Single Gateway

Prefer a simple supervisor or lightweight Kubernetes when the site has a small fixed workload. Keep the operational model simple enough that field teams can recover the gateway.

10.8.2 Store, Factory, or Campus

Use an edge cluster when several services must coordinate locally and the site needs controlled updates, observability, and local failover.

10.8.3 Large Edge Fleet

Use a cloud-managed edge platform when many nodes need policy, workload updates, inventory, and status reporting from one control plane.

10.8.4 Disconnected Operation

Choose an edge approach that caches desired state and keeps local workloads running when the cloud control plane cannot be reached.

K3s and KubeEdge in Context

K3s is a lightweight Kubernetes distribution for environments where a smaller Kubernetes footprint is useful. KubeEdge extends cloud-native orchestration toward edge scenarios where edge nodes, devices, and cloud control need to coordinate across less reliable networks. Validate both against your hardware, network, update cadence, observability requirements, and support model.

10.9 Service Mesh for IoT

A service mesh moves service-to-service concerns into infrastructure: identity, mutual TLS, traffic policy, retries, telemetry, and sometimes authorization.

Inspect Figure 10.3 before treating that infrastructure as a universal improvement. It makes the extra control plane and per-workload proxy path visible, allowing the security and resource costs to be weighed against consistent identity, policy, and telemetry.

Service mesh architecture showing a control plane configuring sidecar proxies for device, telemetry, analytics, alert, command, and user services
Figure 10.3: Service mesh architecture with control plane and sidecar proxies

Read Figure 10.3 from the control plane to the sidecars, then follow a service call through both proxies before it reaches the peer workload. The mesh can authenticate and observe that hop, but the applications still own domain authorization and payload meaning. This ordered reading connects mesh adoption to the chapter’s recurring requirement for explicit operational boundaries.

10.9.1 Good Fit

Use mesh when many services communicate inside a cluster and teams need consistent mTLS, traffic policy, observability, and service identity without reimplementing those concerns in every codebase.

10.9.2 Weak Fit

Avoid mesh when the gateway is highly constrained, the service count is small, the team cannot operate the control plane, or application-level TLS and simple metrics solve the real requirement.

10.9.3 Edge Caution

Sidecars and mesh control planes consume resources and add operational complexity. Test them on the actual edge hardware and workload, not only in a cloud staging cluster.

10.9.4 Security Boundary

Mesh mTLS helps service-to-service identity and encryption. It does not replace device identity, authorization design, API schema validation, secret rotation, or secure firmware practice. Review the boundary from the workload outward: the sidecar can authenticate the peer service and protect transport, while the application must still authorize the requested action and validate its data. Operators must also rotate mesh credentials and observe policy failures. This distinction connects the mesh decision to the running narrative by keeping infrastructure guarantees separate from domain and device security claims.

Blueprint BinaCheckpoint: Runtime Choice
  • You now know how to compare cloud Kubernetes, lightweight edge Kubernetes, KubeEdge-style management, and simpler supervisors against the workload.
  • You now know that service mesh earns its place only when identity, mTLS, traffic policy, telemetry, and team ownership justify the overhead.
  • You now know that event-driven workloads still need orchestration around producers, brokers, consumers, health, scale, and rollout signals.

10.10 Event-Driven Workloads

IoT systems often combine request-response APIs with event streams. Orchestration should respect that difference.

Inspect Figure 10.4 to locate the durable event backbone before assigning scaling responsibilities. The point is to see why producers and consumers can change independently while the broker carries routing, buffering, and lag evidence between them.

Event-driven architecture diagram showing IoT services communicating through publish-subscribe messaging for loose coupling
Figure 10.4: Event-driven architecture: Loose coupling through publish-subscribe messaging

Follow Figure 10.4 from producers into publish-subscribe messaging and then outward to each consumer class. Producers do not wait for every analytics, storage, or notification service; consumers progress at their own rate, while broker depth and lag expose pressure. The connection to orchestration is precise: scale and recover the surrounding workloads without pretending the orchestrator replaces messaging semantics.

10.10.1 Producers

Gateways, ingestion services, and device managers publish telemetry, command status, lifecycle changes, and alerts without knowing every consumer.

10.10.2 Brokers

MQTT brokers, Kafka, or other message platforms buffer, route, retain, and expose consumer lag or queue depth as scaling signals.

10.10.3 Consumers

Analytics, rules, storage, dashboards, and notification services scale independently according to their own lag, throughput, and latency targets.

10.10.4 Orchestrator Role

Kubernetes does not replace the broker. It keeps producers and consumers healthy, configured, discoverable, and scalable around the event backbone.

10.11 Deployment Review Checklist

Use this before sending an IoT service into production.

Image: Is the image immutable, scanned, reproducible, and free of secrets?

Configuration: Can the same image run in development, staging, cloud, and edge with external configuration?

Secrets: Are credentials mounted or injected from a secret manager, and is rotation tested?

Health: Do startup, readiness, and liveness probes reflect real service state?

Resources: Are requests and limits based on measured load rather than guesses?

Scaling: Does the scaling metric lead demand early enough to prevent dropped messages?

State: Can pods be replaced without losing device state, command state, or buffered telemetry?

Rollout: Is rollback fast, documented, and observable through service-level metrics?

Edge: What happens during power loss, WAN loss, clock drift, and a partial update?

Try It: Build a Rollout Review Note

Before approving a container rollout, write a short review note for one IoT workload. Keep it specific enough that another reviewer could replay the decision.

Review fieldWhat to record
WorkloadService name, container image tag, environment, and owner
ReadinessThe dependency checks that must pass before traffic reaches the pod
CapacityCPU, memory, broker lag, queue depth, or latency measurements behind the initial requests and scaling metric
Rollout guardThe metric, alert, or user-visible symptom that would pause or roll back the release
Edge behaviorWhat the workload should do during WAN loss, power recovery, or a partial update

Deliverable: a five-row review note plus one sentence explaining whether the rollout is ready, needs more proof, or should stay in staging.

Common Pitfalls

Kubernetes can restart a failing pod, but it cannot make a service idempotent, prevent duplicate device commands, design database migrations, or decide which messages are safe to retry. Keep application-level reliability patterns in the service design.

If readiness always returns success, clients may hit pods that have not loaded certificates, connected to a broker, or warmed a cache. If liveness fails during normal slow startup, Kubernetes can restart the pod repeatedly. Give each probe a clear meaning.

An ingestion service can fall behind because broker lag grows, database writes slow down, or downstream calls time out. CPU may remain moderate until the backlog is already serious. Add workload-specific metrics where needed.

Telemetry caches, brokers, databases, and local edge queues need storage, backup, retention, and upgrade plans. A Deployment is not automatically the right workload primitive for state.

Mesh can be valuable, but it introduces certificates, policy, sidecars or node proxies, upgrades, dashboards, and failure modes. Validate the benefit before placing it on constrained edge systems or small service sets.

10.12 Label the Diagram

10.13 Code Challenge

10.14 Summary

  • Containers make IoT services portable, but orchestration makes them operable.
  • A good workload contract includes image, configuration, secrets, probes, resources, scaling, and rollout rules.
  • Kubernetes is a strong fit for connected cloud and data-center services; edge deployments need an autonomy and supportability check.
  • Service mesh can centralize mTLS and traffic policy, but it is not free infrastructure.
  • Event-driven services scale best when orchestration uses broker lag, queue depth, and service-level health signals rather than only generic CPU.
Key Takeaway

Use orchestration to make service behavior explicit. The platform can only automate what the workload declares: how to start, when it is ready, how much capacity it needs, how it is discovered, and what safe rollout looks like.

10.15 Knowledge Check

10.16 Try It Yourself

Pick one IoT service from a project or lab and write a one-page deployment review.

  1. Identify the container image, exposed port, configuration inputs, and secret inputs.
  2. Define startup, readiness, and liveness checks in plain language before writing YAML.
  3. Choose initial CPU and memory requests based on a small local load test.
  4. Decide whether autoscaling should use CPU, queue depth, broker lag, or request latency.
  5. Write the rollback trigger: what metric or symptom means the rollout must stop?
  6. For an edge deployment, describe what should happen during WAN loss and power recovery.

10.17 References

10.18 What’s Next

10.18.1 Review the SOA Foundation

SOA and Microservices Fundamentals explains why service boundaries should map to durable capabilities before they become containers.

10.18.2 Strengthen API Contracts

SOA API Design and Discovery shows how clients find services and survive version changes.

10.18.3 Add Runtime Resilience

SOA Resilience Patterns covers timeouts, retries, circuit breakers, and bulkheads that orchestration cannot replace.

10.18.4 Model Device Lifecycles

State Machine Patterns shows how to keep device and command state explicit during deployment changes.

10.20 Continue Your Route

This final part closes the route from Dockerfile Baseline through Navigation. Return to Edge Container Orchestration: Workload Contracts or continue from the design-patterns module index.