Files
0cedd98051 feat: add Kubernetes backend (#1260)
Adds a Kubernetes backend. A `name:kubernetes://image` label runs the job as one pod through the Kubernetes API, with services as containers of the same pod. Step env is exported by a script sent over exec stdin, keeping it out of the pod spec and process arguments, and service env goes into a per-job Secret. Docker actions and container options are rejected. See `docs/kubernetes.md`.

Operators shape job pods with `kubernetes.pod_template`, with per-label `pod_templates` merged in `runs-on` order and a `$services` entry for service containers. The idle cleanup removes pods and Secrets a runner left behind.

The client calls the Kubernetes API directly and runs step commands over `coder/websocket` (same dependency used in gitea) instead of pulling in the heavyweight `kubernetes/client-go`. Includes an e2e test against k3s.

Replaces: https://gitea.com/gitea/runner/pulls/1000
Fixes: https://gitea.com/gitea/runner/issues/31

Assisted-by: Claude Code:claude-opus-5-5
Co-authored-by: Zettat123 <zettat123@gmail.com>
Co-authored-by: bircni <bircni@icloud.com>
Reviewed-on: https://gitea.com/gitea/runner/pulls/1260
Reviewed-by: Lunny Xiao <xiaolunwen@gmail.com>
Reviewed-by: Zettat123 <39446+zettat123@noreply.gitea.com>
Co-authored-by: silverwind <me@silverwind.io>
2026-10-01 06:59:15 +00:00

84 lines
1.8 KiB
YAML

apiVersion: v1
data:
token: << base64 encoded registration token >>
kind: Secret
metadata:
name: runner-secret
---
apiVersion: v1
kind: ServiceAccount
metadata:
name: runner
---
apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
name: runner
rules:
- apiGroups: [""]
resources: ["pods"]
verbs: ["create", "get", "list", "delete"]
- apiGroups: [""]
resources: ["pods/exec"]
verbs: ["create", "get"]
- apiGroups: [""]
resources: ["pods/log"]
verbs: ["get"]
- apiGroups: [""]
resources: ["secrets"]
verbs: ["create", "delete"]
---
apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata:
name: runner
roleRef:
apiGroup: rbac.authorization.k8s.io
kind: Role
name: runner
subjects:
- kind: ServiceAccount
name: runner
---
apiVersion: apps/v1
kind: StatefulSet
metadata:
name: runner
spec:
serviceName: runner
selector:
matchLabels:
app: runner
template:
metadata:
labels:
app: runner
spec:
serviceAccountName: runner
terminationGracePeriodSeconds: 10800 # keep above runner.shutdown_timeout, see README
containers:
- name: runner
image: gitea/runner:nightly
env:
- name: GITEA_INSTANCE_URL
value: http://gitea-http.gitea.svc.cluster.local:3000
- name: GITEA_RUNNER_REGISTRATION_TOKEN
valueFrom:
secretKeyRef:
name: runner-secret
key: token
- name: GITEA_RUNNER_LABELS
value: ubuntu-latest:kubernetes://docker.gitea.com/runner-images:ubuntu-latest
volumeMounts:
- name: runner-data
mountPath: /data
volumeClaimTemplates:
- metadata:
name: runner-data
spec:
accessModes:
- ReadWriteOnce
resources:
requests:
storage: 1Gi