📣 If you have an M1/M2 Mac, see this post instead
What Is Argo CD?
Argo CD is a Kubernetes controller, responsible for continuously monitoring all running applications and comparing their live state to the desired state specified in the Git repository. It can automatically apply any change to the desired state in the Git repository to the target environment, ensuring the applications remain in sync.
In short, it’s awesome! And we’re going to try it out on minikube on our Mac 🤟
Prerequisites
To continue with the steps below, you need to:
- Have Homebrew installed
- Install Docker Desktop for Mac
- Install minikube using Homebrew by simply running
brew install minikube
Launch Minikube locally
Now that we’re all set, let’s get cooking by launching Minikube. If you don’t know it already, Minikube is a lightweight Kubernetes implementation that creates a VM on your local machine and deploys a simple cluster containing only one node. It is, also, awesome!
In a new Terminal window, run the following:
❯ minikube start --driver=hyperkit
Note: Using the hyperkit
driver bypasses a known issue with the docker
driver on MacOS should you decide to add (which we will) an ingress controller for your argocd
deployment, defined here: docker: Ingress not exposed on MacOS · Issue #7332 · kubernetes/minikube
💡 If at any point you believe you messed up, you can always reset minikube with minikube delete
Install ArgoCD
❯ kubectl create namespace argocd
❯ kubectl apply -n argocd -f https://raw.githubusercontent.com/argoproj/argo-cd/stable/manifests/install.yaml
This will create a new namespace, argocd
, where ArgoCD services and application resources will live.
Make sure all argocd
resources are up:
❯ kn argocd
Context "minikube" modified.
Active namespace is "argocd".
❯ kga
NAME READY STATUS RESTARTS AGE
pod/argocd-application-controller-0 1/1 Running 11 (19h ago) 26h
pod/argocd-applicationset-controller-7dd9d4b769-rwgvc 1/1 Running 0 26h
pod/argocd-dex-server-655f944db8-svvkq 1/1 Running 0 26h
pod/argocd-notifications-controller-759b6bcc4d-wmdsl 1/1 Running 1 (20h ago) 26h
pod/argocd-redis-896595fb7-mhcx9 1/1 Running 0 26h
pod/argocd-repo-server-856b477f86-s8qtz 1/1 Running 8 (19h ago) 26h
pod/argocd-server-5bb99cbcb-dsbvz 1/1 Running 0 31m
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
service/argocd-applicationset-controller ClusterIP 10.109.204.182 <none> 7000/TCP,8080/TCP 26h
service/argocd-dex-server ClusterIP 10.110.204.15 <none> 5556/TCP,5557/TCP,5558/TCP 26h
service/argocd-metrics ClusterIP 10.105.76.14 <none> 8082/TCP 26h
service/argocd-notifications-controller-metrics ClusterIP 10.99.243.176 <none> 9001/TCP 26h
service/argocd-redis ClusterIP 10.99.10.128 <none> 6379/TCP 26h
service/argocd-repo-server ClusterIP 10.99.98.96 <none> 8081/TCP,8084/TCP 26h
service/argocd-server ClusterIP 10.108.22.53 <none> 80/TCP,443/TCP 26h
service/argocd-server-metrics ClusterIP 10.98.228.0 <none> 8083/TCP 26h
NAME READY UP-TO-DATE AVAILABLE AGE
deployment.apps/argocd-applicationset-controller 1/1 1 1 26h
deployment.apps/argocd-dex-server 1/1 1 1 26h
deployment.apps/argocd-notifications-controller 1/1 1 1 26h
deployment.apps/argocd-redis 1/1 1 1 26h
deployment.apps/argocd-repo-server 1/1 1 1 26h
deployment.apps/argocd-server 1/1 1 1 26h
NAME DESIRED CURRENT READY AGE
replicaset.apps/argocd-applicationset-controller-7dd9d4b769 1 1 1 26h
replicaset.apps/argocd-dex-server-655f944db8 1 1 1 26h
replicaset.apps/argocd-notifications-controller-759b6bcc4d 1 1 1 26h
replicaset.apps/argocd-redis-896595fb7 1 1 1 26h
replicaset.apps/argocd-repo-server-856b477f86 1 1 1 26h
replicaset.apps/argocd-server-5674bcbc44 0 0 0 26h
replicaset.apps/argocd-server-5bb99cbcb 1 1 1 31m
NAME READY AGE
statefulset.apps/argocd-application-controller 1/1 26h
Note that the following commands are aliases:
kn
– Stands forkubens
, a sweet set of tools used to jump between contexts and namespaces on Kubernetes clusterskga
– Is aliased tokubectl get all
k
is aliased tokubectl
(you’ll see this on the next command)
Now let’s set up port forwarding in order to access the UI. We can see that the service argocd-server
is using ports 80 and 443 – We will use the next command to connect to the API server without exposing the service:
❯ k port-forward svc/argocd-server 8080:443
Forwarding from 127.0.0.1:8080 -> 8080
Forwarding from [::1]:8080 -> 8080
Now if we browse to 127.0.0.1:8080
(or localhost:8080
) we are presented with the ArgoCD UI. Hoorah! 🎉
To login, the default user in admin
, but we still need to retrieve the password. To do so, launch a new Terminal tab or window (this is important: closing or interrupting our existing terminal session will cause us to lose our current connection to the web UI; all next steps until we setup the Ingress should be performed in this new Terminal window) and run:
❯ k get secret argocd-initial-admin-secret -o yaml
apiVersion: v1
data:
password: S05za0QtbnB3MmdmNU5mUQ==
kind: Secret
metadata:
creationTimestamp: "2022-05-31T10:20:12Z"
name: argocd-initial-admin-secret
namespace: argocd
resourceVersion: "133179"
uid: 956bf056-1285-4465-aa77-d8ac87f65d13
type: Opaque
Grab the password and decode it:
❯ echo S05za0QtbnB3MmdmNU5mUQ== | base64 --decode
KNskD-npw2gf5NfQ
⚠️ You should delete the
argocd-initial-admin-secret
from the Argo CD namespace once you changed the password. The secret serves no other purpose than to store the initially generated password in clear and can safely be deleted at any time. It will be re-created on demand by Argo CD if a new admin password must be re-generated.
Alternatively, we can run:
❯ kubectl -n argocd get secret argocd-initial-admin-secret -o jsonpath="{.data.password}" | base64 -d; echo
Sweet, now we have the admin password and can proceed with changing it.
ArgoCD CLI Login
Now that we have the admin password, we are able to sign in to argocd
from the terminal. However, we need to install the argocd cli
first. To do so, run:
❯ brew install argocd
There. That simple.
Now let’s login in to argocd
using the CLI and update the password:
❯ argocd login localhost:8080
WARNING: server certificate had error: x509: “Argo CD” certificate is not trusted. Proceed insecurely (y/n)? y
Username: admin
Password:
'admin:login' logged in successfully
Context 'localhost:8080' updated
❯ argocd account update-password
*** Enter password of currently logged in user (admin):
*** Enter new password for user admin:
*** Confirm new password for user admin:
Password updated
Context 'localhost:8080' updated
Note that you need to enter your current password first (the one we identified in the steps above) before typing your new password twice.
Ingress
So far, we have reached the ArgoCD UI by broswing to http://localhost:8080. However, this is not ideal.
An ingress exposes HTTP and HTTPS routes from outside the cluster to services within the cluster. Traffic routing is controlled by rules defined on the Ingress resource.
Here is a simple example where an Ingress sends all its traffic to one Service:
In short, instead of reaching the ArgoCD UI using localhost:8080
, I would rather this behaves like a “normal” site, like -for example- https://argocd.apexlemons.com
With that in mind, let’s enable the ingress addon for minikube first:
❯ minikube addons enable ingress
To create the ingress, create a new file named argocd-ingress.yaml
with the following content:
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: argocd
namespace: argocd
annotations:
networking.gke.io/v1beta1.FrontendConfig: argocd-frontend-config
spec:
tls:
- secretName: secret-yourdomain-com
rules:
- host: argocd.apexlemons.com
http:
paths:
- pathType: Prefix
path: "/"
backend:
service:
name: argocd-server
port:
number: 80
Note, make sure to replace the host
value above with a domain of your choice (ie argocd.whatever.com
). It can be anything, the beauty is that you don’t even need a domain to make this work, as we will point it to the local minikube IP in the next steps below.
Next, apply it to the argocd
namespace:
❯ kubectl apply -f argocd-ingress.yaml -n argocd
Now however, attempting to browse to https://argocd.apexlemons.com will result in a ERR_TOO_MANY_REDIRECTS
error.
ArgoCD handles TLS termination by itself and always redirects HTTP requests to HTTPS. The problem here is that the nginx ingress controller also handles TLS termination and communicates with the backend service with HTTP and the result is that the ArgoCD’s server always responds with a redirect to HTTPS which is the cause for the multiple redirects. More on this here.
The solution is to ensure that the service doesn’t handle TLS by passing the --insecure
flag to the argocd-server
deployment. Edit the deployment with the following command and then add the required flag:
❯ kubectl edit deployment argocd-server -n argocd
[...]
template:
spec:
containers:
- name: argocd-server
command:
- argocd-server
- --insecure <-- Add this bit
[...]
Next, we need to figure out the IP address of our minikube node and create an entry in our /etc/hosts
file that will point our domain (argocd.apexlemons.com in my case, argocd.whatever.com in yours!) to our minikube node:
❯ minikube ip
192.168.64.3
This is my node’s IP, so I will point my argocd “domain” accordingly by adding the relevant line at the end of my /etc/hosts
file:
192.168.64.3 argocd.apexlemons.com
You may now close the terminal where port forwarding is running and browse to your brand new local Argo CD instance using your preferred URL!
✌🏽