Sunday, December 8, 2024

Argo CD - k8s GitOps on minikube

HOWTO 

Git


Argo CD architecture






 Start minikube

dave@fedora:~$ minikube start --driver=docker
😄  minikube v1.32.0 on Fedora 40
✨  Using the docker driver based on existing profile
👍  Starting control plane node minikube in cluster minikube
🚜  Pulling base image ...
🎉  minikube 1.34.0 is available! Download it: https://github.com/kubernetes/minikube/releases/tag/v1.34.0
💡  To disable this notice, run: 'minikube config set WantUpdateNotification false'

🔄  Restarting existing docker container for "minikube" ...
🐳  Preparing Kubernetes v1.28.3 on Docker 24.0.7 ...
🔗  Configuring bridge CNI (Container Networking Interface) ...
🔎  Verifying Kubernetes components...
    ▪ Using image gcr.io/k8s-minikube/minikube-ingress-dns:0.0.2
    ▪ Using image docker.io/kubernetesui/metrics-scraper:v1.0.8
    ▪ Using image docker.io/kubernetesui/dashboard:v2.7.0
    ▪ Using image registry.k8s.io/ingress-nginx/kube-webhook-certgen:v20231011-8b53cabe0
    ▪ Using image gcr.io/k8s-minikube/storage-provisioner:v5
    ▪ Using image registry.k8s.io/ingress-nginx/kube-webhook-certgen:v20231011-8b53cabe0
    ▪ Using image registry.k8s.io/ingress-nginx/controller:v1.9.4
🔎  Verifying ingress addon...
💡  Some dashboard features require the metrics-server addon. To enable all features please run:

    minikube addons enable metrics-server    


🌟  Enabled addons: ingress-dns, storage-provisioner, dashboard, ingress, default-storageclass
🏄  Done! kubectl is now configured to use "minikube" cluster and "default" namespace by default

 

 

Install Argo CD 


dave@fedora:~$ kubectl create namespace argocd
namespace/argocd created
dave@fedora:~$ kubectl apply -n argocd -f https://raw.githubusercontent.com/argoproj/argo-cd/stable/manifests/install.yaml
customresourcedefinition.apiextensions.k8s.io/applications.argoproj.io created
customresourcedefinition.apiextensions.k8s.io/applicationsets.argoproj.io created
customresourcedefinition.apiextensions.k8s.io/appprojects.argoproj.io created
serviceaccount/argocd-application-controller created
serviceaccount/argocd-applicationset-controller created
serviceaccount/argocd-dex-server created
serviceaccount/argocd-notifications-controller created
serviceaccount/argocd-redis created
serviceaccount/argocd-repo-server created
serviceaccount/argocd-server created
role.rbac.authorization.k8s.io/argocd-application-controller created
role.rbac.authorization.k8s.io/argocd-applicationset-controller created
role.rbac.authorization.k8s.io/argocd-dex-server created
role.rbac.authorization.k8s.io/argocd-notifications-controller created
role.rbac.authorization.k8s.io/argocd-redis created
role.rbac.authorization.k8s.io/argocd-server created
clusterrole.rbac.authorization.k8s.io/argocd-application-controller created
clusterrole.rbac.authorization.k8s.io/argocd-applicationset-controller created
clusterrole.rbac.authorization.k8s.io/argocd-server created
rolebinding.rbac.authorization.k8s.io/argocd-application-controller created
rolebinding.rbac.authorization.k8s.io/argocd-applicationset-controller created
rolebinding.rbac.authorization.k8s.io/argocd-dex-server created
rolebinding.rbac.authorization.k8s.io/argocd-notifications-controller created
rolebinding.rbac.authorization.k8s.io/argocd-redis created
rolebinding.rbac.authorization.k8s.io/argocd-server created
clusterrolebinding.rbac.authorization.k8s.io/argocd-application-controller created
clusterrolebinding.rbac.authorization.k8s.io/argocd-applicationset-controller created
clusterrolebinding.rbac.authorization.k8s.io/argocd-server created
configmap/argocd-cm created
configmap/argocd-cmd-params-cm created
configmap/argocd-gpg-keys-cm created
configmap/argocd-notifications-cm created
configmap/argocd-rbac-cm created
configmap/argocd-ssh-known-hosts-cm created
configmap/argocd-tls-certs-cm created
secret/argocd-notifications-secret created
secret/argocd-secret created
service/argocd-applicationset-controller created
service/argocd-dex-server created
service/argocd-metrics created
service/argocd-notifications-controller-metrics created
service/argocd-redis created
service/argocd-repo-server created
service/argocd-server created
service/argocd-server-metrics created
deployment.apps/argocd-applicationset-controller created
deployment.apps/argocd-dex-server created
deployment.apps/argocd-notifications-controller created
deployment.apps/argocd-redis created
deployment.apps/argocd-repo-server created
deployment.apps/argocd-server created
statefulset.apps/argocd-application-controller created
networkpolicy.networking.k8s.io/argocd-application-controller-network-policy created
networkpolicy.networking.k8s.io/argocd-applicationset-controller-network-policy created
networkpolicy.networking.k8s.io/argocd-dex-server-network-policy created
networkpolicy.networking.k8s.io/argocd-notifications-controller-network-policy created
networkpolicy.networking.k8s.io/argocd-redis-network-policy created
networkpolicy.networking.k8s.io/argocd-repo-server-network-policy created
networkpolicy.networking.k8s.io/argocd-server-network-policy created

 Get pods in argocd namespace

