GitOps uses GIT as a single source of truth to deliver applications and infrastructure.
If your source code has a mechanism of tracking, then why your deployment should not have a mechanism of tracking. So if your CI has a proper Git integrated approach, then why your CD doesn't have a proper Git integrated approach. This is how GitOps came.
When a DevOps Engineer updates the yaml file (Kubernetes deployment yaml file) in GitHub repo, this file should be validated by another DevOps engineer. After the PR validation, its merged to GitHub repository. Once code has changed in GitHub repo, the GitOps controller (Probably ArgoCD or Flux) will read the yaml files and deploys on to kubernetes cluster.
GitOps repository must have a declarative manifest file - Whatever you have seen in Git repository is the same configuration that is deployed on K8 cluster.
When you track resources in Git then one of the main thing that your changes are Versions and your changes are Immutable. (We can use S3 as GitOps repository)
Agents known as GitOps controller (ArgoCD) automatically pull the code from repository.
If someone going to change anything in K8 cluster, then GitOps controller don't allow (means if changed anything then GitOps will override the changes on K8 cluster again) any changes in K8 cluster directly. Because GitOps using single source of truth to deliver applications. If you want to change something, then changes should be updated over GitOps repository.
By the Principle, the Answer is "NO". However, the popular GitOps tools like ArgoCD and Flux targets the Kubernetes.
- Security - Its more secure. If any hackers did any changes on K8 cluster, then GitOps automatically override the changes. (Not prevent, But will override)
- Versioning - Tracking a changes in GitOps repo
- Auto upgrades -
- Auto healing of any unwanted changes -
- Continuous Reconciliation
- ArgoCD
- Flux
- JenkinsX
- Spinnaker
Repo Server - You have a repo server which is talking to Git.
Application Controller -You have a application controller which is talking to kubernetes.
These Repo server and application controller gets the information and compare the state.
Application controller get the information from Repo server and it always tries to see if the state in Git and Kubernetes is same or not.
API Server - You have a API server which is used for UI / CLI authentication.
DEX - You have a DEX which has the SSO capability.
Redis - Which is used for cache - Why we beed caching? Because these are the stateful sets and these application has to be stateful sets and they have to cache the information.
- YAML manifests
- Helm
- Kubernetes Operator
I just used ubuntu22 with t3.medium instance in AWS Cloud. In order to work with ArgoCD, we have a kubernetes cluster environment.
SSH to machine and install below commands to install minikube and kubectl on ubuntu-22.
sudo apt-get update -y
sudo apt-get upgrade -y
sudo apt install ca-certificates curl gnupg wget apt-transport-https -y
sudo install -m 0755 -d /etc/apt/keyrings
curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo gpg --dearmor -o /etc/apt/keyrings/docker.gpg
sudo chmod a+r /etc/apt/keyrings/docker.gpg
echo \
"deb [arch="$(dpkg --print-architecture)" signed-by=/etc/apt/keyrings/docker.gpg] https://download.docker.com/linux/ubuntu \
"$(. /etc/os-release && echo "$VERSION_CODENAME")" stable" | \
sudo tee /etc/apt/sources.list.d/docker.list > /dev/null
sudo apt update
sudo apt install -y docker-ce docker-ce-cli containerd.io docker-buildx-plugin docker-compose-plugin
sudo usermod -aG docker $USER
newgrp docker
curl -LO https://storage.googleapis.com/minikube/releases/latest/minikube-linux-amd64
sudo install minikube-linux-amd64 /usr/local/bin/minikube
minikube version
curl -LO https://storage.googleapis.com/kubernetes-release/release/`curl -s https://storage.googleapis.com/kubernetes-release/release/stable.txt`/bin/linux/amd64/kubectl
chmod +x kubectl
sudo mv kubectl /usr/local/bin/
kubectl version -o yaml
minikube start --driver=docker
minikube status
kubectl create namespace argocd
kubectl apply -n argocd -f https://raw.githubusercontent.com/argoproj/argo-cd/stable/manifests/install.yaml
watch kubectl get pods -n argocd
kubectl port-forward svc/argocd-server -n argocd 8080:443 --address='0.0.0.0'
or
nohup kubectl port-forward svc/argocd-server -n argocd 8080:443 --address='0.0.0.0' &
Default username is "admin"
To know the password, to execute below command
kubectl -n argocd get secret argocd-initial-admin-secret -o jsonpath="{.data.password}" | base64 -d; echo
Navigate to browser and enter - http://ec2-instance-ip:8080
After login, Navigate to User infor -> change password
Just click - Create an Application
Application name - myapp
Project name - default
SYNC POLICY - Automatic
You can use below GitHub repo url for ArgoCD application Repository URL
https://github.com/argoproj/argocd-example-apps
Revision - HEAD
Path - guestbook (You can see this project in above GitHub URL)
Destination - Cluster URL - https://kubernetes.default.svc (Popping up automatically)
Namespace - default
others leave as default
Finally select create option to create application.
Once created, the ArgoCD will pull the deployment and service yaml files of guestbook from Github and deploy to Kubenetes Cluster.
If you check with Kubernetes cluster using below command
kubectl get deploy
If I click myapp in ArgoCD, then it will give overview of deployment like status of the deployment, service and pods
ArgoCD is un-opinionated - Because ArgoCD wont recommend to use specific format. You can use any format like helm format, json format, ksonnet format or kustomize format.
Bydefault, this app is running with port:80.
So we can port-forward with some other port to avoid conflicting. Just use below command to access the app with port:9090
kubectl port-forward svc/guestbook-ui 9090:80 --address='0.0.0.0'
or
nohup kubectl port-forward svc/guestbook-ui 9090:80 --address='0.0.0.0' &
Now, I can access the guestbook-ui app through browser with cluster-ip:9090
This is the way to deploy the app to kubernetes cluster using ArgoCD manifest file method.
Now Im going to deploy the app to kubernetes cluster using ArgoCD with help template. In order to work, I just delete the application in ArgoCD portal.
After deletion, there is no running pods
Navigate to ArgoCD portal and create a new application again.
Repository URL is same as we have used before
https://github.com/argoproj/argocd-example-apps
This time I good to go with helm-guestbook.
Then create a application and check the status
Now check the K8 pods - Yup Its up and running
Its too running with port 80. So again im go to port-forward with some other port:9080.
kubectl port-forward svc/myhelmapp-helm-guestbook 9080:80 --address='0.0.0.0'
Perfect! My app is running with port:9080.
Now we have used helm template to deploy app on K8 cluster
Then delete the application in ArgoCD portal.
SSH to machine and install the commands below,
wget https://github.com/argoproj/argo-cd/releases/latest/download/argocd-linux-amd64
chmod +x argocd-linux-amd64
sudo mv argocd-linux-amd64 /usr/local/bin/argocd
argocd --help
argocd login 13.201.48.19:8080
username: admin
password: ******
argocd app create guestbook --repo https://github.com/argoproj/argocd-example-apps.git --path guestbook --dest-namespace default --dest-server https://kubernetes.default.svc --directory-recurse
kubectl get application -n argocd
kubectl get deploy -n default
kubectl get svc
nohup kubectl port-forward svc/guestbook-ui 9070:80 --address='0.0.0.0' &
Perfect! I can access the guestbook-ui application with port:9070
Thats it!
























