Comprehensive ArgoCD Setup Guide for Kubernetes
This comprehensive guide provides detailed, step-by-step instructions for deploying and configuring ArgoCD in your Kubernetes cluster. It covers installation, initial setup, and best practices, including declarative application definitions, enabling automated sync, configuring SSO, setting up RBAC, enabling monitoring, configuring notifications, performing regular backups, setting resource limits, ensuring high availability, and implementing security hardening to maintain a robust, scalable, and secure GitOps workflow.
Prerequisites
- Kubernetes cluster (v1.19+)
- kubectl CLI tool installed
- Helm (optional)
- Access to a Git repository
- Basic understanding of Kubernetes and GitOps
Step 1: Install ArgoCD
1.1 Create Namespace
apiVersion: v1
kind: Namespace
metadata:
name: argocd
1.2 Install ArgoCD Core Components
kubectl apply -n argocd -f https://raw.githubusercontent.com/argoproj/argo-cd/stable/manifests/install.yaml
1.3 Verify Installation
kubectl get pods -n argocd
Expected output:
NAME READY STATUS RESTARTS AGE
argocd-application-controller-0 1/1 Running 0 2m
argocd-dex-server-5dd657bd9-xm6x4 1/1 Running 0 2m
argocd-redis-759b6bc7f4-r2qzb 1/1 Running 0 2m
argocd-repo-server-7c475dcc7-nf85p 1/1 Running 0 2m
argocd-server-544c4c6b5-p4h9r 1/1 Running 0 2m
Step 2: Access ArgoCD UI
2.1 Get Initial Admin Password
kubectl -n argocd get secret argocd-initial-admin-secret -o jsonpath="{.data.password}" | base64 -d
2.2 Access the UI
Option 1: Port Forwarding
kubectl port-forward svc/argocd-server -n argocd 8080:443
Option 2: LoadBalancer Service
apiVersion: v1
kind: Service
metadata:
name: argocd-server
namespace: argocd
spec:
type: LoadBalancer
ports:
- port: 443
targetPort: 8080
selector:
app.kubernetes.io/name: argocd-server
Step 3: Configure SSO (Optional)
3.1 Setup Dex Configuration
apiVersion: v1
kind: ConfigMap
metadata:
name: argocd-cm
namespace: argocd
labels:
app.kubernetes.io/name: argocd-cm
app.kubernetes.io/part-of: argocd
data:
url: https://argocd.example.com
dex.config: |
connectors:
- type: github
id: github
name: GitHub
config:
clientID: your-client-id
clientSecret: your-client-secret
orgs:
- name: your-github-org
3.2 Configure RBAC
apiVersion: v1
kind: ConfigMap
metadata:
name: argocd-rbac-cm
namespace: argocd
data:
policy.default: role:readonly
policy.csv: |
p, role:org-admin, applications, *, */*, allow
p, role:org-admin, clusters, get, *, allow
g, your-github-org:team-name, role:org-admin
Step 4: Setup Your First Application
4.1 Create Application Manifest
apiVersion: argoproj.io/v1alpha1
kind: Application
metadata:
name: guestbook
namespace: argocd
spec:
project: default
source:
repoURL: https://github.com/argoproj/argocd-example-apps.git
targetRevision: HEAD
path: guestbook
destination:
server: https://kubernetes.default.svc
namespace: guestbook
syncPolicy:
automated:
prune: true
selfHeal: true
syncOptions:
- CreateNamespace=true
4.2 Apply the Application
kubectl apply -f application.yaml
Step 5: Configure High Availability
5.1 HA Manifest
apiVersion: apps/v1
kind: StatefulSet
metadata:
name: argocd-application-controller
namespace: argocd # ✅ Added namespace
spec:
serviceName: "argocd-application-controller" # ✅ Required field
selector: # ✅ Required field
matchLabels:
app: argocd-application-controller
replicas: 3
template:
metadata:
labels:
app: argocd-application-controller
spec:
containers:
- name: argocd-application-controller
args:
- --status-processors=20
- --operation-processors=10
5.2.1 Option 1: Delete & Recreate (Recommended)
If you can afford downtime or the StatefulSet doesn’t have critical persistent data:
kubectl delete sts argocd-application-controller -n argocd
kubectl apply -f application-controller.yaml
This option may result in data loss if the StatefulSet has critical persistent data.
Note: Deleting a StatefulSet does not delete associated PVCs unless explicitly specified.
If you want to delete the PVCs too:
kubectl delete pvc -l app=argocd-application-controller -n argocd
kubectl apply -f application-controller.yaml
5.2.2 Option 2: Modify Allowed Fields (No Downtime)
If you only need to change replicas, template, updateStrategy, or minReadySeconds, use kubectl patch instead of applying a new manifest.
kubectl patch statefulset argocd-application-controller -n argocd --type='strategic' -p '{"spec":{"replicas":5}}'
5.2 Resource Requirements
apiVersion: apps/v1
kind: Deployment
metadata:
name: argocd-server
spec:
template:
spec:
containers:
- name: argocd-server
resources:
requests:
cpu: 500m
memory: 512Mi
limits:
cpu: 1000m
memory: 1024Mi
Step 6: Setup Monitoring
6.1 ServiceMonitor Configuration
apiVersion: monitoring.coreos.com/v1
kind: ServiceMonitor
metadata:
name: argocd-metrics
namespace: argocd
spec:
selector:
matchLabels:
app.kubernetes.io/name: argocd-server # ✅ Match this with the actual service labels
namespaceSelector:
matchNames:
- argocd # ✅ Ensure Prometheus can scrape from this namespace
endpoints:
- port: metrics # ✅ Ensure the service has this port name
interval: 30s # Optional: Set a scrape interval
path: /metrics # Optional: Define the metrics path (default is usually `/metrics`)
Make sure to replace `argocd-server` with the actual name of the ArgoCD server service.
Check that the ArgoCD Service exposing metrics has the correct labels and port:
6.2 Grafana Dashboard
apiVersion: v1
kind: ConfigMap
metadata:
name: argocd-grafana-dashboard
namespace: monitoring
data:
argocd-dashboard.json: |
{
"title": "ArgoCD Dashboard",
"panels": [
{
"title": "Sync Status",
"type": "graph"
},
{
"title": "Application Health",
"type": "graph"
}
]
}
Step 7: Configure Notifications
7.1 Setup Notification Controller
apiVersion: v1
kind: Secret
metadata:
name: argocd-notifications-secret
namespace: argocd
stringData:
slack-token: "xoxb-your-token"
---
apiVersion: v1
kind: ConfigMap
metadata:
name: argocd-notifications-cm
namespace: argocd
data:
service.slack: |
token: $slack-token
trigger.on-sync-status-changed: |
- when: app.status.sync.status == 'Synced'
send: [app-sync-succeeded]
- when: app.status.sync.status == 'OutOfSync'
send: [app-out-of-sync]
Step 8: Backup Configuration
8.1 Backup CronJob
apiVersion: batch/v1
kind: CronJob
metadata:
name: argocd-backup
namespace: argocd
spec:
schedule: "0 0 * * *"
jobTemplate:
spec:
template:
spec:
containers:
- name: argocd-backup
image: bitnami/kubectl
command:
- /bin/sh
- -c
- |
kubectl get applications.argoproj.io -n argocd -o yaml > /backup/applications.yaml
kubectl get appprojects.argoproj.io -n argocd -o yaml > /backup/projects.yaml
Best Practices Checklist
- ✅ Use declarative application definitions
- ✅ Enable automated sync
- ✅ Configure SSO
- ✅ Setup RBAC
- ✅ Enable monitoring
- ✅ Configure notifications
- ✅ Regular backups
- ✅ Resource limits
- ✅ High availability
- ✅ Security hardening
Security Considerations
1. TLS Configuration
apiVersion: v1
kind: Secret
metadata:
name: argocd-secret
namespace: argocd
type: Opaque
data:
tls.crt: <base64-encoded-certificate>
tls.key: <base64-encoded-key>
2. Network Policies
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: argocd-server-network-policy
namespace: argocd
spec:
podSelector:
matchLabels:
app.kubernetes.io/name: argocd-server
policyTypes:
- Ingress
ingress:
- from:
- namespaceSelector:
matchLabels:
name: ingress-nginx
ports:
- protocol: TCP
port: 8080
Troubleshooting Guide
Common Issues and Solutions
-
Application Not Syncing
- Check application logs
- Verify Git credentials
- Check network connectivity
-
UI Not Accessible
- Verify service status
- Check ingress configuration
- Validate TLS certificates
-
Authentication Issues
- Verify SSO configuration
- Check RBAC settings
- Validate user permissions
Conclusion
Following this guide will help you set up a production-ready ArgoCD installation. Remember to regularly update ArgoCD and follow security best practices.