My Argo CD Learning Journey: Getting Started with GitOps
I recently started learning Argo CD, and instead of only reading the documentation or watching tutorials, I decided to learn it by actually setting it up and experimenting with it.
My goal was simple:
I wanted to understand how Argo CD uses Git as the source of truth and how it keeps the Kubernetes cluster in sync with what is defined in Git.
For this learning exercise, I used Minikube as my local Kubernetes cluster and GitHub to store my Kubernetes manifests.
This helped me understand some of the most important Argo CD concepts, especially desired state, actual state, synchronization, drift, and reconciliation.
Setting Up My Learning Environment
I started by creating a local Kubernetes cluster using Minikube.
minikube startThen I verified that my cluster was running:
kubectl get nodesOnce the Kubernetes cluster was ready, I installed Argo CD in a separate namespace:
kubectl create namespace argocdThen I installed Argo CD using its Kubernetes manifests.
After installation, I checked the Argo CD pods:
kubectl get pods -n argocdThis was my first step toward understanding how Argo CD itself runs inside Kubernetes.
Accessing the Argo CD Dashboard
Since I was running everything locally with Minikube, I used port forwarding to access the Argo CD UI.
kubectl port-forward svc/argocd-server -n argocd 8080:443Then I opened Argo CD through my browser.
I also learned how to retrieve the initial admin password from the Kubernetes secret and log in using the Argo CD CLI.
At this point, I had Argo CD running and connected to my local Kubernetes environment.
But I hadn't really understood GitOps yet.
So I decided to build a small application and experiment with it.
Using GitHub as My Source of Truth
I created a GitHub repository for my Argo CD learning project.
Inside the repository, I stored my Kubernetes manifests.
My basic structure looked something like:
argocd-learning/
│
├── manifests/
│ ├── namespace.yaml
│ ├── deployment.yaml
│ └── service.yaml
│
└── README.mdFor the application, I used a simple NGINX deployment.
My Deployment manifest defined the desired number of replicas:
spec:
replicas: 2I committed the manifests and pushed them to GitHub.
This was an important point for me because I started thinking about Git differently.
Previously, I mostly thought of Git as a place to store source code.
With GitOps, I started thinking of Git as:
The source of truth for my Kubernetes desired state.
Connecting Argo CD to GitHub
Next, I created an Argo CD Application and pointed it to my GitHub repository.
I configured:
- GitHub repository
- Manifest path
- Kubernetes cluster
- Kubernetes namespace
The idea was:
GitHub
|
| Kubernetes manifests
v
Argo CD
|
| Deploy
v
Kubernetes / MinikubeArgo CD could now look at the manifests stored in my GitHub repository and compare them with what was actually running in my Kubernetes cluster.
Understanding Desired State and Actual State
This was probably the most important concept I learned.
My Git repository contained:
replicas: 2So my desired state was:
I want 2 replicas.Kubernetes had its own current state.
If Kubernetes was running two replicas:
Desired State = 2
Actual State = 2Argo CD showed the application as:
SyncedThis helped me understand what "sync" actually means.
It isn't simply that Argo CD deployed something once.
It means the state defined in Git and the state in Kubernetes are matching.
My First Reconciliation Experiment
After getting the basic deployment working, I wanted to see what would happen when I changed something in Git.
I changed:
replicas: 2to:
replicas: 4Then I committed the change and pushed it to GitHub.
Now I had:
Git / Desired State
replicas = 4
Kubernetes / Actual State
replicas = 2The two states were different.
Argo CD detected this difference and showed the application as:
OutOfSyncThis was the moment when the concept of reconciliation became much clearer to me.
Argo CD was basically saying:
"The Kubernetes cluster does not currently look like what Git says it should look like."
I then synchronized the application.
After synchronization, Kubernetes had four replicas:
Desired State = 4
Actual State = 4And Argo CD showed:
SyncedThat small experiment helped me understand Argo CD much better than simply reading about it.
Creating Drift Manually
After that, I wanted to try the opposite direction.
Instead of changing Git, I changed Kubernetes directly.
For example:
kubectl scale deployment nginx --replicas=1 -n demoNow my states looked like:
Git
Desired = 4
Kubernetes
Actual = 1I had intentionally created configuration drift.
Argo CD detected the difference.
This was another important lesson for me.
I understood that with GitOps, manually changing Kubernetes doesn't mean that the change becomes the new source of truth.
Git still says:
replicas: 4So the cluster has drifted away from the desired state.
Trying Automated Synchronization
After manually syncing applications, I wanted to see what would happen if I enabled automated synchronization.
I enabled automated sync for my Argo CD application.
Then I changed my Kubernetes manifest in Git again.
For example:
replicas: 3I committed and pushed the change.
This time, I didn't manually run argocd app sync.
I waited for Argo CD to detect the change.
Argo CD noticed the new Git state and reconciled the application.
Eventually, Kubernetes reflected the new configuration.
This gave me a much better understanding of the GitOps workflow:
Change manifest
|
v
Git commit
|
v
Git push
|
v
GitHub
|
v
Argo CD detects change
|
v
Reconciliation
|
v
KubernetesLooking at the Argo CD UI
I also spent some time exploring the Argo CD dashboard.
I looked at:
- Application status
- Sync status
- Health status
- Kubernetes resources
- Deployment
- ReplicaSets
- Pods
- Services
- Git repository
- Application history
- Differences between desired and live state
The resource tree was especially useful for me because I could see how the Kubernetes resources were connected.
For example:
Application
|
+-- Deployment
| |
| +-- ReplicaSet
| |
| +-- Pod
| +-- Pod
|
+-- ServiceIt made the relationship between Argo CD and Kubernetes much easier to visualize.
Checking the Difference Between Git and Kubernetes
One of the things I found useful was looking at the difference between the desired and actual configuration.
For example, Git could contain:
replicas: 4while Kubernetes had:
replicas: 2Argo CD could show me that difference.
Conceptually:
spec:
- replicas: 2
+ replicas: 4This helped me understand that Argo CD isn't just a deployment tool.
It is also continuously comparing the state I declared with the state that exists in the cluster.
What I Learned About Reconciliation
Before working with Argo CD, the word "reconciliation" felt a little abstract to me.
After doing these experiments, I started seeing it more practically.
I think about it like this:
Git
|
| "This is what I want"
v
Argo CD
|
| compare
v
Kubernetes
|
| "This is what I currently have"If they are different:
Desired != Actual
|
v
OutOfSync
|
v
Reconciliation
|
v
Actual → DesiredIf they are the same:
Desired == Actual
|
v
SyncedThat became the core mental model I took away from my Argo CD learning.
What I Understand Now
After going through these hands-on experiments, I have a much better understanding of the basic GitOps workflow.
My understanding now is:
GitHub
|
| Desired State
v
Argo CD
|
| Reconciliation
v
Kubernetes
|
| Actual State
v
CompareGit is where I define what I want.
Argo CD watches that desired state.
Kubernetes is where the application actually runs.
Argo CD continuously checks whether the actual state matches the desired state.
My Next Steps
This was just my starting point with Argo CD.
After understanding the basic workflow, I want to explore more advanced topics such as:
- Helm with Argo CD
- Kustomize
- Argo CD Projects
- ApplicationSets
- App-of-Apps pattern
- Private Git repositories
- Automated sync policies
- Sync waves and hooks
- Secrets management
- Multi-environment deployments
- CI/CD with GitOps
- Deploying to multiple Kubernetes clusters
I think learning the fundamentals through a small Minikube cluster was a good starting point because I could intentionally break things, create drift, change manifests, and observe how Argo CD responded.
Final Thoughts
For me, the biggest takeaway from learning Argo CD wasn't the installation commands.
It was understanding the relationship between Git, desired state, actual state, and reconciliation.
The workflow I have in my head now is:
Developer
|
| Change Kubernetes manifest
v
GitHub
|
| Desired State
v
Argo CD
|
| Reconciliation
v
Kubernetes
|
| Actual State
v
CompareIf the desired and actual states are different, Argo CD detects the drift and can synchronize the cluster.
That hands-on experiment made the GitOps concept much more real for me.
I'm still learning Argo CD, but this gave me a solid foundation to start exploring how GitOps works in more realistic Kubernetes environments.
