commit d3991b7a8583ee7a63c62cd288762e38177ace0e Author: Hans Dominik Werner Date: Wed Apr 15 21:53:39 2026 +0200 initial demo diff --git a/README.md b/README.md new file mode 100644 index 0000000..cf09855 --- /dev/null +++ b/README.md @@ -0,0 +1,111 @@ +# Argo CD + Git Demo Bundle + +Dieses Bundle setzt eine kleine Demo auf einem **bereits existierenden Kubernetes-Cluster** auf. + +Ziel der Demo: +- Ein kleines **Git** im Cluster (Gitea) +- **Argo CD** als GitOps-CD +- Eine kleine **Helm-App** +- Ein sichtbarer **Upgrade-Flow nur über Git/Helm values** + +## Architektur +- Namespace `gitea`: internes Demo-Git +- Namespace `argocd`: Argo CD +- Namespace `demo-app`: Demo-Anwendung + +## Voraussetzung +- `kubectl` Zugriff auf den Cluster +- ausgehender Internetzugriff des Clusters auf Container-Images/Helm Charts +- optional `helm` + +## Schnellstart +1. Namespaces und Basis anlegen: + ```bash + kubectl apply -f bootstrap/namespaces.yaml + ``` + +2. Gitea installieren: + ```bash + helm repo add gitea-charts https://dl.gitea.com/charts/ + helm repo update + helm upgrade --install gitea gitea-charts/gitea \ + -n gitea -f bootstrap/gitea-values.yaml + ``` + +3. Argo CD installieren: + ```bash + kubectl apply -n argocd -f https://raw.githubusercontent.com/argoproj/argo-cd/stable/manifests/install.yaml + ``` + +4. Warten bis Argo CD und Gitea laufen: + ```bash + kubectl -n argocd rollout status deploy/argocd-server --timeout=300s + kubectl -n gitea rollout status statefulset/gitea-postgresql --timeout=300s || true + kubectl -n gitea rollout status deploy/gitea-http --timeout=300s || true + ``` + +5. Gitea lokal erreichbar machen: + ```bash + kubectl -n gitea port-forward svc/gitea-http 3000:3000 + ``` + Dann im Browser `http://localhost:3000` öffnen. + +6. Initialen Admin-User anlegen (falls Setup-Seite erscheint) oder vorhandene Logins nutzen. + +7. Ein neues Repo erstellen, z. B. `gitops-demo`. + +8. Dieses Bundle in euer Repo pushen: + ```bash + git init + git branch -M main + git add . + git commit -m "initial demo" + git remote add origin http://localhost:3000//gitops-demo.git + git push -u origin main + ``` + +9. Argo CD Repo-Secret anpassen: + - Datei `argocd/repo-secret.yaml` + - `url`, `username`, `password` auf euer Gitea-Repo setzen + +10. Repo-Secret und App deployen: + ```bash + kubectl apply -f argocd/repo-secret.yaml + kubectl apply -f argocd/project.yaml + kubectl apply -f apps/demo-app.yaml + ``` + +11. Argo CD UI öffnen: + ```bash + kubectl -n argocd port-forward svc/argocd-server 8080:443 + ``` + UI: `https://localhost:8080` + + Admin-Passwort: + ```bash + kubectl -n argocd get secret argocd-initial-admin-secret -o jsonpath='{.data.password}' | base64 -d; echo + ``` + +## Demo-Flow für Kundentermin +1. Zeige in Gitea die Datei `charts/demo-app/values.yaml` +2. In Argo CD ist die App `Healthy/Synced` +3. Ändere z. B.: + - `image.tag: "1.25"` -> `"1.27"` + - oder `replicaCount: 1` -> `2` + - oder `message: "v1"` -> `"v2 upgraded by gitops"` +4. Commit + Push +5. Argo CD erkennt die Git-Änderung und rollt aus +6. Zeige in Kubernetes: + ```bash + kubectl -n demo-app get deploy,pods,svc,cm + kubectl -n demo-app rollout status deploy/demo-app + ``` + +## Sauberer Upgrade-Nachweis +- **Git ist die einzige Wahrheit**: Keine direkte Cluster-Änderung +- Änderung nur im Repo +- Argo CD erkennt Drift und synchronisiert +- Rollout sauber über Deployment-Update + +## Optional: Image Updater +Wenn ihr in einer zweiten Demo auch zeigen wollt, wie neue Container-Tags automatisch in Git zurückgeschrieben werden, könnt ihr zusätzlich Argo CD Image Updater evaluieren. Für diese Demo ist er nicht nötig. diff --git a/apps/demo-app.yaml b/apps/demo-app.yaml new file mode 100644 index 0000000..635cb8a --- /dev/null +++ b/apps/demo-app.yaml @@ -0,0 +1,22 @@ +apiVersion: argoproj.io/v1alpha1 +kind: Application +metadata: + name: demo-app + namespace: argocd +spec: + project: demo + source: + repoURL: http://gitea-http.gitea.svc.cluster.local:3000/demo-admin/gitops-demo.git + targetRevision: main + path: charts/demo-app + helm: + releaseName: demo-app + destination: + server: https://kubernetes.default.svc + namespace: demo-app + syncPolicy: + automated: + prune: true + selfHeal: true + syncOptions: + - CreateNamespace=true diff --git a/argocd/project.yaml b/argocd/project.yaml new file mode 100644 index 0000000..701497a --- /dev/null +++ b/argocd/project.yaml @@ -0,0 +1,15 @@ +apiVersion: argoproj.io/v1alpha1 +kind: AppProject +metadata: + name: demo + namespace: argocd +spec: + description: Demo project for GitOps customer demo + sourceRepos: + - '*' + destinations: + - namespace: demo-app + server: https://kubernetes.default.svc + clusterResourceWhitelist: + - group: '*' + kind: '*' diff --git a/argocd/repo-secret.yaml b/argocd/repo-secret.yaml new file mode 100644 index 0000000..bc6c0c8 --- /dev/null +++ b/argocd/repo-secret.yaml @@ -0,0 +1,13 @@ +apiVersion: v1 +kind: Secret +metadata: + name: repo-gitops-demo + namespace: argocd + labels: + argocd.argoproj.io/secret-type: repository +stringData: + url: http://gitea-http.gitea.svc.cluster.local:3000/demo-admin/gitops-demo.git + username: demo-admin + password: demo-admin-ChangeMe123! + name: gitops-demo + type: git diff --git a/bootstrap/gitea-values.yaml b/bootstrap/gitea-values.yaml new file mode 100644 index 0000000..118afa0 --- /dev/null +++ b/bootstrap/gitea-values.yaml @@ -0,0 +1,19 @@ +service: + http: + type: ClusterIP + +gitea: + admin: + username: demo-admin + password: demo-admin-ChangeMe123! + email: demo@example.local + +postgresql: + enabled: true + +postgresql-ha: + enabled: false + +persistence: + enabled: true + size: 5Gi diff --git a/bootstrap/namespaces.yaml b/bootstrap/namespaces.yaml new file mode 100644 index 0000000..f52d4dd --- /dev/null +++ b/bootstrap/namespaces.yaml @@ -0,0 +1,14 @@ +apiVersion: v1 +kind: Namespace +metadata: + name: gitea +--- +apiVersion: v1 +kind: Namespace +metadata: + name: argocd +--- +apiVersion: v1 +kind: Namespace +metadata: + name: demo-app diff --git a/charts/demo-app/Chart.yaml b/charts/demo-app/Chart.yaml new file mode 100644 index 0000000..749b3d3 --- /dev/null +++ b/charts/demo-app/Chart.yaml @@ -0,0 +1,5 @@ +apiVersion: v2 +name: demo-app +version: 0.1.0 +appVersion: "1.0.0" +description: Simple GitOps demo app for Argo CD + Helm diff --git a/charts/demo-app/templates/configmap.yaml b/charts/demo-app/templates/configmap.yaml new file mode 100644 index 0000000..7d95f5e --- /dev/null +++ b/charts/demo-app/templates/configmap.yaml @@ -0,0 +1,14 @@ +apiVersion: v1 +kind: ConfigMap +metadata: + name: demo-app-html +data: + index.html: | + + GitOps Demo + +

