Chapter 28Lesson 03~210 minutes

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.

DesignFluxAgentLeast privilegePromotion

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

4. Layer GitLab authorization and Kubernetes RBAC

Use GitLab ci_access to decide which projects/groups/environments receive an Agent context, then use Kubernetes RBAC to decide what that identity can do. Current GitLab supports environment patterns directly in Agent CI access:

ci_access:
  projects:
    - id: platform/payments
      environments:
        - staging
    - id: platform/web
      environments:
        - review/*

On Premium/Ultimate, access_as: ci_job: {} can let Kubernetes authorize using CI-job impersonation metadata. On Free, keep the Agent service account narrowly permissioned; do not pretend project-level authorization alone creates namespace isolation.

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

  1. Is the target production? Prefer GitOps/Flux unless there is a documented reason for push-based mutation.
  2. Can the change be represented declaratively? If yes, version desired state and reconcile it.
  3. Which project/environment needs Agent access? Authorize only that scope.
  4. Which Kubernetes namespace/resources/verbs are required? Encode only those in RBAC.
  5. Which exact image digest is being promoted? Reject tag-only production changes.
  6. 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?

Does environment-restricted ci_access replace Kubernetes RBAC?

Why is rebuilding an image separately for production not artifact promotion?

Which current environment:kubernetes keys should be used for dashboard namespace and Flux resource?

When is a direct kubeconfig variable acceptable?

Next lesson

Next: failure diagnosis

Lesson 4 injects the mistakes that matter in production: broad credentials, over-authorized Agents, namespace collisions, green-before-healthy jobs and tag drift.

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.

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.

Ethereum / ERC-20
0x716c4Ab160C4B66F31a28AE2448BfF68fc3a2ef0 Send only Ethereum/ERC-20 compatible assets to this address.