Running CI inside Kubernetes: Tekton, Argo Workflows and when not to
Kubernetes-native CI gives you pipelines as custom resources and scaling for free. It also gives you a pipeline engine you now operate. When that trade is worth making.
Once a platform team runs Kubernetes, someone proposes running CI on it too. The reasoning is sound: the scheduler already does bin-packing, autoscaling and isolation, and a build is just a pod. Why run a separate system that reimplements all of that?
It is a real option, and for some workloads clearly the right one. It is also the option that most often gets adopted for the wrong reason.
What the two tools are
Tekton models CI as Kubernetes resources: a Step is a container, a Task is a sequence of steps in one pod, a Pipeline wires Tasks into a graph, and a PipelineRun is one execution. There is no bespoke DSL — it is YAML and CRDs, so kubectl, RBAC, admission control and your existing GitOps flow all apply directly.
apiVersion: tekton.dev/v1
kind: Task
metadata: { name: build-image }
spec:
params: [{ name: image }]
workspaces: [{ name: source }]
steps:
- name: build
image: gcr.io/kaniko-project/executor:latest
args: ["--dockerfile=Dockerfile", "--context=$(workspaces.source.path)",
"--destination=$(params.image)", "--cache=true"]
Argo Workflows is a general DAG engine for containers that happens to be usable for CI. Its strength is fan-out: steps that generate a list of items and run a container per item, with artifact passing between them. If your pipeline is really a batch job — process 400 inputs, aggregate — Argo Workflows is a much better fit than any CI product.
Both give you: every step in its own container with its own image, pod-level resource requests, native autoscaling, no runner fleet to maintain separately, and pipelines that live in git as manifests your GitOps controller already reconciles.
What you give up
Developer experience. Tekton YAML is verbose in a way that a .gitlab-ci.yml is not, and a build failure is debugged by reading pod logs rather than a purpose-built UI. Tekton's dashboard and Argo's UI are functional, not delightful. Most developers will not enjoy writing these, so the pipelines end up owned by the platform team — which may be what you want, or may be a bottleneck.
The ecosystem. No marketplace of ready-made integrations. You will write the Slack notification, the deployment gate and the test reporter yourself, or assemble them from container images. Tekton Hub helps a little; it is not the Actions marketplace.
Source integration. Triggering on a pull request, reporting status back to the commit, handling fork PRs safely — all of that is built into Actions and GitLab CI and is your problem here. Tekton Triggers gives you the webhook receiver; the rest is configuration you own.
Someone has to run it. You have traded a managed CI service for a controller in your cluster that needs upgrades, a webhook endpoint that needs to be reachable and secured, and log and artifact storage you provision.
When it is the right call
- You are already running the workload's pipelines as Kubernetes jobs anyway. ML training, data processing, large parallel batch — Argo Workflows is the correct tool and calling it CI is incidental.
- You are building a platform, not just pipelines. If you are exposing a golden path to fifty internal teams and want pipelines composed and enforced by your own controller, Tekton's CRD model is a foundation. This is what several internal developer platforms are built on.
- Air-gapped or sovereign requirements that rule out a SaaS control plane and where you are already committed to running Kubernetes.
- Heterogeneous build environments — a pipeline where each step needs a completely different image and resource profile is exactly what this model expresses well.
When it is not
If your goal is "build a container, run tests, deploy" for twenty microservices, and your code is on GitHub or GitLab, use the CI that came with your forge and put self-hosted runners on the Kubernetes cluster. You get the same bin-packing and autoscaling benefits, with the source integration and developer experience already built. This is the answer for most teams asking the question, and the runner-on-Kubernetes route is a fraction of the operational work.
The pattern we see most often in practice is a split: the forge's CI handles build and test, and Argo Workflows or Tekton handles the pipelines that are really batch compute. Each side is doing what it is good at, and neither is being bent into a shape it does not fit.
Whichever way you go, the security posture is the same as any CI on shared infrastructure — ephemeral pods, no ambient node credentials, OIDC federation for cloud access, and a namespace that nothing else shares.