diff --git a/servers/gcp/k8s/gitea-runner/deployment.yaml b/servers/gcp/k8s/gitea-runner/deployment.yaml index 7cc6659..ef1ff0b 100644 --- a/servers/gcp/k8s/gitea-runner/deployment.yaml +++ b/servers/gcp/k8s/gitea-runner/deployment.yaml @@ -1,16 +1,30 @@ --- -# Gitea Actions runner on GKE. +# Gitea Actions runner on GKE Autopilot. # # Architecture: # - init container registers the runner with Gitea (--no-interactive, idempotent) # - main container runs act_runner daemon -# - docker:dind sidecar provides Docker for build jobs (privileged) -# - emptyDir /data persists runner state within a pod lifetime # -# The runner uses Docker-in-Docker (DinD) rather than a host socket because -# GKE Autopilot does not expose the node's Docker socket. -# DinD requires privileged mode — the ci namespace has -# pod-security.kubernetes.io/enforce: privileged (see namespace.yaml). +# LIMITATION: GKE Autopilot does not allow privileged containers, so Docker-in-Docker +# (DinD) is not available. The runner uses "host" label mode, which runs steps +# directly inside the runner pod container rather than spawning Docker containers. +# forgejo-runner v11 still requires a Docker daemon to start — this deployment +# will fail until one of the following is resolved: +# +# Option A (recommended): Switch to a GKE Standard node pool for the ci namespace. +# Add a standard node pool with sandbox.config.sandboxType=gvisor or allow +# privileged pods on specific node pools. +# +# Option B: Use Cloud Build for docker build steps; use this runner for shell steps. +# Requires forking all workflow files to remove docker steps. +# +# Option C: Point docker_host at an external Docker TCP daemon (e.g., on the GCE runner VM). +# +# Until resolved, the existing GCE VM runner (gitea-runner-1 in us-central1-a) +# handles CI jobs. This deployment is a placeholder for when privileged pods are available. +# +# The ci namespace has pod-security.kubernetes.io/enforce: privileged set +# (see namespace.yaml) but Autopilot's Warden enforces this at the node level. apiVersion: apps/v1 kind: Deployment metadata: @@ -45,28 +59,28 @@ spec: --instance "${GITEA_INSTANCE_URL}" \ --token "${GITEA_RUNNER_REGISTRATION_TOKEN}" \ --name "gke-runner-$(hostname)" \ - --labels "ubuntu-latest:docker://us-central1-docker.pkg.dev/neuron-785695/neuron-ci/ci-base:latest,ubuntu-24.04:docker://us-central1-docker.pkg.dev/neuron-785695/neuron-ci/ci-base:latest,linux,x64" \ + --labels "ubuntu-latest:host,ubuntu-24.04:host,linux,x64" \ --no-interactive fi cat > /data/config.yaml << 'CONFIGEOF' runner: capacity: 2 timeout: 3h - container: - network: host - docker_host: "tcp://localhost:2375" - force_pull: true - valid_volumes: [] - default_image: "us-central1-docker.pkg.dev/neuron-785695/neuron-ci/ci-base:latest" - env: - GITEA_SSH_PRIVATE_KEY: "" + envs: BASH_ENV: "/usr/local/bin/git-ssh-init.sh" + container: + # GKE Autopilot blocks privileged DinD — steps run directly + # in the runner container (host mode). Labels use :host suffix. + network: host + docker_host: "-" + force_pull: false + valid_volumes: [] CONFIGEOF env: + # Use the internal Gitea service to avoid Cloudflare Access auth. + # Gitea is in the same GKE cluster — use the ClusterIP service. - name: GITEA_INSTANCE_URL - value: "https://git.neuralplatform.ai" - - name: DOCKER_HOST - value: "tcp://localhost:2375" + value: "http://gitea.gitea.svc.cluster.local:80" envFrom: - secretRef: name: gitea-runner-token @@ -80,9 +94,7 @@ spec: command: ["act_runner", "daemon", "--config", "/data/config.yaml"] env: - name: GITEA_INSTANCE_URL - value: "https://git.neuralplatform.ai" - - name: DOCKER_HOST - value: "tcp://localhost:2375" + value: "http://gitea.gitea.svc.cluster.local:80" envFrom: - secretRef: name: gitea-runner-token @@ -97,25 +109,6 @@ spec: - mountPath: /data name: data workingDir: /data - - name: dind - image: docker:dind - securityContext: - privileged: true - env: - - name: DOCKER_TLS_CERTDIR - value: "" - resources: - requests: - cpu: "500m" - memory: "512Mi" - limits: - cpu: "4" - memory: "4Gi" - volumeMounts: - - mountPath: /var/lib/docker - name: docker-storage volumes: - name: data emptyDir: {} - - name: docker-storage - emptyDir: {}