The GitLab Agent for Kubernetes is the only way GitLab CI/CD can directly interact with your Kubernetes clusters.

Let’s see it in action. Imagine we have a simple hello-world application we want to deploy.

First, we need to install the agent in our cluster. This involves applying a manifest file that registers the agent with GitLab.

apiVersion: v1
kind: Namespace
metadata:
  name: gitlab-agent
---
apiVersion: apps/v1
kind: Deployment
metadata:
  name: gitlab-agent
  namespace: gitlab-agent
spec:
  replicas: 1
  selector:
    matchLabels:
      app: gitlab-agent
  template:
    metadata:
      labels:
        app: gitlab-agent
    spec:
      containers:
      - name: agent
        image: gitlab.com/gitlab-org/gitlab-agent/gitlab-agent-for-kubernetes:v16.6.0
        args:
        - --config=/etc/agent/config
        - --log-format=json
        env:
        - name: AGENT_SECRET_KEY
          valueFrom:
            secretKeyRef:
              name: gitlab-agent-secret
              key: token
        volumeMounts:
        - name: config-volume
          mountPath: /etc/agent
      volumes:
      - name: config-volume
        configMap:
          name: gitlab-agent-config

This creates a gitlab-agent namespace, a Deployment for the agent itself, and a ConfigMap and Secret that will hold the agent’s configuration and its unique token. The AGENT_SECRET_KEY environment variable pulls the token from the gitlab-agent-secret.

Next, we need to create the agent in GitLab. Navigate to your project’s Infrastructure -> Kubernetes clusters and click Connect a cluster. Choose the "GitLab Agent" option. GitLab will then provide a config.yaml snippet and a token.

Your config.yaml on the agent’s side should look something like this:

ci_access:
  projects:
    - id: your-group/your-project

agent:
  token: gr0ss-token-from-gitlab-ui-here

The id under ci_access specifies which GitLab projects are allowed to use this agent for CI/CD. The token is the secret key that authenticates the agent to GitLab.

Now, in your .gitlab-ci.yml file, you can define a job that uses the agent. This job will run within your Kubernetes cluster.

deploy:
  stage: deploy
  image: registry.gitlab.com/gitlab-org/cluster-integration/kubectl:latest
  script:
    - echo "Deploying application..."
    - kubectl apply -f k8s/deployment.yaml
    - kubectl apply -f k8s/service.yaml
  environment:
    name: production
    kubernetes:
      namespace: default
      agent: your-group/your-project:your-agent-name

The crucial part here is environment.kubernetes.agent. This tells GitLab CI/CD to route the execution of this job through the specified agent. The format is group/project:agent-name. The image for the job, registry.gitlab.com/gitlab-org/cluster-integration/kubectl:latest, is a container that has kubectl installed, allowing us to interact with the cluster.

The agent itself acts as a bridge. When a CI/CD job is triggered that targets a Kubernetes cluster via an agent, GitLab sends a request to the agent’s WebSocket server. The agent then establishes a secure connection back to GitLab. This outbound-only connection is key: it means you don’t need to expose your Kubernetes API server to the public internet. The agent polls GitLab for work, and when it finds a job targeted at its cluster, it pulls the job definition and executes it using the cluster’s credentials.

The kubernetes.namespace within the environment block specifies where in the cluster the CI/CD job should operate. This is where your kubectl apply commands will run.

This system fundamentally shifts how CI/CD interacts with Kubernetes. Instead of your CI runner needing direct access to the cluster’s API, the agent in the cluster pulls instructions from GitLab. This significantly enhances security by avoiding the need to expose your Kubernetes API to external networks. The agent handles authentication and authorization, ensuring only authorized GitLab projects can deploy to your cluster.

What most people miss is that the agent’s configuration (config.yaml) also defines what CI/CD can do. You can restrict access to specific projects (ci_access), and importantly, you can configure repositories to allow the agent to clone Git repositories directly from GitLab, enabling it to fetch Kubernetes manifests without the CI job needing to check out the code itself. This is powerful for GitOps workflows where the agent is responsible for maintaining the desired state from a dedicated GitOps repository.

The next logical step after getting deployments working is to configure the agent for GitOps, using its ability to monitor a separate repository for manifest changes.

Want structured learning?

Take the full Gitlab course →