Compare commits
15 Commits
f6469a73a2
...
main
| Author | SHA1 | Date | |
|---|---|---|---|
| 020b248bbe | |||
| fef69d587f | |||
| 2a07b6decf | |||
| 7dda8715c1 | |||
| 02b4f1f926 | |||
| 2e5037d6f4 | |||
| c2c265c898 | |||
| cffaa7449d | |||
| 1432e9e114 | |||
| 4c214a9928 | |||
| e10c72a34f | |||
| fd769794f9 | |||
| b6af771fd9 | |||
| 40d7f794aa | |||
| 73b35bfd14 |
6
.gitignore
vendored
Normal file
6
.gitignore
vendored
Normal file
@@ -0,0 +1,6 @@
|
||||
.env
|
||||
|
||||
# OS/editor
|
||||
.DS_Store
|
||||
*.swp
|
||||
CLAUDE.md
|
||||
74
README.md
74
README.md
@@ -10,6 +10,7 @@ Git repo (cluster-bootstrap)
|
||||
└── ArgoCD watches bootstrap/apps/ → syncs all Applications
|
||||
|
||||
Bootstrap order (sync waves):
|
||||
Wave -1 → argocd (self-managed, once bootstrapped)
|
||||
Wave 0 → metallb (LoadBalancer IPs)
|
||||
Wave 1 → metallb-config (IPAddressPool + L2Advertisement)
|
||||
Wave 2 → envoy-gateway (HTTP gateway controller)
|
||||
@@ -45,35 +46,13 @@ helm version
|
||||
|
||||
---
|
||||
|
||||
## Phase 2 — Fill in NFS details
|
||||
|
||||
Edit `manifests/nfs-provisioner/values.yaml` before pushing — replace the two placeholders:
|
||||
## Phase 2 — Install tools
|
||||
|
||||
```bash
|
||||
git clone https://gitea.fireflylab.cc/duynguyen/cluster-bootstrap.git
|
||||
sudo dnf install -y httpd-tools
|
||||
```
|
||||
|
||||
```bash
|
||||
cd cluster-bootstrap
|
||||
```
|
||||
|
||||
Open `manifests/nfs-provisioner/values.yaml` and set:
|
||||
- `nfs.server` — xpen NAS IP address
|
||||
- `nfs.path` — NFS export path (e.g. `/volume1/k8s`)
|
||||
|
||||
Then commit and push:
|
||||
|
||||
```bash
|
||||
git add manifests/nfs-provisioner/values.yaml
|
||||
```
|
||||
|
||||
```bash
|
||||
git commit -m "set nfs server and path"
|
||||
```
|
||||
|
||||
```bash
|
||||
git push origin main
|
||||
```
|
||||
`htpasswd` generates the admin password hash used in Phase 3.1.
|
||||
|
||||
---
|
||||
|
||||
@@ -89,50 +68,45 @@ helm repo add argo https://argoproj.github.io/argo-helm
|
||||
helm repo update
|
||||
```
|
||||
|
||||
Install ArgoCD:
|
||||
Install ArgoCD (`values.yaml` has no `configs.secret` block — chart auto-generates a random admin password):
|
||||
|
||||
```bash
|
||||
helm install argocd argo/argo-cd -n argocd --create-namespace -f manifests/argocd/values.yaml
|
||||
```
|
||||
|
||||
Wait for ArgoCD to be ready:
|
||||
Wait for ready:
|
||||
|
||||
```bash
|
||||
kubectl wait --for=condition=available deployment/argocd-server -n argocd --timeout=120s
|
||||
```
|
||||
|
||||
Get initial admin password:
|
||||
(Optional) inspect manually: `kubectl port-forward svc/argocd-server -n argocd 8080:443` → `https://localhost:8080`. Not needed for bootstrap.
|
||||
|
||||
### 3.1 Set admin password on the Secret
|
||||
|
||||
Patched directly on `argocd-secret`, never in `values.yaml`/Git — keeps `configs.secret` absent so self-heal (wave -1) never touches it, password stays stable forever:
|
||||
|
||||
```bash
|
||||
kubectl get secret argocd-initial-admin-secret -n argocd -o jsonpath='{.data.password}' | base64 -d
|
||||
read -s -p "ArgoCD admin password: " PW; echo
|
||||
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
|
||||
```
|
||||
|
||||
Port-forward to access UI (MetalLB + Envoy not running yet):
|
||||
|
||||
```bash
|
||||
kubectl port-forward svc/argocd-server -n argocd 8080:443
|
||||
```
|
||||
|
||||
Open `https://localhost:8080` — login with `admin` and the password above.
|
||||
Rotate: repeat with new hash + new `admin.passwordMtime` (required for ArgoCD to accept the change).
|
||||
|
||||
---
|
||||
|
||||
## 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 seed manifest, committed to Git — not created via UI/CLI. Only manifest ever applied by hand:
|
||||
|
||||
| Field | Value |
|
||||
|-------|-------|
|
||||
| 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` |
|
||||
```bash
|
||||
kubectl apply -f bootstrap-app.yaml
|
||||
```
|
||||
|
||||
Click **Create**. ArgoCD syncs all child Applications in wave order automatically.
|
||||
ArgoCD syncs all child Applications in wave order automatically, including self-managing itself (`bootstrap/apps/argocd.yaml`, wave -1).
|
||||
|
||||
Monitor progress:
|
||||
|
||||
@@ -265,8 +239,10 @@ All Applications should be `Synced` / `Healthy`.
|
||||
```
|
||||
cluster-bootstrap/
|
||||
├── README.md
|
||||
├── bootstrap-app.yaml # root seed Application — the only manifest applied by hand
|
||||
├── bootstrap/
|
||||
│ └── apps/ # ArgoCD Application CRDs
|
||||
│ ├── argocd.yaml # wave -1 — self-managed ArgoCD
|
||||
│ ├── metallb.yaml # wave 0 — Helm chart
|
||||
│ ├── metallb-config.yaml # wave 1 — IPAddressPool + L2Advertisement
|
||||
│ ├── envoy-gateway.yaml # wave 2 — Helm chart
|
||||
|
||||
18
bootstrap-app.yaml
Normal file
18
bootstrap-app.yaml
Normal file
@@ -0,0 +1,18 @@
|
||||
apiVersion: argoproj.io/v1alpha1
|
||||
kind: Application
|
||||
metadata:
|
||||
name: bootstrap
|
||||
namespace: argocd
|
||||
spec:
|
||||
project: default
|
||||
source:
|
||||
repoURL: https://gitea.fireflylab.cc/duynguyen/cluster-bootstrap.git
|
||||
targetRevision: main
|
||||
path: bootstrap/apps
|
||||
destination:
|
||||
server: https://kubernetes.default.svc
|
||||
namespace: argocd
|
||||
syncPolicy:
|
||||
automated:
|
||||
prune: true
|
||||
selfHeal: true
|
||||
22
bootstrap/apps/argocd.yaml
Normal file
22
bootstrap/apps/argocd.yaml
Normal file
@@ -0,0 +1,22 @@
|
||||
apiVersion: argoproj.io/v1alpha1
|
||||
kind: Application
|
||||
metadata:
|
||||
name: argocd
|
||||
namespace: argocd
|
||||
annotations:
|
||||
argocd.argoproj.io/sync-wave: "-1"
|
||||
spec:
|
||||
project: default
|
||||
sources:
|
||||
- repoURL: https://argoproj.github.io/argo-helm
|
||||
chart: argo-cd
|
||||
targetRevision: "7.8.26"
|
||||
helm:
|
||||
valueFiles:
|
||||
- $values/manifests/argocd/values.yaml
|
||||
- repoURL: https://gitea.fireflylab.cc/duynguyen/cluster-bootstrap.git
|
||||
targetRevision: main
|
||||
ref: values
|
||||
destination:
|
||||
server: https://kubernetes.default.svc
|
||||
namespace: argocd
|
||||
@@ -8,7 +8,7 @@ metadata:
|
||||
spec:
|
||||
project: default
|
||||
sources:
|
||||
- repoURL: https://charts.gateway.envoyproxy.io
|
||||
- repoURL: docker.io/envoyproxy
|
||||
chart: gateway-helm
|
||||
targetRevision: "v1.7.1"
|
||||
helm:
|
||||
@@ -26,3 +26,4 @@ spec:
|
||||
selfHeal: true
|
||||
syncOptions:
|
||||
- CreateNamespace=true
|
||||
- ServerSideApply=true
|
||||
|
||||
@@ -26,3 +26,9 @@ spec:
|
||||
selfHeal: true
|
||||
syncOptions:
|
||||
- CreateNamespace=true
|
||||
ignoreDifferences:
|
||||
- group: apiextensions.k8s.io
|
||||
kind: CustomResourceDefinition
|
||||
jsonPointers:
|
||||
- /status
|
||||
- /spec/conversion/webhook/clientConfig/caBundle
|
||||
|
||||
@@ -18,6 +18,12 @@ global:
|
||||
configs:
|
||||
params:
|
||||
server.insecure: true # TLS terminated at Envoy Gateway
|
||||
repositories:
|
||||
envoy-gateway-oci:
|
||||
url: docker.io/envoyproxy
|
||||
name: envoy-gateway-oci
|
||||
type: helm
|
||||
enableOCI: "true"
|
||||
|
||||
server:
|
||||
replicas: 1
|
||||
|
||||
Reference in New Issue
Block a user