diff --git a/docs/source/compute_config/kubernetes.md b/docs/source/compute_config/kubernetes.md index 047ee1c8a..6183e621e 100644 --- a/docs/source/compute_config/kubernetes.md +++ b/docs/source/compute_config/kubernetes.md @@ -1,10 +1,10 @@ # Kubernetes -Lithops with kubernetes as serverless compute backend. +Lithops with Kubernetes as serverless compute backend. ## Installation -1. Install kubernetes backend dependencies: +1. Install Kubernetes backend dependencies: ```bash python3 -m pip install lithops[kubernetes] @@ -58,35 +58,34 @@ k8s: docker_namespace : # namespace name from https://cloud.ibm.com/registry/namespaces ``` -## Summary of configuration keys for kubernetes: +## Summary of configuration keys for Kubernetes: |Group|Key|Default|Mandatory|Additional info| |---|---|---|---|---| -|k8s | kubecfg_path | |no | Path to kubecfg file. Mandatory if config file not in `~/.kube/config` or KUBECONFIG env var not present| -|k8s | kubecfg_context | |no | kubernetes context to use from your kubeconfig file. It will use the default active context if not provided | -|k8s | namespace | default |no | Kubernetes namespace to use for lithops execution | +|k8s | kubecfg_path | |no | Path to the kubecfg file. Mandatory if the config file is not in `~/.kube/config` or the `KUBECONFIG` env var is not present| +|k8s | kubecfg_context | |no | Kubernetes context to use from your kubeconfig file. The default active context will be used if not provided | +|k8s | namespace | default |no | Kubernetes namespace to use for Lithops execution | |k8s | docker_server | docker.io |no | Container registry URL | |k8s | docker_user | |no | Container registry user name | |k8s | docker_password | |no | Container registry password/token. In case of Docker hub, login to your docker hub account and generate a new access token [here](https://hub.docker.com/settings/security)| -|k8s | rabbitmq_executor | False | no | Alternative K8s backend accelerating parallel function execution (map) thanks to rabbitmq group calls and warm-state pods of higher granularity. For more information [here](./kubernetes_rabbitmq.md).| +|k8s | rabbitmq_executor | False | no | Alternative K8s backend that accelerates parallel function execution (map) by using RabbitMQ group calls and warm-state pods with higher granularity. For more information, see [here](./kubernetes_rabbitmq.md). | |k8s | max_workers | 100 | no | Max number of workers per `FunctionExecutor()`| -|k8s | worker_processes | 1 | no | Number of Lithops processes within a given worker. This can be used to parallelize function activations within a worker. It is recommendable to set this value to the same number of CPUs of the container. | +|k8s | worker_processes | 1 | no | Number of Lithops processes within a given worker. This can be used to parallelize function activations within a worker. It is recommended to set this value to the same number of CPUs as the container. | |k8s | runtime | |no | Docker image name.| |k8s | runtime_cpu | 1 |no | CPU limit. Default 1vCPU | |k8s | runtime_memory | 512 |no | Memory limit in MB. Default 512MB | |k8s | runtime_timeout | 600 |no | Runtime timeout in seconds. Default 600 seconds | |k8s | master_timeout | 600 |no | Master pod timeout in seconds. Default 600 seconds | |k8s | container_security_context | PSS Baseline (drop ALL caps, no privilege escalation, RuntimeDefault seccomp) | no | Mapping injected as the container `securityContext` on every Lithops pod. Set to `null` to disable. | -|k8s | pod_security_context | | no | Mapping injected as the pod-level `securityContext`. Required for clusters enforcing Pod Security Standards Restricted (e.g. EGI Rancher, GKE Autopilot, OpenShift). Requires a non-root runtime image. | +|k8s | pod_security_context | | no | Mapping injected as the pod-level `securityContext`. Required for clusters enforcing Pod Security Standards Restricted (e.g. EGI Rancher, GKE Autopilot, OpenShift). The runtime image must have a non-root `USER` directive — the bundled `runtime/kubernetes/Dockerfile` and the auto-built default ship with `USER 1000:1000`. | |k8s | runtime_arch | auto-detected from cluster nodes; falls back to `amd64` if mixed or unknown | no | Architecture passed to `docker build --platform=linux/`. Set explicitly when targeting a specific architecture on a mixed-arch cluster. Allowed values: `amd64`, `arm64`. | ## Running on Pod Security Standards Restricted clusters -Clusters enforcing the [Pod Security Standards "Restricted"](https://kubernetes.io/docs/concepts/security/pod-security-standards/) profile (Rancher with EGI policies, GKE Autopilot, OpenShift, AKS with Azure Policy, EKS with admission controllers) require pods to run as a non-root user with additional hardening. Set `pod_security_context` and use a runtime image that has a non-root `USER` directive: +Clusters enforcing the [Pod Security Standards "Restricted"](https://kubernetes.io/docs/concepts/security/pod-security-standards/) profile (Rancher with EGI policies, GKE Autopilot, OpenShift, AKS with Azure Policy, EKS with admission controllers) require pods to run as a non-root user with additional hardening. The bundled runtime image and the auto-built default already ship as `USER 1000:1000`, so a custom non-root rebuild is no longer required — set `pod_security_context` to opt in: ```yaml k8s: - runtime: /: pod_security_context: runAsNonRoot: true runAsUser: 1000 diff --git a/lithops/serverless/backends/k8s/config.py b/lithops/serverless/backends/k8s/config.py index ecb71a5a5..64a34fcad 100644 --- a/lithops/serverless/backends/k8s/config.py +++ b/lithops/serverless/backends/k8s/config.py @@ -48,36 +48,45 @@ DOCKERFILE_DEFAULT = """ -RUN apt-get update && apt-get install -y \ - zip redis-server curl \ - && apt-get clean \ +RUN apt-get update && apt-get install -y --no-install-recommends \\ + zip unzip redis-server curl ca-certificates \\ + && apt-get clean \\ && rm -rf /var/lib/apt/lists/* -RUN pip install --upgrade --ignore-installed setuptools six pip \ - && pip install --upgrade --no-cache-dir --ignore-installed \ - flask \ - pika \ - boto3 \ - ibm-cloud-sdk-core \ - ibm-cos-sdk \ - redis \ - requests \ - PyYAML \ - kubernetes \ - numpy \ - cloudpickle \ - ps-mem \ - tblib \ +# Pin setuptools<81 (PEP 517 build envs included) so legacy sdists that +# import pkg_resources still build. +RUN echo 'setuptools<81' > /tmp/constraints.txt +ENV PIP_CONSTRAINT=/tmp/constraints.txt + +RUN pip install --no-cache-dir 'setuptools<81' six wheel \\ + && pip install --no-cache-dir \\ + flask \\ + pika \\ + boto3 \\ + ibm-cloud-sdk-core \\ + ibm-cos-sdk \\ + redis \\ + requests \\ + PyYAML \\ + kubernetes \\ + numpy \\ + cloudpickle \\ + ps-mem \\ + tblib \\ psutil -ENV PYTHONUNBUFFERED TRUE +ENV PYTHONUNBUFFERED=TRUE +ENV APP_HOME=/lithops + +# Non-root user matches the PSS Restricted recipe in the k8s docs. +RUN groupadd -g 1000 lithops && useradd -m -u 1000 -g 1000 lithops -# Copy Lithops proxy and lib to the container image. -ENV APP_HOME /lithops WORKDIR $APP_HOME COPY lithops_k8s.zip . -RUN unzip lithops_k8s.zip && rm lithops_k8s.zip +RUN unzip lithops_k8s.zip && rm lithops_k8s.zip && chown -R lithops:lithops $APP_HOME + +USER 1000:1000 """ JOB_DEFAULT = """ diff --git a/runtime/kubernetes/Dockerfile b/runtime/kubernetes/Dockerfile index 6277be8b1..f743fd186 100644 --- a/runtime/kubernetes/Dockerfile +++ b/runtime/kubernetes/Dockerfile @@ -13,12 +13,17 @@ FROM python:3.10-slim-bookworm # Python 3.12 #FROM python:3.12-slim-bookworm -RUN apt-get update && apt-get install -y \ - zip redis-server curl \ +RUN apt-get update && apt-get install -y --no-install-recommends \ + zip unzip redis-server curl ca-certificates \ && apt-get clean \ && rm -rf /var/lib/apt/lists/* -RUN pip install --upgrade setuptools six pip \ +# Pin setuptools<81 (PEP 517 build envs included) so legacy sdists that +# import pkg_resources still build. +RUN echo 'setuptools<81' > /tmp/constraints.txt +ENV PIP_CONSTRAINT=/tmp/constraints.txt + +RUN pip install --no-cache-dir 'setuptools<81' six wheel \ && pip install --no-cache-dir \ flask \ pika \ @@ -36,11 +41,15 @@ RUN pip install --upgrade setuptools six pip \ tblib \ psutil -ENV PYTHONUNBUFFERED TRUE +ENV PYTHONUNBUFFERED=TRUE +ENV APP_HOME=/lithops + +# Non-root user matches the PSS Restricted recipe in docs/source/compute_config/kubernetes.md. +RUN groupadd -g 1000 lithops && useradd -m -u 1000 -g 1000 lithops -# Copy Lithops proxy and lib to the container image. -ENV APP_HOME /lithops WORKDIR $APP_HOME COPY lithops_k8s.zip . -RUN unzip lithops_k8s.zip && rm lithops_k8s.zip +RUN unzip lithops_k8s.zip && rm lithops_k8s.zip && chown -R lithops:lithops $APP_HOME + +USER 1000:1000