From 79802e60c0b59dd6c153e1d48b7ba961beeec289 Mon Sep 17 00:00:00 2001 From: Quetzalli Date: Tue, 3 Feb 2026 23:48:06 +0100 Subject: [PATCH 01/13] draft 1 of new k8 docs --- .../aws/enterprise/kubernetes/concepts.md | 100 ++++++ .../kubernetes/deploy-helm-chart.md | 245 +++++++++++++++ .../docs/aws/enterprise/kubernetes/faq.md | 285 ++++++++++++++++++ .../docs/aws/enterprise/kubernetes/index.md | 54 ++++ .../{ => kubernetes}/kubernetes-executor.md | 2 +- .../kubernetes/kubernetes-operator.md | 266 ++++++++++++++++ 6 files changed, 951 insertions(+), 1 deletion(-) create mode 100644 src/content/docs/aws/enterprise/kubernetes/concepts.md create mode 100644 src/content/docs/aws/enterprise/kubernetes/deploy-helm-chart.md create mode 100644 src/content/docs/aws/enterprise/kubernetes/faq.md create mode 100644 src/content/docs/aws/enterprise/kubernetes/index.md rename src/content/docs/aws/enterprise/{ => kubernetes}/kubernetes-executor.md (99%) create mode 100644 src/content/docs/aws/enterprise/kubernetes/kubernetes-operator.md diff --git a/src/content/docs/aws/enterprise/kubernetes/concepts.md b/src/content/docs/aws/enterprise/kubernetes/concepts.md new file mode 100644 index 00000000..669ab019 --- /dev/null +++ b/src/content/docs/aws/enterprise/kubernetes/concepts.md @@ -0,0 +1,100 @@ +--- +title: Concepts +description: Concepts & Architecture +template: doc +sidebar: + order: 2 +tags: ["Enterprise"] +--- + +## Concepts & Architecture + +This conceptual guide explains how LocalStack runs inside a Kubernetes cluster, how workloads are executed, and how networking and DNS behave in a Kubernetes-based deployment. + + +## How the LocalStack pod works + +The LocalStack pod runs the LocalStack runtime and acts as the central coordinator for all emulated AWS services within the cluster. + +Its primary responsibilities include: + +* Exposing the LocalStack edge endpoint and AWS service API ports +* Receiving and routing incoming AWS API requests +* Orchestrating services that require additional compute (for example Lambda, Glue, ECS, and EC2) +* Managing the lifecycle of compute workloads spawned on behalf of AWS services + +From a Kubernetes perspective, the LocalStack pod is a standard pod that fully participates in cluster networking. It is typically exposed through a Kubernetes `Service`, and all AWS API interactions—whether from inside or outside the cluster—are routed through this pod. + + +## Execution modes + +LocalStack supports two execution modes for running compute workloads: + +* Docker executor +* Kubernetes-native executor + +### Docker executor + +The Docker executor runs workloads as containers started via a Docker runtime that is accessible from the LocalStack pod. This provides a simple, self-contained execution model without Kubernetes-level scheduling. + +However, Kubernetes does not provide a Docker daemon inside pods by default. To use the Docker executor in Kubernetes, the LocalStack pod must be given access to a Docker-compatible runtime (commonly via a Docker-in-Docker sidecar), which adds complexity and security concerns. + +### Kubernetes-native executor + +The Kubernetes-native executor runs workloads as Kubernetes pods. In this mode, LocalStack communicates directly with the Kubernetes API to create, manage, and clean up pods on demand. + +This execution mode provides stronger isolation, better security, and full integration with Kubernetes scheduling, resource limits, and lifecycle management. + +The execution mode is configured using the `CONTAINER_RUNTIME` environment variable. + + +## Child pods + +For compute-oriented AWS services, LocalStack can execute workloads either within the LocalStack pod itself or as separate Kubernetes pods. + +When the Kubernetes-native executor is enabled, LocalStack launches compute workloads as dedicated Kubernetes pods (referred to here as *child pods*). These include: + +* Lambda function invocations +* Glue jobs +* ECS tasks and Batch jobs +* EC2 instances +* RDS databases +* Apache Airflow workflows +* Amazon Managed Service for Apache Flink +* Amazon DocumentDB databases +* Redis instances +* CodeBuild containers + +For example, each Glue job run or ECS task invocation results in a new pod created from the workload’s configured runtime image and resource requirements. + +These child pods execute independently of the LocalStack pod. Kubernetes is responsible for scheduling them, enforcing resource limits, and managing their lifecycle. Most child pods are short-lived and terminate once the workload completes, though some services (such as Lambda) may keep pods running for longer periods. + + +## Networking model + +LocalStack runs as a standard Kubernetes pod and is accessed through a Kubernetes `Service` that exposes the edge API endpoint and any additional service ports. + +Other pods within the cluster communicate with LocalStack through this Service using normal Kubernetes DNS resolution and cluster networking. + +When the Kubernetes-native executor is enabled, child pods communicate with LocalStack in the same way, by sending API requests over the cluster network to the LocalStack Service. + + +## DNS behavior + +LocalStack includes a DNS server capable of resolving AWS-style service endpoints. + +In a Kubernetes deployment: + +* The DNS server can be exposed through the same Kubernetes Service as the LocalStack API ports. +* This allows transparent resolution of AWS service hostnames and `localhost.localstack.cloud` to LocalStack endpoints from within the cluster. + +This enables applications running in Kubernetes to interact with LocalStack using standard AWS SDK endpoint resolution without additional configuration. + + +## When to choose the Kubernetes-native executor + +The Kubernetes-native executor should be used when LocalStack is deployed inside a Kubernetes cluster and workloads must run reliably and securely. + +It is the recommended execution mode for nearly all Kubernetes deployments, because Kubernetes does not include a Docker daemon inside pods and does not provide native Docker access. The Kubernetes-native executor aligns with Kubernetes’ workload model, enabling pod-level isolation, scheduling, and resource governance. + +The Docker executor should only be used in Kubernetes environments that have been explicitly modified to provide Docker runtime access to the LocalStack pod. Such configurations are uncommon, often restricted, and can introduce security risks. As a result, the Kubernetes-native executor is the operationally supported and recommended execution mode for Kubernetes-based deployments. diff --git a/src/content/docs/aws/enterprise/kubernetes/deploy-helm-chart.md b/src/content/docs/aws/enterprise/kubernetes/deploy-helm-chart.md new file mode 100644 index 00000000..df1d2ee3 --- /dev/null +++ b/src/content/docs/aws/enterprise/kubernetes/deploy-helm-chart.md @@ -0,0 +1,245 @@ +--- +title: Deploy with Helm +description: Install and run LocalStack on Kubernetes using the official Helm chart. +template: doc +sidebar: + order: 3 +tags: ["Enterprise"] +--- + +## Introduction + +A Helm chart is a package that bundles Kubernetes manifests into a reusable, configurable deployment unit. It makes applications easier to install, upgrade, and manage. + +Using the LocalStack Helm chart lets you deploy LocalStack to Kubernetes with set defaults while still customizing resources, persistence, networking, and environment variables through a single `values.yaml`. This approach is especially useful for teams running LocalStack in shared clusters or CI environments where repeatable, versioned deployments matter. + +## Getting Started + +This guide shows you how to install and run LocalStack on Kubernetes using the official Helm chart. It walks you through adding the Helm repository, installing and configuring LocalStack, and verifying that your deployment is running and accessible in your cluster. + +## Prerequisites + +* **Kubernetes** 1.19 or newer +* **Helm** 3.2.0 or newer +* A working Kubernetes cluster (self-hosted, managed, or local) +* `kubectl` installed and configured for your cluster +* Helm CLI installed and available in your shell `PATH` + +:::note +**Namespace note:** All commands in this guide assume installation into the **`default`** namespace. +If you’re using a different namespace: +* Add `--namespace ` (and `--create-namespace` on first install) to Helm commands +* Add `-n ` to `kubectl` commands +::: + +## Install + +### 1) Add Helm repo + +```bash +helm repo add localstack https://localstack.github.io/helm-charts +helm repo update +``` + +### 2) Install with default configuration + +```bash +helm install localstack localstack/localstack +``` + +This creates the LocalStack resources in your cluster using the chart defaults. + +:::note +### Install LocalStack Pro + +If you want to use the `localstack-pro` image, create a `values.yaml` file: + +```yaml +image: + repository: localstack/localstack-pro + +extraEnvVars: + - name: LOCALSTACK_AUTH_TOKEN + value: "" +``` + +Then install using your custom values: + +```bash +helm install localstack localstack/localstack -f values.yaml +``` + +::: + +#### Auth token from a Kubernetes Secret + +If your auth token is stored in a Kubernetes Secret, you can reference it using `valueFrom`: + +```yaml +extraEnvVars: + - name: LOCALSTACK_AUTH_TOKEN + valueFrom: + secretKeyRef: + name: + key: +``` + +## Configure + +The chart ships with sensible defaults, but most production-ish setups will want a small `values.yaml` to customize behavior. + +### View all default values + +```bash +helm show values localstack/localstack +``` + +### Override values with a custom `values.yaml` + +Create a `values.yaml` and apply it during install/upgrade: + +```bash +helm upgrade --install localstack localstack/localstack -f values.yaml +``` + +:::note +Keep the existing **parameters table** in this page (or embed it as a collapsible section). + +If you’re migrating from the existing Kubernetes docs page, preserve the parameter names and meaning so users can “diff” old vs new without re-learning. +::: + +## Verify + +### 1) Check the Pod status + +```bash +kubectl get pods +``` + +After a short time, you should see the LocalStack Pod in `Running` status: + +```text +NAME READY STATUS RESTARTS AGE +localstack-7f78c7d9cd-w4ncw 1/1 Running 0 1m9s +``` + +### 2) Optional: Port-forward to access LocalStack from localhost + +If you’re running a **local cluster** (for example, k3d) and LocalStack is not exposed externally, port-forward the service: + +```bash +kubectl port-forward svc/localstack 4566:4566 +``` + +Now verify connectivity with the AWS CLI: + +```bash +aws sts get-caller-identity --endpoint-url "http://0.0.0.0:4566" +``` + +Example response: + +```json +{ + "UserId": "AKIAIOSFODNN7EXAMPLE", + "Account": "000000000000", + "Arn": "arn:aws:iam::000000000000:root" +} +``` + +## Common customizations + +### Enable persistence + +If you want state to survive Pod restarts, enable PVC-backed persistence: + +* Set: `persistence.enabled = true` + +Example `values.yaml`: + +```yaml +persistence: + enabled: true +``` + +:::note +This is especially useful for workflows where you seed resources or rely on state across restarts. +::: + + +### Set Pod resource requests and limits + +Some environments (notably **EKS on Fargate**) may terminate Pods with low/default resource allocations. Consider setting explicit requests/limits: + +```yaml +resources: + requests: + cpu: 1 + memory: 1Gi + limits: + cpu: 2 + memory: 2Gi +``` + +### Add env vars and startup scripts + +You can inject environment variables or run a startup script to: + +* pre-configure LocalStack +* seed AWS resources +* tweak LocalStack behavior + +Use: + +* `extraEnvVars` for environment variables +* `startupScriptContent` for startup scripts + +Example pattern: + +```yaml +extraEnvVars: + - name: DEBUG + value: "1" + +startupScriptContent: | + echo "Starting up..." + # add your initialization logic here +``` + +### Install into a different namespace + +Use `--namespace` and create it on first install: + +```bash +helm install localstack localstack/localstack --namespace localstack --create-namespace +``` + +Then include the namespace on kubectl commands: + +```bash +kubectl get pods -n localstack +``` + +### Update installation + +```bash +helm repo update +helm upgrade localstack localstack/localstack +``` + +If you use a `values.yaml`: + +```bash +helm upgrade localstack localstack/localstack -f values.yaml +``` + + +### Helm chart options + +Run: + +```bash +helm show values localstack/localstack +``` + +Keep the parameter tables on this page for quick reference (especially for common settings like persistence, resources, env vars, and service exposure). \ No newline at end of file diff --git a/src/content/docs/aws/enterprise/kubernetes/faq.md b/src/content/docs/aws/enterprise/kubernetes/faq.md new file mode 100644 index 00000000..2566d87c --- /dev/null +++ b/src/content/docs/aws/enterprise/kubernetes/faq.md @@ -0,0 +1,285 @@ +--- +title: FAQ +description: FAQ +template: doc +sidebar: + order: 6 +tags: ["Enterprise"] +--- + +# Troubleshooting FAQ + +This section covers common issues when running LocalStack on Kubernetes and how to diagnose them. + + +## The LocalStack Pod won’t start + +### Potential issues + +* The auth token is invalid. If license activation fails, the Pod will terminate immediately. +* The container image cannot be pulled or takes a long time to pull. +* The Pod cannot be scheduled because no nodes have sufficient capacity or nodes are tainted. +* **When using the Operator:** the Operator cannot validate the LocalStack license and refuses to create the Pod. + +### Potential fixes + +1. Check the Pod status + + List all Pods in the cluster and locate the LocalStack Pod: + + ```bash + kubectl get pods -A + ``` + +2. Describe the Pod + + If the Pod exists, inspect it for scheduling or startup errors: + + ```bash + kubectl describe pod -n + ``` + + Errors are typically visible in the `Events:` section. + + Example: + + ```text + Back-off restarting failed container localstack in pod + ``` + + This indicates that the LocalStack container crashed after startup. + +3. Check Pod logs + + If the Pod started but then crashed: + + ```bash + kubectl logs -n + ``` + + Startup errors are usually found near the end of the log output. Debugging is similar to running LocalStack in Docker—there is nothing Kubernetes-specific about most startup failures. + +4. If the Pod was never created + + * **Helm:** check the output of `helm install` + * **Operator:** check the Operator logs: + + ```bash + kubectl logs -n localstack-operator-system deployments/localstack-operator-system + ``` + + +## Services are unavailable + +If an AWS service fails to start or respond: + +* Verify that your LocalStack license includes the service you are trying to use. +* Check the LocalStack Pod logs for license-related or service-specific errors. + +There are typically no additional Kubernetes-level actions required for this issue. + + +## DNS resolution failures + +### DNS timeouts + +If you see errors such as: + +```text +Unable to get DNS result from upstream server for domain . The DNS operation timed out. +``` + +* Check whether the upstream DNS server was detected correctly. + +* Look for a log line like: + + ```text + Determined fallback dns: + ``` + +* If the detected DNS server is not valid for your cluster, set it explicitly using the `DNS_SERVER` configuration option. + + +### `localhost.localstack.cloud` does not resolve + +* **Inside LocalStack-spawned compute Pods** + + * Ensure `DNS_ADDRESS` is **not** set to `0`. + +* **Inside other Pods in the cluster** + + * Configure the Pod DNS settings to use the LocalStack Service IP. + * Set `dnsPolicy: None` and define a custom DNS config and search domains. + * See: [https://kubernetes.io/docs/concepts/services-networking/dns-pod-service/#pod-dns-config](https://kubernetes.io/docs/concepts/services-networking/dns-pod-service/#pod-dns-config) + +* **Alternative** + + * Configure your cluster DNS (for example CoreDNS) to forward requests ending in `localhost.localstack.cloud` to the LocalStack DNS server. + * This is done automatically when using the LocalStack Operator. + + +## Permission / RBAC issues + +### Docker permission errors + +```text +Creating Docker SDK client failed +``` + +This is expected in Kubernetes. LocalStack attempts to connect to a Docker socket, which is typically unavailable in Pods. Docker is **not required** for running LocalStack on Kubernetes. + + +### Filesystem permission errors + +```text +PermissionError: [Errno 13] Permission denied: '/etc/resolv.conf' +``` + +This is expected when running LocalStack as a non-root user. Transparent endpoint injection may not work for init scripts or extensions in this case. + + +### Kubernetes API permission errors + +```text +kubernetes.client.exceptions.ApiException: (403) Reason: Forbidden +``` + +This indicates missing or incorrect RBAC permissions for the LocalStack Pod’s ServiceAccount. + +* If using the official Helm chart or Operator, update to the latest version: + + * Helm: `helm repo update localstack` + * Operator: re-apply the latest controller manifest +* If deploying LocalStack manually (not recommended), ensure the ServiceAccount role includes the required permissions: + [https://github.com/localstack/helm-charts/blob/main/charts/localstack/templates/role.yaml](https://github.com/localstack/helm-charts/blob/main/charts/localstack/templates/role.yaml) + + +## Networking problems + +### LocalStack or spawned Pods cannot connect to other cluster resources + +* Ensure the LocalStack Pod uses: + + ```yaml + dnsPolicy: ClusterFirst + ``` + + +### LocalStack cannot connect to real AWS + +Common causes: + +* **Transparent Endpoint Injection** + + * Review: [https://docs.localstack.cloud/aws/capabilities/networking/transparent-endpoint-injection/](https://docs.localstack.cloud/aws/capabilities/networking/transparent-endpoint-injection/) +* **Egress restrictions** + + * Ensure cluster network policies allow outbound internet access. + + +### Spawned Pods cannot connect to LocalStack + +* Spawned compute workloads should connect to LocalStack using: + + ```text + localhost.localstack.cloud + ``` + +* Using the Kubernetes Service name is possible, but host-based access (for example S3 virtual-host addressing) will not work. + +* Verify that the LocalStack DNS server is running (see DNS resolution failures). + + +### Other Pods cannot connect to LocalStack + +* Use the Kubernetes Service name created by Helm or the Operator. +* Confirm the LocalStack Pod is running. + +:::note +API responses returned by LocalStack include the `localhost.localstack.cloud` domain. +You can override this by setting: + +```text +LOCALSTACK_HOST= +``` +::: + + +### Cannot connect from the host machine + +* For local clusters (k3d, kind): + + * Ensure ports are forwarded correctly. + * Port `4566` (and service ports `4510–4559`) must be exposed. + * See: + + * [https://k3d.io/v5.3.0/usage/exposing_services/](https://k3d.io/v5.3.0/usage/exposing_services/) + * [https://kind.sigs.k8s.io/docs/user/configuration/#extra-port-mappings](https://kind.sigs.k8s.io/docs/user/configuration/#extra-port-mappings) + +* Alternatively, use port-forwarding: + + ```bash + kubectl port-forward -n 4566 + ``` + + +## Child containers are not spawning + +### Docker runtime errors + +```text +DockerNotAvailable: Docker not available +``` + +* Ensure `CONTAINER_RUNTIME=kubernetes` is set. +* Verify your license includes Kubernetes support. +* When using Helm, ensure `lambda.executor: kubernetes` is not overriding the runtime unintentionally. + + +### Image pull failures + +```text +ErrImagePull +``` + +This usually means the cluster restricts which images can be pulled. + +* Allow the LocalStack images in your cluster +* If you must use a custom image name or pull-through cache, see: + [https://docs.localstack.cloud/aws/capabilities/config/configuration/](https://docs.localstack.cloud/aws/capabilities/config/configuration/) + + +### Admission or security policy failures + +Errors such as: + +```text +kubernetes.utils.create_from_yaml.FailToCreateError +``` + +* Ensure you are running the latest LocalStack and Helm chart / Operator version. +* Check for: + + * Validating admission webhooks + [https://kubernetes.io/docs/reference/access-authn-authz/admission-controllers/#validatingadmissionwebhook](https://kubernetes.io/docs/reference/access-authn-authz/admission-controllers/#validatingadmissionwebhook) + * Pod Security Admission restrictions + [https://kubernetes.io/docs/concepts/security/pod-security-admission/](https://kubernetes.io/docs/concepts/security/pod-security-admission/) + + +### Child Pod timeouts + +If a child Pod is created but times out: + +* This is commonly caused by slow or blocked image pulls. +* Inspect the child Pod status and events, similar to diagnosing a LocalStack Pod startup failure. + + +## Logs to check + +* Check LocalStack Pod logs as described in **The LocalStack Pod won’t start** +* If using the Operator, also check the Operator logs: + + ```bash + kubectl logs -n localstack-operator-system deployments/localstack-operator-system + ``` + diff --git a/src/content/docs/aws/enterprise/kubernetes/index.md b/src/content/docs/aws/enterprise/kubernetes/index.md new file mode 100644 index 00000000..c55dfde2 --- /dev/null +++ b/src/content/docs/aws/enterprise/kubernetes/index.md @@ -0,0 +1,54 @@ +--- +title: Overview +description: Kubernetes with LocalStack +template: doc +sidebar: + order: 1 +tags: ["Enterprise"] +--- + +## Overview + +LocalStack is a local AWS cloud environment that emulates core AWS services for development and testing. + +When deployed on Kubernetes, services that typically spawn Docker containers (such as Lambda, ECS, or RDS) instead spawn Kubernetes pods within the same cluster. Behavior is improved by allowing dynamic scaling, isolation, and native Kubernetes orchestration. + +Supported cases: + +- Local Development Environments: Provide isolated, consistent environments for individual developers or small teams. +- CI/CD Pipeline Testing: Run end-to-end integration tests in a reproducible, cloud-like environment during CI/CD workflows. + +## Requirements: + +- K8s Cluster (k3d, minikube) +- Kubectl +- Helm +- LS helm chart +- LS operator + + +## DIY vs Helm Chart vs Operator + +| Deployment approach | Pros | Cons | +|---------------------|------|------| +| **DIY (YAML manifests)** | · Full control over Kubernetes configuration and resources | · Time-consuming to set up and maintain
· Manual updates and lifecycle management | +| **Helm chart** | · Simplifies deployment using templates and `values.yaml`
· Supports versioning, upgrades, and rollbacks
· Supports both LocalStack Community and Pro images | · Customization is limited to chart values and overrides | +| **Operator** | · Declarative, self-managed control plane
· Built-in validation, defaulting, and reconciliation logic | · Limited to the LocalStack Pro image only
· Steeper learning curve compared to Helm | + + +## Licensing + +While the LocalStack Community image can be deployed in Kubernetes, it does not support containerized service functionality required for full cloud-like behavior. Services such as Lambda, which require spawning and managing compute containers at runtime, only support pod creation with the LocalStack Pro image. The Community edition lacks the runtime capabilities needed to dynamically instantiate and orchestrate workloads in Kubernetes. + +## Help & Support + +LocalStack Pro (with a valid license) is the only version that provides: + +- Official support and integration for Kubernetes environments. +- Dynamic pod creation by services like Lambda, ECS, RDS, etc. + +Community image users: + +- Can be deployed in Kubernetes cluster for basic service emulation (e.g., S3, SQS). +- Do not receive official Kubernetes support. +- Cannot use features like Lambda execution. \ No newline at end of file diff --git a/src/content/docs/aws/enterprise/kubernetes-executor.md b/src/content/docs/aws/enterprise/kubernetes/kubernetes-executor.md similarity index 99% rename from src/content/docs/aws/enterprise/kubernetes-executor.md rename to src/content/docs/aws/enterprise/kubernetes/kubernetes-executor.md index 49eae43f..a6987e4c 100644 --- a/src/content/docs/aws/enterprise/kubernetes-executor.md +++ b/src/content/docs/aws/enterprise/kubernetes/kubernetes-executor.md @@ -3,7 +3,7 @@ title: Kubernetes Executor description: Configuring Kubernetes Executor for compute services in LocalStack Enterprise. template: doc sidebar: - order: 4 + order: 5 tags: ["Enterprise"] --- diff --git a/src/content/docs/aws/enterprise/kubernetes/kubernetes-operator.md b/src/content/docs/aws/enterprise/kubernetes/kubernetes-operator.md new file mode 100644 index 00000000..4db44968 --- /dev/null +++ b/src/content/docs/aws/enterprise/kubernetes/kubernetes-operator.md @@ -0,0 +1,266 @@ +--- +title: Deploy LocalStack Operator +description: Deploy and manage LocalStack in a Kubernetes cluster using the LocalStack Operator. +template: doc +sidebar: + order: 4 +tags: ["Enterprise"] +--- + +## Introduction + +The LocalStack Operator provides a Kubernetes-native way to deploy and manage LocalStack instances. It abstracts Kubernetes-specific configuration and automates operational tasks, making LocalStack deployments more consistent and easier to maintain. + +The Operator manages the full lifecycle of LocalStack resources and enables advanced Kubernetes integrations that are difficult to configure manually. + +## Getting started + +This guide explains how to deploy and manage LocalStack in a Kubernetes cluster using the LocalStack Operator. + + +### Advanced features + +The Operator supports the following advanced capabilities: + +* Cluster DNS configuration to correctly resolve AWS-style subdomains +* Automatic loading of Cloud Pods on startup +* Support for initialization hooks +* Simplified logging configuration +* Automatic mounting of a PersistentVolumeClaim (PVC) for the LocalStack data directory, enabling artifact caching and persistence + +### Prerequisites + +Before installing the LocalStack Operator, ensure you have: + +* A running Kubernetes cluster +* A LocalStack license that includes Kubernetes features +* An authentication token for that license + +:::note +A separate auth token must be used for each LocalStack instance. +::: + +### Deploy Operator + +The easiest way to install the Operator controller is to apply the published manifests directly from GitHub. + +```bash +# Install the latest version +kubectl apply -f https://github.com/localstack/localstack-operator/releases/latest/download/controller.yaml +``` + +To install a specific version: + +```bash +# Example: install v0.4.0 +kubectl apply -f https://github.com/localstack/localstack-operator/releases/v0.4.0/download/controller.yaml +``` + +See the Operator releases page for all available versions. + + +### Deploy LocalStack instance + +Once the Operator is running, you can deploy a LocalStack instance by creating a `LocalStack` custom resource. + +A minimal example looks like this: + +```yaml +apiVersion: api.localstack.cloud/v1alpha1 +kind: LocalStack +metadata: + name: localstack + namespace: my-namespace +spec: + image: localstack/localstack-pro:latest + dnsProvider: coredns + dnsConfigName: coredns + dnsConfigNamespace: kube-system + envFrom: + - secretRef: + name: localstack-auth-token +``` + +In this example, the LocalStack auth token is read from a Kubernetes Secret named `localstack-auth-token`. + +You can create this Secret with: + +```bash +kubectl create secret generic localstack-auth-token \ + --from-literal=LOCALSTACK_AUTH_TOKEN="$LOCALSTACK_AUTH_TOKEN" +``` + +The auth token must be available in the `LOCALSTACK_AUTH_TOKEN` environment variable when creating the Secret. + +notes::: +More advanced examples are available in the LocalStack Operator GitHub repository. +::: + +## Accessing LocalStack + +By default, the Operator creates a `ClusterIP` Service named: + +```text +localstack- +``` + +For the example above (`name: localstack`), the Service name is: + +```text +localstack-localstack +``` + +This Service exposes: + +* The LocalStack gateway port (`4566`) +* AWS service ports +* Port `53` for DNS + +Using standard Kubernetes DNS resolution, the Service can be reached at: + +* `localstack-localstack` (same namespace) +* `localstack-localstack.my-namespace` +* `localstack-localstack.my-namespace.svc.cluster.local` + +When `dnsProvider: coredns` is configured, LocalStack can also be reached through **any subdomain** of these service names. + + +## CRDs + +The LocalStack Operator introduces a `LocalStack` Custom Resource Definition (CRD) that controls how LocalStack instances are deployed and configured. + +:::Note +CRD documentation is currently maintained manually. For a full reference of available fields, see: [https://github.com/localstack/localstack-operator/blob/v0.4.0/api-docs.md](https://github.com/localstack/localstack-operator/blob/v0.4.0/api-docs.md) +::: + + +## Permissions + +The Operator manifest creates all required `Roles`, `ClusterRoles`, and `bindings`. + + +| **Kind** | **Name** | **API Groups** | **Resources** | **Verbs** | +| --- | --- | --- | --- | --- | +| **Role** | `localstack-operator-leader-election-role` | | `configmaps` | get, list, watch, create, update, patch, delete | +| | | `coordination.k8s.io` | `leases` | get, list, watch, create, update, patch, delete | +| | | | `events` | create, patch | +| **ClusterRole** | `localstack-operator-manager-role` | | `configmaps` | delete, get, list, patch, update, watch | +| | | | `events` | create, patch | +| | | | `pods`, `pods/exec`, `pods/log` | create, delete, deletecollection, get, list, patch, update, watch | +| | | | `secrets` | get, list, watch | +| | | | `serviceaccounts` | create, delete, get, list, update, watch | +| | | | `services` | create, delete, get, list, patch, update, watch | +| | | `api.localstack.cloud` | `localstacks` | create, delete, get, list, patch, update, watch | +| | | `api.localstack.cloud` | `localstacks/finalizers` | update | +| | | `api.localstack.cloud` | `localstacks/status` | get, patch, update | +| | | `apps` | `deployments` | create, delete, get, list, patch, update, watch | +| | | `apps` | `deployments/scale` | create, delete, get, list, patch, update, watch | +| | | `rbac.authorization.k8s.io` | `rolebindings`, `roles` | create, delete, list, update, watch | +| **ClusterRole** | `localstack-operator-metrics-reader` | | (nonResourceURLs: `/metrics`) | get | +| **ClusterRole** | `localstack-operator-proxy-role` | `authentication.k8s.io` | `tokenreviews` | create | +| | | `authorization.k8s.io` | `subjectaccessreviews` | create | + + +### Manager ClusterRole + +This ClusterRole allows the Operator to manage LocalStack resources and related Kubernetes objects. + +Resources include: + +* Pods (including exec and logs) +* Services +* Secrets +* Deployments +* ServiceAccounts +* LocalStack CRDs (`localstacks`, `status`, `finalizers`) +* RBAC roles and role bindings + +Verbs include: + +```text +create, delete, get, list, watch, patch, update +``` + + +### Metrics and proxy ClusterRoles + +Additional ClusterRoles are created for: + +* Reading metrics (`/metrics`) +* Authentication and authorization reviews (`tokenreviews`, `subjectaccessreviews`) + + +## DNS handling + +The LocalStack Operator configures cluster DNS to forward AWS-style subdomain requests to the LocalStack DNS server. + +This enables features such as: + +* S3 virtual-host–style addressing +* API Gateway domain name resolution + +Example from another pod in the cluster: + +```bash +aws apigatewayv2 create-api \ + --name testGatewayProxy \ + --protocol-type HTTP \ + --target "https://httpbin.org" +``` + +Example response: + +```json +{ + "ApiEndpoint": "http://1d4b6907.execute-api.localstack-localstack.my-namespace:4566", + "ApiId": "1d4b6907" +} +``` + +Calling the API: + +```bash +curl http://1d4b6907.execute-api.localstack-localstack.my-namespace:4566/json +``` + +This works without additional DNS configuration in client applications. + + +## Update + +The Operator can be upgraded by applying a newer controller manifest. + +Example: + +```bash +# Install an older version +kubectl apply -f https://github.com/localstack/localstack-operator/releases/download/v0.3.3/controller.yaml + +# Upgrade to a newer version +kubectl apply -f https://github.com/localstack/localstack-operator/releases/download/v0.4.1/controller.yaml +``` + +Kubernetes will handle rolling updates of the Operator deployment. + + +## Verify + +To verify that the Operator and LocalStack instance are running: + +```bash +kubectl get pods -n my-namespace +kubectl get localstacks -n my-namespace +``` + +Ensure that: + +* The Operator controller pod is running +* The LocalStack resource reports a healthy status +* The LocalStack Service is created + +:::note +* The LocalStack Operator is available **only with licenses that include Kubernetes features** +* Each LocalStack instance requires its **own auth token** +* The Operator supports **LocalStack Pro images only** +* DNS integration and Cloud Pod automation are Operator-exclusive features +::: \ No newline at end of file From 631500363cba0dd5f53e10fb4b8942758eca780d Mon Sep 17 00:00:00 2001 From: Quetzalli Date: Wed, 4 Feb 2026 00:04:43 +0100 Subject: [PATCH 02/13] updating astro config js file to fix updated left hand nav --- astro.config.mjs | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/astro.config.mjs b/astro.config.mjs index 1b38c0a6..b2d6c45e 100644 --- a/astro.config.mjs +++ b/astro.config.mjs @@ -440,12 +440,13 @@ export default defineConfig({ slug: 'aws/enterprise', }, { - label: 'Single Sign-On', - autogenerate: { directory: '/aws/enterprise/sso' }, + label: 'Kubernetes', + autogenerate: { directory: '/aws/enterprise/kubernetes' }, + collapsed: true, }, { - label: 'Kubernetes Executor', - slug: 'aws/enterprise/kubernetes-executor', + label: 'Single Sign-On', + autogenerate: { directory: '/aws/enterprise/sso' }, }, { label: 'Enterprise Image', From 7074a7e9811688a9d305e5e5846acaf9ef13ca68 Mon Sep 17 00:00:00 2001 From: Quetzalli Date: Thu, 12 Feb 2026 16:15:37 +0100 Subject: [PATCH 03/13] add architecture diagram --- astro.config.mjs | 2 +- public/images/aws/k8s-concepts.png | Bin 0 -> 111995 bytes .../docs/aws/enterprise/kubernetes/concepts.md | 4 +++- 3 files changed, 4 insertions(+), 2 deletions(-) create mode 100644 public/images/aws/k8s-concepts.png diff --git a/astro.config.mjs b/astro.config.mjs index b2d6c45e..bfc38a1f 100644 --- a/astro.config.mjs +++ b/astro.config.mjs @@ -441,7 +441,7 @@ export default defineConfig({ }, { label: 'Kubernetes', - autogenerate: { directory: '/aws/enterprise/kubernetes' }, + autogenerate: { directory: '/aws/enterprise/' }, collapsed: true, }, { diff --git a/public/images/aws/k8s-concepts.png b/public/images/aws/k8s-concepts.png new file mode 100644 index 0000000000000000000000000000000000000000..f8410c90dd710df74c2095a5b54bf27be4015f9a GIT binary patch literal 111995 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 Date: Thu, 12 Feb 2026 07:38:47 -0800 Subject: [PATCH 04/13] Apply suggestion from @quetzalliwrites --- src/content/docs/aws/enterprise/kubernetes/concepts.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/content/docs/aws/enterprise/kubernetes/concepts.md b/src/content/docs/aws/enterprise/kubernetes/concepts.md index 678f69ff..2f5f7a99 100644 --- a/src/content/docs/aws/enterprise/kubernetes/concepts.md +++ b/src/content/docs/aws/enterprise/kubernetes/concepts.md @@ -23,7 +23,7 @@ Its primary responsibilities include: * Orchestrating services that require additional compute (for example Lambda, Glue, ECS, and EC2) * Managing the lifecycle of compute workloads spawned on behalf of AWS services -From a Kubernetes perspective, the LocalStack pod is a standard pod that fully participates in cluster networking. It is typically exposed through a Kubernetes `Service`, and all AWS API interactions—whether from inside or outside the cluster—are routed through this pod. +From a Kubernetes perspective, the LocalStack pod is a standard pod that fully participates in cluster networking. It is typically exposed through a Kubernetes `Service`, and all AWS API interactions —whether from inside or outside the cluster— are routed through this pod. ![How the Localstack Pod works](/images/aws/k8s-concepts.png) From 1c1e9f1f003581c675cff9a99d3d4bab5734974a Mon Sep 17 00:00:00 2001 From: Quetzalli Date: Thu, 12 Feb 2026 07:39:37 -0800 Subject: [PATCH 05/13] Apply suggestion from @simonrw Co-authored-by: Simon Walker --- src/content/docs/aws/enterprise/kubernetes/concepts.md | 1 + 1 file changed, 1 insertion(+) diff --git a/src/content/docs/aws/enterprise/kubernetes/concepts.md b/src/content/docs/aws/enterprise/kubernetes/concepts.md index 2f5f7a99..53fce82f 100644 --- a/src/content/docs/aws/enterprise/kubernetes/concepts.md +++ b/src/content/docs/aws/enterprise/kubernetes/concepts.md @@ -89,6 +89,7 @@ In a Kubernetes deployment: * The DNS server can be exposed through the same Kubernetes Service as the LocalStack API ports. * This allows transparent resolution of AWS service hostnames and `localhost.localstack.cloud` to LocalStack endpoints from within the cluster. +* If a custom domain is used to refer to the LocalStack Kubernetes service (via `LOCALSTACK_HOST`) then this name and subdomains of this name are also resolved by the LocalStack DNS server This enables applications running in Kubernetes to interact with LocalStack using standard AWS SDK endpoint resolution without additional configuration. From 42bb872239321d0bf5591b1168caaf0e414b841d Mon Sep 17 00:00:00 2001 From: Quetzalli Date: Thu, 12 Feb 2026 16:45:33 +0100 Subject: [PATCH 06/13] fix headings --- src/content/docs/aws/enterprise/kubernetes/concepts.md | 2 -- src/content/docs/aws/enterprise/kubernetes/deploy-helm-chart.md | 2 -- src/content/docs/aws/enterprise/kubernetes/faq.md | 2 -- src/content/docs/aws/enterprise/kubernetes/index.md | 1 - .../docs/aws/enterprise/kubernetes/kubernetes-executor.md | 2 -- .../docs/aws/enterprise/kubernetes/kubernetes-operator.md | 2 -- 6 files changed, 11 deletions(-) diff --git a/src/content/docs/aws/enterprise/kubernetes/concepts.md b/src/content/docs/aws/enterprise/kubernetes/concepts.md index 53fce82f..e9159f68 100644 --- a/src/content/docs/aws/enterprise/kubernetes/concepts.md +++ b/src/content/docs/aws/enterprise/kubernetes/concepts.md @@ -7,8 +7,6 @@ sidebar: tags: ["Enterprise"] --- -## Concepts & Architecture - This conceptual guide explains how LocalStack runs inside a Kubernetes cluster, how workloads are executed, and how networking and DNS behave in a Kubernetes-based deployment. diff --git a/src/content/docs/aws/enterprise/kubernetes/deploy-helm-chart.md b/src/content/docs/aws/enterprise/kubernetes/deploy-helm-chart.md index df1d2ee3..6e9e0e04 100644 --- a/src/content/docs/aws/enterprise/kubernetes/deploy-helm-chart.md +++ b/src/content/docs/aws/enterprise/kubernetes/deploy-helm-chart.md @@ -7,8 +7,6 @@ sidebar: tags: ["Enterprise"] --- -## Introduction - A Helm chart is a package that bundles Kubernetes manifests into a reusable, configurable deployment unit. It makes applications easier to install, upgrade, and manage. Using the LocalStack Helm chart lets you deploy LocalStack to Kubernetes with set defaults while still customizing resources, persistence, networking, and environment variables through a single `values.yaml`. This approach is especially useful for teams running LocalStack in shared clusters or CI environments where repeatable, versioned deployments matter. diff --git a/src/content/docs/aws/enterprise/kubernetes/faq.md b/src/content/docs/aws/enterprise/kubernetes/faq.md index 2566d87c..ba29a266 100644 --- a/src/content/docs/aws/enterprise/kubernetes/faq.md +++ b/src/content/docs/aws/enterprise/kubernetes/faq.md @@ -7,8 +7,6 @@ sidebar: tags: ["Enterprise"] --- -# Troubleshooting FAQ - This section covers common issues when running LocalStack on Kubernetes and how to diagnose them. diff --git a/src/content/docs/aws/enterprise/kubernetes/index.md b/src/content/docs/aws/enterprise/kubernetes/index.md index c55dfde2..1303db77 100644 --- a/src/content/docs/aws/enterprise/kubernetes/index.md +++ b/src/content/docs/aws/enterprise/kubernetes/index.md @@ -7,7 +7,6 @@ sidebar: tags: ["Enterprise"] --- -## Overview LocalStack is a local AWS cloud environment that emulates core AWS services for development and testing. diff --git a/src/content/docs/aws/enterprise/kubernetes/kubernetes-executor.md b/src/content/docs/aws/enterprise/kubernetes/kubernetes-executor.md index a6987e4c..46a44364 100644 --- a/src/content/docs/aws/enterprise/kubernetes/kubernetes-executor.md +++ b/src/content/docs/aws/enterprise/kubernetes/kubernetes-executor.md @@ -7,8 +7,6 @@ sidebar: tags: ["Enterprise"] --- -## Introduction - LocalStack Enterprise provides a Kubernetes executor for various emulated services. It allows you to run these services as Kubernetes pods in your Kubernetes clusters. By default, LocalStack uses the `docker` backend for these services. diff --git a/src/content/docs/aws/enterprise/kubernetes/kubernetes-operator.md b/src/content/docs/aws/enterprise/kubernetes/kubernetes-operator.md index 4db44968..a1cfb95f 100644 --- a/src/content/docs/aws/enterprise/kubernetes/kubernetes-operator.md +++ b/src/content/docs/aws/enterprise/kubernetes/kubernetes-operator.md @@ -7,8 +7,6 @@ sidebar: tags: ["Enterprise"] --- -## Introduction - The LocalStack Operator provides a Kubernetes-native way to deploy and manage LocalStack instances. It abstracts Kubernetes-specific configuration and automates operational tasks, making LocalStack deployments more consistent and easier to maintain. The Operator manages the full lifecycle of LocalStack resources and enables advanced Kubernetes integrations that are difficult to configure manually. From ee77105572a98fe6b5362b23fb02507f34502e0c Mon Sep 17 00:00:00 2001 From: Quetzalli Date: Thu, 12 Feb 2026 12:04:11 -0800 Subject: [PATCH 07/13] Apply suggestions from code review Co-authored-by: Simon Walker --- .../aws/enterprise/kubernetes/concepts.md | 2 +- .../kubernetes/deploy-helm-chart.md | 10 ++++---- .../docs/aws/enterprise/kubernetes/index.md | 24 ++++++++++++------- .../kubernetes/kubernetes-operator.md | 12 +++++----- 4 files changed, 27 insertions(+), 21 deletions(-) diff --git a/src/content/docs/aws/enterprise/kubernetes/concepts.md b/src/content/docs/aws/enterprise/kubernetes/concepts.md index e9159f68..c9b35e3d 100644 --- a/src/content/docs/aws/enterprise/kubernetes/concepts.md +++ b/src/content/docs/aws/enterprise/kubernetes/concepts.md @@ -98,4 +98,4 @@ The Kubernetes-native executor should be used when LocalStack is deployed inside It is the recommended execution mode for nearly all Kubernetes deployments, because Kubernetes does not include a Docker daemon inside pods and does not provide native Docker access. The Kubernetes-native executor aligns with Kubernetes’ workload model, enabling pod-level isolation, scheduling, and resource governance. -The Docker executor should only be used in Kubernetes environments that have been explicitly modified to provide Docker runtime access to the LocalStack pod. Such configurations are uncommon, often restricted, and can introduce security risks. As a result, the Kubernetes-native executor is the operationally supported and recommended execution mode for Kubernetes-based deployments. +The Docker executor is not supported for use inside Kubernetes clusters. While it may function in environments that have been explicitly configured to expose a Docker-compatible runtime to the LocalStack pod, such setups are uncommon and may introduce security or operational complexity. For Kubernetes-based deployments, the Kubernetes-native executor is the supported and recommended execution mode. diff --git a/src/content/docs/aws/enterprise/kubernetes/deploy-helm-chart.md b/src/content/docs/aws/enterprise/kubernetes/deploy-helm-chart.md index 6e9e0e04..a76c622c 100644 --- a/src/content/docs/aws/enterprise/kubernetes/deploy-helm-chart.md +++ b/src/content/docs/aws/enterprise/kubernetes/deploy-helm-chart.md @@ -3,7 +3,7 @@ title: Deploy with Helm description: Install and run LocalStack on Kubernetes using the official Helm chart. template: doc sidebar: - order: 3 + order: 4 tags: ["Enterprise"] --- @@ -67,7 +67,6 @@ Then install using your custom values: helm install localstack localstack/localstack -f values.yaml ``` -::: #### Auth token from a Kubernetes Secret @@ -80,11 +79,10 @@ extraEnvVars: secretKeyRef: name: key: -``` ## Configure -The chart ships with sensible defaults, but most production-ish setups will want a small `values.yaml` to customize behavior. +The chart ships with sensible defaults, but most production setups will want a small `values.yaml` to customize behavior. ### View all default values @@ -167,7 +165,7 @@ This is especially useful for workflows where you seed resources or rely on stat ### Set Pod resource requests and limits -Some environments (notably **EKS on Fargate**) may terminate Pods with low/default resource allocations. Consider setting explicit requests/limits: +Some environments (notably **EKS on Fargate**) may terminate the LocalStack pod if not configured with reasonable requests/limits: ```yaml resources: @@ -179,7 +177,7 @@ resources: memory: 2Gi ``` -### Add env vars and startup scripts +### Add environment variables and startup scripts You can inject environment variables or run a startup script to: diff --git a/src/content/docs/aws/enterprise/kubernetes/index.md b/src/content/docs/aws/enterprise/kubernetes/index.md index 1303db77..1729ecb1 100644 --- a/src/content/docs/aws/enterprise/kubernetes/index.md +++ b/src/content/docs/aws/enterprise/kubernetes/index.md @@ -19,20 +19,28 @@ Supported cases: ## Requirements: -- K8s Cluster (k3d, minikube) -- Kubectl -- Helm -- LS helm chart -- LS operator +- K8s Cluster (such as k3d, minikube, EKS) +- [kubectl](https://kubernetes.io/docs/reference/kubectl/) +- (Optional) [Helm](https://helm.sh/) +- (Optional) LS helm chart +- (Optional) LS operator -## DIY vs Helm Chart vs Operator +## Deployment methods + +LocalStack can be deployed into a Kubernetes cluster using multiple methods: +* using the LocalStack Operator +* using the LocalStack helm chart +* by manually creating Kubernetes manifests + + +The table below compares these methods. | Deployment approach | Pros | Cons | |---------------------|------|------| -| **DIY (YAML manifests)** | · Full control over Kubernetes configuration and resources | · Time-consuming to set up and maintain
· Manual updates and lifecycle management | -| **Helm chart** | · Simplifies deployment using templates and `values.yaml`
· Supports versioning, upgrades, and rollbacks
· Supports both LocalStack Community and Pro images | · Customization is limited to chart values and overrides | | **Operator** | · Declarative, self-managed control plane
· Built-in validation, defaulting, and reconciliation logic | · Limited to the LocalStack Pro image only
· Steeper learning curve compared to Helm | +| **Helm chart** | · Simplifies deployment using templates and `values.yaml`
· Supports versioning, upgrades, and rollbacks
· Supports both LocalStack Community and Pro images | · Customization is limited to chart values and overrides | +| **DIY (YAML manifests)** | · Full control over Kubernetes configuration and resources | · Time-consuming to set up and maintain
· Manual updates and lifecycle management | ## Licensing diff --git a/src/content/docs/aws/enterprise/kubernetes/kubernetes-operator.md b/src/content/docs/aws/enterprise/kubernetes/kubernetes-operator.md index a1cfb95f..bdd0567c 100644 --- a/src/content/docs/aws/enterprise/kubernetes/kubernetes-operator.md +++ b/src/content/docs/aws/enterprise/kubernetes/kubernetes-operator.md @@ -3,11 +3,11 @@ title: Deploy LocalStack Operator description: Deploy and manage LocalStack in a Kubernetes cluster using the LocalStack Operator. template: doc sidebar: - order: 4 + order: 3 tags: ["Enterprise"] --- -The LocalStack Operator provides a Kubernetes-native way to deploy and manage LocalStack instances. It abstracts Kubernetes-specific configuration and automates operational tasks, making LocalStack deployments more consistent and easier to maintain. +The LocalStack Operator is our Kubernetes-native way to deploy and manage LocalStack instances. It abstracts Kubernetes-specific configuration and automates operational tasks, making LocalStack deployments more consistent and easier to maintain. It can manage multiple LocalStack instances within a cluster to provide isolated local clouds for multiple users. The Operator manages the full lifecycle of LocalStack resources and enables advanced Kubernetes integrations that are difficult to configure manually. @@ -20,7 +20,7 @@ This guide explains how to deploy and manage LocalStack in a Kubernetes cluster The Operator supports the following advanced capabilities: -* Cluster DNS configuration to correctly resolve AWS-style subdomains +* Cluster DNS configuration to correctly resolve AWS-style subdomains in the same namespace * Automatic loading of Cloud Pods on startup * Support for initialization hooks * Simplified logging configuration @@ -54,7 +54,7 @@ To install a specific version: kubectl apply -f https://github.com/localstack/localstack-operator/releases/v0.4.0/download/controller.yaml ``` -See the Operator releases page for all available versions. +See the [Operator releases page](https://github.com/localstack/localstack-operator/releases) for all available versions. ### Deploy LocalStack instance @@ -88,7 +88,7 @@ kubectl create secret generic localstack-auth-token \ --from-literal=LOCALSTACK_AUTH_TOKEN="$LOCALSTACK_AUTH_TOKEN" ``` -The auth token must be available in the `LOCALSTACK_AUTH_TOKEN` environment variable when creating the Secret. +With this example, the auth token must be available in the `LOCALSTACK_AUTH_TOKEN` environment variable when creating the Secret. notes::: More advanced examples are available in the LocalStack Operator GitHub repository. @@ -128,7 +128,7 @@ When `dnsProvider: coredns` is configured, LocalStack can also be reached throug The LocalStack Operator introduces a `LocalStack` Custom Resource Definition (CRD) that controls how LocalStack instances are deployed and configured. :::Note -CRD documentation is currently maintained manually. For a full reference of available fields, see: [https://github.com/localstack/localstack-operator/blob/v0.4.0/api-docs.md](https://github.com/localstack/localstack-operator/blob/v0.4.0/api-docs.md) +CRD documentation is currently maintained manually. For a full reference of available fields, see: [https://github.com/localstack/localstack-operator/blob/main/api-docs.md](https://github.com/localstack/localstack-operator/blob/main/api-docs.md) ::: From f39d378c1874da67da9153ffbf77590249fb5ba1 Mon Sep 17 00:00:00 2001 From: Quetzalli Date: Thu, 12 Feb 2026 12:25:11 -0800 Subject: [PATCH 08/13] Apply suggestion from @quetzalliwrites --- src/content/docs/aws/enterprise/kubernetes/concepts.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/content/docs/aws/enterprise/kubernetes/concepts.md b/src/content/docs/aws/enterprise/kubernetes/concepts.md index c9b35e3d..c8762944 100644 --- a/src/content/docs/aws/enterprise/kubernetes/concepts.md +++ b/src/content/docs/aws/enterprise/kubernetes/concepts.md @@ -92,7 +92,7 @@ In a Kubernetes deployment: This enables applications running in Kubernetes to interact with LocalStack using standard AWS SDK endpoint resolution without additional configuration. -## When to choose the Kubernetes-native executor +## Choose execution mode The Kubernetes-native executor should be used when LocalStack is deployed inside a Kubernetes cluster and workloads must run reliably and securely. From 0e6d0a4047449acbc66ca9f37d816f757d801422 Mon Sep 17 00:00:00 2001 From: Quetzalli Date: Thu, 12 Feb 2026 12:32:07 -0800 Subject: [PATCH 09/13] Apply suggestion from @quetzalliwrites --- .../docs/aws/enterprise/kubernetes/deploy-helm-chart.md | 5 ----- 1 file changed, 5 deletions(-) diff --git a/src/content/docs/aws/enterprise/kubernetes/deploy-helm-chart.md b/src/content/docs/aws/enterprise/kubernetes/deploy-helm-chart.md index a76c622c..3ce52850 100644 --- a/src/content/docs/aws/enterprise/kubernetes/deploy-helm-chart.md +++ b/src/content/docs/aws/enterprise/kubernetes/deploy-helm-chart.md @@ -98,11 +98,6 @@ Create a `values.yaml` and apply it during install/upgrade: helm upgrade --install localstack localstack/localstack -f values.yaml ``` -:::note -Keep the existing **parameters table** in this page (or embed it as a collapsible section). - -If you’re migrating from the existing Kubernetes docs page, preserve the parameter names and meaning so users can “diff” old vs new without re-learning. -::: ## Verify From 6ea5559429331cc71a2926e25dd1d339b3ba08f6 Mon Sep 17 00:00:00 2001 From: Quetzalli Date: Thu, 12 Feb 2026 12:35:07 -0800 Subject: [PATCH 10/13] fix missing code block close Updated installation instructions for LocalStack Pro and added note about customizing the chart with a values.yaml file. --- .../docs/aws/enterprise/kubernetes/deploy-helm-chart.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/content/docs/aws/enterprise/kubernetes/deploy-helm-chart.md b/src/content/docs/aws/enterprise/kubernetes/deploy-helm-chart.md index 3ce52850..a990f4b2 100644 --- a/src/content/docs/aws/enterprise/kubernetes/deploy-helm-chart.md +++ b/src/content/docs/aws/enterprise/kubernetes/deploy-helm-chart.md @@ -47,7 +47,6 @@ helm install localstack localstack/localstack This creates the LocalStack resources in your cluster using the chart defaults. -:::note ### Install LocalStack Pro If you want to use the `localstack-pro` image, create a `values.yaml` file: @@ -79,8 +78,9 @@ extraEnvVars: secretKeyRef: name: key: +``` -## Configure +## Configure chart The chart ships with sensible defaults, but most production setups will want a small `values.yaml` to customize behavior. @@ -233,4 +233,4 @@ Run: helm show values localstack/localstack ``` -Keep the parameter tables on this page for quick reference (especially for common settings like persistence, resources, env vars, and service exposure). \ No newline at end of file +Keep the parameter tables on this page for quick reference (especially for common settings like persistence, resources, env vars, and service exposure). From 3e4c677ab48b5a56a928da01bffb0d796ff2dc21 Mon Sep 17 00:00:00 2001 From: Quetzalli Date: Thu, 12 Feb 2026 12:47:36 -0800 Subject: [PATCH 11/13] Apply suggestions from code review --- src/content/docs/aws/enterprise/kubernetes/faq.md | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/content/docs/aws/enterprise/kubernetes/faq.md b/src/content/docs/aws/enterprise/kubernetes/faq.md index ba29a266..874e1688 100644 --- a/src/content/docs/aws/enterprise/kubernetes/faq.md +++ b/src/content/docs/aws/enterprise/kubernetes/faq.md @@ -165,7 +165,9 @@ This indicates missing or incorrect RBAC permissions for the LocalStack Pod’s ### LocalStack cannot connect to real AWS -Common causes: +You may want LocalStack to connect to real AWS when testing hybrid workflows, forwarding specific requests, or accessing resources that are not fully emulated locally. + +Common causes for connection failure: * **Transparent Endpoint Injection** From a3714127d9a16ddb0e5c7ff2cd24bdee38926d7a Mon Sep 17 00:00:00 2001 From: Quetzalli Date: Thu, 12 Feb 2026 12:48:52 -0800 Subject: [PATCH 12/13] add certificate error to faq Added a section on certificate issues when spawning child pods, including error details and a solution for configuring NO_PROXY. --- src/content/docs/aws/enterprise/kubernetes/faq.md | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/src/content/docs/aws/enterprise/kubernetes/faq.md b/src/content/docs/aws/enterprise/kubernetes/faq.md index 874e1688..ed1398ea 100644 --- a/src/content/docs/aws/enterprise/kubernetes/faq.md +++ b/src/content/docs/aws/enterprise/kubernetes/faq.md @@ -225,6 +225,18 @@ LOCALSTACK_HOST= ## Child containers are not spawning +### Certificate issues when spawning child pods + +If you experience the following error when creating child pods (i.e., Lambda pod failure), then your proxy settings might be applied to cluster internal communication: + +``` +localstack.services.lambda_.invocation.assignment.AssignmentException: Could not start new environment: MaxRetryError:MyHTTPSConnectionPool(host='192.168.0.1', port=443): Max retries exceeded with url: /api/v1/namespaces/ns-perf-a39e28bf-c600-498d-9ecc-41419eca1007/pods/lambda-pod-52c280f8dd194dc72bced60e190db6ef/log (Caused by SSLError(SSLCertVerificationError(1, '[SSL: CERTIFICATE_VERIFY_FAILED] certificate verify failed: unable to get local issuer certificate (_ssl.c:1032)'))) +``` + +If you are using `HTTP_PROXY` or `HTTPS_PROXY` environment variables to configure a TLS terminating proxy server (i.e., corporate environments), then you may need to add the Kubernetes API server IP address to the `NO_PROXY` environment variable. + +In the example above, add `NO_PROXY=192.168.0.1` to your pod environment variables. + ### Docker runtime errors ```text From 98a7e0f657290eea760006a862c0ba7e69e41d1f Mon Sep 17 00:00:00 2001 From: Quetzalli Date: Thu, 12 Feb 2026 13:00:20 -0800 Subject: [PATCH 13/13] Apply suggestions from code review Co-authored-by: Simon Walker --- src/content/docs/aws/enterprise/kubernetes/index.md | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/content/docs/aws/enterprise/kubernetes/index.md b/src/content/docs/aws/enterprise/kubernetes/index.md index 1729ecb1..eeb95047 100644 --- a/src/content/docs/aws/enterprise/kubernetes/index.md +++ b/src/content/docs/aws/enterprise/kubernetes/index.md @@ -10,11 +10,12 @@ tags: ["Enterprise"] LocalStack is a local AWS cloud environment that emulates core AWS services for development and testing. -When deployed on Kubernetes, services that typically spawn Docker containers (such as Lambda, ECS, or RDS) instead spawn Kubernetes pods within the same cluster. Behavior is improved by allowing dynamic scaling, isolation, and native Kubernetes orchestration. +When LocalStack is deployed on Kubernetes and configured to use the Kubernetes-native executor (by setting `CONTAINER_RUNTIME=kubernetes`), services that would normally spawn Docker containers (ie., Lambda, ECS, or RDS) instead create Kubernetes pods within the cluster. This enables dynamic scaling, isolation, and native Kubernetes orchestration. Supported cases: - Local Development Environments: Provide isolated, consistent environments for individual developers or small teams. +- Hosted Development Environments: Provide scalable and isolated development environments for teams. - CI/CD Pipeline Testing: Run end-to-end integration tests in a reproducible, cloud-like environment during CI/CD workflows. ## Requirements: @@ -38,7 +39,7 @@ The table below compares these methods. | Deployment approach | Pros | Cons | |---------------------|------|------| -| **Operator** | · Declarative, self-managed control plane
· Built-in validation, defaulting, and reconciliation logic | · Limited to the LocalStack Pro image only
· Steeper learning curve compared to Helm | +| **Operator** | · Declarative, self-managed control plane
· Built-in validation, defaulting, and reconciliation logic | · Steeper learning curve compared to Helm | | **Helm chart** | · Simplifies deployment using templates and `values.yaml`
· Supports versioning, upgrades, and rollbacks
· Supports both LocalStack Community and Pro images | · Customization is limited to chart values and overrides | | **DIY (YAML manifests)** | · Full control over Kubernetes configuration and resources | · Time-consuming to set up and maintain
· Manual updates and lifecycle management |