mirror of
https://github.com/khuedoan/homelab.git
synced 2024-12-22 19:54:33 +07:00
refactor(argocd)!: merge bootstrap and system
This is a breaking change and requires cluster rebuild (carefully replacing the ApplicationSets may should work but I didn't bother at the current alpha stage): - ApplicationSets are merged into a single root one to use the progressive sync feature when it's ready. - Switched to server side apply to avoid CRDs not ready issues. Also replace the apply script with Ansible, since the Ansible Helm dependency update feature was released.
This commit is contained in:
parent
6c294a5d6a
commit
8d00d55eb1
10
Makefile
10
Makefile
@ -5,7 +5,7 @@
|
||||
KUBECONFIG = $(shell pwd)/metal/kubeconfig.yaml
|
||||
KUBE_CONFIG_PATH = $(KUBECONFIG)
|
||||
|
||||
default: metal bootstrap external smoke-test post-install clean
|
||||
default: metal system external smoke-test post-install clean
|
||||
|
||||
configure:
|
||||
./scripts/configure
|
||||
@ -14,8 +14,8 @@ configure:
|
||||
metal:
|
||||
make -C metal
|
||||
|
||||
bootstrap:
|
||||
make -C bootstrap
|
||||
system:
|
||||
make -C system
|
||||
|
||||
external:
|
||||
make -C external
|
||||
@ -48,10 +48,6 @@ test:
|
||||
clean:
|
||||
docker compose --project-directory ./metal/roles/pxe_server/files down
|
||||
|
||||
dev:
|
||||
make -C metal cluster env=dev
|
||||
make -C bootstrap
|
||||
|
||||
docs:
|
||||
mkdocs serve
|
||||
|
||||
|
@ -1,15 +0,0 @@
|
||||
.POSIX:
|
||||
|
||||
default: namespace argocd root
|
||||
|
||||
namespace:
|
||||
kubectl create namespace argocd --dry-run=client --output=yaml \
|
||||
| kubectl apply -f -
|
||||
|
||||
.PHONY: argocd
|
||||
argocd:
|
||||
cd argocd && ./apply.sh
|
||||
|
||||
.PHONY: root
|
||||
root:
|
||||
cd root && ./apply.sh
|
@ -1,18 +0,0 @@
|
||||
#!/bin/sh
|
||||
|
||||
VALUES="values.yaml"
|
||||
|
||||
kubectl get ingress argocd-server --namespace argocd \
|
||||
|| VALUES="values-seed.yaml"
|
||||
|
||||
helm template \
|
||||
--dependency-update \
|
||||
--include-crds \
|
||||
--namespace argocd \
|
||||
--values "${VALUES}" \
|
||||
argocd . \
|
||||
| kubectl apply -n argocd -f -
|
||||
|
||||
kubectl -n argocd wait --timeout=60s --for condition=Established \
|
||||
crd/applications.argoproj.io \
|
||||
crd/applicationsets.argoproj.io
|
@ -1,12 +0,0 @@
|
||||
argo-cd:
|
||||
server:
|
||||
metrics: &metrics
|
||||
enabled: false
|
||||
serviceMonitor:
|
||||
enabled: false
|
||||
controller:
|
||||
metrics: *metrics
|
||||
repoServer:
|
||||
metrics: *metrics
|
||||
redis:
|
||||
metrics: *metrics
|
@ -1,31 +0,0 @@
|
||||
argo-cd:
|
||||
global:
|
||||
domain: argocd.khuedoan.com
|
||||
configs:
|
||||
params:
|
||||
server.insecure: true
|
||||
controller.diff.server.side: true
|
||||
cm:
|
||||
resource.ignoreResourceUpdatesEnabled: true
|
||||
resource.customizations.ignoreResourceUpdates.all: |
|
||||
jsonPointers:
|
||||
- /status
|
||||
server:
|
||||
ingress:
|
||||
enabled: true
|
||||
ingressClassName: nginx
|
||||
annotations:
|
||||
cert-manager.io/cluster-issuer: letsencrypt-prod
|
||||
tls: true
|
||||
metrics: &metrics
|
||||
enabled: true
|
||||
serviceMonitor:
|
||||
enabled: true
|
||||
dex:
|
||||
enabled: false
|
||||
controller:
|
||||
metrics: *metrics
|
||||
repoServer:
|
||||
metrics: *metrics
|
||||
redis:
|
||||
metrics: *metrics
|
@ -1 +0,0 @@
|
||||
# TODO convert ./argocd/apply.sh and ./root/apply.sh to Ansible playbook
|
@ -1,3 +0,0 @@
|
||||
apiVersion: v2
|
||||
name: root
|
||||
version: 0.0.0
|
@ -1,13 +0,0 @@
|
||||
#!/bin/sh
|
||||
|
||||
VALUES="values.yaml"
|
||||
|
||||
kubectl get ingress gitea --namespace gitea \
|
||||
|| VALUES="values-seed.yaml"
|
||||
|
||||
helm template \
|
||||
--include-crds \
|
||||
--namespace argocd \
|
||||
--values "${VALUES}" \
|
||||
argocd . \
|
||||
| kubectl apply -n argocd -f -
|
@ -1,41 +0,0 @@
|
||||
{{- range $index, $stack := .Values.stacks }}
|
||||
---
|
||||
apiVersion: argoproj.io/v1alpha1
|
||||
kind: ApplicationSet
|
||||
metadata:
|
||||
name: {{ $stack.name }}
|
||||
namespace: {{ $.Release.Namespace }}
|
||||
spec:
|
||||
generators:
|
||||
- git:
|
||||
repoURL: {{ $.Values.gitops.repo }}
|
||||
revision: {{ $.Values.gitops.revision }}
|
||||
directories:
|
||||
- path: {{ $stack.name }}/*
|
||||
template:
|
||||
metadata:
|
||||
name: '{{ `{{path.basename}}` }}'
|
||||
spec:
|
||||
destination:
|
||||
name: in-cluster
|
||||
namespace: '{{ default `{{path.basename}}` $stack.namespace }}'
|
||||
project: default # TODO
|
||||
source:
|
||||
repoURL: {{ $.Values.gitops.repo }}
|
||||
path: '{{ `{{path}}` }}'
|
||||
targetRevision: {{ $.Values.gitops.revision }}
|
||||
syncPolicy:
|
||||
automated:
|
||||
prune: true
|
||||
selfHeal: true
|
||||
retry:
|
||||
limit: 10
|
||||
backoff:
|
||||
duration: 1m
|
||||
factor: 2
|
||||
maxDuration: 16m
|
||||
syncOptions:
|
||||
- CreateNamespace=true
|
||||
- ApplyOutOfSyncOnly=true
|
||||
- ServerSideApply=true
|
||||
{{- end }}
|
@ -1,2 +0,0 @@
|
||||
gitops:
|
||||
repo: https://github.com/khuedoan/homelab
|
@ -1,9 +0,0 @@
|
||||
gitops:
|
||||
repo: http://gitea-http.gitea:3000/ops/homelab
|
||||
revision: master
|
||||
stacks:
|
||||
- name: bootstrap
|
||||
namespace: argocd # Override default value
|
||||
- name: system
|
||||
- name: platform
|
||||
- name: apps
|
@ -10,8 +10,6 @@
|
||||
|--------------| +------------+
|
||||
| ./system |- - - -| ./external |
|
||||
|--------------| +------------+
|
||||
| ./bootstrap |
|
||||
|--------------|
|
||||
| ./metal |
|
||||
|--------------|
|
||||
| HARDWARE |
|
||||
@ -21,7 +19,6 @@
|
||||
Main components:
|
||||
|
||||
- `./metal`: bare metal management, install Linux and Kubernetes
|
||||
- `./bootstrap`: GitOps bootstrap with ArgoCD
|
||||
- `./system`: critical system components for the cluster (load balancer, storage, ingress, operation tools...)
|
||||
- `./platform`: essential components for service hosting platform (git, build runners, dashboards...)
|
||||
- `./apps`: user facing applications
|
||||
@ -41,15 +38,11 @@ Everything is automated, after you edit the configuration files, you just need t
|
||||
- Create an ephemeral, stateless PXE server
|
||||
- Install Linux on all servers in parallel
|
||||
- Build a Kubernetes cluster (based on k3s)
|
||||
- (2) Build the `./bootstrap` layer:
|
||||
- Install ArgoCD
|
||||
- Configure the root app to manage other layers (and also manage itself)
|
||||
|
||||
From now on, ArgoCD will do the rest:
|
||||
|
||||
- (3) Build the `./system` layer (storage, networking, monitoring, etc)
|
||||
- (4) Build the `./platform` layer (Gitea, Grafana, SSO, etc)
|
||||
- (5) Build the `./apps` layer: (Syncthing, Jellyfin, etc)
|
||||
- (2) Bootstrap the `./system` layer:
|
||||
- Install ArgoCD and the root app to manage itself and other layers, from now on ArgoCD will do the rest
|
||||
- Install the remaining components (storage, monitoring, etc)
|
||||
- (3) Build the `./platform` layer (Gitea, Grafana, SSO, etc)
|
||||
- (4) Deploy applications in the `./apps` layer
|
||||
|
||||
```mermaid
|
||||
flowchart TD
|
||||
@ -57,11 +50,8 @@ flowchart TD
|
||||
pxe[PXE Server] -.-> linux[Fedora Server] --> k3s
|
||||
end
|
||||
|
||||
subgraph bootstrap[./bootstrap]
|
||||
argocd[ArgoCD] --> rootapp[Root app]
|
||||
end
|
||||
|
||||
subgraph system[./system]
|
||||
argocd[ArgoCD and root app]
|
||||
nginx[NGINX]
|
||||
rook-ceph[Rook Ceph]
|
||||
cert-manager
|
||||
@ -79,96 +69,18 @@ flowchart TD
|
||||
cloudflare -.-> external-dns
|
||||
cloudflare -.-> cloudflared
|
||||
|
||||
subgraph platform
|
||||
subgraph platform[./platform]
|
||||
Gitea
|
||||
Woodpecker
|
||||
Grafana
|
||||
end
|
||||
|
||||
subgraph apps
|
||||
subgraph apps[./apps]
|
||||
homepage[Homepage]
|
||||
jellyfin[Jellyfin]
|
||||
matrix[Matrix]
|
||||
paperless[Paperless]
|
||||
end
|
||||
|
||||
make[Run make] -- 1 --> metal -- 2 --> bootstrap -. 3 .-> system -. 4 .-> platform -. 5 .-> apps
|
||||
make[Run make] -- 1 --> metal -- 2 --> system -. 3 .-> platform -. 4 .-> apps
|
||||
```
|
||||
|
||||
Below is the pseudo code for the entire process, you don't have to read it right now, but it will be handy for debugging.
|
||||
|
||||
??? detailed "Detailed provisioning flow"
|
||||
|
||||
```
|
||||
Human run make:
|
||||
build ./metal:
|
||||
install the OS:
|
||||
download the installer image and extract it
|
||||
create a PXE server on the controller using Docker Compose:
|
||||
DHCP server
|
||||
TFTP server
|
||||
HTTP server
|
||||
create init config for each machine
|
||||
turn the machines on via WoL
|
||||
the machines boot:
|
||||
select network boot automatically
|
||||
broadcast DHCP request
|
||||
DHCP server reply:
|
||||
machine IP
|
||||
TFTP server (next-server) IP
|
||||
get boot files from TFTP server
|
||||
GRUB
|
||||
GRUB config with URL to init config based on MAC address
|
||||
kernel
|
||||
initrd
|
||||
boot to the kernel
|
||||
download from HTTP server:
|
||||
init config from the URL in GRUB config
|
||||
remaining files required to boot
|
||||
install the OS based on the init config:
|
||||
configure the system
|
||||
remaining files required to install
|
||||
reboot to the new OS
|
||||
controller see the machines are ready
|
||||
build a Kubernetes cluster:
|
||||
download k3s binary
|
||||
generate cluster token
|
||||
copy k3s config files
|
||||
enable k3s service and form a cluster
|
||||
create KUBECONFIG file
|
||||
install Cilium
|
||||
build ./bootstrap:
|
||||
install ArgoCD:
|
||||
apply helm chart
|
||||
wait for status
|
||||
install root app:
|
||||
select values file:
|
||||
if Gitea unreachable (first install):
|
||||
get data from GitHub
|
||||
else:
|
||||
get data from Gitea
|
||||
apply helm chart
|
||||
wait for status
|
||||
ArgoCD apply the rest:
|
||||
clone git repo
|
||||
install components based on directories:
|
||||
./bootstrap (it manages itself):
|
||||
argocd
|
||||
root
|
||||
./system:
|
||||
storage
|
||||
loadbalancer
|
||||
ingress
|
||||
etc
|
||||
./platform (depends on ./system):
|
||||
git:
|
||||
migrate the homelab repository from GitHub
|
||||
ArgoCD switch the source from GitHub to Gitea
|
||||
ci
|
||||
dashboards
|
||||
etc
|
||||
./apps (depends on ./system and ./platform):
|
||||
homepage
|
||||
jellyfin
|
||||
etc
|
||||
```
|
||||
|
3
scripts/configure
vendored
3
scripts/configure
vendored
@ -57,7 +57,6 @@ def main() -> None:
|
||||
paths=[
|
||||
".ci",
|
||||
"apps",
|
||||
"bootstrap",
|
||||
"platform",
|
||||
"system",
|
||||
"external"
|
||||
@ -68,7 +67,7 @@ def main() -> None:
|
||||
pattern=upstream_config['seed_repo'],
|
||||
replacement=seed_repo,
|
||||
paths=[
|
||||
"bootstrap",
|
||||
"system",
|
||||
"platform"
|
||||
]
|
||||
)
|
||||
|
8
system/Makefile
Normal file
8
system/Makefile
Normal file
@ -0,0 +1,8 @@
|
||||
.POSIX:
|
||||
|
||||
export KUBECONFIG = $(shell pwd)/../metal/kubeconfig.yaml
|
||||
|
||||
.PHONY: bootstrap
|
||||
bootstrap:
|
||||
ansible-playbook \
|
||||
bootstrap.yml
|
@ -5,3 +5,6 @@ dependencies:
|
||||
- name: argo-cd
|
||||
version: 6.4.1
|
||||
repository: https://argoproj.github.io/argo-helm
|
||||
- name: argocd-apps
|
||||
version: 2.0.0
|
||||
repository: https://argoproj.github.io/argo-helm
|
28
system/argocd/values-seed.yaml
Normal file
28
system/argocd/values-seed.yaml
Normal file
@ -0,0 +1,28 @@
|
||||
argo-cd:
|
||||
server:
|
||||
metrics: &metrics
|
||||
enabled: false
|
||||
serviceMonitor:
|
||||
enabled: false
|
||||
controller:
|
||||
metrics: *metrics
|
||||
repoServer:
|
||||
metrics: *metrics
|
||||
redis:
|
||||
metrics: *metrics
|
||||
argocd-apps:
|
||||
applicationsets:
|
||||
root:
|
||||
generators:
|
||||
- git:
|
||||
repoURL: &repoURL https://github.com/khuedoan/homelab
|
||||
revision: &revision master
|
||||
directories:
|
||||
- path: system/*
|
||||
- path: platform/*
|
||||
- path: apps/*
|
||||
template:
|
||||
spec:
|
||||
source:
|
||||
repoURL: *repoURL
|
||||
targetRevision: *revision
|
69
system/argocd/values.yaml
Normal file
69
system/argocd/values.yaml
Normal file
@ -0,0 +1,69 @@
|
||||
argo-cd:
|
||||
global:
|
||||
domain: argocd.khuedoan.com
|
||||
configs:
|
||||
params:
|
||||
server.insecure: true
|
||||
controller.diff.server.side: true
|
||||
cm:
|
||||
resource.ignoreResourceUpdatesEnabled: true
|
||||
resource.customizations.ignoreResourceUpdates.all: |
|
||||
jsonPointers:
|
||||
- /status
|
||||
server:
|
||||
ingress:
|
||||
enabled: true
|
||||
ingressClassName: nginx
|
||||
annotations:
|
||||
cert-manager.io/cluster-issuer: letsencrypt-prod
|
||||
tls: true
|
||||
metrics: &metrics
|
||||
enabled: true
|
||||
serviceMonitor:
|
||||
enabled: true
|
||||
dex:
|
||||
enabled: false
|
||||
controller:
|
||||
metrics: *metrics
|
||||
repoServer:
|
||||
metrics: *metrics
|
||||
redis:
|
||||
metrics: *metrics
|
||||
argocd-apps:
|
||||
applicationsets:
|
||||
root:
|
||||
namespace: argocd
|
||||
generators:
|
||||
- git:
|
||||
repoURL: &repoURL http://gitea-http.gitea:3000/ops/homelab
|
||||
revision: &revision master
|
||||
directories:
|
||||
- path: system/*
|
||||
- path: platform/*
|
||||
- path: apps/*
|
||||
template:
|
||||
metadata:
|
||||
name: '{{path.basename}}'
|
||||
spec:
|
||||
destination:
|
||||
name: in-cluster
|
||||
namespace: '{{path.basename}}'
|
||||
project: default # TODO
|
||||
source:
|
||||
repoURL: *repoURL
|
||||
path: '{{path}}'
|
||||
targetRevision: *revision
|
||||
syncPolicy:
|
||||
automated:
|
||||
prune: true
|
||||
selfHeal: true
|
||||
retry:
|
||||
limit: 10
|
||||
backoff:
|
||||
duration: 1m
|
||||
factor: 2
|
||||
maxDuration: 16m
|
||||
syncOptions:
|
||||
- CreateNamespace=true
|
||||
- ApplyOutOfSyncOnly=true
|
||||
- ServerSideApply=true
|
36
system/bootstrap.yml
Normal file
36
system/bootstrap.yml
Normal file
@ -0,0 +1,36 @@
|
||||
- name: Bootstrapping the cluster
|
||||
hosts: localhost
|
||||
tasks:
|
||||
- name: Create ArgoCD namespace
|
||||
kubernetes.core.k8s:
|
||||
api_version: v1
|
||||
kind: Namespace
|
||||
name: argocd
|
||||
state: present
|
||||
|
||||
- name: Check if this is the first installation
|
||||
kubernetes.core.k8s_info:
|
||||
kind: Pod
|
||||
label_selectors:
|
||||
- app.kubernetes.io/instance=gitea
|
||||
field_selectors:
|
||||
- status.phase=Running
|
||||
register: first_install
|
||||
|
||||
- name: Render ArgoCD manifests from Helm chart
|
||||
kubernetes.core.helm_template:
|
||||
chart_ref: ./argocd
|
||||
include_crds: true
|
||||
release_name: argocd
|
||||
release_namespace: argocd
|
||||
dependency_update: true
|
||||
values_files:
|
||||
- "argocd/{{ (first_install.resources | length == 0) | ternary('values-seed.yaml', 'values.yaml') }}"
|
||||
register: argocd_manifests
|
||||
|
||||
- name: Apply ArgoCD manifests
|
||||
kubernetes.core.k8s:
|
||||
resource_definition: "{{ argocd_manifests.stdout }}"
|
||||
apply: true
|
||||
server_side_apply:
|
||||
field_manager: argocd-controller
|
Loading…
Reference in New Issue
Block a user