- references
- https://argo-cd.readthedocs.io/en/stable/
- https://www.atlassian.com/git/tutorials/gitops
- https://about.gitlab.com/topics/gitops/
- https://codefresh.io/learn/gitops/
- https://chatgpt.com/
- https://www.harness.io/blog/what-is-argo-cd
- https://devtron.ai/what-is-argo-cd-the-gitops-tool-for-kubernetes
- https://medium.com/@akulamanojkumar988/argo-cd-a909b5c62acb
- goals of this workshop
- introduction to GitOps and ArgoCD
- principles and benefits of GitOps
- how ArgoCD implements these principles to manage Kubernetes deployments
- hands-on installation and setup
- install and configure ArgoCD on a local Kubernetes cluster running with Docker Desktop
- application deployment with ArgoCD
- continuous deployment and syncing
- explore how to automatically sync application states from a Git repository to a Kubernetes cluster
- best practices and advanced features
- automated sync policies and notifications
- introduction to GitOps and ArgoCD
- workshop plan
- it may be interesting to first take a look here: https://github.com/mtumilowicz/go-continuous-deployment-workshop
- installing argocd
- run k8s locally with docker desktop
- install argocd
kubectl create namespace argocd kubectl apply -n argocd -f https://raw.githubusercontent.com/argoproj/argo-cd/stable/manifests/install.yaml
- log into argocd
kubectl port-forward svc/argocd-server -n argocd 8080:443
kubectl -n argocd get secret argocd-initial-admin-secret -o jsonpath="{.data.password}" | base64 -d; echo
- it is password
- https://localhost:8080
- login: admin
- password from previous substep
- once you changed the password => delete the argocd-initial-admin-secret from the Argo CD namespace
- no other purpose than to store the initially generated password
- once you changed the password => delete the argocd-initial-admin-secret from the Argo CD namespace
- verify that there is nothing in
Applications
- adding app
- checkout this app: https://github.com/mtumilowicz/helm-workshop
- create 1.1 docker image with
greeting
endpoint - create 1.2 docker image with
greeting2
endpoint - command:
./gradlew bootBuildImage
- create 1.1 docker image with
kubectl apply -f greeting-app/application.yaml
- verify that there is app added in
Applications
- http://localhost:31234/app/greeting
- should return
greeting
- should return
- checkout this app: https://github.com/mtumilowicz/helm-workshop
- sync
push commit that changes deployment.image.version
- from
1.1
and1.2
- from
- wait few seconds
- verify that argocd is in sync for that App
- http://localhost:31234/app/greeting
- should return
greeting2
- should return
- problem: configuration still feels disconnected from the live system
- technologies like Docker Containers, Ansible, Terraform, and Kubernetes utilize static declarative configuration files
- configuration files are naturally added to Git for tracking and review
- stored in a central location, documented and accessible by many team members
- configuration merged => live system is manually updated
- to match the state of the static repo
- solution: exact problem GitOps solves
- is code-based infrastructure and operational procedures that rely on Git as a source control system
- evolution of Infrastructure as Code (IaC) and a DevOps best practice
- leverages Git as the single source of truth
- mechanism for creating, updating, and deleting system architecture
- any configuration drift, such as manual changes or errors, is overwritten by GitOps automation
- environment converges on the desired state defined in Git
- live syncing pull request workflow is the core essence of GitOps
- ensures that a system’s cloud infrastructure is immediately reproducible based on the state of a Git repository
- GitOps "operator"
- mechanism that sits between the pipeline and the orchestration system
- pull request starts the pipeline that then triggers the operator
- operator examines the state of the repository and then start of the orchestration and syncs them
- vs DevOps
- GitOps is a branch of DevOps
- in GitOps: Git repository is the source of truth for the deployment state
- uses Git workflows
- in DevOps: application or server configuration files is the source of truth for the deployment state
- may not necessarily be centralized in a single repository
- uses configuration management tools (like Ansible)
- continuous reconciliation may not be a primary focus
- traditional CD and GitOps differ on the core principles of push and pull-based deployments
- most CI/CD processes work on a push mechanism
- things move to their respective destination at the trigger of an event
- example: developer has to configure the clusters using tools like Kubectl and Helm in the pipeline to apply changes
- pull-based CD mechanism means the destination triggers an event to pull the data from the source(git) to deploy at the destination
- most CI/CD processes work on a push mechanism
- cons
- automating git commits may create conflicts
- multiple CI processes can cause conflicts when writing to the same repository
- example: when multiple CI processes try to push changes to the same branch
- Git cannot automatically resolve the conflicts, leading to potential integration issues
- example: when multiple CI processes try to push changes to the same branch
- solution: using multiple repositories
- example: one for each namespace
- multiple CI processes can cause conflicts when writing to the same repository
- too many git repositories
- number of GitOps repositories typically increases with each new environment or application
- solution: use fewer Git repositories (e.g., one per cluster)
- doesn’t centrally manage secrets
- secrets are manage outside the standard CI/CD process
- automating git commits may create conflicts
- is a declarative, GitOps continuous delivery tool for Kubernetes
- turns "ClickOps" into GitOps
- follows GitOps pattern of using Git repositories as the source of truth for defining the desired application state
- Kubernetes manifests can be specified in several ways
- helm
- values
- As of v2.6, values files can be sourced from a separate repository than the Helm chart (multiple sources for Applications)
- most common scenario
- use an external/public Helm chart and override the Helm values with your own local values
- cloning the Helm chart => duplication + need to monitor it manually for upstream changes
- use an external/public Helm chart and override the Helm values with your own local values
- is a beta feature
- most common scenario
- declarative syntax
source: helm: valueFiles: - values-production.yaml
- As of v2.6, values files can be sourced from a separate repository than the Helm chart (multiple sources for Applications)
- release name
- overriding the Helm release name might cause problems when the chart you are deploying is using the app.kubernetes.io/instance label
- declarative syntax
source: helm: releaseName: myRelease
- hooks
- Argo CD cannot know if it is running a first-time "install" or an "upgrade" - every operation is a "sync'.
- apps that have pre-install and pre-upgrade will have those hooks run at the same time
- Argo CD cannot know if it is running a first-time "install" or an "upgrade" - every operation is a "sync'.
- values
- other: kustomize, jsonnet, plain directory of YAML/json manifests, custom
- helm
- Kubernetes manifests can be specified in several ways
- automates the deployment of the desired application states in the specified target environments
- can track updates to branches, tags, or pinned to a specific version of manifests at a Git commit
- every 3m (by default) Argo CD checks for changes to the app manifests
- to eliminate delay from polling, the API server can be configured to receive webhook events
- example: Git webhook notifications from GitHub
- assumes by default that manifests only change when the repo changes
- change this duration using the
timeout.reconciliation
setting in the argocd-cm ConfigMap
- to eliminate delay from polling, the API server can be configured to receive webhook events
- implemented as a Kubernetes controller
- Kubernetes faces challenges with the traditional CD mechanism
- CI/CD tools, like Jenkins, sit outside the cluster
- Argo CD sits inside the cluster
- continuously monitors running applications and compares the current, live state against the desired target state (Git repo)
- deployed application whose live state deviates from the target state is considered
OutOfSync
- argoCD provides facilities to automatically or manually sync the live state back to the desired target state
- automated sync policy
- triggered when it detects differences between the desired manifests in Git, and the live state in the cluster
- benefit: CI/CD pipelines no longer need direct access to the Argo CD API server to perform the deployment
- pipeline makes a commit and push to the Git repository with the changes to the manifests
- pruning
- default: automated sync will not delete resources when Argo CD detects the resource is no longer defined in Git
- self-healing
- default: changes that are made to the live cluster will not trigger automated sync
- selfHeal flag is set to true => sync will be attempted again after self heal timeout (5 seconds by default)
- controlled by
--self-heal-timeout-seconds
- controlled by
- automated sync policy
- argoCD provides facilities to automatically or manually sync the live state back to the desired target state
- deployed application whose live state deviates from the target state is considered
- Kubernetes faces challenges with the traditional CD mechanism
- resource objects
- can be defined declaratively using Kubernetes manifests
- can be updated using kubectl apply, without needing to touch the argocd command-line tool
kubectl apply -n argocd -f application.yaml
- Application
- represents a deployed application instance in an environment
- example
apiVersion: argoproj.io/v1alpha1 kind: Application metadata: name: greeting-app namespace: argocd spec: destination: // reference to the target cluster and namespace namespace: default server: https://kubernetes.default.svc source: // reference to the desired state in Git path: greeting-app/helm repoURL: https://github.com/mtumilowicz/argocd-workshop.git targetRevision: HEAD project: default syncPolicy: automated: prune: true selfHeal: true
- Argo CD is able to manage itself since all settings are represented by Kubernetes manifests
- create Kustomize based application which uses base Argo CD manifests from https://github.com/argoproj/argo-cd and apply required changes on top
- AppProject
- epresents a logical grouping of applications
- example: frontend, backend, data-services, and infrastructure
- if unspecified, an application belongs to the default project
- created automatically and by default, permits deployments from any source repo, to any cluster, and all resource Kinds
- if unspecified, an application belongs to the default project
- logical grouping of applications, which is useful when Argo CD is used by multiple teams
- enforce role-based access control (RBAC)
- ensures that team A cannot accidentally modify the applications managed by team B
- restrict what may be deployed (trusted Git source repositories)
- restrict where apps may be deployed to (destination clusters and namespaces)
- restrict what kinds of objects may or may not be deployed (e.g. RBAC, CRDs, DaemonSets, NetworkPolicy etc...)
- defining project roles to provide application RBAC (bound to OIDC groups and/or JWT tokens)
- ensures that team A cannot accidentally modify the applications managed by team B
- other: ConfigMap, Secret, Cluster etc
- components
- API Server
- like a Kubernetes API server
- primary functionalities
- application deployment and management
- executing rollback on user-defined actions
- managing cluster credentials stored in K8s secrets
- enforcing RBAC
- Git Webhooks
- Repository Server
- manages interactions with Git repositories
- responsible for cloning Git repository, keeping it up to date and generating manifests using the appropriate tool
- makes a local cache of the application manifest and Git repositories
- clones the repository into /tmp (or the path specified in the TMPDIR env variable)
- Pod might run out of disk space if it has too many repositories or if the repositories have a lot of files
- mount a persistent volume
- Pod might run out of disk space if it has too many repositories or if the repositories have a lot of files
- Application Controller
- handles the reconciliation of applications
- API Server
- can display a badge with health and sync status for any application
- notification subscriptions
- example: slack
apiVersion: argoproj.io/v1alpha1 kind: Application metadata: annotations: notifications.argoproj.io/subscribe.on-sync-succeeded.slack: my-channel1;my-channel2
- example: slack
- best practices
- clean separation of application code vs. application config
- separate Git repository to hold your Kubernetes manifests
- deployment files change independently from the source code
- pros
- modify just the manifests without triggering an entire CI build
- example: bump the number of replicas in a Deployment spec
- much cleaner Git history
- separation of access
- developers may not necessarily be the same people who can/should push to production environments
- pushing manifest changes to the same Git repository can trigger an infinite loop
- modify just the manifests without triggering an entire CI build
- separate Git repository to hold your Kubernetes manifests
- ensuring manifests at git revisions are truly immutable
- it is possible for manifests to change without source code change
- example: caused by changes made to an upstream helm/kustomize repository
vs
resources: - github.com/argoproj/argo-cd//manifests/cluster-install
bases: - github.com/argoproj/argo-cd//manifests/cluster-install?ref=v0.11.1
- example: caused by changes made to an upstream helm/kustomize repository
- it is possible for manifests to change without source code change
- clean separation of application code vs. application config