GitLab 20 🦊 GitOps Workflows and Kubernetes Cluster Integrations
The previous chapter covered deploying applications to named environments. This chapter covers the mechanism that connects GitLab to a Kubernetes cluster and the workflow that keeps the cluster synchronized with a Git repository. GitLab provides a Kubernetes agent that runs inside the cluster and maintains a bidirectional connection to GitLab. The recommended workflow is GitOps: the cluster pulls its desired state from a Git repository (via Flux), and the agent provides the connection and observability. The exam tests the distinction between the GitOps workflow (pull-based, recommended) and the CI/CD workflow (push-based, weaker security model), the agent registration and installation steps, and the role of Flux as the GitOps operator .
Key point: The GitLab agent runs inside the cluster and communicates with GitLab via the agent server (KAS). The GitOps workflow uses Flux to pull manifests from a Git repository and reconcile the cluster state. The CI/CD workflow uses the agent to run kubectl commands from a pipeline, pushing changes to the cluster. GitLab recommends GitOps for production and considers the CI/CD workflow a migration path with a weaker security model .
Why GitOps and the Kubernetes agent exist
The cluster connection problem. A Kubernetes cluster behind a firewall or NAT cannot accept inbound connections from GitLab. The agent solves this by opening an outbound bidirectional channel to the agent server (KAS). GitLab communicates with the cluster through this channel, and the cluster does not need a public endpoint . The agent also provides real-time API access, event push, and a low-latency cache of Kubernetes objects.
The push versus pull problem. In a CI/CD workflow, the pipeline pushes changes to the cluster. This works, but the pipeline must hold credentials with write access to the cluster, and the security model is weaker because every job has the same access. In a GitOps workflow, the cluster pulls changes from the Git repository. The agent does not need write access from the pipeline; Flux reconciles the state, and the agent provides observability. The GitOps workflow is pull-based, and GitLab actively invests in it as the first-class experience .
The drift problem. A cluster can be modified by kubectl commands, Helm releases, or operators. These changes are not in the Git repository, and the cluster state drifts from the desired state. GitOps with Flux includes automatic drift remediation: Flux compares the cluster state to the Git repository and reapplies the manifests when they diverge. The agent provides the visualization of the cluster state in the GitLab UI .
The agent registration problem. The agent must be registered before it can be installed. The registration creates a record in GitLab and generates an access token. The token is used by the Helm installation to authenticate the agent. The agent configuration file (.gitlab/agents/<agent-name>/config.yaml) is optional but required for authorizing other projects or groups to access the agent .
The trade-off. The GitOps workflow requires Flux to be bootstrapped in the cluster, and it requires the manifests to be structured for Flux reconciliation. The CI/CD workflow is simpler to set up for a single pipeline but has a weaker security model and is not recommended for production .
a. Registering and installing the agent
The agent is registered in a GitLab project. The registration generates an access token, which is used by the Helm installation.
# Register the agent
Operate → Kubernetes clusters → Connect a cluster (agent)
Agent name: my-agent
Register
# Copy the access token.
The agent is installed with Helm. The default installation grants cluster-admin to the agent’s service account, which is not recommended for production. The installation should be customized to use a service account with restricted permissions .
# Install the agent with Helm
helm repo add gitlab https://charts.gitlab.io
helm repo update
helm upgrade --install my-agent gitlab/gitlab-agent \
--namespace gitlab-agent-my-agent \
--create-namespace \
--set image.tag=<current-agent-version> \
--set config.token=<your-token> \
--set config.kasAddress=wss://kas.gitlab.com
The config.kasAddress is the agent server address. On GitLab.com, it is wss://kas.gitlab.com. On self-managed instances, it is wss://<gitlab-hostname> or grpcs://<gitlab-hostname> .
b. The GitOps workflow with Flux
The GitOps workflow uses Flux as the GitOps operator. Flux is bootstrapped in the cluster and configured to watch a Git repository (or an OCI registry) for manifests. The agent detects the Flux GitRepository objects and configures a Receiver, which triggers reconciliation when a git push occurs .
# .gitlab/agents/<agent-name>/config.yaml
gitops:
manifest_projects:
- id: my-group/my-manifests
paths:
- glob: 'manifests/**/*.yaml'
The manifest_projects block tells the agent which GitLab projects contain the Kubernetes manifests. The agent detects changes and notifies Flux. Flux pulls the manifests and applies them to the cluster.
The source for Flux can be a Git repository or an OCI registry. GitLab recommends using OCI images for source control because they are immutable and can be scanned for security issues. The default Git branch can store cluster state without triggering a sync when OCI is used .
The immediate Git repository reconciliation feature reduces the delay between a git push and the cluster reconciliation. The agent detects the push and triggers the Flux Receiver. The GitRepository.spec.interval should still be set to an acceptable duration because not every push event is guaranteed to be received .
c. The CI/CD workflow: push-based deployment
The CI/CD workflow uses the agent to run kubectl commands from a pipeline. The agent connection provides a kubeconfig context, and the pipeline selects it with kubectl config use-context.
deploy:
stage: deploy
image: debian:13-slim
variables:
KUBECTL_VERSION: v1.34
before_script:
- kubectl config use-context my-group/my-project:my-agent
script:
- kubectl apply -f manifests/
The context format is <path/to/agent/project>:<agent-name>. The agent connection is available in every CI/CD job that is authorized to use it. The authorization is configured in the agent configuration file under ci_access .
The CI/CD workflow is considered push-based because GitLab pushes changes to the cluster. The security model is weaker because the pipeline credentials have the same access as the agent’s service account. GitLab recommends this workflow only for pipeline-driven processes or as a migration path, not for production deployments .
The access_as attribute in the agent configuration file can restrict the pipeline’s access. The ci_job: {} setting impersonates the CI/CD job, so the permissions are scoped to the job rather than the agent’s service account .
Complete Example Session
# ============================================
# PART 1: REGISTER THE AGENT
# ============================================
# Operate → Kubernetes clusters → Connect a cluster (agent)
# Agent name: production-agent
# Register
# Copy the access token.
# ============================================
# PART 2: CREATE THE AGENT CONFIG
# ============================================
cat > .gitlab/agents/production-agent/config.yaml <<'EOF'
gitops:
manifest_projects:
- id: my-group/k8s-manifests
paths:
- glob: 'manifests/**/*.yaml'
EOF
git add .gitlab/agents/production-agent/config.yaml
git commit -m "Add agent configuration"
git push origin main
# ============================================
# PART 3: INSTALL THE AGENT
# ============================================
helm repo add gitlab https://charts.gitlab.io
helm repo update
helm upgrade --install production-agent gitlab/gitlab-agent \
--namespace gitlab-agent-production \
--create-namespace \
--set config.token=<your-token> \
--set config.kasAddress=wss://kas.gitlab.com
# ============================================
# PART 4: VERIFY THE CONNECTION
# ============================================
# Operate → Kubernetes clusters
# Connection status: Connected
# ============================================
# PART 5: BOOTSTRAP FLUX
# ============================================
flux bootstrap gitlab \
--owner=my-group \
--repository=k8s-manifests \
--branch=main \
--path=manifests
# ============================================
# PART 6: ADD A MANIFEST
# ============================================
cat > manifests/nginx.yaml <<'EOF'
apiVersion: apps/v1
kind: Deployment
metadata:
name: nginx
spec:
replicas: 1
selector:
matchLabels:
app: nginx
template:
metadata:
labels:
app: nginx
spec:
containers:
- name: nginx
image: nginx:1.25
EOF
git add manifests/nginx.yaml
git commit -m "Add nginx deployment"
git push origin main
# ============================================
# PART 7: OBSERVE THE RECONCILIATION
# ============================================
# The agent detects the push and triggers Flux.
# Flux applies the manifest to the cluster.
# Operate → Kubernetes clusters → View
# The nginx deployment appears.
# ============================================
# PART 8: CI/CD WORKFLOW (ALTERNATIVE)
# ============================================
deploy:
stage: deploy
image: debian:13-slim
before_script:
- kubectl config use-context my-group/k8s-manifests:production-agent
script:
- kubectl apply -f manifests/nginx.yaml
# ============================================
# PART 9: VERIFY THE CLUSTER STATE
# ============================================
kubectl get deployments
# NAME READY UP-TO-DATE AVAILABLE
# nginx 1/1 1 1
The nine parts trace the agent lifecycle: registration, configuration, installation, verification, Flux bootstrap, manifest addition, reconciliation observation, CI/CD alternative, and cluster verification.
Quick Reference
Agent Registration
| Step | Location |
|---|---|
| Register agent | Operate → Kubernetes clusters |
| Token | Generated at registration |
| Config file | .gitlab/agents/<name>/config.yaml |
Installation
| Method | Command |
|---|---|
| Helm | helm upgrade --install <name> gitlab/gitlab-agent |
| KAS address (GitLab.com) | wss://kas.gitlab.com |
| KAS address (self-managed) | wss://<hostname> |
Workflows
| Workflow | Model | Recommended |
|---|---|---|
| GitOps | Pull (Flux) | Yes |
| CI/CD | Push (kubectl) | Migration only |
Agent Configuration
| Key | Purpose |
|---|---|
gitops.manifest_projects | Projects with manifests |
ci_access.projects | Projects authorized for CI/CD |
access_as | Impersonation mode |
Context Format
| Workflow | Context |
|---|---|
| GitOps | Not needed (Flux handles) |
| CI/CD | <path/to/agent/project>:<agent-name> |
Best Practices
✅ Do This:
gitops:
manifest_projects:
- id: my-group/k8s-manifests
<!-- Configure GitOps for the agent --> # ✅
kubectl config use-context my-group/my-project:my-agent
<!-- Select the agent context in CI/CD --> # ✅
# Use OCI registry for Flux source
<!-- Immutable and scannable --> # ✅
❌ Don’t Do This:
# Grant cluster-admin to the agent in production
<!-- Overly broad permissions --> # ❌
# Use CI/CD workflow for production deployments
<!-- Weaker security model --> # ❌
# Skip Flux bootstrap for GitOps
<!-- Flux is the reconciler --> # ❌
Common Pitfalls
| Pitfall | Why It Happens | Fix |
|---|---|---|
| Agent not connecting | Wrong KAS address | Use wss://kas.gitlab.com |
| GitOps not reconciling | Flux not bootstrapped | Run flux bootstrap |
| CI/CD context not found | Agent not authorized | Check ci_access in config |
| Manifests not applied | Wrong path in manifest_projects | Verify glob pattern |
| Drift not remediated | Flux not running | Check Flux pods |
Real-World Examples
1. Register Agent
Operate → Kubernetes clusters → Connect a cluster
2. Agent Config
gitops:
manifest_projects:
- id: my-group/manifests
3. Install with Helm
helm upgrade --install my-agent gitlab/gitlab-agent --set config.token=...
4. Verify Connection
Operate → Kubernetes clusters → Connected
5. Flux Bootstrap
flux bootstrap gitlab --owner=my-group --repository=manifests
6. Add Manifest
apiVersion: apps/v1
kind: Deployment
metadata:
name: nginx
7. CI/CD Context
before_script:
- kubectl config use-context my-group/project:my-agent
8. CI/CD Deploy
script:
- kubectl apply -f manifests/
9. Check Cluster
kubectl get deployments
10. View in GitLab
Operate → Kubernetes clusters → View
Visual
GitOps Workflow
┌──────────────────────────────────────────────┐
│ GitLab project (manifests) │
└──────────────────┬───────────────────────────┘
│ git push
▼
┌──────────────────────────────────────────────┐
│ Agent detects push │
│ Triggers Flux Receiver │
└──────────────────┬───────────────────────────┘
│
▼
┌──────────────────────────────────────────────┐
│ Flux pulls manifests │
│ Applies to cluster │
└──────────────────┬───────────────────────────┘
│
▼
┌──────────────────────────────────────────────┐
│ Cluster state reconciled │
│ Agent reports to GitLab UI │
└──────────────────────────────────────────────┘
CI/CD Workflow
┌──────────────────────────────────────────────┐
│ GitLab pipeline │
└──────────────────┬───────────────────────────┘
│ kubectl apply
▼
┌──────────────────────────────────────────────┐
│ Agent connection (KAS) │
└──────────────────┬───────────────────────────┘
│
▼
┌──────────────────────────────────────────────┐
│ Kubernetes cluster │
│ (push-based) │
└──────────────────────────────────────────────┘
Summary
| Item | Value |
|---|---|
| Agent purpose | Cluster connection and observability |
| Agent server | KAS (wss://kas.gitlab.com on GitLab.com) |
| Recommended workflow | GitOps with Flux |
| GitOps model | Pull-based |
| CI/CD model | Push-based |
| Flux bootstrap | flux bootstrap gitlab |
| Agent config | .gitlab/agents/<name>/config.yaml |
| CI/CD context | <path/to/agent/project>:<agent-name> |
Key takeaways:
- The agent connects the cluster to GitLab. It runs inside the cluster and opens an outbound channel to KAS. It does not require a public endpoint on the cluster .
- The GitOps workflow is recommended. Flux pulls manifests from a Git repository or OCI registry and reconciles the cluster state. The agent provides the connection and the GitLab UI visualization .
- The CI/CD workflow is push-based. The pipeline runs
kubectlcommands through the agent connection. It is simpler for pipeline-driven processes but has a weaker security model and is not recommended for production . - Flux is the GitOps operator. It must be bootstrapped in the cluster. The agent detects Flux
GitRepositoryobjects and triggers reconciliation on push . - The agent configuration file is optional but required for authorization. The
gitops.manifest_projectsblock tells the agent which projects contain manifests. Theci_accessblock authorizes projects to use the agent from CI/CD .
Remember: The agent is the connection. The GitOps workflow is the pull. The CI/CD workflow is the push. Flux is the reconciler. The agent configuration is the authorization. The exam tests the distinction between the two workflows and the components that make each work.
Stop using slow, ad-bloated tool sites! 🤮
🔎 Search “KandZ Tools” on Google to use many professional utilities for free.
KandZ.me is the ultimate minimalist hub for:
✅ Finance (Mortgage, Interest, Inflation)
✅ Tech (Base64, JSON, Dev Suite, IP)
✅ Health (BMI, BMR, TDEE)
✅ Productivity (Timer, Workspace, QR)
⚡️ Fast & Private
🔒 No data leaves your device
💎 100% Free
🔗 Use it now: https://tools.kandz.me
🔖 Bookmark it—you’ll need it later!