Repair Kubernetes Drift with Argo CD
Use GitOps and Argo CD to detect and repair Kubernetes configuration drift.
Introduction
30 Second Summary
A carefully configured system can drift away from the plan whenever someone makes a direct change. Those small differences can stay hidden until they cause a larger problem.
In this project, you will build a GitOps workflow that makes Git the source of truth for an NGINX workload inside the KodeKloud ArgoCD Playground. You will prove Argo CD's self-healing by changing the live Kubernetes workload and watching it return to Git's declared state.
What You'll Build
Picture scaling a live NGINX Deployment from two replicas to five, then watching Argo CD return it to the count recorded in Git.
By the end of this project, you'll have:
- A reviewable desired state in Gitea that makes every workload change visible in Git history.
- A manual sync demonstration that stays Missing and OutOfSync until you approve the deployment.
- An automated reconciliation flow that deploys a Git change without another approval. The same flow repairs live replica drift.
- Secret Mission: Pause automatic correction so a live scale to four replicas persists. Resume reconciliation to restore Git's declared count.
Are there any prerequisites?
You'll need a KodeKloud subscription plus working knowledge of Kubernetes Deployment and Service resources, namespaces, and kubectl. The browser-based playground keeps the workload off your Linux machine.
Before We Start
A clear source of truth makes the reconciliation loop easier to understand before you touch the playground. This checkpoint locks in how Git defines the NGINX workload while Argo CD repairs conflicting Kubernetes drift.
Verify the Playground
Running Kubernetes locally would consume the machine resources you need for the GitOps lesson. A managed playground keeps this step focused on proving the environment is ready.
The browser-based KodeKloud ArgoCD Playground includes Argo CD and Gitea beside the cluster.
You will verify its Git tooling. You will also prove that kubectl can reach the cluster control plane.
In this step, get ready to:
- Launch the managed playground within its one-hour session.
- Verify the supplied cluster, kubectl, Git, and Argo CD pods.
- Create a Gitea repository with a usable HTTPS clone URL.
Launch the managed playground
The playground supplies the services this project needs inside one temporary browser session. Starting it establishes the environment that every later step uses.
- Navigate to the KodeKloud ArgoCD Playground page in your browser.
- Start a new session using the session control on the playground page.
You should see the playground workspace load with its session timer. Your managed environment is now live and ready for its first checks.
- Confirm that the session page shows a 1 hr duration.
- Use the supplied workspace control to open the terminal.
You should see a terminal prompt inside the playground workspace.
- Use the supplied service link to open the Argo CD web interface.
- Use the supplied service link to open the Gitea web interface.
You should now have the terminal, Argo CD interface, and Gitea interface available in the active session.
Why use a managed playground?
A local cluster adds container runtime, driver, and memory decisions before you can study reconciliation. The managed environment keeps those setup choices outside this project.
You still verify every supplied component because the remaining work depends on a responsive cluster and running Argo CD services.
Verify the supplied tools
A loaded interface only proves that the web page responds. Command-line checks prove that the cluster, client tools, and Argo CD control plane can support the project.
Before you run the checks, predict which results would prove the environment is ready.
- Check the cluster, client tools, and Argo CD pods by running these commands:
kubectl cluster-info
kubectl version
git --version
kubectl get pods -n argocd
What do these checks prove?
- The cluster information identifies the control plane that kubectl can reach.
- The Kubernetes version output confirms communication between the client and server.
- The Git version output confirms that the playground includes the command-line tooling needed for repository work.
- The pod list confirms that the Argo CD control plane is running in the argocd namespace.
You should see a control-plane address, Kubernetes version information, a Git version, and Argo CD pods with running status. You have now proved that the managed environment can accept project work.
Missing a supplied tool or namespace?
- Restart the managed playground if a supplied command is missing or the argocd namespace is unavailable.
- Avoid installing replacement components inside this temporary environment.
Ask for help if the restarted session still fails: help me diagnose my KodeKloud playground checks.
Create the Gitea repository
The repository gives the next step a place to publish the desired state. Initializing it with a README creates a default branch that Git can clone.
This part is a little fiddly because each session uses its own hostname. The correct HTTPS clone URL must come from the repository page in your active session.
- Switch back to the Gitea interface from earlier.
- Use Gitea's repository creation flow to start a new repository.
You should see the form for configuring the new repository.
- Enter gitops-demo as the repository name.
- Enable README initialization for the repository.
- Complete the repository creation flow using the page control.
The new repository page should load with a README on its default branch. That gives the project a real first commit before you add any manifests.
- Use the repository's clone controls to display its HTTPS clone URL.
- Copy the HTTPS clone URL shown by the active Gitea session.
- Store the copied URL for the next step: your-gitea-https-clone-url.
Before you check the repository, predict what should prove it is ready for cloning.
- Refresh the gitops-demo repository page.
- Switch back to the Argo CD interface from earlier.
You should see the README on the repository's default branch with the active session's HTTPS clone URL available. The Argo CD interface should still load inside the same playground session.
Your managed environment is verified and your Gitea repository is ready. Next, you will publish the NGINX desired state and let Argo CD discover it.
Publish Desired State
Your playground is ready. The empty Gitea repository now needs a reviewable description of the workload.
GitOps treats Git as the source of truth for the desired Kubernetes state. Argo CD compares that declaration with the live cluster.
Publishing the desired state alone does not create the workload. This step makes that gap visible before you approve reconciliation.
In this step, get ready to:
- Prepare a local clone for Git commits.
- Write the three desired-state YAML files.
- Prove that the Git state remains unapplied before manual sync.
Set up the repository workspace
A local clone gives you a workspace for the manifests. The Git identity records who authored the commit.
- In the commands below, replace your-gitea-https-clone-url with the session-specific URL stored in GITEA_REPO_URL.
- Prepare the local repository workspace by running the edited commands:
export GITEA_REPO_URL='your-gitea-https-clone-url'
git clone "$GITEA_REPO_URL" gitops-demo
cd gitops-demo
git config user.name "Argo CD Learner"
git config user.email "learner@example.com"
mkdir -p manifests bootstrap
What do these commands prepare?
- The GITEA_REPO_URL environment variable holds the clone URL from your active session.
- The clone command creates the local gitops-demo directory from the repository.
- The two identity settings attach your learner name to future commits.
- The manifests directory holds the workload definitions.
- The bootstrap directory holds the Argo CD Application definition.
- Check that the clone output reports a successful download from your active Gitea session.
- Check that your terminal prompt now points to the local gitops-demo directory.
Repository clone did not work?
Confirm that you replaced the placeholder with the HTTPS clone URL from the current session. A hostname copied from another playground session does not point to this repository.
If the one-hour playground has expired, restart it before repeating the clone.
Help me diagnose the repository clone in my KodeKloud ArgoCD Playground.
Define the desired state
The workload needs separate definitions for its Pods and network access. The Application definition tells Argo CD where to find those files.
- Use the playground file editor to create manifests/deployment.yaml inside the cloned gitops-demo directory.
- Paste this definition into manifests/deployment.yaml:
apiVersion: apps/v1
kind: Deployment
metadata:
name: gitops-demo
labels:
app: gitops-demo
spec:
replicas: 1
selector:
matchLabels:
app: gitops-demo
template:
metadata:
labels:
app: gitops-demo
spec:
containers:
- name: nginx
image: nginx:1.31.5-alpine
ports:
- name: http
containerPort: 80
What does the Deployment define?
- The Deployment starts with one replica so the first synchronized release has one Pod.
- The matching app: gitops-demo labels connect the Deployment selector to its Pod template.
- The container runs the pinned NGINX image.
- The named http port gives the Service a stable target.
- Save manifests/deployment.yaml.
- Check that the saved file shows replicas: 1 above the selector.
Deployment file looks different?
Check that the label beneath the selector matches the label in the Pod template. YAML indentation must also match the reference.
Help me compare my Deployment YAML with the project definition.
- Use the playground file editor to create manifests/service.yaml inside the cloned gitops-demo directory.
- Paste this definition into manifests/service.yaml:
apiVersion: v1
kind: Service
metadata:
name: gitops-demo
spec:
selector:
app: gitops-demo
ports:
- name: http
protocol: TCP
port: 80
targetPort: http
What does the Service define?
- The Service selector targets Pods carrying the app: gitops-demo label.
- The Service exposes TCP port 80 inside the cluster.
- The targetPort: http value resolves to the named container port.
- Save manifests/service.yaml.
- Check that the saved selector matches app: gitops-demo in the Deployment.
Service selector does not match?
Compare the Service selector with the Pod template label in manifests/deployment.yaml. Both values must use the same spelling.
Help me check how my Service selects the NGINX Pods.
- Use the playground file editor to create bootstrap/application.yaml inside the cloned gitops-demo directory.
- Paste this definition into bootstrap/application.yaml:
apiVersion: argoproj.io/v1alpha1
kind: Application
metadata:
name: gitops-demo
namespace: argocd
spec:
project: default
source:
repoURL: your-gitea-https-clone-url
targetRevision: HEAD
path: manifests
destination:
server: https://kubernetes.default.svc
namespace: gitops-demo
What does the Application define?
- The Application resource registers gitops-demo with Argo CD.
- The source fields point to the latest revision in the repository's manifests directory.
- The destination fields target the in-cluster Kubernetes API and the gitops-demo namespace.
- No syncPolicy is present, so the Application starts in manual mode.
- Replace your-gitea-https-clone-url with the HTTPS URL stored in GITEA_REPO_URL.
- Save bootstrap/application.yaml.
- Check that repoURL contains the URL from your active Gitea session.
Application source looks wrong?
Make sure the repoURL value contains only the HTTPS clone URL. Leave targetRevision: HEAD unchanged.
Help me validate the Git source in my Argo CD Application YAML.
Use these tabs to compare all three desired-state files before publishing them.
✔️ Awesome, I've got everything!
Your three YAML files are ready. Confirm that you saved each file before continuing.
ⓧ I'd like to double check the full code
apiVersion: apps/v1
kind: Deployment
metadata:
name: gitops-demo
labels:
app: gitops-demo
spec:
replicas: 1
selector:
matchLabels:
app: gitops-demo
template:
metadata:
labels:
app: gitops-demo
spec:
containers:
- name: nginx
image: nginx:1.31.5-alpine
ports:
- name: http
containerPort: 80
Deployment reference
This file declares one NGINX replica with matching selector labels and a named HTTP port.
apiVersion: v1
kind: Service
metadata:
name: gitops-demo
spec:
selector:
app: gitops-demo
ports:
- name: http
protocol: TCP
port: 80
targetPort: http
Service reference
This file exposes port 80 to Pods selected by the shared application label.
apiVersion: argoproj.io/v1alpha1
kind: Application
metadata:
name: gitops-demo
namespace: argocd
spec:
project: default
source:
repoURL: your-gitea-https-clone-url
targetRevision: HEAD
path: manifests
destination:
server: https://kubernetes.default.svc
namespace: gitops-demo
Application reference
This file connects the repository's manifest directory to the destination namespace without an automated synchronization policy.
Test the GitOps boundary
A commit gives Argo CD a desired revision to compare against the cluster. The Application resource creates that comparison boundary.
Before you run these commands, do you think registering the desired state creates the Deployment immediately?
- Publish the desired state and register the Application by running these commands:
git add manifests bootstrap
git commit -m "Add GitOps demo"
git push
kubectl apply -f bootstrap/application.yaml
What do these commands do?
- The first command stages the three YAML files.
- The commit records the first desired-state revision.
- The push publishes that revision to Gitea.
- The final command creates the Argo CD Application resource from bootstrap/application.yaml.
- Switch back to the Argo CD interface from earlier.
- Reload the browser page to fetch the new Application.
- Select the gitops-demo Application.
- Inspect the resource view to determine whether the Deployment and Service exist in the live cluster.
You will see the Deployment and Service marked Missing and OutOfSync. This intended shortfall proves that Git content does not deploy itself.
The Application can read the desired state, but no synchronization has been approved. The target namespace and workload therefore remain absent.
Application or resources not visible?
Reload the Argo CD page after the push and Application update complete. Confirm that repoURL contains the clone URL from the current session.
If the Application appears without its resources, check that path: manifests matches the repository directory name.
Help me diagnose why Argo CD cannot show my desired resources.
Your source of truth is published, and Argo CD can see the difference from the live cluster. Next, you will approve the first synchronization and watch the workload appear.
Expose the Manual Sync Gap
Your Argo CD Application can already compare the desired state in Git with the Kubernetes cluster. Its Missing and OutOfSync status shows that a manual policy is waiting for your approval.
Now you will approve the first revision. A second commit will test whether Git alone can update the live replica count.
In this step, get ready to:
- Manually synchronize the first Git revision from Argo CD.
- Confirm one ready NGINX replica and the deployed Service.
- Publish a two-replica commit to Gitea and prove that it remains unapplied.
Synchronize the first revision
A manual sync turns the reviewed Git revision into running cluster resources. This approval creates the one-replica baseline for the test that follows.
- Return to the Argo CD interface from earlier.
- Select the gitops-demo Application.
- Click Sync.
- Click Synchronize.
- Watch the resource tree until both resources finish creating.
You'll see the Deployment and Service move from Missing and OutOfSync to Synced and Healthy.
Good work. The first Git revision is now running as a Kubernetes workload.
Confirm the one-replica deployment
The resource tree shows Argo CD's view of the deployment. The cluster commands confirm what Kubernetes is actually running.
Before you check, how many ready replicas do you expect Kubernetes to report?
- Confirm the rollout and list the created resources by running these commands:
kubectl rollout status deployment/gitops-demo -n gitops-demo
kubectl get deployment,service -n gitops-demo
What do these commands prove?
- The first command waits for the Deployment rollout to finish.
- The second command lists the Deployment and Service in the gitops-demo namespace.
You'll see the rollout complete with one ready replica. The resource list also includes the gitops-demo Service.
Is the rollout still waiting?
Confirm that the Application reached Synced before you retry the cluster checks.
If the namespace is missing, return to the Application resource tree to confirm that synchronization finished.
Help me diagnose why the first Argo CD synchronization did not create my workload.
Publish the two-replica request
The next commit changes only the desired replica count. The live cluster will reveal how manual sync handles a new request from Git.
- Return to manifests/deployment.yaml in the editor from the previous step.
- Find the replicas: 1 line under spec.
- Replace it with replicas: 2.
- Save manifests/deployment.yaml.
✔️ Awesome, I've got everything!
Your saved manifests/deployment.yaml now requests two replicas.
ⓧ I'd like to double check the full code
apiVersion: apps/v1
kind: Deployment
metadata:
name: gitops-demo
labels:
app: gitops-demo
spec:
replicas: 2
selector:
matchLabels:
app: gitops-demo
template:
metadata:
labels:
app: gitops-demo
spec:
containers:
- name: nginx
image: nginx:1.31.5-alpine
ports:
- name: http
containerPort: 80
What changed in the manifest?
Only spec.replicas changes from one to two. Everything else stays identical so the commit expresses one reviewable decision.
- Publish the replica change to Gitea by running these commands:
git add manifests/deployment.yaml
git commit -m "Scale GitOps demo to two replicas"
git push
What does this publish?
- The first command stages only the Deployment manifest.
- The second command records the two-replica request in Git history.
- The third command sends the commit to the configured Gitea remote.
You'll see Git record the new commit and push it to the repository.
Did the push fail?
Confirm that the terminal is still inside the local gitops-demo clone.
Check the active Gitea session credentials if the remote rejects the push.
Help me fix this Git push without losing my two-replica commit.
- Return to the gitops-demo Application in Argo CD.
- Refresh the Application.
- Wait until Argo CD detects the latest Gitea commit.
Before you check, do you think Kubernetes already has two ready replicas?
- Check the live Deployment replica count by running this command:
kubectl get deployment gitops-demo -n gitops-demo
What is this checking?
This command reads the live Deployment directly from Kubernetes. Comparing that result with Argo CD reveals whether the pushed commit was applied.
You'll still see one ready replica. Argo CD reports OutOfSync because Git requests two replicas while manual synchronization still requires approval.
That shortfall is intentional. You have proved that a Git commit is only a request under manual sync.
Does Argo CD still show Synced?
Wait for Argo CD to detect the pushed revision. Refresh the Application after the source revision changes.
If Kubernetes already shows two replicas, confirm that nobody approved another manual synchronization.
Help me work out why my manual-sync Application is not showing the expected gap.
Git now requests two replicas while the cluster stays on the last approved revision. Next, you will let Argo CD close that gap automatically.
Enable Automated Reconciliation
The latest Git commit in Gitea asks for two replicas. Your live Deployment still runs one because manual sync has left the reviewed change waiting for approval.
Automated reconciliation closes that gap. Argo CD watches the desired state in Git. It brings Kubernetes into line when Git changes.
In this step, get ready to:
- Configure automated sync with self-healing.
- Apply the updated Application policy.
- Verify the reconciled two-replica state.
Add the automated sync policy
An Application's sync policy controls how Argo CD responds to differences between Git and the live cluster. This policy enables automatic synchronization while keeping automatic deletion disabled.
- Open bootstrap/application.yaml in the playground file editor.
- Place your cursor below the namespace: gitops-demo line.
- Add the final sync policy by pasting this block:
syncPolicy:
automated:
prune: false
selfHeal: true
syncOptions:
- CreateNamespace=true
What does this policy control?
- The automated block allows Argo CD to reconcile an Application when it becomes OutOfSync.
- The selfHeal: true setting allows Argo CD to repair differences in the live cluster.
- The prune: false setting keeps automatic resource deletion disabled.
- The CreateNamespace=true option preserves automatic creation of the destination namespace during synchronization.
- Save bootstrap/application.yaml.
Your repoURL should keep the session-specific Gitea URL you added earlier. The reference view uses your-gitea-https-clone-url only to show where that URL belongs.
✔️ Awesome, I've got everything!
Your Application manifest now includes the automated sync policy. Make sure the file is saved before continuing.
ⓧ I'd like to double check the full code
Compare your Application manifest with this reference. Keep your own session-specific Gitea URL in the repoURL field.
apiVersion: argoproj.io/v1alpha1
kind: Application
metadata:
name: gitops-demo
namespace: argocd
spec:
project: default
source:
repoURL: your-gitea-https-clone-url
targetRevision: HEAD
path: manifests
destination:
server: https://kubernetes.default.svc
namespace: gitops-demo
syncPolicy:
automated:
prune: false
selfHeal: true
syncOptions:
- CreateNamespace=true
This full-file reference shows the final Application structure. The new syncPolicy block sits under spec at the same indentation level as source and destination.
The bootstrap manifest belongs in the same Git history as the workload it controls. Committing this update gives the policy a reviewable record in Gitea.
- Use the same Gitea credentials from your earlier push if the terminal asks you to authenticate.
- Publish the updated Application manifest by running these commands:
git add bootstrap/application.yaml
git commit -m "Enable automated reconciliation"
git push
What do these commands record?
- The git add command stages the updated Application manifest.
- The git commit command records the reconciliation policy in your repository history.
- The git push command publishes that record to Gitea.
You should see the new commit recorded locally. The push output confirms that the remote repository received it.
Could not publish the policy?
- Confirm that the terminal is still inside the local gitops-demo clone.
- Retry the push with the same Gitea credentials you used earlier.
Ask for help with the repository update: help me diagnose why my Application manifest commit will not push to Gitea.
Before you apply this update, do you think the pending two-replica revision will still need a manual synchronization?
- Update the live Application policy by running this command:
kubectl apply -f bootstrap/application.yaml
What does this command change?
The command updates the existing gitops-demo Application in the argocd namespace. Argo CD can now act on the Git revision that is already waiting.
The Application update completes without another manual sync. Argo CD starts reconciling the pending two-replica revision.
Application update failed?
- Check the indentation of the syncPolicy block against the full-file reference.
- Confirm that bootstrap/application.yaml still contains your session-specific Gitea URL.
Get help with the manifest: help me diagnose why kubectl cannot apply my Argo CD Application policy.
Watch the pending commit reconcile
Automated sync runs when Argo CD detects that an Application is OutOfSync. The previously blocked Git change now provides a direct test of that behavior.
- Return to the gitops-demo Application in the Argo CD interface from earlier.
- Watch the Deployment move toward two replicas in the resource tree.
Before you check the cluster, what replica count do you expect Kubernetes to report now?
- Confirm the automated rollout by running these commands:
kubectl rollout status deployment/gitops-demo -n gitops-demo
kubectl get deployment gitops-demo -n gitops-demo
What do these checks prove?
- The rollout command waits for the updated Deployment to become ready.
- The get command shows the desired replica count beside the number of ready replicas.
The rollout command finishes successfully. The Deployment reaches 2/2 ready replicas without another manual synchronization.
Still seeing one replica?
- Confirm that manifests/deployment.yaml contains replicas: 2.
- Confirm that the latest Gitea commit contains the two-replica manifest.
- Check that the live Application includes selfHeal: true under the automated policy.
Investigate the stalled reconciliation: help me find why my Argo CD Application remains at one replica after enabling automated sync.
Confirm the final reconciliation state
The Application summary connects the Git revision to the resources now running in the cluster. Its policy settings also show which automatic actions Argo CD can perform.
- Return to the gitops-demo Application summary in the Argo CD interface.
- Confirm that the source revision matches the latest Gitea commit.
- Confirm that automatic sync is enabled.
- Confirm that self-heal is enabled.
- Confirm that pruning remains disabled.
- Inspect the resource tree to confirm that the Deployment and Service are healthy.
Before the final check, what should the READY column show if Git and the live cluster now agree?
- Verify the final Deployment state by running this command:
kubectl get deployment gitops-demo -n gitops-demo
What confirms success?
The command reads the live Deployment from the gitops-demo namespace. Its READY column proves whether both Git-defined replicas are available.
You should see 2/2 in the READY column. The Argo CD interface should report Synced and Healthy.
That pending commit now runs as two healthy replicas without a manual click. Next, you will change the live cluster directly and watch self-healing defend Git's desired state.
Test Self-Healing
Your Argo CD Application now deploys Git's two-replica revision automatically. That proves a reviewed commit can reach Kubernetes without manual approval.
Self-healing faces a harder test when someone changes the live Deployment without touching Git. This step creates that drift so you can watch the GitOps control loop reject it.
In this step, get ready to:
- Create live drift by scaling the Deployment to five replicas without changing Git.
- Observe Argo CD detect the drift before it restores Git's two-replica state.
Create live replica drift
The desired state remains at two replicas in manifests/deployment.yaml. The live state changes when you scale the running Deployment directly.
- Keep the Argo CD resource view open in its existing tab.
- Plan to stop the watch with Ctrl+C after the repair.
Before you run this, do you think five replicas will remain live or return to Git's declared count?
- Expose live drift by running these commands:
kubectl scale deployment/gitops-demo --replicas=5 -n gitops-demo
kubectl get deployment gitops-demo -n gitops-demo -w
What do these commands test?
- The kubectl scale command writes a replica count of 5 directly to the live Deployment.
- The kubectl get command watches the Deployment so each replica update appears in the terminal.
- Git remains unchanged throughout the test.
You'll see the desired replica count briefly reach 5. It then returns to 2 as Argo CD applies the Git-defined state.
In the Argo CD resource view, you'll briefly see OutOfSync during the comparison. The Application returns to Synced after the repair.
- Stop the watch by pressing Ctrl+C.
Did the drift disappear too quickly?
- Repeat the test while watching the Argo CD resource view if the terminal only shows two replicas.
- Confirm automated sync remains enabled if five replicas persist.
- Confirm self-heal remains enabled if Argo CD detects drift without repairing it.
Help me diagnose why Argo CD did not visibly self-heal my Deployment.
Confirm Git stayed authoritative
Self-healing changes the cluster to match Git. It leaves the repository's desired state untouched.
- Switch back to the gitops-demo repository in the Gitea interface from earlier.
- Select manifests/deployment.yaml in the repository file browser.
You'll still see replicas: 2 in the manifest. This proves the direct scale never changed Git.
Before the final check, which replica count do you expect Kubernetes to report now?
- Check the repaired Deployment by running:
kubectl get deployment gitops-demo -n gitops-demo
What does this check prove?
- The kubectl get deployment command reads the Deployment's current live state.
- The READY column compares ready replicas with the desired live count.
You'll see 2/2 in the READY column. Both Git and the live cluster now declare two replicas.
- Switch back to the gitops-demo Application in Argo CD to confirm the repair.
The sync status reads Synced. The health status reads Healthy.
You have proved the full self-healing loop. Argo CD detected an imperative cluster change and restored the state declared in Git.
Secret mission
Pause and Resume the Reconciler
You have watched Argo CD repair live drift automatically. Now pause correction to prove detection keeps working. Resume self-healing without changing Git's desired state.
Clean Up Your Resources
Clean Up Your Resources
The KodeKloud ArgoCD Playground adds no cost beyond your existing subscription. Choose how to handle the temporary resources before the one-hour session ends.
Resources you used:
- A Gitea repository named gitops-demo plus its local terminal clone.
- An Argo CD Application named gitops-demo in the argocd namespace.
- A Kubernetes namespace named gitops-demo containing the Deployment plus the Service.
Keep everything running
Keeping the demo needs no action. Choose this option if you want to continue working during the active playground session.
- Use the existing Argo CD resource tree to confirm that the Application remains Synced.
- Use the same resource tree to confirm that the Application remains Healthy.
- Continue testing the reconciler before the one-hour playground session ends.
Pause - I'll come back to this later
Preserve your work outside the playground because the session is temporary. Your three YAML files plus your Git history contain everything needed to revisit the demonstration.
- Copy the contents of manifests/deployment.yaml from Gitea into a file on your own machine.
- Copy the contents of manifests/service.yaml from Gitea into a file on your own machine.
- Copy the contents of bootstrap/application.yaml from Gitea into a file on your own machine.
- Record the commit history from the gitops-demo repository in notes outside the playground.
Delete - I don't want to use this again
Deletion is permanent inside this temporary session. Only the demo resources you created are affected.
- Delete the gitops-demo Application from Argo CD by running this command in the connected playground terminal:
kubectl delete application gitops-demo -n argocd
Why Delete the Application First?
Deleting the Application stops Argo CD from reconciling gitops-demo. Pruning is disabled.
The workload stays in its namespace until the next command removes it. This order prevents the reconciler from restoring the workload.
You should see a deletion confirmation for the Application. That closes the reconciler cleanly.
Application Not Deleting?
- Confirm that the playground session is still active.
- Check that the command names the argocd namespace.
- Check that the command names the gitops-demo Application.
Help me diagnose the Application deletion.
- Delete the gitops-demo namespace by running this command in the connected playground terminal:
kubectl delete namespace gitops-demo
What Does Namespace Deletion Remove?
Deleting the gitops-demo namespace removes its Deployment plus its Service. This clears the running workload from Kubernetes.
You should see a deletion confirmation for the namespace. The cluster side of your demo is now clean.
Namespace Not Deleting?
- Confirm that the Application deletion finished.
- Check that the command names the gitops-demo namespace.
Help me diagnose the namespace deletion.
- Allow the active playground session to expire after its one-hour window.
The temporary Gitea repository ends with the playground session. The terminal clone ends with the same temporary environment.
Nice Work!
Nice Work!
You did it! You built a GitOps control loop that keeps a Kubernetes workload aligned with Git through Argo CD.
Your live drift test showed that Git's declared replica count wins whenever self-healing is active.
You learned how to:
- Publish desired state: You stored reviewable manifests for an NGINX Deployment plus its Service in Gitea. Git became the source of truth for the workload.
- Expose the manual gap: You observed Missing plus OutOfSync before the first sync. You then proved that a new Git commit stays unapplied in manual mode.
- Automate reconciliation: You enabled automated sync with self-healing. Automatic pruning remained disabled. Argo CD repaired a live scale from five replicas back to Git's declared two.
- Secret Mission: You paused automatic correction while Argo CD continued detecting drift. You resumed reconciliation. The Deployment returned to two ready replicas.
Ready to quiz yourself?