Automate Kubernetes deployment using Argo CD
Argo CD is a declarative Git-Ops continuous delivery tool created for Kubernetes.
k8s application manifests should be version controlled in a git repository. Argo CD uses the git repository as a source of truth which represent the desired state of the application.
Argo CD is implemented as a k8s controller which continuously monitor current or live state with the desired state described in the git repository and automate the deployment of desired state in k8s environment.
Prerequisite
Before moving forward, some tools are required to complete the exercise,
- A local Kubernetes cluster, for example Docker Desktop or Minikube
- kubectl
- Git account and git CLI
- Argo CD
The installation instructions for local Kubernetes cluster can be found in respective links.
Installing Argo CD
As mentioned before, Argo CD is implemented as a custom controller, so it needs to be deployed in k8s.
Let's create a separate namespace for Argo CD installation.
kubectl create ns argocd
Protip
To switch into a namespace, if you want to work within it for long, you can use:
kubectl config set-context --current --namespace=argocd
This official way is a little complex to remember and run every time when you want to switch to a new namespace.
To get rid of this, you can grab a tool called kubens
which is in kubectx package for mac and
Linux, since I am using windows, I need to install it separately using,
choco install kubens --version=0.9.1
After installing kubens, you can list down all namespaces in current context using kubens and to print out the
current namespace you can use kubens -c
To switch to argocd namespace, we can now use
kubens argocd
which is much easier to remember and handy.
Coming back to our main section, now lets install ArgoCD in newly created namespace.
kubectl apply -n argocd -f https://raw.githubusercontent.com/argoproj/argo-cd/stable/manifests/install.yaml
This took around 3-5 minutes, you can check the status of deployment using kubectl get deployment
which will give output as follows:
NAME READY UP-TO-DATE AVAILABLE AGE
argocd-dex-server 1/1 1 1 5m28s
argocd-redis 1/1 1 1 5m28s
argocd-repo-server 1/1 1 1 5m28s
argocd-server 1/1 1 1 5m28s
Access Argo CD API Server
By default, the Argo CD API server is not exposed with an external IP. To access the API server, choose one of the following techniques to expose the Argo CD API server:
kubectl patch svc argocd-server -n argocd -p '{"spec": {"type": "LoadBalancer"}}'
kubectl port-forward svc/argocd-server -n argocd 8081:443
Use localhost:8081
to access the API server in browser.
Login to Argo CD
Default username to login to Argo CD server is admin
, to get the password there are several ways.
One way is to get the initial admin password using command below. The password is base 64
encoded, so if on windows use Git Bash to use the decode function.
kubectl -n argocd get secret argocd-initial-admin-secret -o jsonpath="{.data.password}" | base64 -d
This will return the decoded password that can be used directly.
Another way is to patch the argocd-secret
and update the admin.password
field which should be encrypted with Bcrypt password hashing function. One can use the online tools like bcrypt-generator.com to get the hash.
Here the updated password is admin
.
kubectl -n argocd patch secret argocd-secret -p '{"stringData": {"admin.password": "$2a$10$aDulNEmKSuPr8rUH7CvMguvkz/x5wRJuiZgXOw4cc4Zzk2RhpRpBi", "admin.passwordMtime": "'$(date +%FT%T)'"}}'
After login, target page will show the list of application. As there are no applications, so this section is blank for now.
Login using Argo CD CLI
First install Argo CD CLI as per the operating system.
For mac or Linux, use the below command to install it.
brew install argocd
For windows, follow the link, download and add the entry in path variable.
To login through CLI, use the command mentioned below:
argocd login localhost:8081 --username admin --password admin --insecure
Argo CD installation and Login part is completed. Now the next step is to create a demo application and update k8s manifest to deploy in cluster.
The Demo Application
As it already discussed that Argo CD uses git repository to automate the deployment, so a git repository is required. Here I am using github repository.
git clone https://github.com/aprabhat/argo-cd-color-app.git
After cloning, switch to dev
branch, check for the deploy folder and take a look at deployment and service manifest files.
Now create another namespace in which the demo application will be deployed.
kubectl create ns practice
Create k8s resource of type Argo CD application using the above repo as source. For this create color-app.yaml file with following content. Here, targetRevision
represents the branch name and path
represents the location from root directory where the k8s manifest resides.
apiVersion: argoproj.io/v1alpha1
kind: Application
metadata:
name: color-app
namespace: argocd
spec:
project: default
source:
repoURL: https://github.com/aprabhat/argo-cd-color-app.git
targetRevision: dev
path: deploy
destination:
server: https://kubernetes.default.svc
namespace: practice
Save and apply this yaml file.
kubectl apply -f app.yaml
This will create a resource of type application. The new application is now available in Argo CD dashboard.
The app list and status can also be fetched by using Argo CD CLI using argocd app list
command.
Click on the app tile in UI and check for the resources created for the application.
The app is created but not deployed as the syncPolicy
is not set and default to manual. So a manual synchronization is required.
argocd app sync color-app
Once the sync is completed, the application details UI will also be updated with all the resources created for k8s application.
Now let's update the application to be on auto sync mode. To do so, update the color-app.yaml file for syncPolicy
and apply it again using kubectl apply -f color-app.yaml
.
apiVersion: argoproj.io/v1alpha1
kind: Application
metadata:
name: color-app
namespace: argocd
spec:
project: default
source:
repoURL: https://github.com/aprabhat/argo-cd-color-app.git
targetRevision: dev
path: deploy
destination:
server: https://kubernetes.default.svc
namespace: practice
syncPolicy:
automated: {}
To test the auto sync, update the deployment.yaml file for replicas and push the change to git repository. Check the application details in Argo CD UI dashboard for the pods if they scaled to 2.
This time as syncPolicy
is set to automated, there is no need to do a manual sync.
Finally you can check for the deployed application. First describe the service from practice namespace using kubectl -n practice describe svc color-service
Name: color-service
Namespace: practice
Labels: app.kubernetes.io/instance=color-app
Annotations: <none>
Selector: app=color
Type: NodePort
IP Family Policy: SingleStack
IP Families: IPv4
IP: 10.110.20.25
IPs: 10.110.20.25
LoadBalancer Ingress: localhost
Port: <unset> 3000/TCP
TargetPort: 3000/TCP
NodePort: <unset> 30007/TCP
Endpoints: 10.1.0.19:3000,10.1.0.20:3000
Session Affinity: None
External Traffic Policy: Cluster
Events: <none>
To access the sample application deployed use the localhost:<NodePort>. In this case it is localhost:30007, open this in the browser. The nice UI will appear on the browser window.
In few simple steps, you are able to automate the deployment of k8s application using Argo CD.
Although this post is not covering all the scenarios or production system use cases but it is a good place to have a glimpse of how Argo CD works and to understand how to automate k8s application deployment with Argo CD.
Conclusion
In the era of microservice, as the number of k8s workloads keeps on increasing, deploying the tens or hundred of pods at the same time is a tedious task.
In this situation, Argo CD is a great tool which enable teams to automate the deployment on multiple environments(testing, staging production). Argo CD will definitely helps the scrum teams to save time by automating the Continuous Delivery process and reduce common errors.