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.