A scannable reference of architectural patterns the CNPE exam tests. Read top-to-bottom, or jump to a section.
Platform Architecture and Infrastructure
Provision and manage multi-cloud infrastructure using Kubernetes-native, declarative APIs.
Use Crossplane. Install cloud provider CRDs (e.g., provider-aws). Define platform abstractions with Composition and CompositeResourceDefinition (XRD).
Why: Unifies application and infrastructure management under a single control plane and GitOps workflow, abstracting provider specifics from developers.
Manage the lifecycle (create, upgrade, delete) of multiple Kubernetes clusters across different providers declaratively.
Implement Cluster API (CAPI) with relevant infrastructure providers (e.g., CAPA for AWS, CAPZ for Azure). Define clusters as Kubernetes resources in a management cluster.
Why: Treats cluster lifecycle as code, enabling GitOps for clusters themselves. CAPI MachineHealthChecks provide automated node remediation.
Provide strong isolation between tenant workloads on a shared Kubernetes platform.
Combine dedicated node pools (compute), NetworkPolicies (network), RBAC (API), ResourceQuotas (resource), and Pod Security Standards (security). Consider virtual clusters (vCluster) for control plane isolation.
Why: A defense-in-depth strategy is required. No single feature provides complete isolation. Each layer addresses a different aspect of tenancy.
Manage configurations and workloads for a large number of downstream clusters from a central point.
Designate a "hub" cluster to host platform control plane tools (ArgoCD, Flux, Crossplane, policy engines). "Spoke" clusters run workloads and are managed from the hub.
Why: Centralizes management, policy enforcement, and observability, simplifying multi-cluster operations and ensuring consistency.
Provide development teams with isolated, cluster-admin-like environments without the overhead of physical clusters.
Use vCluster. Each vCluster runs a separate K8s control plane as pods within a host cluster namespace, sharing the host worker nodes.
Why: Offers strong API-level isolation at lower cost than full clusters. The vCluster syncer materializes necessary resources on the host cluster.
Ensure disaster recovery for stateful workloads with low RPO/RTO.
Use a CSI driver that supports synchronous or asynchronous cross-region/cross-cluster data replication (e.g., Rook-Ceph, Portworx).
Why: Replication is critical for data availability in a regional failure. Local snapshots or high-performance tiers do not address cross-site DR.
Improve application availability by distributing replicas across failure domains.
Use Pod Topology Spread Constraints in workload specs. Define `topologyKey` (e.g., `topology.kubernetes.io/zone`) and `whenUnsatisfiable: ScheduleAnyway` or `DoNotSchedule`.
Why: Prevents all replicas of a service from being scheduled in a single zone or on a single node, mitigating impact from localized infrastructure failures.
Manage policies and RBAC for teams with hierarchical organizational structures.
Implement the Hierarchical Namespace Controller (HNC). Create parent-child namespace relationships to propagate RBAC, NetworkPolicies, and ResourceQuotas.
Why: HNC simplifies management by allowing platform admins to set policies at a team/org level (parent namespace) which are automatically inherited by all sub-namespaces.
GitOps and Continuous Delivery
Implement advanced, automated deployment strategies like canary or blue-green with metric-based analysis and rollback.
Use Argo Rollouts. Define a Rollout resource with a strategy (e.g., canary) that includes traffic routing configuration (for a service mesh) and an AnalysisTemplate referencing a metrics provider like Prometheus.
Why: Decouples deployment from application logic. Automates traffic shifting and analysis, safely promoting releases and automatically rolling back on failure, reducing deployment risk.
Manage secrets in a GitOps workflow without storing plaintext credentials in Git.
Use Sealed Secrets (encrypts secrets for a specific cluster) or External Secrets Operator (syncs from Vault, AWS/GCP/Azure secret managers). Commit only the encrypted secret or the reference resource to Git.
Why: Keeps sensitive data out of Git while allowing secrets to be managed declaratively as part of the GitOps workflow, maintaining a single source of truth.
Automate the creation and management of ArgoCD Applications for multiple clusters, environments, or microservices.
Use an ApplicationSet. Define a template for the Application and use a generator (e.g., cluster, git, matrix) to dynamically create Applications based on cluster lists, Git directories, or other sources.
Why: Eliminates manual Application creation, enabling scalable management of hundreds of applications or clusters from a single definition.
Provide ephemeral preview environments for developers to test changes in a pull request.
Use ArgoCD ApplicationSet with a Pull Request generator. It automatically creates an Application when a PR is opened and deletes it when the PR is closed/merged.
Why: Enables developers to validate changes in a live environment before merging, improving code quality and reducing integration issues, without manual environment management.
Manage a large, complex set of applications and platform components with ArgoCD in a structured way.
Implement the App-of-Apps pattern. A root Application manages other child Applications, which can in turn manage other Applications, creating a hierarchical structure.
Why: Provides a single entrypoint for bootstrapping a cluster or environment while allowing modular, team-based management of individual application sets.
Ensure resources are deployed in the correct order (e.g., CRDs before CRs, infrastructure before applications).
In ArgoCD, use Sync Waves and resource health checks. In Flux, use `dependsOn` in Kustomization or HelmRelease resources.
Why: Declarative systems apply resources in parallel by default. Explicit ordering mechanisms are required to manage dependencies between resources.
Implement a complete GitOps pipeline using Flux.
Combine Flux controllers: Source Controller (for Git/Helm/OCI sources), Kustomize Controller (to apply manifests), and Helm Controller (for HelmReleases). Use Notification Controller for alerts.
Why: Flux is a composable set of specialized controllers. Understanding the role of each is key to building and troubleshooting Flux-based continuous delivery.
Ensure the live cluster state continuously matches the desired state in Git, reverting any manual changes.
Configure ArgoCD Application with `syncPolicy.automated.selfHeal: true`. ArgoCD will detect drift and automatically sync to revert unauthorized changes.
Why: Self-healing is a core GitOps principle that enforces Git as the single source of truth and prevents configuration drift, which is critical for compliance and stability.
Promote application versions across environments (dev -> staging -> prod) with proper audit and approval gates.
Use separate directories or branches per environment in Git. Promote changes by creating pull requests (e.g., from staging to prod branch/directory). Enforce PR reviews.
Why: Leverages Git for audit trails and approvals. The PR process becomes the formal promotion gate, ensuring changes are reviewed before reaching production.
Implement multi-tenancy in a shared ArgoCD instance, restricting teams to their own resources.
Create ArgoCD Projects for each team. Configure projects to restrict source Git repositories, destination clusters/namespaces, and permitted resource kinds. Integrate with SSO and map groups to project roles.
Why: Projects are the primary mechanism for multi-tenant isolation and RBAC in ArgoCD, enabling secure self-service application deployment.
Platform APIs and Self-Service Capabilities
Design a self-service API for developers to provision infrastructure without needing cloud-specific knowledge.
Define a high-level API with a CompositeResourceDefinition (XRD). Implement the API with a Composition that maps the high-level fields to underlying managed resources. Developers interact with a simple Composite Resource Claim (XRC).
Why: This three-layer model (Claim -> Composition -> Managed Resource) separates the user-facing API from the implementation, providing a clean abstraction and enabling platform governance.
Enable developers to bootstrap new projects, microservices, or infrastructure declaratively and in compliance with organizational standards.
Create Backstage Software Templates. The template defines input parameters (a form UI) and a series of scaffolder actions (e.g., fetch skeleton, create Git repo, register in catalog).
Why: Automates "golden path" workflows, reducing developer cognitive load, ensuring consistency, and accelerating project setup from minutes to seconds.
Create a single, centralized place to discover all software, services, APIs, and their ownership within an organization.
Implement the Backstage Software Catalog. Ingest `catalog-info.yaml` entity descriptors from Git repositories to build a searchable graph of software components and their relationships.
Why: The catalog is the core of an IDP, providing discoverability and a foundation for other features like TechDocs, API docs, and CI/CD status visibility.
A Kubernetes operator needs to clean up external resources (e.g., cloud storage, DNS records) when a Custom Resource is deleted.
Use finalizers. In the controller, add a finalizer to the CR on creation. In the reconciliation loop, if `deletionTimestamp` is set, perform cleanup logic and then remove the finalizer.
Why: Finalizers prevent Kubernetes from deleting a resource until the controller has successfully completed its cleanup tasks, preventing orphaned external resources.
Provide Kubernetes workloads with secure, short-lived access to cloud provider APIs without managing static credentials.
Use cloud provider Workload Identity solutions (AWS IRSA, GCP Workload Identity, Azure Workload Identity). This links a Kubernetes ServiceAccount to a cloud IAM role, allowing pods to obtain temporary credentials.
Why: Eliminates the risk of long-lived static credentials. It is the most secure pattern for granting cloud permissions to pods.
Communicate the state and progress of a custom resource reconciliation back to users and automation tools.
Enable the status subresource in the CRD definition. The controller should update the status with conditions (e.g., `Type: Ready`, `Status: True`) and observed state.
Why: Separates the desired state (spec) from the observed state (status). Provides a standard, watchable mechanism for clients to understand resource health and readiness.
Evolve platform APIs (CRDs) without breaking existing clients or users.
Follow Kubernetes API versioning conventions (v1alpha1 -> v1beta1 -> v1). When introducing breaking changes, create a new version and implement a conversion webhook to translate between stored and served versions.
Why: Conversion webhooks allow the API server to serve multiple versions of a resource simultaneously while maintaining a single storage version, enabling graceful API evolution.
Observability and Operations
Create actionable alerts based on service reliability targets that balance sensitivity with avoiding alert fatigue.
Define SLOs and calculate error budgets. Implement multi-window, multi-burn-rate alerting that triggers when the rate of error budget consumption threatens the SLO.
Why: Alerting on error budget burn is more meaningful than simple threshold alerts. It directly ties alerts to user-facing impact and SLO violations.
Implement a vendor-agnostic, unified pipeline for collecting, processing, and exporting observability signals (traces, metrics, logs).
Deploy the OpenTelemetry Collector. Configure pipelines with receivers (e.g., OTLP, Jaeger), processors (e.g., batch, attributes), and exporters (e.g., Prometheus, Loki, Tempo, vendor backends).
Why: Decouples instrumentation from the observability backend, allowing the platform to switch or add backends without re-instrumenting applications. Provides a central point for processing and enrichment.
Declaratively configure Prometheus to discover and scrape metrics from Kubernetes workloads.
Use the Prometheus Operator. Create `ServiceMonitor` or `PodMonitor` Custom Resources that use label selectors to define which services or pods Prometheus should scrape.
Why: Provides a Kubernetes-native way to manage scrape configurations, integrating seamlessly with application deployments and GitOps workflows.
During an incident investigation, quickly navigate from an anomalous metric (e.g., latency spike) to the specific requests that caused it.
Use Prometheus exemplars. Instrument applications to attach trace IDs to metric observations. Configure Prometheus and Grafana to display exemplars, providing direct links from metrics to traces in a tracing backend like Tempo or Jaeger.
Why: Drastically reduces MTTR by directly linking the "what" (metric) to the "why" (trace), eliminating manual correlation efforts.
Establish a baseline for monitoring the health of any user-facing or critical service.
Monitor the four "Golden Signals": Latency (response time), Traffic (requests per second), Errors (rate of failed requests), and Saturation (resource utilization).
Why: These four signals provide a comprehensive, high-level view of service health and user experience, applicable to nearly any kind of service.
Provide teams with visibility into the cost of their Kubernetes workloads for chargeback or showback.
Deploy an open-source tool like OpenCost or Kubecost. These tools allocate cloud costs to Kubernetes resources (pods, namespaces, labels) based on their resource requests and usage.
Why: Translates infrastructure bills into meaningful, application-centric cost data, enabling teams to understand and optimize their resource consumption.
Reduce alert noise during large-scale outages by suppressing symptomatic alerts.
Configure `inhibit_rules` in Alertmanager. For example, inhibit all alerts for a specific cluster if a "ClusterUnreachable" alert is already firing.
Why: Prevents an "alert storm" by silencing lower-priority alerts that are symptoms of a higher-priority, root-cause alert, allowing on-call to focus on the real problem.
Proactively test platform and application resilience by injecting failures in a controlled manner.
Use a chaos engineering tool like Chaos Mesh or Litmus. Define experiments with a limited blast radius (e.g., specific namespaces or labels) and automated stop conditions based on SLOs or critical metrics.
Why: Moves beyond reactive incident response to proactively finding weaknesses in the system before they cause production outages.
Security and Policy Enforcement
Choose a policy engine for enforcing guardrails on a Kubernetes platform.
Choose Kyverno for Kubernetes-native YAML-based policies or OPA/Gatekeeper for a more powerful, general-purpose policy language (Rego).
Why: Kyverno has a lower barrier to entry for Kubernetes engineers. OPA/Gatekeeper is more flexible and can be used outside Kubernetes but has a steeper learning curve.
Implement platform policies that can block non-compliant resources, add default values, or automatically create related resources.
Use a policy engine like Kyverno. Use `validate` rules to block/audit, `mutate` rules to add defaults (e.g., securityContext, labels), and `generate` rules to create resources (e.g., default NetworkPolicy).
Why: Different policy types serve different purposes. Combining them allows for a robust, multi-faceted governance strategy that both enforces and helps users comply.
Enforce baseline security hardening for all pods running on the platform.
Use Pod Security Standards (PSS) via the built-in Pod Security Admission controller. Label namespaces with `pod-security.kubernetes.io/enforce=baseline` or `restricted`.
Why: PSS provides a standardized, built-in mechanism to prevent common security issues like privilege escalation and host namespace access, forming a foundational security layer.
Ensure that only trusted container images, built by the official CI/CD pipeline, can be deployed to the cluster.
Implement image signing in CI using Sigstore/Cosign. Use a policy engine (Kyverno, Gatekeeper) as an admission controller to verify image signatures against a trusted key before allowing a pod to be created.
Why: Cryptographic verification provides strong guarantees about image provenance and integrity, preventing deployment of tampered or unauthorized images.
Implement a zero-trust security model where service-to-service communication is authenticated by cryptographic workload identity, not network location.
Use SPIFFE/SPIRE to issue short-lived, rotatable cryptographic identities (SVIDs) to workloads. Enforce mutual TLS (mTLS) using a service mesh, which validates SVIDs on every request.
Why: Moves security from network perimeter controls to workload-centric identity, providing strong authentication even for internal traffic and limiting the blast radius of a compromised node or pod.
Isolate workloads at the network level, enforcing a "default-deny" posture and only allowing required communication paths.
Implement Kubernetes NetworkPolicies. Apply a default-deny policy to each namespace, then add specific ingress/egress policies that allow traffic based on pod/namespace labels.
Why: Reduces the lateral movement attack surface. Compromise of one pod does not automatically grant network access to all other services in the cluster.
Create a comprehensive and tamper-proof audit trail of all actions performed on the Kubernetes API server for security and compliance.
Enable Kubernetes audit logging on the API server. Configure an audit policy to log relevant events (e.g., all write requests). Ship audit logs to a secure, immutable storage backend or SIEM.
Why: Audit logs are essential for incident investigation, compliance reporting (e.g., PCI-DSS, SOC2), and detecting anomalous API activity.