Kubernetes Agent, Cluster Access, GitOps-Oriented Delivery, Kubernetes Deployments, and Environment Integration: Configuration, Design Choices, and Tradeoffs
Choose deliberately between CI push and Flux GitOps, Agent and direct kubeconfig, isolated and shared namespaces, and mutable tags versus digests while preserving least privilege and auditability.
Learning objectives
- Choose between CI push and Flux GitOps based on control-plane and trust requirements.
- Compare Agent connectivity with a direct kubeconfig variable and understand why static production kubeconfigs are high-risk.
- Design project/namespace boundaries, Agent authorization and Kubernetes RBAC together.
- Choose immutable artifact promotion over rebuild-or-tag drift.
- Use current GitLab environment/dashboard syntax without depending on deprecated certificate-based behavior.
1. Start with the state you must protect
The design problem is not “which kubectl command is
shortest?” It is who may change which cluster/namespace, which
immutable artifact may be promoted, what desired state is reviewed,
who reconciles it, what GitLab records, and how runtime health is
independently proven. Keep CI_PIPELINE_SOURCE and
CI_COMMIT_SHA tied to the manifest and image digest.
2. CI push versus GitOps reconciliation
| Choice | Use when | Strength | Main risk/control |
|---|---|---|---|
| CI/CD push through Agent | Disposable/dev workflows, migrations, imperative operations that GitOps does not model well | Simple pipeline-driven sequence; Agent avoids direct inbound API exposure | Pipeline obtains mutation capability. GitLab documents this as a weaker security model and advises against production deployment with this workflow. |
| Flux GitOps | Production desired state can be declared and reconciled continuously | Cluster-side controller reconciles reviewed Git/OCI desired state and drift | Must govern repository/OCI write access, Flux scope and reconciliation health. |
GitOps also changes recovery. Reconciliation can restore declared state after drift; a push pipeline usually needs an explicit rerun or repair. Neither model makes application rollback automatically safe—stateful services and schema changes still require domain-aware procedures.
3. Agent versus direct kubeconfig
| Dimension | GitLab Agent | Static kubeconfig variable |
|---|---|---|
| Credential lifetime/exposure | Agent-mediated context is supplied to authorized jobs; no need to store a production kubeconfig in project variables | Usually long-lived bearer/client credential copied into CI variable state |
| Network direction | Agent initiates outbound connection to KAS | Runner must directly reach Kubernetes API endpoint |
| Authorization surface |
GitLab ci_access plus Kubernetes
service-account/RBAC or optional impersonation
|
Whatever authority the embedded kubeconfig credential has |
| Revocation/audit | Change Agent authorization/RBAC; preserve project/environment scope | Rotate/delete kubeconfig credential everywhere it was copied |
| Recommended production direction | Agent + GitOps/Flux where applicable | Avoid as default; use only with a deliberate bounded design |
5. Per-project namespace or shared namespace?
| Model | Advantages | Risks | Observable evidence |
|---|---|---|---|
| Dedicated namespace per app/team | Clear quotas, RBAC, labels, NetworkPolicy and cleanup boundary | Namespace sprawl; platform automation needed | Namespace UID, RoleBindings, quotas, app labels, owner annotations |
| Shared namespace | Fewer objects; useful for tightly coupled small systems | Name collisions, broader lateral access, harder quotas and cleanup ownership | Resource owner labels, service accounts, RBAC subjects, collision tests |
| Ephemeral namespace per MR | Strong review-app isolation and cleanup boundary | Resource/cost churn; needs deterministic cleanup | MR/ref → namespace mapping, TTL/stop evidence, resource inventory |
Do not encode arbitrary branch text directly into privileged cluster identifiers without normalization and collision handling. Chapter 20’s dynamic-environment discipline applies here too.
6. Mutable tag or image digest?
A tag is useful release metadata; a digest is deployment identity. A safe promotion pipeline produces one image, verifies it, records its registry digest, and promotes references to those same bytes through environments. Rebuilding separately in staging and production creates two artifacts even if the source SHA is the same.
containers:
- name: payments
image: registry.example.test/platform/payments@sha256:0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef
imagePullPolicy: IfNotPresent
imagePullPolicy does not turn a tag into an immutable
identity. The digest does.
7. Raw manifests, Helm, Kustomize and OCI desired state
The format choice should not weaken evidence. Record the exact rendered desired state or versioned package/OCI digest that reached reconciliation. For Helm, preserve chart version/digest and values identity. For Kustomize, preserve the Git revision and rendered output hash. For Flux OCI artifacts, preserve the OCI digest and Flux source/reconciliation status.
8. GitLab environment integration: history, dashboard and health remain separate
Current environment YAML can associate a deployment with an Agent and dashboard namespace:
environment:
name: production
url: https://app.example.test
kubernetes:
agent: platform/cluster-agents:prod-agent
dashboard:
namespace: app-production
This improves traceability and dashboard visibility. It does not grant Kubernetes RBAC, does not perform the deployment by itself, and does not prove the HTTP service is healthy.
9. Flux resource integration
For a Flux-backed environment, the dashboard can also identify the Flux resource using current nested syntax:
environment:
name: production
kubernetes:
agent: platform/cluster-agents:prod-agent
dashboard:
namespace: flux-system
flux_resource_path: kustomize.toolkit.fluxcd.io/v1/namespaces/flux-system/kustomizations/app-production
The older direct kubernetes: namespace and
kubernetes: flux_resource_path keys are deprecated for
dashboard configuration.
10. Runner host state is not cluster state
A runner only needs network/tooling access appropriate to the chosen
workflow. With the Agent, the runner does not need to be installed
in the target cluster. Pin or record the
kubectl/Helm/Flux tool versions used by the job; a
different client/toolchain can change rendering and API behavior
without changing repository YAML.
kubectl version --client --output=yaml
helm version --short 2>/dev/null || true
flux version --client 2>/dev/null || true
kubectl config current-context
kubectl auth can-i patch deployments -n app-staging
11. Security boundaries that should stay explicit
- Do not place a production cluster-admin kubeconfig in a general CI/CD variable.
- Do not authorize an entire group to an Agent when only one deployment project needs it.
- Do not give a namespaced application deployer permission to create ClusterRoles or read unrelated Secrets.
- Do not run untrusted merge-request code in a job that receives production cluster access.
- Do not use a mutable image tag as the only production artifact identity.
- Do not interpret GitLab environment visibility as Kubernetes authorization.
12. Tier/offering reality
| Capability | Current availability used here | Mandatory lab treatment |
|---|---|---|
| Agent CI/CD workflow | Free / Premium / Ultimate | Mapped conceptually; no real Agent required. |
Project/group/environment ci_access |
Free / Premium / Ultimate | Explained and represented in sample config. |
CI-job impersonation access_as: ci_job |
Premium / Ultimate | Optional only; local ServiceAccount RBAC is the Free substitute. |
| Kubernetes dashboard | Free / Premium / Ultimate; Beta |
Optional mapping; local kubectl evidence is
mandatory.
|
| Flux GitOps | External open-source Flux + GitLab integration | Concept/design mapping; no cloud or managed cluster required. |
| Certificate-based cluster integration | Deprecated | Not used. |
13. Worked scenario: choose the control model
A 20-person team deploys a stateless web service to staging and production. Staging needs fast previews; production requires strong drift control and minimal CI credentials.
| Decision | Choice | Why | Proof |
|---|---|---|---|
| Staging reviews | Agent CI/CD push to per-review namespace | Short-lived disposable state and direct feedback are acceptable | MR/ref → environment/namespace, context, digest, rollout and cleanup evidence |
| Production | Flux GitOps from reviewed desired-state repository/OCI artifact | Keeps reconciliation capability in cluster and minimizes pipeline mutation power | Desired-state revision/digest, Flux Ready state, workload imageID, GitLab deployment/environment record |
| Artifact promotion | Same image digest in staging and production | Eliminates rebuild variance | Registry digest + producer SHA/pipeline + runtime imageID |
| Cluster access | Narrow Agent authorization + namespace RBAC | Limits project and Kubernetes blast radius |
ci_access, RoleBinding,
auth can-i evidence
|
14. Decision checklist
- Is the target production? Prefer GitOps/Flux unless there is a documented reason for push-based mutation.
- Can the change be represented declaratively? If yes, version desired state and reconcile it.
- Which project/environment needs Agent access? Authorize only that scope.
- Which Kubernetes namespace/resources/verbs are required? Encode only those in RBAC.
- Which exact image digest is being promoted? Reject tag-only production changes.
- Which GitLab environment/deployment record should link to the rollout? Capture it separately from health.
Knowledge check
Why might a production team choose Flux even though a CI job can run kubectl through the Agent?
Flux keeps reconciliation capability in the cluster, continuously reconciles declared state, and matches GitLab’s current GitOps recommendation. GitLab describes push-based CI/CD as a weaker security model for production.
Does environment-restricted ci_access replace Kubernetes RBAC?
No. It controls which jobs receive/access the Agent connection. Kubernetes RBAC still determines what the resulting identity can do in the cluster.
Why is rebuilding an image separately for production not artifact promotion?
A rebuild creates new bytes and therefore a new digest. Promotion should move/reference the exact previously verified artifact.
Which current environment:kubernetes keys should be used for dashboard namespace and Flux resource?
Use kubernetes.dashboard.namespace and kubernetes.dashboard.flux_resource_path. The older direct namespace/flux_resource_path form is deprecated.
When is a direct kubeconfig variable acceptable?
Only in a deliberately bounded use case with strong rotation/scope controls; it should not be the default production GitLab integration when the Agent/GitOps model is available.
Version and compatibility note
GitLab and GitLab Runner evolve continuously. Treat version-sensitive YAML, runner/executor behavior, APIs, security features, policy controls, tiers, and deprecations as assumptions to verify against the current official GitLab documentation before production use. Preserve the exact project/ref/SHA, compiled configuration, pipeline/job IDs, runner/tool versions, and external target evidence used for any reproducible lab or incident record.
Official references and version notes
Documentation verification date: 2026-09-12.
Current GitLab documentation lists the Agent CI/CD workflow as Free,
Premium, and Ultimate on GitLab.com, Self-Managed, and Dedicated.
Authorized CI/CD jobs receive a KUBECONFIG containing
contexts for authorized agent connections; the context identifies
the agent configuration project and agent name.
ci_access can authorize projects/groups and can
restrict access to named environment patterns. The current per-agent
authorization limit is 500 projects and 500 groups. CI-job
impersonation with access_as: ci_job is
Premium/Ultimate; the mandatory lab therefore demonstrates true
Kubernetes namespace-scoped ServiceAccount RBAC locally instead of
pretending that paid impersonation is Free. GitLab recommends Flux
for GitOps; the Agent’s legacy built-in pull-based GitOps
functionality was removed in GitLab 17.0. Certificate-based cluster
integration was deprecated in GitLab 14.5. The Kubernetes dashboard
is currently Beta and available on all tiers. For
environment:kubernetes, dashboard namespace/Flux
resource settings belong under dashboard:; the older
direct namespace/flux_resource_path form
is deprecated. GitLab’s current Agent overview explicitly
characterizes the CI/CD workflow as push-based and weaker for
production; this chapter therefore uses push-based mutation for the
disposable lab, not as the production recommendation.
- Using GitLab CI/CD with a Kubernetes cluster — official reference.
- GitLab Agent for Kubernetes — official reference.
- Get started connecting a Kubernetes cluster — official reference.
- Install the Agent for Kubernetes — official reference.
- Migrate legacy Agent GitOps to Flux — official reference.
- Dashboard for Kubernetes — official reference.
- CI/CD YAML syntax — environment:kubernetes — official reference.
- Deprecated CI/CD keywords — official reference.
- Migrate from certificate-based Kubernetes integration — official reference.
- GitLab-managed Kubernetes resources — official reference.
- Kubernetes RBAC authorization — official reference.
- Kubernetes Deployments — official reference.
- kind quick start — official reference.
- Flux documentation — official reference.
Current assumptions used in this chapter: Version-sensitive YAML, Runner/executor behavior, APIs, security features, policy controls, tiers, and deprecations must be verified against the exact GitLab, GitLab Runner, tool, and external-system versions used in production. Preserve the exact project/ref/SHA, compiled configuration, pipeline/job IDs, runner/tool versions, and external target evidence used for reproducible work.
Keep the academy open
Support free, practical DevOps education.
Every lesson is designed to remain readable in a browser, downloadable from GitHub, and usable without a paid learning platform. Contributions help expand and maintain the curriculum.
0x716c4Ab160C4B66F31a28AE2448BfF68fc3a2ef0
Send only Ethereum/ERC-20 compatible assets to this
address.