If you’re using Kubernetes 1.29 or later, you can use the SidecarContainers feature, which significantly improves lifecycle management. For more information about why you would want to use sidecar containers, see Sidecar Containers in the Kubernetes documentation.
To use Kubernetes sidecar containers with Kong Mesh, enable the experimental.sidecarContainers/KUMA_EXPERIMENTAL_SIDECAR_CONTAINERS option.
This feature supports adding the injected Kuma container to initContainers with restartPolicy: Always, which marks it as a sidecar container. Refer to the Kubernetes docs to learn more about how they work.
The following lifecycle subsections are irrelevant when using this feature.
When enabled, the ordering of the sidecar startup and shutdown is enforced by Kubernetes.
To use the mesh in an init container, ensure that it comes after kuma-sidecar.
Kong Mesh injects its sidecar at the front of the list but can’t guarantee that its webhook runs last.
Draining incoming connections gracefully is handled via a preStop hook on the kuma-sidecar container.
If the terminationGracePeriodSeconds has elapsed, ordering and thus correct behavior of the sidecar is no longer guaranteed. The grace period should be set to long enough that your workload finishes shutdown before it elapses.
Your application should itself initiate graceful shutdown when it receives SIGTERM.
Kubernetes works largely asynchronously, So if your application exits too quickly it’s possible that requests are still routed to the Pod and fail.
See this learnk8s.io article to learn about this problem and potential solutions.
When your application receives SIGTERM, you may need to wait some time.
This can either be done in the application itself or you can add a preStop command to your container:
kind: Deployment
# ...
spec:
template:
spec:
containers:
- name: app-container
lifecycle:
preStop:
exec:
command: ["/bin/sleep", "15"]
On Kubernetes, a Dataplane resource is automatically created by kuma-cp. For each Pod with the sidecar-injection label, a new Dataplane resource is created.
To allow the data plane to join the mesh in a graceful way, you need to make sure the application is ready to serve traffic before it can be considered a valid traffic destination.
Due to the way Kong Mesh implements transparent proxying and sidecars in Kubernetes, network calls from init containers while running a mesh can be a challenge.
When injecting init containers into a Pod via webhooks, such as the Vault init container, there is no guarantee of the order in which the init containers run.
The ordering of init containers also doesn’t provide a solution when the Kong Mesh CNI is used, as traffic redirection to the sidecar occurs even before any init container runs.
To solve this issue, start the init container with a specific user ID and exclude specific ports from interception, and the port of DNS interception.
Here is an example of annotations to enable HTTPS traffic for a container running as user id 1234:
apiVersion: v1
king: Deployment
metadata:
name: my-deployment
spec:
template:
metadata:
annotations:
traffic.kuma.io/exclude-outbound-tcp-ports-for-uids: "443:1234"
traffic.kuma.io/exclude-outbound-udp-ports-for-uids: "53:1234"
spec:
initContainers:
- name: my-init-container
...
securityContext:
runAsUser: 1234
With network calls inside the mesh with mTLS enabled, using the init container is impossible because kuma-dp is responsible for encrypting the traffic and only runs after all init containers have exited.
By default, containers start in arbitrary order, so an app container can start even though the sidecar container might not be ready to receive traffic.
Making initial requests, such as connecting to a database, can fail for a brief period after the Pod starts.
To mitigate this problem try setting:
With these, the app container waits for the data plane container to be ready to serve traffic.
The waitForDataplaneReady setting relies on the fact that defining a postStart hook causes Kubernetes to run containers sequentially based on their order of occurrence in the containers list.
This isn’t documented and could change in the future.
It also depends on injecting the kuma-sidecar container as the first container in the Pod, which isn’t guaranteed since other mutating webhooks can rearrange the containers.
To leave the mesh in a graceful shutdown, you need to remove the traffic destination from all the clients before shutting it down.
When the Kong Mesh sidecar receives a SIGTERM signal, it:
- Starts draining Envoy listeners.
- Waits the entire drain time.
- Terminates.
While draining, Envoy can still accept connections, however:
- It is marked unhealthy on the Envoy Admin
/ready endpoint.
- It sends
connection: close for HTTP/1.1 requests and the GOAWAY frame for HTTP/2. This forces clients to close their connection and reconnect to the new instance.
Whenever a user or system deletes a Pod, Kubernetes does the following:
- Marks the Pod as terminated.
- Performs the following actions concurrently on every container:
- Executes any pre-stop hook, if defined.
- Sends a SIGTERM signal.
- Waits until the container is terminated for the maximum amount of graceful termination time (by default, this is 60 seconds).
- Sends a SIGKILL to the container.
- Removes the Pod object from the system.
When a Pod is marked as terminated, the control plane marks the Dataplane object as unhealthy, which triggers a configuration update to all the clients to remove it as a destination.
This can take a couple of seconds depending on the size of the mesh, resources available to the control plane, XDS configuration interval, etc.
To learn how Kubernetes handles the Pod lifecycle, see the Kubernetes docs.
If the application served by the Kong Mesh sidecar quits immediately after the SIGTERM signal, there is a high chance that clients will still try to send traffic to this destination. To mitigate this, you must either:
When a Pod is deleted, its matching Dataplane resource is deleted as well. This is possible thanks to the
owner reference set on the Dataplane resource.