|
|
|
@@ -46,27 +46,13 @@ helm version
|
|
|
|
|
|
|
|
|
|
|
|
---
|
|
|
|
---
|
|
|
|
|
|
|
|
|
|
|
|
## Phase 2 — Set credentials
|
|
|
|
## Phase 2 — Install tools
|
|
|
|
|
|
|
|
|
|
|
|
Install tools (one-time):
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
```bash
|
|
|
|
```bash
|
|
|
|
sudo dnf install -y httpd-tools gettext
|
|
|
|
sudo dnf install -y httpd-tools
|
|
|
|
```
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
|
|
Copy and fill in `.env`:
|
|
|
|
`htpasswd` is used in Phase 3.1 to generate the admin password hash. No `.env` file, no `envsubst` — the password never touches Git.
|
|
|
|
|
|
|
|
|
|
|
|
```bash
|
|
|
|
|
|
|
|
cp .env.example .env
|
|
|
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
Generate bcrypt hash and set it in `.env`:
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
```bash
|
|
|
|
|
|
|
|
htpasswd -nbBC 10 "" YOUR_PASSWORD | tr -d ':\n' | sed 's/$2y/$2a/'
|
|
|
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
`.env` is gitignored — never commit it.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
---
|
|
|
|
---
|
|
|
|
|
|
|
|
|
|
|
|
@@ -82,15 +68,13 @@ helm repo add argo https://argoproj.github.io/argo-helm
|
|
|
|
helm repo update
|
|
|
|
helm repo update
|
|
|
|
```
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
|
|
Install ArgoCD (`envsubst` fills `$ARGOCD_ADMIN_PASSWORD_HASH` from `.env` before helm reads the values):
|
|
|
|
Install ArgoCD:
|
|
|
|
|
|
|
|
|
|
|
|
```bash
|
|
|
|
```bash
|
|
|
|
source .env
|
|
|
|
helm install argocd argo/argo-cd -n argocd --create-namespace -f manifests/argocd/values.yaml
|
|
|
|
```
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
|
|
```bash
|
|
|
|
`values.yaml` deliberately has no `configs.secret` block — the chart auto-generates a random admin password, stored in `argocd-initial-admin-secret`. That's replaced with your own in 3.1.
|
|
|
|
envsubst < manifests/argocd/values.yaml | helm install argocd argo/argo-cd -n argocd --create-namespace -f -
|
|
|
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
Wait for ArgoCD to be ready:
|
|
|
|
Wait for ArgoCD to be ready:
|
|
|
|
|
|
|
|
|
|
|
|
@@ -98,49 +82,41 @@ Wait for ArgoCD to be ready:
|
|
|
|
kubectl wait --for=condition=available deployment/argocd-server -n argocd --timeout=120s
|
|
|
|
kubectl wait --for=condition=available deployment/argocd-server -n argocd --timeout=120s
|
|
|
|
```
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
|
|
Port-forward to access UI (MetalLB + Envoy not running yet):
|
|
|
|
Check pods are up:
|
|
|
|
|
|
|
|
|
|
|
|
```bash
|
|
|
|
```bash
|
|
|
|
kubectl port-forward svc/argocd-server -n argocd 8080:443
|
|
|
|
kubectl get pods -n argocd
|
|
|
|
```
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
|
|
Open `https://localhost:8080` — login with `admin` and the password you chose.
|
|
|
|
> UI login isn't needed for bootstrap (Phase 4 applies the root Application via `kubectl`). Only port-forward if you want to inspect ArgoCD manually: `kubectl port-forward svc/argocd-server -n argocd 8080:443`, then open `https://localhost:8080` with `admin` / your chosen password.
|
|
|
|
|
|
|
|
|
|
|
|
### 3.1 Bake the hash into values.yaml for self-management
|
|
|
|
### 3.1 Set your own admin password directly on the Secret
|
|
|
|
|
|
|
|
|
|
|
|
ArgoCD won't run `envsubst` when it self-manages — replace the placeholder with the real hash so future syncs work:
|
|
|
|
Set it once, straight on `argocd-secret` (the Secret ArgoCD actually reads) — never in `values.yaml`, never committed to Git:
|
|
|
|
|
|
|
|
|
|
|
|
```bash
|
|
|
|
```bash
|
|
|
|
source .env
|
|
|
|
read -s -p "ArgoCD admin password: " PW; echo
|
|
|
|
sed -i "s|\$ARGOCD_ADMIN_PASSWORD_HASH|$ARGOCD_ADMIN_PASSWORD_HASH|" manifests/argocd/values.yaml
|
|
|
|
HASH=$(htpasswd -nbBC 12 "" "$PW" | tr -d ':\n' | sed 's/$2y/$2a/')
|
|
|
|
|
|
|
|
kubectl patch secret argocd-secret -n argocd --type merge -p \
|
|
|
|
|
|
|
|
"{\"stringData\":{\"admin.password\":\"$HASH\",\"admin.passwordMtime\":\"$(date -u +%FT%TZ)\"}}"
|
|
|
|
|
|
|
|
unset PW HASH
|
|
|
|
```
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
|
|
```bash
|
|
|
|
**Why this stays stable across self-management:** `values.yaml` never declares `configs.secret.argocdServerAdminPassword`, so the Helm chart's rendered manifest never includes `admin.password`/`admin.passwordMtime`. Once ArgoCD self-manages (wave -1, `selfHeal: true`), it only reconciles fields present in its own rendered output — it has no opinion on keys it never declared, so your patched hash survives every sync, forever. If that block is ever added back to `values.yaml`, the next self-heal overwrites it — don't add it.
|
|
|
|
git add manifests/argocd/values.yaml && git commit -m "set argocd admin password hash"
|
|
|
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
```bash
|
|
|
|
To rotate later: repeat the same `kubectl patch` with a new hash and a new `admin.passwordMtime` (ArgoCD only accepts the change if the Mtime also changes).
|
|
|
|
git push origin main
|
|
|
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
---
|
|
|
|
---
|
|
|
|
|
|
|
|
|
|
|
|
## Phase 4 — Create bootstrap app in ArgoCD UI
|
|
|
|
## Phase 4 — Apply the root bootstrap Application
|
|
|
|
|
|
|
|
|
|
|
|
In ArgoCD UI, create a new Application:
|
|
|
|
`bootstrap-app.yaml` (repo root) is the one seed manifest — it lives in Git, not created ad-hoc via UI/CLI. Per GitOps practice, every Application ArgoCD runs must be recreatable from Git; a UI-created app that's stored nowhere can't survive a rebuild. This is the only manifest ever applied by hand — everything downstream (including ArgoCD managing itself, wave -1) is reached by ArgoCD syncing `bootstrap/apps/` from here.
|
|
|
|
|
|
|
|
|
|
|
|
| Field | Value |
|
|
|
|
```bash
|
|
|
|
|-------|-------|
|
|
|
|
kubectl apply -f bootstrap-app.yaml
|
|
|
|
| Application Name | `bootstrap` |
|
|
|
|
```
|
|
|
|
| Project | `default` |
|
|
|
|
|
|
|
|
| Sync Policy | Automated (enable Prune + Self Heal) |
|
|
|
|
|
|
|
|
| Repository URL | `https://gitea.fireflylab.cc/duynguyen/cluster-bootstrap.git` |
|
|
|
|
|
|
|
|
| Revision | `main` |
|
|
|
|
|
|
|
|
| Path | `bootstrap/apps` |
|
|
|
|
|
|
|
|
| Cluster URL | `https://kubernetes.default.svc` |
|
|
|
|
|
|
|
|
| Namespace | `argocd` |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
Click **Create**. ArgoCD syncs all child Applications in wave order automatically.
|
|
|
|
ArgoCD syncs all child Applications in wave order automatically, including self-managing itself via `bootstrap/apps/argocd.yaml` (wave -1).
|
|
|
|
|
|
|
|
|
|
|
|
Monitor progress:
|
|
|
|
Monitor progress:
|
|
|
|
|
|
|
|
|
|
|
|
@@ -273,6 +249,7 @@ All Applications should be `Synced` / `Healthy`.
|
|
|
|
```
|
|
|
|
```
|
|
|
|
cluster-bootstrap/
|
|
|
|
cluster-bootstrap/
|
|
|
|
├── README.md
|
|
|
|
├── README.md
|
|
|
|
|
|
|
|
├── bootstrap-app.yaml # root seed Application — the only manifest applied by hand
|
|
|
|
├── bootstrap/
|
|
|
|
├── bootstrap/
|
|
|
|
│ └── apps/ # ArgoCD Application CRDs
|
|
|
|
│ └── apps/ # ArgoCD Application CRDs
|
|
|
|
│ ├── argocd.yaml # wave -1 — self-managed ArgoCD
|
|
|
|
│ ├── argocd.yaml # wave -1 — self-managed ArgoCD
|
|
|
|
|