I first encountered Argo on the Civo community Slack, when it was mentioned as something exciting by Alex Ellis. After reading a little about the project, I decided to try it out, and document my experience. In the following guide, we will deploy Argo to manage GitOps in Kubernetes for two different Git repository-based projects.
What is Argo CD?
According to the official site:
Argo CD is a declarative, GitOps continuous delivery tool for Kubernetes.
Argo CD follows the GitOps
pattern of using Git
repositories as the source of truth for defining the desired application state, and manages the Kubernetes deployment of these applications.
Why Argo CD?
Again, quoting the official site:
Application definitions, configurations, and environments should be declarative and version controlled. Application deployment and lifecycle management should be automated, auditable, and easy to understand.
An Argo deployment of an application can follow a branch of a git repository, or be pinned to a particular release. Configuration of the app will be on the basis of what is defined in the repository, and that repository only.
Deployment
Pre-Requisites
To follow along with this guide, you will have to have a Civo account with access to the managed Kubernetes service. If you do not yet have an account, you can sign up here and benefit from $250 free credit for 1 month.
You will also need to have kubectl installed to manage namespaces and secrets on the cluster.
Creating the cluster
Once you have an account and are looking at your account dashboard, you should have a link to the Kubernetes panel. Inside, there is the option to create a cluster that would look like this:
once created it would look like this:
Next, we will need to ensure we can manage our cluster from the command line using kubectl
. Click the link on the cluster page to download your kubeconfig
file and set it as your KUBECONFIG variable.
Installing Argo CD
Once you have access to your cluster as the current context, the first thing will be, referencing the argo documentation site, to run the following in the cluster:
$ kubectl create namespace argocd
$ kubectl apply -n argocd -f
https://raw.githubusercontent.com/argoproj/argo-cd/stable/manifests/install.yaml
This will create a namespace with the name argocd
in our cluster, and then it will install all the necessary things for argo to run.
Once everything is displayed, we will need to get the password generated by Argo to be able to login in the interface. We will do it this way:
$ kubectl get secret -n argocd argocd-initial-admin-secret -o jsonpath='{.data.password}' | base64 -d; echo
Now, logging in to Argo
can be done in two ways, using your CLI or through the web interface. For access on the web there are two more options: the first is to create an ingress, explained on the Argo site. The second is to make a port-forward
with kubectl
in the following way, and is the one we will use to not expose argo to the wider internet:
kubectl port-forward svc/argocd-server -n argocd 8080:443
Now we can access the Argo CD UI using localhost:8080
. Note that, as the default Argo-generated SSL certificate is self-signed, this will generate an error in your browser that you will have to bypass.
The username to the Argo web interface will be admin
and the password is the one you displayed earlier using the console command above.
Adding a new repo to Argo
To start with Argo, the first thing will be to add a git repository through the menu:
then we go to Repositories
Clicking on the link, we enter the repositories manager. Inside we click on connect Git repo using HTTPS
that would open a sidebar to put the data of our git repo, in our case we will only use the url because what we will deploy in this example will be OpenFaaS, which is a public repository.
The url of the repository is https://github.com/openfaas/faas-netes
After we add it it will look like this:
Installing OpenFaaS
Requirements
So far we have Argo CD running, and the OpenFaas repo ready. The next step will be to create the cluster namespace for OpenFaaS and it is done in this way:
$ kubectl apply -f
https://raw.githubusercontent.com/openfaas/faas-netes/master/namespaces.yml
after this we need to generate a password for OpenFaaS. Once generated do not forget it, or use one that you already know in place of the generator.
# generate a random password
PASSWORD=$(head -c 12 /dev/urandom | shasum| cut -d' ' -f1)
kubectl -n openfaas create secret generic basic-auth
--from-literal=basic-auth-user=admin \
--from-literal=basic-auth-password="$PASSWORD"
Deploying
Once this is ready, we can go to the Argo interface and create an application by clicking on New application
then fill in the fields. To make it simple, you can click on Edit as yaml
and paste the following rather than input the individual fields:
apiVersion: argoproj.io/v1alpha1
metadata:
name: openfaas
spec:
destination:
namespace: openfaas
server: 'https://kubernetes.default.svc'
source:
path: chart/openfaas
repoURL: 'https://github.com/openfaas/faas-netes'
targetRevision: HEAD
helm:
valueFiles:
- values.yaml
project: default
syncPolicy:
automated:
prune: false
selfHeal: true
Once you have done this, click on save
and create
and voila. Now we can see how the app syncs itself and it will look something like this:
Creating the ingress for OpenFaaS
Once this is done we can create the ingress for OpenFaaS in the following way. Note that you will have to change the host
value! Your host line would be the url that the Civo cluster administration panel gives you. In my case this was 30df4151-3aa7-4a03-96ec-545cdd1f040e.k8s.civo.com
.
Create the following file as openfaas-ingress.yaml
on your computer:
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: openfaas-ingress
namespace: openfaas
annotations:
kubernetes.io/ingress.class: traefik
spec:
rules:
- host: openfaas.30df4151-3aa7-4a03-96ec-545cdd1f040e.k8s.civo.com
http:
paths:
- path: /
pathType: Prefix
backend:
service:
name: gateway
port:
number: 8080
Using kubectl
apply the ingress:
$ kubectl apply -f openfaas-ingress.yaml
Now you should be able to visit the URL of your cluster host, in my case http://openfaas.30df4151-3aa7-4a03-96ec-545cdd1f040e.k8s.civo.com
.
Have a play with the help of the documentation here.
If any changes are made to the master branch of the OpenFaaS repository, these would be automatically synced through Argo to your particular deployment. GitOps!
One more test
After finishing the above guide, I wanted to try if Argo would work for other projects, and decided to try. We will repeat the option of adding a new repo but this time we are going to use the Docker voting app example found at https://github.com/dockersamples/example-voting-app.
We can see the two connected repos in the UI:
Once this is done, we will create a namespace in our Kubernetes cluster using kubectl create namespace vote
. Then we will create a new application in the Argo interface, just like in the OpenFaaS example above. This time, this is the yaml:
apiVersion: argoproj.io/v1alpha1
metadata:
name: vote
spec:
destination:
namespace: vote
server: 'https://kubernetes.default.svc'
source:
path: k8s-specifications
repoURL: 'https://github.com/dockersamples/example-voting-app'
targetRevision: HEAD
project: default
syncPolicy:
automated:
prune: false
selfHeal: true
This is a bit different from the previous one since in this case I will use the k8s-specifications
directory to deploy, since this directory contains all the yaml for kubernetes, so we can see it works also for deployments without helm
. Now for the ingress for this project:
Save the following as vote-ingress.yaml
, once again changing the host
lines to be the URL of your civo cluster, preserving the vote
and result
prefix:
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: vote-ingress
namespace: vote
annotations:
kubernetes.io/ingress.class: traefik
spec:
rules:
- host: vote.30df4151-3aa7-4a03-96ec-545cdd1f040e.k8s.civo.com
http:
paths:
- path: /
pathType: Prefix
backend:
service:
name: vote
port:
number: 5000
---
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: result-ingress
namespace: vote
annotations:
kubernetes.io/ingress.class: traefik
spec:
rules:
- host: result.30df4151-3aa7-4a03-96ec-545cdd1f040e.k8s.civo.com
http:
paths:
- path: /
pathType: Prefix
backend:
service:
name: result
port:
number: 5001
Once again, apply the ingress:
$ kubectl apply -f vote_ingress.yaml
ingress.networking.k8s.io/vote-ingress created
ingress.networking.k8s.io/result-ingress created
Now you can visit your equivalents of vote.30df4151-3aa7-4a03-96ec-545cdd1f040e.k8s.civo.com
to vote and result.30df4151-3aa7-4a03-96ec-545cdd1f040e.k8s.civo.com
to see the results.
At the end the dashboard of Argo look like this:
Conclusion
Well now I think that everything is ready. I hope you liked Argo CD, I still have some more tests to do but everything points to it being a great tool to run GitOps. The above are simple examples, but you could easily deploy an application from your own repository, push changs and see them reflected in your cluster deployment as soon as Argo refreshes.