feat(ex02): deploy podinfo via GitOps
- apps/apps/podinfo.yaml: ArgoCD Application for podinfo - manifests/apps/podinfo/: namespace, deployment (6.6.2), service - docs/01-argocd-bootstrap.md: Exercise 01 participant guide - docs/02-deploy-podinfo.md: Exercise 02 participant guide
This commit is contained in:
parent
621d2cbcde
commit
a5e57583b5
6 changed files with 355 additions and 0 deletions
22
apps/apps/podinfo.yaml
Normal file
22
apps/apps/podinfo.yaml
Normal file
|
|
@ -0,0 +1,22 @@
|
|||
apiVersion: argoproj.io/v1alpha1
|
||||
kind: Application
|
||||
metadata:
|
||||
name: podinfo
|
||||
namespace: argocd
|
||||
annotations:
|
||||
argocd.argoproj.io/sync-wave: "10"
|
||||
spec:
|
||||
project: workshop
|
||||
source:
|
||||
repoURL: https://github.com/innspire/ops-demo.git
|
||||
targetRevision: HEAD
|
||||
path: manifests/apps/podinfo
|
||||
destination:
|
||||
server: https://kubernetes.default.svc
|
||||
namespace: podinfo
|
||||
syncPolicy:
|
||||
automated:
|
||||
prune: true
|
||||
selfHeal: true
|
||||
syncOptions:
|
||||
- CreateNamespace=true
|
||||
117
docs/01-argocd-bootstrap.md
Normal file
117
docs/01-argocd-bootstrap.md
Normal file
|
|
@ -0,0 +1,117 @@
|
|||
# Exercise 01 — Bootstrap ArgoCD
|
||||
|
||||
**Time**: ~30 min
|
||||
**Goal**: Get ArgoCD running on your local k3s cluster and apply the App-of-Apps root application.
|
||||
|
||||
---
|
||||
|
||||
## What you'll learn
|
||||
- How to install ArgoCD via Helm
|
||||
- The App-of-Apps pattern: one ArgoCD Application that manages all others
|
||||
- How ArgoCD watches a Git repository and syncs cluster state
|
||||
|
||||
---
|
||||
|
||||
## Prerequisites
|
||||
|
||||
Make sure your VM is up and you are SSHed in:
|
||||
|
||||
```bash
|
||||
vagrant up # first time takes ~10 min (downloads images)
|
||||
vagrant ssh
|
||||
cd /vagrant
|
||||
```
|
||||
|
||||
Verify k3s is healthy:
|
||||
|
||||
```bash
|
||||
kubectl get nodes
|
||||
# NAME STATUS ROLES AGE VERSION
|
||||
# ops-demo Ready control-plane,master Xm v1.31.x+k3s1
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Steps
|
||||
|
||||
### 1. Run the bootstrap script
|
||||
|
||||
```bash
|
||||
./scripts/bootstrap.sh
|
||||
```
|
||||
|
||||
This script:
|
||||
1. Creates the `argocd` namespace
|
||||
2. Installs ArgoCD via Helm (chart 7.7.11 → ArgoCD v2.13.x)
|
||||
3. Applies `apps/project.yaml` — a permissive `AppProject` for all workshop apps
|
||||
4. Applies `apps/root.yaml` — the App-of-Apps entry point
|
||||
|
||||
At the end it prints the admin password. **Copy it now.**
|
||||
|
||||
---
|
||||
|
||||
### 2. Open the ArgoCD UI
|
||||
|
||||
In a second terminal on your laptop (not the VM), run:
|
||||
|
||||
```bash
|
||||
vagrant ssh -- -L 8080:localhost:8080 &
|
||||
# or, inside the VM:
|
||||
kubectl port-forward svc/argocd-server -n argocd 8080:443
|
||||
```
|
||||
|
||||
Then open **https://localhost:8080** in your browser (accept the self-signed cert).
|
||||
|
||||
Login: `admin` / `<password from script output>`
|
||||
|
||||
---
|
||||
|
||||
### 3. Explore the root Application
|
||||
|
||||
In the ArgoCD UI you should see one application: **root**.
|
||||
|
||||
- Click it. Notice it is syncing the `apps/` directory from this repo.
|
||||
- It found `apps/argocd.yaml` and `apps/project.yaml` and is managing them.
|
||||
- ArgoCD is now **self-managing** — any change you push to `apps/` will be picked up automatically.
|
||||
|
||||
```bash
|
||||
# Confirm from the CLI too
|
||||
kubectl get applications -n argocd
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
### 4. Check the self-managing ArgoCD app
|
||||
|
||||
Click the **argocd** application in the UI. It should show **Synced / Healthy**.
|
||||
|
||||
ArgoCD is now reconciling its own Helm release from Git. If you push a change to
|
||||
`manifests/argocd/values.yaml`, ArgoCD will apply it to itself.
|
||||
|
||||
---
|
||||
|
||||
## Expected outcome
|
||||
|
||||
```
|
||||
NAME SYNC STATUS HEALTH STATUS
|
||||
argocd Synced Healthy
|
||||
root Synced Healthy
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Troubleshooting
|
||||
|
||||
| Symptom | Fix |
|
||||
|---------|-----|
|
||||
| `kubectl get nodes` shows NotReady | Wait 30–60 s; k3s is starting |
|
||||
| Helm install fails with timeout | Run `kubectl get pods -n argocd` — if image pull is slow, wait |
|
||||
| UI shows "Unknown" sync status | Click **Refresh** on the application |
|
||||
| Port-forward drops | Re-run the `kubectl port-forward` command |
|
||||
|
||||
---
|
||||
|
||||
## What's next
|
||||
|
||||
In Exercise 02 you will deploy your first application — **podinfo** — purely through
|
||||
Git: no `kubectl apply`, just a YAML file committed to the repo.
|
||||
158
docs/02-deploy-podinfo.md
Normal file
158
docs/02-deploy-podinfo.md
Normal file
|
|
@ -0,0 +1,158 @@
|
|||
# Exercise 02 — Deploy podinfo via GitOps
|
||||
|
||||
**Time**: ~30 min
|
||||
**Goal**: Deploy a real application to the cluster purely through Git — no `kubectl apply`.
|
||||
|
||||
---
|
||||
|
||||
## What you'll learn
|
||||
- How adding an ArgoCD `Application` manifest to Git is the only deploy action needed
|
||||
- How to read ArgoCD sync status and application health
|
||||
- The GitOps feedback loop: commit → push → ArgoCD detects change → cluster updated
|
||||
|
||||
---
|
||||
|
||||
## Prerequisites
|
||||
|
||||
Exercise 01 complete: ArgoCD is running and the root app is Synced.
|
||||
|
||||
---
|
||||
|
||||
## Background: what is podinfo?
|
||||
|
||||
`podinfo` is a tiny Go web app by Stefan Prodan (ArgoCD's author) — often used in
|
||||
Kubernetes demos. It shows its own version number, has `/healthz` and `/readyz`
|
||||
endpoints, and looks good in a browser. No external dependencies, no secrets needed.
|
||||
|
||||
---
|
||||
|
||||
## Steps
|
||||
|
||||
### 1. Understand what already exists
|
||||
|
||||
The repo already contains the podinfo manifests. Take a look:
|
||||
|
||||
```bash
|
||||
ls manifests/apps/podinfo/
|
||||
# namespace.yaml deployment.yaml service.yaml
|
||||
```
|
||||
|
||||
Open `manifests/apps/podinfo/deployment.yaml` and find the image tag:
|
||||
|
||||
```yaml
|
||||
image: ghcr.io/stefanprodan/podinfo:6.6.2
|
||||
```
|
||||
|
||||
This is version **6.6.2**. Remember it — you'll upgrade it later.
|
||||
|
||||
---
|
||||
|
||||
### 2. Create the ArgoCD Application
|
||||
|
||||
This is the only thing you need to "deploy" the app — tell ArgoCD to watch the manifests:
|
||||
|
||||
```bash
|
||||
cat apps/apps/podinfo.yaml
|
||||
```
|
||||
|
||||
You'll see it points ArgoCD at `manifests/apps/podinfo/` in this repo. The app
|
||||
already exists in the repo, so ArgoCD's root app will pick it up automatically.
|
||||
|
||||
Check ArgoCD now — you should already see a **podinfo** application appearing.
|
||||
|
||||
> **The GitOps point**: You didn't run any `kubectl apply` for podinfo. You committed
|
||||
> `apps/apps/podinfo.yaml` to Git, and ArgoCD synced it. That's the entire workflow.
|
||||
|
||||
---
|
||||
|
||||
### 3. Watch it sync
|
||||
|
||||
```bash
|
||||
kubectl get application podinfo -n argocd -w
|
||||
```
|
||||
|
||||
Wait until you see `Synced` and `Healthy`. Then:
|
||||
|
||||
```bash
|
||||
kubectl get pods -n podinfo
|
||||
# NAME READY STATUS RESTARTS AGE
|
||||
# podinfo-xxxxxxxxx-xxxxx 1/1 Running 0 30s
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
### 4. Verify the app is working
|
||||
|
||||
Port-forward to test locally (inside the VM):
|
||||
|
||||
```bash
|
||||
kubectl port-forward svc/podinfo -n podinfo 9898:80
|
||||
```
|
||||
|
||||
In another terminal (or using curl inside the VM):
|
||||
|
||||
```bash
|
||||
curl http://localhost:9898
|
||||
# {"hostname":"podinfo-xxx","version":"6.6.2", ...}
|
||||
```
|
||||
|
||||
You can see `"version":"6.6.2"` — that matches the image tag in `deployment.yaml`.
|
||||
|
||||
---
|
||||
|
||||
### 5. Make a GitOps change
|
||||
|
||||
Let's change the UI color to prove the loop works.
|
||||
|
||||
Edit `manifests/apps/podinfo/deployment.yaml` and change:
|
||||
```yaml
|
||||
value: "#6C48C5"
|
||||
```
|
||||
to any hex color you like, e.g.:
|
||||
```yaml
|
||||
value: "#2ecc71"
|
||||
```
|
||||
|
||||
Commit and push:
|
||||
|
||||
```bash
|
||||
git add manifests/apps/podinfo/deployment.yaml
|
||||
git commit -m "chore: change podinfo UI color"
|
||||
git push
|
||||
```
|
||||
|
||||
Within ~3 minutes (ArgoCD's default poll interval) you'll see the pod restart and
|
||||
the new color appear. You can also click **Refresh** in the ArgoCD UI to trigger
|
||||
an immediate sync.
|
||||
|
||||
---
|
||||
|
||||
## Expected outcome
|
||||
|
||||
```
|
||||
NAME SYNC STATUS HEALTH STATUS
|
||||
podinfo Synced Healthy
|
||||
```
|
||||
|
||||
```bash
|
||||
curl http://localhost:9898 | jq .version
|
||||
# "6.6.2"
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Troubleshooting
|
||||
|
||||
| Symptom | Fix |
|
||||
|---------|-----|
|
||||
| Application stuck in "Progressing" | `kubectl describe pod -n podinfo` — usually image pull |
|
||||
| `ImagePullBackOff` | Image was pre-pulled; run `kubectl get events -n podinfo` |
|
||||
| ArgoCD shows OutOfSync after push | Click **Refresh** or wait 3 min for next poll |
|
||||
|
||||
---
|
||||
|
||||
## What's next
|
||||
|
||||
podinfo is running but only accessible via port-forward. In Exercise 03 you'll
|
||||
expose it on your LAN using MetalLB (a real load balancer) and Ingress-Nginx,
|
||||
so you can reach it from your laptop's browser without any port-forward.
|
||||
42
manifests/apps/podinfo/deployment.yaml
Normal file
42
manifests/apps/podinfo/deployment.yaml
Normal file
|
|
@ -0,0 +1,42 @@
|
|||
apiVersion: apps/v1
|
||||
kind: Deployment
|
||||
metadata:
|
||||
name: podinfo
|
||||
namespace: podinfo
|
||||
spec:
|
||||
replicas: 1
|
||||
selector:
|
||||
matchLabels:
|
||||
app: podinfo
|
||||
template:
|
||||
metadata:
|
||||
labels:
|
||||
app: podinfo
|
||||
spec:
|
||||
containers:
|
||||
- name: podinfo
|
||||
image: ghcr.io/stefanprodan/podinfo:6.6.2
|
||||
ports:
|
||||
- containerPort: 9898
|
||||
name: http
|
||||
env:
|
||||
- name: PODINFO_UI_COLOR
|
||||
value: "#6C48C5"
|
||||
readinessProbe:
|
||||
httpGet:
|
||||
path: /readyz
|
||||
port: 9898
|
||||
initialDelaySeconds: 5
|
||||
periodSeconds: 10
|
||||
livenessProbe:
|
||||
httpGet:
|
||||
path: /healthz
|
||||
port: 9898
|
||||
initialDelaySeconds: 5
|
||||
periodSeconds: 30
|
||||
resources:
|
||||
requests:
|
||||
cpu: 50m
|
||||
memory: 64Mi
|
||||
limits:
|
||||
memory: 128Mi
|
||||
4
manifests/apps/podinfo/namespace.yaml
Normal file
4
manifests/apps/podinfo/namespace.yaml
Normal file
|
|
@ -0,0 +1,4 @@
|
|||
apiVersion: v1
|
||||
kind: Namespace
|
||||
metadata:
|
||||
name: podinfo
|
||||
12
manifests/apps/podinfo/service.yaml
Normal file
12
manifests/apps/podinfo/service.yaml
Normal file
|
|
@ -0,0 +1,12 @@
|
|||
apiVersion: v1
|
||||
kind: Service
|
||||
metadata:
|
||||
name: podinfo
|
||||
namespace: podinfo
|
||||
spec:
|
||||
selector:
|
||||
app: podinfo
|
||||
ports:
|
||||
- port: 80
|
||||
targetPort: 9898
|
||||
name: http
|
||||
Loading…
Add table
Reference in a new issue