# Cluster probe for the loosely coupled Kubernetes transport. # # Runs `loosely_coupled_k8s_job` from a single throwaway pod. The point is to # prove the part of this service that no test can reach: that the dispatching # process creates payload Jobs and that messages come back over the pod log # stream. It clears readiness checks L4-L9 in one run. # # Deliberately NOT a Dagster deployment. No webserver, no daemon, no database, # no code location registration. That sidesteps the control-plane version skew - # the pod is its own control plane, so the 1.13.19 images here have nothing to be # compatible with. Everything lives in one namespace you delete afterwards. # # --- Before applying ------------------------------------------------------- # # Credentials, only if your registry needs them. The Gitea images referenced # below do NOT: a bare GET returns 401, but that is the start of the Docker # token handshake, and completing it anonymously returns the manifest. A probe # pod carrying no credentials pulled and ran on the sandbox on 2026-08-31. # # If you point this at a registry that does require authentication, remember the # payload Jobs need it too. PipesK8sClient sets no serviceAccountName, so they # run as `default` and inherit nothing from the pod below; patch that account or # pass imagePullSecrets through base_pod_spec in dispatch_external_work_k8s. A # payload pod that cannot pull leaves the op waiting until pod_wait_timeout, # which reads like a hung workload rather than a missing credential. # # kubectl apply -f yaml/loosely-coupled/probe-pipes-k8s.yaml # # On sandbox-cat-dat use yaml/sandbox/probe-pipes-k8s-sandbox.yaml instead: that # cluster's access is Rancher project-scoped, so this file's namespace and RBAC # cannot be created there. The sandbox variant needs neither. # # `--dry-run=server` reports "namespaces distexec-probe not found" for the four # namespaced objects. That is the dry run declining to create the namespace it # would need, not a fault in the manifests; `--dry-run=client` passes clean. # # LIMITATION under a restricted Pod Security namespace. This pod satisfies the # restricted standard, but the payload Jobs do not: PipesK8sClient builds those # pod specs and this service passes no securityContext through base_pod_spec, so # such a namespace would admit the dispatcher and reject every payload it # creates. Leave the probe namespace unlabelled, or add the fields to # base_pod_spec in dispatch_external_work_k8s first. # # --- Reading the result ---------------------------------------------------- # # kubectl -n distexec-probe logs -f job/pipes-probe # kubectl -n distexec-probe get jobs -l app.kubernetes.io/name=distributed-execution-payload # # Success is RUN_SUCCESS plus four payload Jobs, one per work unit. The # summarise_results output carries contributing_workers; on a cluster those # should be four distinct pod hostnames, which is the claim the guide makes and # a laptop cannot demonstrate. # # A run that reaches RUN_FAILURE with "no pipes messages received" means the # payload ran but its log stream never came back - check the pods/log rule # below before suspecting the payload. # # --- Teardown -------------------------------------------------------------- # # kubectl delete namespace distexec-probe # # NOT CLUSTER-VERIFIED. Written against the published images and the RBAC the # pipes client is documented to need, but not yet applied to a cluster. apiVersion: v1 kind: Namespace metadata: name: distexec-probe labels: app.kubernetes.io/name: distributed-execution app.kubernetes.io/component: probe --- apiVersion: v1 kind: ServiceAccount metadata: name: pipes-dispatcher namespace: distexec-probe imagePullSecrets: - name: gitea-registry --- apiVersion: rbac.authorization.k8s.io/v1 kind: Role metadata: name: pipes-dispatcher namespace: distexec-probe rules: - apiGroups: ["batch"] resources: ["jobs", "jobs/status"] verbs: ["create", "get", "list", "watch", "delete"] # pods/log is the message channel for PipesK8sPodLogsMessageReader, not just # an observability convenience. Without it the payload runs to completion and # reports nothing, and the op fails on an empty message list. - apiGroups: [""] resources: ["pods", "pods/log", "pods/status"] verbs: ["get", "list", "watch"] --- apiVersion: rbac.authorization.k8s.io/v1 kind: RoleBinding metadata: name: pipes-dispatcher namespace: distexec-probe subjects: - kind: ServiceAccount name: pipes-dispatcher namespace: distexec-probe roleRef: kind: Role name: pipes-dispatcher apiGroup: rbac.authorization.k8s.io --- apiVersion: batch/v1 kind: Job metadata: name: pipes-probe namespace: distexec-probe spec: # One shot. A retry would obscure which attempt produced which payload Jobs. backoffLimit: 0 activeDeadlineSeconds: 1800 template: metadata: labels: app.kubernetes.io/name: distributed-execution app.kubernetes.io/component: probe spec: restartPolicy: Never serviceAccountName: pipes-dispatcher # A service account with automountServiceAccountToken: false - which the # platform's dagster-svc-account uses - leaves the pipes client selecting # in-cluster auth and then failing on "Service token file does not exist". automountServiceAccountToken: true securityContext: runAsNonRoot: true runAsUser: 1000 runAsGroup: 1000 # Makes the emptyDir writable by UID 1000, which DAGSTER_HOME needs. fsGroup: 1000 seccompProfile: type: RuntimeDefault containers: - name: dispatcher image: gitea.dataprovider01.sandbox-cat-dat.simpl-europe.eu/j.r/distributed-execution:5122da4691f9 imagePullPolicy: IfNotPresent # Satisfies the restricted Pod Security standard. The int cluster did # not enforce it when this was written and the sandbox was not checked; # a cluster that does enforce it rejects the pod outright. securityContext: allowPrivilegeEscalation: false capabilities: drop: - ALL command: - dagster - job - execute - -f - src/distributed_execution/repository.py - -j - loosely_coupled_k8s_job env: - name: DAGSTER_HOME value: /dagster-home # Must be the same commit as the image above. - name: PIPES_PAYLOAD_IMAGE value: gitea.dataprovider01.sandbox-cat-dat.simpl-europe.eu/j.r/distributed-execution-payload:5122da4691f9 - name: PIPES_PAYLOAD_NAMESPACE value: distexec-probe volumeMounts: - name: dagster-home mountPath: /dagster-home resources: requests: cpu: 200m memory: 512Mi limits: cpu: "1" memory: 1Gi volumes: # The job runs on multiprocess_executor, so the instance has to be a real # sqlite instance on disk rather than an ephemeral one. - name: dagster-home emptyDir: {}