{"id":22125701,"url":"https://github.com/qjoly/gitops","last_synced_at":"2025-08-10T14:05:06.469Z","repository":{"id":148383287,"uuid":"602247357","full_name":"qjoly/GitOps","owner":"qjoly","description":"Homelab setup based on Omni and Talos.","archived":false,"fork":false,"pushed_at":"2025-08-04T20:59:28.000Z","size":5221,"stargazers_count":70,"open_issues_count":13,"forks_count":2,"subscribers_count":4,"default_branch":"main","last_synced_at":"2025-08-04T23:14:37.926Z","etag":null,"topics":["argocd","k8s-at-home","kubernetes","omni","talos","vault"],"latest_commit_sha":null,"homepage":"https://qjoly.github.io/GitOps/","language":null,"has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"wtfpl","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/qjoly.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null}},"created_at":"2023-02-15T20:03:40.000Z","updated_at":"2025-08-02T06:29:29.000Z","dependencies_parsed_at":"2023-10-15T14:30:08.300Z","dependency_job_id":"21254780-c550-47ea-8267-ca5084d673b3","html_url":"https://github.com/qjoly/GitOps","commit_stats":null,"previous_names":[],"tags_count":4,"template":false,"template_full_name":null,"purl":"pkg:github/qjoly/GitOps","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/qjoly%2FGitOps","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/qjoly%2FGitOps/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/qjoly%2FGitOps/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/qjoly%2FGitOps/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/qjoly","download_url":"https://codeload.github.com/qjoly/GitOps/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/qjoly%2FGitOps/sbom","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":269734150,"owners_count":24466554,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","status":"online","status_checked_at":"2025-08-10T02:00:08.965Z","response_time":71,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["argocd","k8s-at-home","kubernetes","omni","talos","vault"],"created_at":"2024-12-01T16:37:14.456Z","updated_at":"2025-08-10T14:05:06.459Z","avatar_url":"https://github.com/qjoly.png","language":null,"funding_links":[],"categories":[],"sub_categories":[],"readme":"\u003cp align=\"center\"\u003e\n    \u003cimg src=\"https://avatars.githubusercontent.com/u/82603435?v=4\" width=\"140px\" alt=\"Helm LOGO\"/\u003e\n    \u003cbr\u003e\n    \u003ca href=\"https://a-cup-of.coffee\"\u003e\u003cimg src=\"https://readme-typing-svg.herokuapp.com?font=Fira+Code\u0026pause=1000\u0026center=true\u0026vCenter=true\u0026width=435\u0026lines=Homelab+made+simple;Talos+go+brrrrr;GitOps+FTW;No+inspiration+for+what+I'm+going+to+write+here\" alt=\"Typing SVG\" /\u003e\u003c/a\u003e\n\u003c/p\u003e\n\n\u003cdiv align=\"center\"\u003e\n\n  [![Blog](https://img.shields.io/badge/Blog-blue?style=for-the-badge\u0026logo=buymeacoffee\u0026logoColor=white)](https://a-cup-of.coffee/)\n  [![Kubernetes](https://img.shields.io/badge/Kubernetes-v1.31.3-blue?style=for-the-badge\u0026logo=kubernetes\u0026logoColor=white)](https://kubernetes.io/)\n  [![Linux](https://img.shields.io/badge/Talos-v1.9.5-blue?style=for-the-badge\u0026logo=linux\u0026logoColor=white)](https://talos.dev/)\n\n\u003c/div\u003e\n\n# HomeLab\n\n\u003cdiv align=\"center\"\u003e\n\n*Homelab setup based on Omni and Talos.*\n\n\u003c/div\u003e\n\n## Overview\n\nThis repository contains the configuration files for my homelab. The homelab is a collection of servers and services that I run at home or in the cloud. The homelab is used for learning, testing, and hosting projects.\n\n## Stack \n\nTo avoid headaches and to keep things simple, I use [Talos](https://www.talos.dev/) to manage the Kubernetes cluster (don't hesitate to check [a little article I wrote about it](https://a-cup-of.coffee/blog/talos/)). To be more specific, I have a self-hosted [Omni](https://www.siderolabs.com/platform/saas-for-kubernetes/) instance to manage all clusters with a single endpoint and secure them with SSO.\n\n### Core Components\n\n- [**Omni** (Self-hosted)](https://www.siderolabs.com/platform/saas-for-kubernetes/) : Manage all nodes between clusters and regions.\n- [Cilium](https://cilium.io/) as CNI and LB (ARP mode)\n- [ArgoCD](https://argoproj.github.io/argo-cd/) to manage the GitOps workflow\n- ~~[Nginx Ingress Controller](https://kubernetes.github.io/ingress-nginx/) for Ingress management (and [Istio](https://istio.io/) deployed on some clusters)~~\n- [Traefik Ingress Controller](https://doc.traefik.io/traefik/getting-started/install-traefik/#use-the-helm-chart) for Ingress management (as well as for middleware management). \n- [Cert Manager](https://cert-manager.io/) for TLS certificates.\n- Storage:\n  - [Rook](https://rook.io/) for multiple nodes cluster.\n  - OpenEBS + LVM (or ZFS) for single-node cluster.\n  - [ZFS](https://openzfs.github.io/openzfs-docs/) + [Local-Path-Provisioner](https://github.com/rancher/local-path-provisioner) (**Only on Cortado cluster**).\n- ~~[Reflector](https://github.com/emberstack/kubernetes-reflector/blob/main/README.md) to sync secrets across namespaces (requirement for External Secrets + Vault).~~ (Removed 16/12/2024)\n- [External Secrets](https://external-secrets.io/latest/) to fetch secrets from a remote store.\n- [Vault](https://www.vaultproject.io/) as a secret store to store secrets.\n- [Cloudflare Tunnels](https://developers.cloudflare.com/cloudflare-one/connections/connect-networks/) to expose services to the internet (**Only on the `turing` cluster**).\n- [Volsync](https://github.com/backube/volsync) to create backup and send backup (using restic) to a minio server (**Only on Cortado cluster**).\n\n### Cluster\n\n- [**Cortado** : Single node bare-metal cluster hosted by OVH.](https://github.com/qjoly/GitOps/tree/main/cortado) - This cluster is mainly used for backups and small applications (gaming, small sites, etc.).\n\u003cdiv align=\"center\"\u003e\n\n[![Talos](https://img.shields.io/endpoint?url=https%3A%2F%2Fkromgo.cortado.thoughtless.eu%2Ftalos_version\u0026style=flat-square\u0026logo=talos\u0026logoColor=white\u0026color=red\u0026label=%20)](https://talos.dev)\n[![Kubernetes](https://img.shields.io/endpoint?url=https%3A%2F%2Fkromgo.cortado.thoughtless.eu%2Fkubernetes_version\u0026style=flat-square\u0026logo=kubernetes\u0026logoColor=white\u0026color=blue\u0026label=%20)](https://kubernetes.io)\u0026nbsp;\u0026nbsp;\n![Age](https://img.shields.io/endpoint?url=https%3A%2F%2Fkromgo.cortado.thoughtless.eu%2Fcluster_age_days\u0026style=flat-square\u0026label=Age)\n![Uptime-Days](https://img.shields.io/endpoint?url=https%3A%2F%2Fkromgo.cortado.thoughtless.eu%2Fcluster_uptime_days\u0026style=flat-square\u0026label=Uptime)\n![Node-Count](https://img.shields.io/endpoint?url=https%3A%2F%2Fkromgo.cortado.thoughtless.eu%2Fcluster_node_count\u0026style=flat-square\u0026label=Nodes)\n![Pod-Count](https://img.shields.io/endpoint?url=https%3A%2F%2Fkromgo.cortado.thoughtless.eu%2Fcluster_pod_count\u0026style=flat-square\u0026label=Pods)\n![CPU-Usage](https://img.shields.io/endpoint?url=https%3A%2F%2Fkromgo.cortado.thoughtless.eu%2Fcluster_cpu_usage\u0026style=flat-square\u0026label=CPU)\n![Memory-Usage](https://img.shields.io/endpoint?url=https%3A%2F%2Fkromgo.cortado.thoughtless.eu%2Fcluster_memory_usage\u0026style=flat-square\u0026label=Memory)\n\n\u003c/div\u003e\n\n- [**Mocha** : Another node bare-metal cluster hosted by OVH](https://github.com/qjoly/GitOps/tree/main/mocha), production cluster (128GB RAM, 8 CPU, 2x512Go NVMe)\n\u003cdiv align=\"center\"\u003e\n\n[![Talos](https://img.shields.io/endpoint?url=https%3A%2F%2Fkromgo.mocha.thoughtless.eu%2Ftalos_version\u0026style=flat-square\u0026logo=talos\u0026logoColor=white\u0026color=red\u0026label=%20)](https://talos.dev)\n[![Kubernetes](https://img.shields.io/endpoint?url=https%3A%2F%2Fkromgo.mocha.thoughtless.eu%2Fkubernetes_version\u0026style=flat-square\u0026logo=kubernetes\u0026logoColor=white\u0026color=blue\u0026label=%20)](https://kubernetes.io)\u0026nbsp;\u0026nbsp;\n![Age](https://img.shields.io/endpoint?url=https%3A%2F%2Fkromgo.mocha.thoughtless.eu%2Fcluster_age_days\u0026style=flat-square\u0026label=Age)\n![Uptime-Days](https://img.shields.io/endpoint?url=https%3A%2F%2Fkromgo.mocha.thoughtless.eu%2Fcluster_uptime_days\u0026style=flat-square\u0026label=Uptime)\n![Node-Count](https://img.shields.io/endpoint?url=https%3A%2F%2Fkromgo.mocha.thoughtless.eu%2Fcluster_node_count\u0026style=flat-square\u0026label=Nodes)\n![Pod-Count](https://img.shields.io/endpoint?url=https%3A%2F%2Fkromgo.mocha.thoughtless.eu%2Fcluster_pod_count\u0026style=flat-square\u0026label=Pods)\n![CPU-Usage](https://img.shields.io/endpoint?url=https%3A%2F%2Fkromgo.mocha.thoughtless.eu%2Fcluster_cpu_usage\u0026style=flat-square\u0026label=CPU)\n![Memory-Usage](https://img.shields.io/endpoint?url=https%3A%2F%2Fkromgo.mocha.thoughtless.eu%2Fcluster_memory_usage\u0026style=flat-square\u0026label=Memory)\n\n\u003c/div\u003e\n\n- **Turing** : A cluster based on small devices (ARM and x86) at home. This cluster is used for local hosting and testing. (Prometheus not yet available)\n\u003cdiv align=\"center\"\u003e\n\n[![Talos](https://img.shields.io/endpoint?url=https%3A%2F%2Fkromgo.turing.thoughtless.eu%2Ftalos_version\u0026style=flat-square\u0026logo=talos\u0026logoColor=white\u0026color=red\u0026label=%20)](https://talos.dev)\n[![Kubernetes](https://img.shields.io/endpoint?url=https%3A%2F%2Fkromgo.turing.thoughtless.eu%2Fkubernetes_version\u0026style=flat-square\u0026logo=kubernetes\u0026logoColor=white\u0026color=blue\u0026label=%20)](https://kubernetes.io)\u0026nbsp;\u0026nbsp;\n![Age](https://img.shields.io/endpoint?url=https%3A%2F%2Fkromgo.turing.thoughtless.eu%2Fcluster_age_days\u0026style=flat-square\u0026label=Age)\n![Uptime-Days](https://img.shields.io/endpoint?url=https%3A%2F%2Fkromgo.turing.thoughtless.eu%2Fcluster_uptime_days\u0026style=flat-square\u0026label=Uptime)\n![Node-Count](https://img.shields.io/endpoint?url=https%3A%2F%2Fkromgo.turing.thoughtless.eu%2Fcluster_node_count\u0026style=flat-square\u0026label=Nodes)\n![Pod-Count](https://img.shields.io/endpoint?url=https%3A%2F%2Fkromgo.turing.thoughtless.eu%2Fcluster_pod_count\u0026style=flat-square\u0026label=Pods)\n![CPU-Usage](https://img.shields.io/endpoint?url=https%3A%2F%2Fkromgo.turing.thoughtless.eu%2Fcluster_cpu_usage\u0026style=flat-square\u0026label=CPU)\n![Memory-Usage](https://img.shields.io/endpoint?url=https%3A%2F%2Fkromgo.turing.thoughtless.eu%2Fcluster_memory_usage\u0026style=flat-square\u0026label=Memory)\n\n\u003c/div\u003e\n\n- **Kubevirt** : See below :p \n\n\n## About the 'Kubevirt' Virtual Cluster\n\nWhile this repository primarily contains three physical clusters (`mocha`, `cortado`, and `turing`), a fourth cluster configuration exists in the `kubevirt` directory. This is a virtual cluster that runs as workloads on top of another cluster (primarily hosted on `mocha` due to its greater resource capacity).\n\nThis virtual cluster is provisioned using [Kubevirt](https://kubevirt.io/) technology integrated with the Omni Infrastructure provider. For a detailed exploration of this setup, you can read [my article about Omni and Kubevirt integration](https://a-cup-of.coffee/blog/omni/).\n\n### Why Use a Virtual Cluster?\n\nThere are two primary motivations behind maintaining a separate virtual cluster:\n\n1. **Network Isolation**: It allows for different pod CIDR and service CIDR ranges than the host cluster, preventing network overlaps that could cause routing issues.\n\n2. **Configuration Testing**: It provides an isolated environment that mirrors my production clusters with the same core components (metrics server, ArgoCD, ApplicationSet, etc.), making it perfect for testing configurations and upgrades safely.\n\n## Usage\n\nTo use this repository, you need to have the Omni CLI installed. You can find the installation instructions [here](https://omni.siderolabs.com/how-to-guides/install-and-configure-omnictl).\n\nDownload the `omniconfig` file from the Omni instance and merge it with the one in your home directory.\n\n```bash\nomnictl config merge ./omniconfig.yaml\n```\n\nThen, you can deploy the cluster based on the MachineClass you have configured.\n\n```bash\ncd lungo\nomnictl cluster template sync -f template.yaml\n```\n\nThis will create a new cluster based on the configuration you have set in the `template.yaml` file. You can download the kubeconfig file using the following command:\n\n```bash\nomnictl kubeconfig --cluster lungo\n```\n\n\u003cdetails\u003e\n\u003csummary\u003eExample of kubeconfig file\u003c/summary\u003e\n\n```yaml\napiVersion: v1\nkind: Config\nclusters:\n  - cluster:\n      server: https://omni.home.une-tasse-de.cafe:8100/\n    name: omni-lungo\ncontexts:\n  - context:\n      cluster: omni-lungo\n      namespace: default\n      user: omni-lungo-quentinj@une-pause-cafe.fr\n    name: omni-lungo\ncurrent-context: omni-lungo\nusers:\n- name: omni-lungo-quentinj@une-pause-cafe.fr\n  user:\n    exec:\n      apiVersion: client.authentication.k8s.io/v1beta1\n      args:\n        - oidc-login\n        - get-token\n        - --oidc-issuer-url=https://omni.home.une-tasse-de.cafe/oidc\n        - --oidc-client-id=native\n        - --oidc-extra-scope=cluster:lungo\n      command: kubectl\n      env: null\n      provideClusterInfo: false\n```\n\u003c/details\u003e\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fqjoly%2Fgitops","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fqjoly%2Fgitops","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fqjoly%2Fgitops/lists"}