Files
container.training/slides/k8s/gitworkflows.md
Jérôme Petazzoni 0b95eac799 ✒️ Merge ArgoCD chapter
With huge thanks to @antweiss and @guilhem

Includes and closes #602
2024-06-21 18:13:53 +02:00

5.6 KiB

Git-based workflows (GitOps)

  • Deploying with kubectl has downsides:

    • we don't know who deployed what and when

    • there is no audit trail (except the API server logs)

    • there is no easy way to undo most operations

    • there is no review/approval process (like for code reviews)

  • We have all these things for code, though

  • Can we manage cluster state like we manage our source code?


Reminder: Kubernetes is declarative

  • All we do is create/change resources

  • These resources have a perfect YAML representation

  • All we do is manipulate these YAML representations

    (kubectl run generates a YAML file that gets applied)

  • We can store these YAML representations in a code repository

  • We can version that code repository and maintain it with best practices

    • define which branch(es) can go to qa/staging/production

    • control who can push to which branches

    • have formal review processes, pull requests, test gates...


Enabling git-based workflows

  • There are a many tools out there to help us do that; with different approaches

  • "Git host centric" approach: GitHub Actions, GitLab...

    the workflows/action are directly initiated by the git platform

  • "Kubernetes cluster centric" approach: ArgoCD, [FluxCD]..

    controllers run on our clusters and trigger on repo updates

  • This is not an exhaustive list (see also: Jenkins)

  • We're going to talk mostly about "Kubernetes cluster centric" approaches here


The road to production

In no specific order, we need to at least:

  • Choose a tool

  • Choose a cluster / app / namespace layout
    (one cluster per app, different clusters for prod/staging...)

  • Choose a repository layout
    (different repositories, directories, branches per app, env, cluster...)

  • Choose an installation / bootstrap method

  • Choose how new apps / environments / versions will be deployed

  • Choose how new images will be built


Flux vs ArgoCD (1/2)

  • Flux:

    • fancy setup with an (optional) dedicated flux bootstrap command
      (with support for specific git providers, repo creation...)

    • deploying an app requires multiple CRDs
      (Kustomization, HelmRelease, GitRepository...)

    • supports Helm charts, Kustomize, raw YAML

  • ArgoCD:

    • simple setup (just apply YAMLs / install Helm chart)

    • fewer CRDs (basic workflow can be implement with a single "Application" resource)

    • supports Helm charts, Jsonnet, Kustomize, raw YAML, and arbitrary plugins


Flux vs ArgoCD (2/2)

  • Flux:

    • sync interval is configurable per app
    • no web UI out of the box
    • CLI relies on Kubernetes API access
    • CLI can easily generate custom resource manifests (with --export)
    • self-hosted (flux controllers are managed by flux itself by default)
    • one flux instance manages a single cluster
  • ArgoCD:

    • sync interval is configured globally
    • comes with a web UI
    • CLI can use Kubernetes API or separate API and authentication system
    • one ArgoCD instance can manage multiple clusters

Cluster, app, namespace layout

  • One cluster per app, different namespaces for environments?

  • One cluster per environment, different namespaces for apps?

  • Everything on a single cluster? One cluster per combination?

  • Something in between:

    • prod cluster, database cluster, dev/staging/etc cluster

    • prod+db cluster per app, shared dev/staging/etc cluster

  • And more!

Note: this decision isn't really tied to GitOps!


Repository layout

So many different possibilities!

  • Source repos

  • Cluster/infra repos/branches/directories

  • "Deployment" repos (with manifests, charts)

  • Different repos/branches/directories for environments

🤔 How to decide?


Permissions

  • Different teams/companies = different repos

    • separate platform team → separate "infra" vs "apps" repos

    • teams working on different apps → different repos per app

  • Branches can be "protected" (production, main...)

    (don't need separate repos for separate environments)

  • Directories will typically have the same permissions

  • Managing directories is easier than branches

  • But branches are more "powerful" (cherrypicking, rebasing...)


Resource hierarchy

  • Git-based deployments are managed by Kubernetes resources

    (e.g. Kustomization, HelmRelease with Flux; Application with ArgoCD)

  • We will call these resources "GitOps resources"

  • These resources need to be managed like any other Kubernetes resource

    (YAML manifests, Kustomizations, Helm charts)

  • They can be managed with Git workflows too!


Cluster / infra management

  • How do we provision clusters?

  • Manual "one-shot" provisioning (CLI, web UI...)

  • Automation with Terraform, Ansible...

  • Kubernetes-driven systems (Crossplane, CAPI)

  • Infrastructure can also be managed with GitOps


Example 1

  • Managed with YAML/Charts:

    • core components (CNI, CSI, Ingress, logging, monitoring...)

    • GitOps controllers

    • critical application foundations (database operator, databases)

    • GitOps manifests

  • Managed with GitOps:

    • applications

    • staging databases


Example 2

  • Managed with YAML/Charts:

    • essential components (CNI, CoreDNS)

    • initial installation of GitOps controllers

  • Managed with GitOps:

    • upgrades of GitOps controllers

    • core components (CSI, Ingress, logging, monitoring...)

    • operators, databases

    • more GitOps manifests for applications!


Concrete example

  • Source code repository (not shown here)

  • Infrastructure repository (shown below), single branch

@@INCLUDE[slides/k8s/gitopstree.txt]

???

:EN:- GitOps :FR:- GitOps