Kubernetes and What We Support

This page defines where L7 Informatics’ responsibility for an L7|ESP deployment on Kubernetes ends and the customer’s begins. Every other Kubernetes page in this documentation should be read in light of it.

In short

  • L7 Informatics supports the L7|ESP container image and the L7|ESP Helm chart.

  • The chart is a Kubernetes chart. It installs on any conformant Kubernetes cluster: EKS, AKS, GKE, OpenShift, MicroK8s or any other.

  • The cluster, and everything it depends on, is the customer’s to build, operate and troubleshoot.

  • Deploy with the chart. Where Helm cannot be used to install, render the chart to manifests (see Deploying manifests instead of a Helm release). Manifests written by hand are not the L7|ESP chart.

What Kubernetes is

Kubernetes is a cloud abstraction. It gives every cluster the same API for running containers, whoever built the cluster and wherever it runs. That is the point of it: an application is described once, as a Helm chart, and that one chart runs on any conformant Kubernetes.

Amazon EKS, Azure AKS, Google GKE, Red Hat OpenShift, MicroK8s and the other distributions are all implementations of that same API, certified by the CNCF’s Certified Kubernetes conformance program. The L7|ESP chart is not an AKS chart or an EKS chart. It is a Kubernetes chart.

It follows that:

  • Because L7|ESP has a Helm chart, L7|ESP runs on Kubernetes, and therefore on every conformant Kubernetes distribution.

  • Every Kubernetes distribution exists to run containers, and L7|ESP is a container. There is no conformant Kubernetes that cannot run the L7|ESP container.

  • Conformance is about the API, not capacity. It guarantees the chart installs and the scheduler understands the pod it describes — it doesn’t say anything about whether a given cluster’s nodes are big enough to run it. A cluster still needs nodes sized to the L7|ESP container’s resource requirements (see System Tuning), the same as it needs enough disk for its database. That sizing is the customer’s, like the rest of the cluster.

The layers of a deployment

An L7|ESP deployment on Kubernetes has three layers, and each has an owner:

Layer

What it is

Owner

Application

The L7|ESP container image and the L7|ESP Helm chart

L7 Informatics

Platform

The Kubernetes cluster, its container runtime, and the services it depends on

Customer

Infrastructure

The cloud account or data center the cluster runs in

Customer

L7|ESP is a container image. Images run wherever images run: Docker, Podman, Kubernetes, or whatever runtime the customer has chosen.

Helm is how an application is installed onto Kubernetes. It is the application layer, not the infrastructure. L7 Informatics is deliberately not prescriptive about the platform or infrastructure underneath it.

What L7 Informatics supports

  • The L7|ESP container image, on any standard container runtime.

  • The L7|ESP Helm chart published to oci://l7esp.azurecr.io/helm/l7esp, installed on any conformant Kubernetes cluster as described in the Helm deployment guide, or rendered to manifests from that chart as described in Deploying manifests instead of a Helm release.

  • The behavior of L7|ESP itself once it is running: its startup, its upgrades, its connection to the database, and its logs.

Deploying L7|ESP on Kubernetes with the chart is routine at L7 Informatics: every pull request to L7|ESP gets its own preview environment, deployed to Kubernetes with the same chart customers use. L7 Informatics develops and runs the chart on Azure AKS and Amazon EKS. Those are platforms we have run it on, not the limit of where it runs: customers run the same chart on other distributions, such as Red Hat OpenShift, because it is a Kubernetes chart.

What L7 Informatics does not support

The Kubernetes cluster and everything it depends on belong to the customer. L7 Informatics does not build, operate, upgrade, secure or troubleshoot it. That includes:

  • Provisioning the cluster and its nodes, and sizing them to the resource requirements in System Tuning. A node too small to schedule the L7|ESP container shows up as Pending/FailedScheduling or OOMKilled.

  • Cluster upgrades and Kubernetes version management

  • The container runtime

  • Networking, DNS, network policies, ingress controllers and load balancers

  • TLS certificates and their renewal

  • Storage classes and persistent volumes

  • RBAC, service accounts, and security policies, including distribution-specific defaults such as OpenShift Security Context Constraints

  • Access to the cluster: who holds kubectl access, and how logs are retrieved

  • Managed services the cluster depends on, such as the PostgreSQL database, including its credentials and any credential rotation policy

  • Monitoring, backup and recovery of the cluster

  • Kubernetes manifests for L7|ESP written by the customer, or rendered from the chart and then edited. These are not the L7|ESP chart; L7 Informatics supports only the L7|ESP image running within them.

If L7|ESP fails to start or crashes on a customer’s cluster, the first question is whether the cluster is healthy and correctly configured. A container that is killed for exceeding its memory limit, cannot mount its volume, cannot reach its database, or is blocked by a network or security policy is a cluster configuration problem, and resolving it is the customer’s responsibility.

Whose problem is it?

Most failures show up in the pod’s status or in kubectl get events, and the status alone usually says which layer the problem is in:

What you see

What it usually means

Owner

Pod Pending, FailedScheduling

No node has the CPU or memory the pod requests, or no node matches its scheduling rules

Customer

Pod Pending, FailedMount or an unbound PersistentVolumeClaim

The storage class or volume cannot be provisioned or attached

Customer

ImagePullBackOff or ErrImagePull

The cluster cannot reach the registry, or the pull secret is missing or wrong. Contact L7 Informatics only if the registry credentials L7 Informatics issued are rejected.

Customer

OOMKilled

The container exceeded the memory limit set for it on the cluster

Customer

CrashLoopBackOff with database connection or authentication errors in the log

