diff --git a/.server-changes/kubernetes-worker-automount-service-account-token.md b/.server-changes/kubernetes-worker-automount-service-account-token.md new file mode 100644 index 00000000000..a2464fe4f1b --- /dev/null +++ b/.server-changes/kubernetes-worker-automount-service-account-token.md @@ -0,0 +1,6 @@ +--- +area: supervisor +type: feature +--- + +Self-hosted Kubernetes deployments can now let run pods reach the Kubernetes API. A new option makes mounting the pod's service account token configurable (off by default), so workloads that need in-cluster access — like backup tooling — can be granted it. diff --git a/apps/supervisor/src/env.ts b/apps/supervisor/src/env.ts index 32e669b5914..adec0d78941 100644 --- a/apps/supervisor/src/env.ts +++ b/apps/supervisor/src/env.ts @@ -165,6 +165,14 @@ export const Env = z KUBERNETES_NAMESPACE: z.string().default("default"), KUBERNETES_WORKER_NODETYPE_LABEL: z.string().default("v4-worker"), KUBERNETES_IMAGE_PULL_SECRETS: z.string().optional(), // csv + // Mount an in-cluster ServiceAccount token/CA into run pods so workload code can reach the + // Kubernetes API (e.g. via @kubernetes/client-node or CLIs like velero/kubectl). Defaults to + // false to preserve the existing hardened behavior. Only enable when runs use a ServiceAccount + // with appropriately scoped RBAC. + KUBERNETES_WORKER_AUTOMOUNT_SERVICE_ACCOUNT_TOKEN: BoolEnv.default(false), + // ServiceAccount to run worker pods under. Only useful alongside + // KUBERNETES_WORKER_AUTOMOUNT_SERVICE_ACCOUNT_TOKEN=true; leaves the cluster default when unset. + KUBERNETES_WORKER_SERVICE_ACCOUNT_NAME: z.string().optional(), KUBERNETES_EPHEMERAL_STORAGE_SIZE_LIMIT: z.string().default("10Gi"), KUBERNETES_EPHEMERAL_STORAGE_SIZE_REQUEST: z.string().default("2Gi"), KUBERNETES_STRIP_IMAGE_DIGEST: BoolEnv.default(false), diff --git a/apps/supervisor/src/workloadManager/kubernetes.ts b/apps/supervisor/src/workloadManager/kubernetes.ts index 282ac80b4fd..d24b36c4863 100644 --- a/apps/supervisor/src/workloadManager/kubernetes.ts +++ b/apps/supervisor/src/workloadManager/kubernetes.ts @@ -317,8 +317,13 @@ export class KubernetesWorkloadManager implements WorkloadManager { get #defaultPodSpec(): Omit { return { restartPolicy: "Never", - automountServiceAccountToken: false, + automountServiceAccountToken: env.KUBERNETES_WORKER_AUTOMOUNT_SERVICE_ACCOUNT_TOKEN, imagePullSecrets: this.getImagePullSecrets(), + ...(env.KUBERNETES_WORKER_SERVICE_ACCOUNT_NAME + ? { + serviceAccountName: env.KUBERNETES_WORKER_SERVICE_ACCOUNT_NAME, + } + : {}), ...(env.KUBERNETES_SCHEDULER_NAME ? { schedulerName: env.KUBERNETES_SCHEDULER_NAME, diff --git a/docs/self-hosting/env/supervisor.mdx b/docs/self-hosting/env/supervisor.mdx index ffa057747fe..dcfa2be9b02 100644 --- a/docs/self-hosting/env/supervisor.mdx +++ b/docs/self-hosting/env/supervisor.mdx @@ -48,6 +48,8 @@ mode: "wide" | `KUBERNETES_NAMESPACE` | No | default | The namespace that runs should be in. | | `KUBERNETES_WORKER_NODETYPE_LABEL` | No | v4-worker | Nodes for runs need this label, e.g. `nodetype=v4-worker`. | | `KUBERNETES_IMAGE_PULL_SECRETS` | No | — | Image pull secrets (CSV). | +| `KUBERNETES_WORKER_AUTOMOUNT_SERVICE_ACCOUNT_TOKEN` | No | false | Mount an in-cluster ServiceAccount token/CA into run pods so workloads can reach the Kubernetes API. Enable only with scoped RBAC. | +| `KUBERNETES_WORKER_SERVICE_ACCOUNT_NAME` | No | — | ServiceAccount to run worker pods under. Pairs with the automount option above. | | `KUBERNETES_EPHEMERAL_STORAGE_SIZE_LIMIT` | No | 10Gi | Ephemeral storage size limit. Applies to all runs. | | `KUBERNETES_EPHEMERAL_STORAGE_SIZE_REQUEST` | No | 2Gi | Ephemeral storage size request. Applies to all runs. | | **Metrics** | | | |