$ kubectl get pod -n argocd
NAME                                                READY   STATUS              RESTARTS   AGE
argocd-application-controller-0                     0/1     ContainerCreating   0          20s
argocd-applicationset-controller-5c787df94f-npjn9   0/1     ContainerCreating   0          22s
argocd-dex-server-6bb9b5fc75-x4vt8                  0/1     Init:0/1            0          22s
argocd-notifications-controller-7ccbd7fb6-dm8bq     0/1     ContainerCreating   0          22s
argocd-redis-c5c567495-cgtrl                        0/1     Init:0/1            0          22s
argocd-repo-server-799b498d8b-pc2l8                 0/1     Init:0/1            0          22s
argocd-server-f6d4d8775-9hlcj                       0/1     ContainerCreating   0          21s

Get services in argocd namespace
$ kubectl get svc -n argocd
NAME                                      TYPE        CLUSTER-IP      EXTERNAL-IP   PORT(S)                      AGE
argocd-applicationset-controller          ClusterIP   10.101.144.51   <none>        7000/TCP,8080/TCP            105s
argocd-dex-server                         ClusterIP   10.111.165.14   <none>        5556/TCP,5557/TCP,5558/TCP   105s
argocd-metrics                            ClusterIP   10.100.56.238   <none>        8082/TCP                     105s
argocd-notifications-controller-metrics   ClusterIP   10.111.151.85   <none>        9001/TCP                     105s
argocd-redis                              ClusterIP   10.97.35.44     <none>        6379/TCP                     104s
argocd-repo-server                        ClusterIP   10.109.34.145   <none>        8081/TCP,8084/TCP            104s
argocd-server                             ClusterIP   10.99.111.141   <none>        80/TCP,443/TCP               104s
argocd-server-metrics                     ClusterIP   10.106.186.75   <none>        8083/TCP                     104s

Port forward to access Argo CD UI
$ kubectl port-forward svc/argocd-server -n argocd 8080:443
Forwarding from 127.0.0.1:8080 -> 8080
Forwarding from [::1]:8080 -> 8080

Get admin password
$ kubectl get secret argocd-initial-admin-secret -n argocd -o yaml
apiVersion: v1
data:
  password: ab123==
kind: Secret
metadata:
  creationTimestamp: "2024-12-15T07:58:19Z"
  name: argocd-initial-admin-secret
  namespace: argocd
  resourceVersion: "190652"
  uid: a017dc3e-3232-40f6-a2e6-374872963888
type: Opaque

$ echo ab123|base64 --decode

Open UI at https://127.0.0.1:8080/applications





Apply application.yaml on k8s cluster via kubectl

apiVersion: argoproj.io/v1alpha1
kind: Application
metadata:
  name: guestbook
  namespace: argocd
spec:
  project: default

  source:
    repoURL: https://github.com/dveselka/devops-k8s.git
    targetRevision: HEAD
    path: argocd
    
  destination:
    server: https://kubernetes.default.svc
    namespace: myapp

  syncPolicy:
    syncOptions:
    - CreateNamespace = true  


    automated:
      selfHeal: true
      prune: true

Apply

$ cp * /git/devops-k8s/argocd
dave@dave:/git/argocd-app-config/dev$ ls
application.yaml  deployment.yaml  service.yaml
dave@dave:/git/argocd-app-config/dev$ kubectl apply -f application.yaml 
application.argoproj.io/guestbook created

Argo CD UI - unsynced


Argo CD UI with synced application 





Argo CD descriptors






Get pods in myapp namespace
$  kubectl get pods -n myapp
NAME                     READY   STATUS    RESTARTS   AGE
myapp-55c645d9b5-62llh   1/1     Running   0          6m29s
myapp-55c645d9b5-vmtmb   1/1     Running   0          6m29s

Get services in myapp namespace
$  kubectl get svc  -n myapp
NAME            TYPE        CLUSTER-IP       EXTERNAL-IP   PORT(S)    AGE
myapp-service   ClusterIP   10.104.101.233   <none>        8080/TCP   6m35s

Minikube dashboard



Deployments 







2 comments:

  1. Great post, Daniel! 👏

    As someone involved in DevOps consulting, I found your step-by-step guide on setting up Argo CD on Minikube incredibly practical. It's a solid resource for demonstrating GitOps workflows in a local Kubernetes environment — especially useful for prototyping solutions before rolling them out at scale.

    Your clear explanation of port forwarding and UI access simplifies adoption for beginners and is a great reference even for experienced practitioners. Looking forward to more insights, especially around scaling GitOps practices or integrating Argo CD with enterprise CI/CD pipelines.

    Keep up the great work — this kind of content is invaluable for the DevOps community!

    ReplyDelete
  2. Great walkthrough! Setting up Argo CD on Minikube this clearly really helps simplify GitOps for beginners. It’s interesting to see how GitOps and DevOps approaches complement each other in modern workflows — some recent thoughts on that blend are pretty insightful: GitOps vs DevOps and which model fits your project.

    ReplyDelete