{"id":51656057,"url":"https://github.com/madmmas/kubeoperator-journey","last_synced_at":"2026-07-14T09:04:06.741Z","repository":{"id":371119795,"uuid":"1297403340","full_name":"madmmas/kubeoperator-journey","owner":"madmmas","description":"Companion code for \"From Zero to Kubernetes Operators with Kubebuilder\" — blog series on madmmasblog.vercel.app","archived":false,"fork":false,"pushed_at":"2026-07-13T13:00:40.000Z","size":26,"stargazers_count":0,"open_issues_count":0,"forks_count":0,"subscribers_count":0,"default_branch":"main","last_synced_at":"2026-07-13T14:13:49.797Z","etag":null,"topics":["controller-runtime","crd","go","golang","k8s","kubebuilder","kubernetes","operators","platform-engineering","tutorial"],"latest_commit_sha":null,"homepage":"https://madmmasblog.vercel.app","language":"Go","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/madmmas.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":null,"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,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null}},"created_at":"2026-07-11T11:57:57.000Z","updated_at":"2026-07-13T13:01:38.000Z","dependencies_parsed_at":null,"dependency_job_id":null,"html_url":"https://github.com/madmmas/kubeoperator-journey","commit_stats":null,"previous_names":["madmmas/kubeoperator-journey"],"tags_count":4,"template":false,"template_full_name":null,"purl":"pkg:github/madmmas/kubeoperator-journey","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/madmmas%2Fkubeoperator-journey","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/madmmas%2Fkubeoperator-journey/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/madmmas%2Fkubeoperator-journey/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/madmmas%2Fkubeoperator-journey/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/madmmas","download_url":"https://codeload.github.com/madmmas/kubeoperator-journey/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/madmmas%2Fkubeoperator-journey/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":35453848,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-05-26T15:22:16.424Z","status":"online","status_checked_at":"2026-07-14T02:00:06.603Z","response_time":114,"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":["controller-runtime","crd","go","golang","k8s","kubebuilder","kubernetes","operators","platform-engineering","tutorial"],"created_at":"2026-07-14T09:04:06.026Z","updated_at":"2026-07-14T09:04:06.732Z","avatar_url":"https://github.com/madmmas.png","language":"Go","funding_links":[],"categories":[],"sub_categories":[],"readme":"# KubeOperator Journey\n\n\u003e **Companion code for the blog series: \"From Zero to Kubernetes Operators with Kubebuilder\"**\n\u003e\n\u003e Series: [From Zero to Kubernetes Operators with Kubebuilder](https://madmmasblog.vercel.app/series/from-zero-to-kubernetes-operators-with-kubebuilder/)\n\nThis repository contains working code examples organized by blog post.\nEach tag matches a specific post so you can check out exactly the code state\nfor that point in the series.\n\n## Series Structure\n\n| Post | Tag | Topic |\n|------|-----|-------|\n| [Blog 1](https://madmmasblog.vercel.app/blog/kubeoperator-journey/phase-1/blog-01-why-operators-exist) | `blog-01` | Why Kubernetes Operators Exist — The Problem They Actually Solve |\n| [Blog 2](https://madmmasblog.vercel.app/blog/kubeoperator-journey/phase-1/blog-02-control-loop) | `blog-02` | The Kubernetes Control Loop — Explained by Building One |\n| [Blog 3](https://madmmasblog.vercel.app/blog/kubeoperator-journey/phase-1/blog-03-kubebuilder-scaffold) | `blog-03` | Kubebuilder From Zero — Scaffold, Structure, and Your First CRD |\n| [Blog 4](https://madmmasblog.vercel.app/blog/kubeoperator-journey/phase-1/blog-04-first-reconciliation-loop) | `blog-04` | Your First Reconciliation Loop — Line by Line |\n| ... | ... | ... |\n\n## Prerequisites\n\n| Blog | What you need |\n|------|----------------|\n| 1–2 | Go 1.21+ |\n| 3 | Go + [Kubebuilder](https://book.kubebuilder.io/quick-start.html) |\n| 4 | Above, plus a Docker runtime, `kind`, `kubectl`, and `make` to run against a local cluster |\n\nInstall steps for everything are in [Tooling setup](#tooling-setup) below.\n\n## Running Blog 1\n\n```bash\ngit checkout blog-01\ngo run ./cmd/why-operators\n```\n\n## Running Blog 2\n\n```bash\ngit checkout blog-02\ngo run ./cmd/control-loop\n```\n\n## Blog 3 — scaffold reference\n\n`blog-03` ships a **reference** `DatabaseCluster` types file (not a full Kubebuilder project):\n\n```bash\ngit checkout blog-03\n# Study: kubebuilder/api/v1alpha1/databasecluster_types.go\n```\n\nGenerate the real scaffold locally (as the post walks through):\n\n```bash\nkubebuilder init --domain madmmas.dev --repo github.com/madmmas/kubeoperator-journey\nkubebuilder create api --group databases --version v1alpha1 --kind DatabaseCluster --resource --controller\n```\n\n## Blog 4 — Reconcile implementation\n\n`blog-04` adds the production-layout API types and a complete `Reconcile()` implementation:\n\n```bash\ngit checkout blog-04\n# Study:\n#   api/v1alpha1/databasecluster_types.go\n#   api/v1alpha1/groupversion_info.go\n#   internal/controller/databasecluster_controller.go\n# Example CR: internal/crd/database-cluster-example.yaml\n```\n\nThis repo does **not** include a full Kubebuilder project (`Makefile`, manager `cmd/`, generated CRDs). To run against a cluster, generate the scaffold from Blog 3, then use these files as the types + controller implementation:\n\n```bash\nkind create cluster --name kubeoperator-dev\nmake generate manifests install\nmake run\n# In another terminal:\nkubectl apply -f internal/crd/database-cluster-example.yaml\nkubectl get databasecluster -w\n```\n\n## Tooling setup\n\nCommands below prefer Homebrew on macOS. Linux alternatives are noted where useful.\n\n### 1. Go (Blog 1+)\n\n```bash\n# macOS\nbrew install go\n\n# Linux (example)\n# See https://go.dev/doc/install\n```\n\nConfirm:\n\n```bash\ngo version   # need 1.21+ for this repo; Kubebuilder may want a newer Go — use the latest stable\n```\n\nPut Go binaries on your `PATH` (needed for `go install` tools):\n\n```bash\nexport PATH=\"$(go env GOPATH)/bin:$PATH\"\n# add that line to ~/.zshrc or ~/.bashrc\n```\n\n### 2. Git\n\n```bash\nbrew install git          # macOS, if missing\n# Linux: sudo apt install git   /   sudo dnf install git\ngit --version\n```\n\n### 3. Make (Blog 4 — `make generate`, `make run`, …)\n\nKubebuilder projects use a `Makefile`. On macOS, `make` comes with Xcode Command Line Tools:\n\n```bash\nxcode-select --install    # macOS, if `make` is missing\n# Linux: sudo apt install build-essential\nmake --version\n```\n\n### 4. Container runtime — Rancher Desktop (Blog 4)\n\n`kind` runs cluster nodes as containers, so it needs a Docker-compatible API. [Rancher Desktop](https://rancherdesktop.io/) provides that without Docker Desktop.\n\n1. Install Rancher Desktop and open it once so the VM starts.\n2. Preferences → Container Engine → **dockerd (moby)** → Apply (restart).  \n   `kind` needs the Docker API; plain `containerd` is not enough for the usual workflow.\n3. Optional: Preferences → Kubernetes → disable **Enable Kubernetes**.  \n   Rancher’s built-in K3s is separate from `kind`. Turning it off frees CPU/RAM. Keep `kubectl` installed — Rancher Desktop still provides it.\n4. Verify:\n\n   ```bash\n   docker version\n   docker ps\n   ```\n\n**Alternatives:** Docker Desktop, or any engine that exposes a Docker API `kind` can use.\n\nTroubleshooting (macOS): if pods inside kind fail DNS lookups, try Preferences → Virtual Machine → Emulation → **QEMU** instead of VZ, then recreate the cluster.\n\n### 5. kubectl (Blog 4)\n\nOften installed with Rancher Desktop. Otherwise:\n\n```bash\nbrew install kubectl\n# Linux: see https://kubernetes.io/docs/tasks/tools/\nkubectl version --client\n```\n\n### 6. kind (Blog 4)\n\n```bash\nbrew install kind\n# or: go install sigs.k8s.io/kind@latest\n\nkind version\nkind create cluster --name kubeoperator-dev\nkubectl cluster-info --context kind-kubeoperator-dev\n```\n\nDelete when finished:\n\n```bash\nkind delete cluster --name kubeoperator-dev\n```\n\n### 7. Kubebuilder (Blog 3+)\n\nOfficial install ([Kubebuilder Quick Start](https://book.kubebuilder.io/quick-start.html)):\n\n```bash\ncurl -L -o kubebuilder \"https://go.kubebuilder.io/dl/latest/$(go env GOOS)/$(go env GOARCH)\"\nchmod +x kubebuilder \u0026\u0026 sudo mv kubebuilder /usr/local/bin/\nkubebuilder version\n```\n\nOn macOS you can also use `brew install kubebuilder` (community formula; the curl method above is what the project documents).\n\nScaffolding a project will pull related tools (`controller-gen`, `kustomize`, etc.) via the generated `Makefile` when you run `make` targets — you usually do not install those by hand.\n\n### Quick verify\n\n```bash\ngo version\ndocker version\nkubectl version --client\nkind version\nkubebuilder version\nmake --version\n```\n\n## Repository Layout\n\n```\nkubeoperator-journey/\n├── cmd/\n│   ├── why-operators/                         # Blog 1 — the problem demo\n│   └── control-loop/                          # Blog 2 — control loop simulation\n├── kubebuilder/api/v1alpha1/                  # Blog 3 — reference types (study only)\n├── api/v1alpha1/                              # Blog 4 — real Kubebuilder API path\n│   ├── databasecluster_types.go\n│   └── groupversion_info.go\n└── internal/\n    ├── problem/                               # Blog 1 — manual operator simulation\n    ├── watcher/                               # Blog 2 — etcd analogue (store + watch)\n    ├── reconciler/                            # Blog 2 — Watch→Enqueue→Reconcile pattern\n    ├── controller/                            # Blog 4 — DatabaseCluster Reconcile()\n    └── crd/                                   # Example DatabaseCluster YAML\n```\n\n## License\n\nMIT\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fmadmmas%2Fkubeoperator-journey","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fmadmmas%2Fkubeoperator-journey","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fmadmmas%2Fkubeoperator-journey/lists"}