Argo CD + Helm Demo

+

Message: {{ .Values.message }}

+

Image tag: {{ .Values.image.tag }}

+ + diff --git a/charts/demo-app/templates/deployment.yaml b/charts/demo-app/templates/deployment.yaml new file mode 100644 index 0000000..a450421 --- /dev/null +++ b/charts/demo-app/templates/deployment.yaml @@ -0,0 +1,29 @@ +apiVersion: apps/v1 +kind: Deployment +metadata: + name: demo-app + labels: + app: demo-app +spec: + replicas: {{ .Values.replicaCount }} + selector: + matchLabels: + app: demo-app + template: + metadata: + labels: + app: demo-app + spec: + containers: + - name: nginx + image: "{{ .Values.image.repository }}:{{ .Values.image.tag }}" + imagePullPolicy: {{ .Values.image.pullPolicy }} + ports: + - containerPort: 80 + volumeMounts: + - name: html + mountPath: /usr/share/nginx/html + volumes: + - name: html + configMap: + name: demo-app-html diff --git a/charts/demo-app/templates/service.yaml b/charts/demo-app/templates/service.yaml new file mode 100644 index 0000000..6ee81ef --- /dev/null +++ b/charts/demo-app/templates/service.yaml @@ -0,0 +1,13 @@ +apiVersion: v1 +kind: Service +metadata: + name: demo-app + labels: + app: demo-app +spec: + type: {{ .Values.service.type }} + selector: + app: demo-app + ports: + - port: {{ .Values.service.port }} + targetPort: 80 diff --git a/charts/demo-app/values.yaml b/charts/demo-app/values.yaml new file mode 100644 index 0000000..127e63b --- /dev/null +++ b/charts/demo-app/values.yaml @@ -0,0 +1,12 @@ +replicaCount: 1 + +image: + repository: nginx + tag: "1.25" + pullPolicy: IfNotPresent + +service: + type: ClusterIP + port: 80 + +message: "v1 from git" diff --git a/docs/demo-script.md b/docs/demo-script.md new file mode 100644 index 0000000..ad51d73 --- /dev/null +++ b/docs/demo-script.md @@ -0,0 +1,45 @@ +# Demo-Script (5 Minuten) + +## 1. Setup zeigen +- Gitea UI offen +- Argo CD UI offen +- Kubernetes Namespace `demo-app` + +## 2. Vorher-Zustand zeigen +```bash +kubectl -n demo-app get deploy,pods,svc,cm +kubectl -n demo-app get cm demo-app-html -o yaml +``` + +## 3. Git-Änderung machen +In `charts/demo-app/values.yaml` ändern: +```yaml +replicaCount: 2 +image: + tag: "1.27" +message: "v2 upgraded by gitops" +``` + +Dann: +```bash +git add charts/demo-app/values.yaml +git commit -m "demo: upgrade app" +git push +``` + +## 4. Argo CD zeigen +- App geht kurz auf OutOfSync / Progressing +- danach wieder Synced / Healthy + +## 5. Ergebnis zeigen +```bash +kubectl -n demo-app get deploy,pods,svc,cm +kubectl -n demo-app rollout status deploy/demo-app +kubectl -n demo-app get cm demo-app-html -o yaml +``` + +## 6. Optional Browser-Check +```bash +kubectl -n demo-app port-forward svc/demo-app 8081:80 +``` +Dann im Browser `http://localhost:8081`.