The database is unreachable, or its credentials changed or were rotated

Customer

CreateContainerConfigError, permission denied, or a security policy violation

A missing secret or config map, or an RBAC or security policy blocking the container

Customer

The cluster is healthy, but L7|ESP logs an error during startup or upgrade

A problem in L7|ESP itself

L7 Informatics

Pods are Running and Ready, but L7|ESP behaves incorrectly

A problem in L7|ESP itself

L7 Informatics

When the cluster side is fixed, L7|ESP starts normally. Nothing in L7|ESP needs to change for a cluster problem to be resolved.

Deploying manifests instead of a Helm release

Helm does not have to manage the release. Some organizations do not allow Helm to install anything onto their clusters, and others deploy through GitOps and need plain manifests in a repository. Either way, the L7|ESP chart still applies: one command renders it to manifests on a workstation, without touching the cluster, and those manifests are then applied with kubectl or whatever tooling the organization uses.

  1. Log in to the L7 container registry, as in the Helm deployment guide:

    $ helm registry login l7esp.azurecr.io --username <username> --password <token>
    
  2. Render the chart, with the same values.yaml you would have installed it with:

    $ helm template l7esp-example \
        oci://l7esp.azurecr.io/helm/l7esp \
        --namespace <l7esp-namespace> \
        --version <chart-version> \
        --values ./values.yaml \
        --api-versions networking.k8s.io/v1/IngressClass \
        --skip-tests \
        --output-dir ./l7esp-manifests
    

    Both of the last two flags are required:

    • --api-versions networking.k8s.io/v1/IngressClass tells Helm that the cluster has the Kubernetes networking.k8s.io/v1 Ingress API. helm template does not connect to the cluster, so it cannot discover this itself, and chart versions that check for the API refuse to render the Ingress without it, failing with You must have atleast networking.k8s.io/v1beta1 to use ingressClass. The error does not mean the cluster is too old: every Kubernetes release since 1.19 has this API. The flag is harmless when the Ingress is disabled, and with chart versions that no longer need it.

    • --skip-tests leaves out the chart’s test pods. Helm runs them only on helm test; kubectl apply would instead create them alongside L7|ESP and never remove them.

  3. Apply the rendered manifests:

    $ kubectl apply --recursive --filename ./l7esp-manifests --namespace <l7esp-namespace>
    

Manifests rendered this way, from a released chart version and a values.yaml, are the L7|ESP chart and are supported like a Helm install. To change the deployment, change values.yaml and render again; do not edit the rendered files. Include the chart version and values.yaml (with credentials removed) in any support request, so L7 Informatics can render the same manifests.

With GitOps, the values.yaml is what you maintain. Keep it in the repository alongside the rendered manifests, and when a new chart version is released, render again with the new --version and commit the result.

Manifests written by hand, or rendered and then edited, are not the L7|ESP chart. They are the customer’s own deployment of the L7|ESP image, and L7 Informatics supports only the image within them. They also have to be rewritten by hand to pick up every change in each new chart release, work that rendering does in a single command, so in practice they fall behind the chart and break on upgrade.

Questions about specific distributions

Is GKE, OpenShift, Rancher, or another distribution supported?

If it is conformant Kubernetes, the L7|ESP chart installs on it, and L7 Informatics supports the image and the chart running there exactly as it does anywhere else. The cluster is the customer’s, as it is on every distribution.

Why doesn’t this documentation list the supported distributions?

Because naming a configuration implies that it is the configuration that was tested, and that it is the only one supported. The L7|ESP chart does not depend on any one distribution, so there is no list to give. The platform guides below are examples, not that list.

Platform guides are examples

The Amazon EKS, Azure AKS and MicroK8s guides, and the infrastructure-as-code templates they include, are worked examples of standing up a cluster that the L7|ESP chart can be installed on. They are a starting point, not a supported or prescribed configuration. A cluster created from them is the customer’s cluster, operated under the customer’s responsibility like any other.

Being ready to run L7|ESP on Kubernetes

Running an application on Kubernetes assumes that the team operating the cluster can operate it. Before deploying L7|ESP, make sure that within your own organization:

  • Someone with kubectl access to the L7|ESP namespace is available to the people supporting L7|ESP.

  • Container logs can be retrieved promptly, so they can be shared with L7 Informatics when needed.

  • Resource requests and limits for L7|ESP have been set per System Tuning and agreed with the cluster’s operators.

  • The owners of the database know that L7|ESP uses it, and any credential rotation is coordinated with the L7|ESP deployment.

L7 Informatics can help diagnose a problem in L7|ESP itself much faster when these are in place. They cannot be provided by L7 Informatics on the customer’s behalf.

Opening a support request

When a problem is in L7|ESP itself, include the following with the request. Collecting it needs kubectl and helm access to the L7|ESP namespace. If the chart was rendered to manifests rather than installed with Helm, give the chart version and the values.yaml it was rendered with in place of the two helm commands.

  • The chart version and the L7|ESP image tag:

    helm list --namespace <namespace>
    
  • The values the release was installed with, with passwords, tokens and other credentials removed:

    helm get values <release> --namespace <namespace>
    
  • The pod’s status and recent events:

    kubectl get pods --namespace <namespace>
    kubectl describe pod <pod> --namespace <namespace>
    kubectl get events --namespace <namespace> --sort-by=.lastTimestamp
    
  • The container logs, including those of the previous container if it restarted:

    kubectl logs <pod> --namespace <namespace>
    kubectl logs <pod> --namespace <namespace> --previous
    
  • The Kubernetes distribution and version the cluster runs.