{"id":19075787,"url":"https://github.com/lpsm-dev/kubernetes-metacontroller","last_synced_at":"2025-04-13T22:52:23.079Z","repository":{"id":245602784,"uuid":"818731037","full_name":"lpsm-dev/kubernetes-metacontroller","owner":"lpsm-dev","description":"🥷 A project that shows how to write and deploy a custom controller in Kubernetes using Metacontroller","archived":false,"fork":false,"pushed_at":"2025-03-26T03:10:39.000Z","size":167,"stargazers_count":2,"open_issues_count":2,"forks_count":0,"subscribers_count":1,"default_branch":"main","last_synced_at":"2025-03-27T13:11:18.230Z","etag":null,"topics":["addons","crd-controller","ingress-nginx","kubernetes","kubernetes-controller","labs","metacontroller","pocs"],"latest_commit_sha":null,"homepage":"","language":"Python","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/lpsm-dev.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":"CONTRIBUTING.md","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}},"created_at":"2024-06-22T17:37:27.000Z","updated_at":"2025-03-04T03:49:53.000Z","dependencies_parsed_at":"2024-06-23T01:01:08.248Z","dependency_job_id":"ab00d9d8-8a39-4a23-8288-c114cbe64ea8","html_url":"https://github.com/lpsm-dev/kubernetes-metacontroller","commit_stats":null,"previous_names":["lpsm-dev/kubernetes-metacontroller"],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/lpsm-dev%2Fkubernetes-metacontroller","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/lpsm-dev%2Fkubernetes-metacontroller/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/lpsm-dev%2Fkubernetes-metacontroller/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/lpsm-dev%2Fkubernetes-metacontroller/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/lpsm-dev","download_url":"https://codeload.github.com/lpsm-dev/kubernetes-metacontroller/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":248794566,"owners_count":21162614,"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","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":["addons","crd-controller","ingress-nginx","kubernetes","kubernetes-controller","labs","metacontroller","pocs"],"created_at":"2024-11-09T01:56:00.289Z","updated_at":"2025-04-13T22:52:23.051Z","avatar_url":"https://github.com/lpsm-dev.png","language":"Python","funding_links":[],"categories":[],"sub_categories":[],"readme":"\u003c!-- BEGIN_DOCS --\u003e\n\u003cdiv align=\"center\"\u003e\n\n\u003ca name=\"readme-top\"\u003e\u003c/a\u003e\n\n\u003cimg alt=\"header\" src=\"https://github.com/lpsm-dev/lpsm-dev/blob/02421b0d81397fe8df3ab40e21752b8d0bb9105f/.github/assets/kubernetes.gif\" width=\"300\"/\u003e\n\nHello Human 👽! Bem-vindo ao meu repositório 👋\n\nPronto para derrubar um cluster Kubernetes? 🤡 hahaha\n\n[![Commitizen friendly](https://img.shields.io/badge/commitizen-friendly-brightgreen.svg)](https://www.conventionalcommits.org/en/v1.0.0/)\n[![Semantic Release](https://img.shields.io/badge/%20%20%F0%9F%93%A6%F0%9F%9A%80-semantic--release-e10079.svg)](https://semantic-release.gitbook.io/semantic-release/usage/configuration)\n[![Built with Devbox](https://jetpack.io/img/devbox/shield_galaxy.svg)](https://jetpack.io/devbox/docs/contributor-quickstart/)\n\n\u003c/div\u003e\n\n# Sumário\n\n\u003cdetails\u003e\n  \u003csummary\u003e\u003cstrong\u003eExpandir\u003c/strong\u003e\u003c/summary\u003e\n\n\u003c!-- START doctoc generated TOC please keep comment here to allow auto update --\u003e\n\u003c!-- DON'T EDIT THIS SECTION, INSTEAD RE-RUN doctoc TO UPDATE --\u003e\n\n- [Visão Geral](#vis%C3%A3o-geral)\n  - [Objetivo](#objetivo)\n  - [Contexto e Motivação](#contexto-e-motiva%C3%A7%C3%A3o)\n- [Tecnologias](#tecnologias)\n- [Entendendo](#entendendo)\n  - [O que são Controladores no Kubernetes?](#o-que-s%C3%A3o-controladores-no-kubernetes)\n  - [O que são Custom Resource Definitions (CRDs)?](#o-que-s%C3%A3o-custom-resource-definitions-crds)\n  - [Metacontroller](#metacontroller)\n  - [Tipos de Metacontrollers](#tipos-de-metacontrollers)\n  - [Metacontroller vs. Operadores Tradicionais](#metacontroller-vs-operadores-tradicionais)\n- [Arquitetura](#arquitetura)\n- [Implementação](#implementa%C3%A7%C3%A3o)\n  - [Pré-requisitos](#pr%C3%A9-requisitos)\n  - [Passo a Passo](#passo-a-passo)\n- [Conclusão](#conclus%C3%A3o)\n- [Referências](#refer%C3%AAncias)\n- [Contributing](#contributing)\n- [Versioning](#versioning)\n- [Troubleshooting](#troubleshooting)\n- [Show your support](#show-your-support)\n\n\u003c!-- END doctoc generated TOC please keep comment here to allow auto update --\u003e\n\n\u003cp align=\"right\"\u003e(\u003ca href=\"#readme-top\"\u003eback to top\u003c/a\u003e)\u003c/p\u003e\n\n\u003c/details\u003e\n\n# Visão Geral\n\n## Objetivo\n\nDeixando as brincadeiras de lado, nesse repositório apresento a vocês um exemplo prático de como eu criei um controlador personalizado no Kubernetes utilizando a ferramenta [Metacontroller](https://github.com/metacontroller/metacontroller).\n\nMinha proposta é colocar a mão na massa e documentar todo esse processo, desde o conceitual até a implementação prática, para que você possa entender como funciona e como pode ser útil para o seu dia a dia.\n\n## Contexto e Motivação\n\nO Kubernetes é uma plataforma incrível por inúmeras razões. Ele não só gerencia e organiza cargas de trabalho de forma excepcional (desde que você não faça merda kkkk), mas sua verdadeira força reside na flexibilidade. Com essa característica intrínseca, o Kubernetes pode ser ampliado e personalizado de forma praticamente infinita, permitindo que você o adapte exatamente de acordo com as suas necessidades. É essa capacidade de moldar o Kubernetes para atender a requisitos únicos que o torna uma ferramenta indispensável para qualquer empresa e que me motivo a explorar e compartilhar esse conhecimento.\n\n\u003cp align=\"right\"\u003e(\u003ca href=\"#readme-top\"\u003eback to top\u003c/a\u003e)\u003c/p\u003e\n\n# Tecnologias\n\nPara a implementação desse projeto, foram utilizadas as seguintes tecnologias:\n\n- [Docker](https://docs.docker.com/get-docker/)\n- [Kind](https://kind.sigs.k8s.io/)\n- [Kubernetes](https://kubernetes.io/)\n- [Metacontroller](https://metacontroller.github.io/metacontroller/intro.html)\n- [Python](https://www.python.org/)\n\nExistem outras ferramentas envolvidas, mas essas são as principais que você precisa conhecer para entender o projeto.\n\n\u003cp align=\"right\"\u003e(\u003ca href=\"#readme-top\"\u003eback to top\u003c/a\u003e)\u003c/p\u003e\n\n# Entendendo\n\n## O que são Controladores no Kubernetes?\n\nControladores são loops que observam o estado do cluster através da API do Kubernetes e realizam ações para alinhar o estado atual ao estado desejado. Eles são essenciais para a automação e extensibilidade do Kubernetes. Exemplos de controladores nativos incluem:\n\n- **Deployments**: Garante que um conjunto de pods esteja sempre em execução.\n- **StatefulSets**: Gerencia aplicações stateful com identidade persistente.\n- **Horizontal Pod Autoscaler (HPA)**: Ajusta automaticamente o número de réplicas de pods com base na carga de CPU ou outras métricas.\n\n## O que são Custom Resource Definitions (CRDs)?\n\nOs **Custom Resource Definitions (CRDs)** permitem que os usuários definam novos tipos de recursos no Kubernetes, expandindo sua API sem modificar o código-fonte do Kubernetes. Eles são a base para a criação de controladores personalizados, pois possibilitam a adição de novos objetos específicos ao cluster.\n\n**Como ele funciona?**\n\n- Você cria um CRD para definir um novo tipo de recurso (exemplo: `MyCustomResource`).\n- O Kubernetes passa a reconhecer esse recurso e permite que ele seja gerenciado via `kubectl`, API e operadores.\n- Um controlador personalizado pode ser implementado para monitorar e agir sobre esse novo recurso.\n\n```yaml\napiVersion: apiextensions.k8s.io/v1\nkind: CustomResourceDefinition\nmetadata:\n  name: widgets.example.com\nspec:\n  group: example.com\n  versions:\n    - name: v1\n      served: true\n      storage: true\n  scope: Namespaced\n  names:\n    plural: widgets\n    singular: widget\n    kind: Widget\n```\n\n## Metacontroller\n\nO **Metacontroller** é um componente que simplifica a implementação de **controladores personalizados** sem exigir o desenvolvimento completo de um controlador em `Go` usando o `client-go`. Em vez disso, ele permite que os desenvolvedores criem controladores como **webhooks**, podendo ser escritos em qualquer linguagem que suporte HTTP, como `Python`, `Node.js` ou `Bash`.\n\n**Como ele funciona?**\n\n- O Metacontroller monitora recursos no Kubernetes.\n- Quando há mudanças, ele aciona um webhook definido pelo usuário.\n- O webhook responde informando como o estado desejado deve ser ajustado.\n- O Metacontroller aplica essas mudanças automaticamente no cluster.\n\n**Entre seus principais benefícios, podemos destacar**:\n\n- Reduz a complexidade do desenvolvimento de controladores personalizados\n- Permite o uso de qualquer linguagem para a lógica de controle\n- Funciona como um intermediário entre o Kubernetes e os webhooks\n\n## Tipos de Metacontrollers\n\nO Metacontroller oferece diferentes tipos de controladores que podem ser utilizados dependendo do caso de uso:\n\n**CompositeController**\n\nPermite definir objetos \"pai\" que gerenciam um conjunto de objetos \"filho\". Útil para criar abstrações que agrupam múltiplos recursos. Exemplo: Criar um **Application CRD** que gera automaticamente Deployments, Services e ConfigMaps associados.\n\n**DecoratorController**\n\nModifica objetos existentes ao adicionar novos recursos sem alterar sua definição original. Adicionar sidecars automaticamente a todos os pods que correspondem a um critério.\n\n## Metacontroller vs. Operadores Tradicionais\n\n| Característica                  | Metacontroller       | Operadores com client-go              |\n| ------------------------------- | -------------------- | ------------------------------------- |\n| **Facilidade de implementação** | Alta (webhooks)      | Média (Go, client-go)                 |\n| **Linguagem suportada**         | Qualquer linguagem   | Principalmente Go                     |\n| **Flexibilidade**               | Alta                 | Média                                 |\n| **Integração com Kubernetes**   | Boa                  | Boa                                   |\n| **Uso recomendado**             | Casos simples/médios | Casos complexos e performance crítica |\n\n# Arquitetura\n\nA partir de agora, vou de fato ir para a implementação prática do controlador personalizado usando o Metacontroller. Para isso, vamos criar um exemplo simples de um controlador que gerencia um recurso personalizado chamado `PodService`. Esse recurso é uma abstraction que combina um Pod e um Service, permitindo que você defina ambos em um único objeto.\n\nA arquitetura do projeto é:\n\n```mermaid\ngraph TD\n    A[\"Custom Resource (CR)\"] --\u003e|Detectado pelo Metacontroller| B[\"Webhook (sync)\"]\n    B --\u003e|Recebe requisição com estado atual| C[\"Processa lógica no Webhook\"]\n    C --\u003e|Define estado desejado| D{\"Quais recursos devem ser gerenciados?\"}\n\n    D --\u003e|Criar Pod| E[\"Definir Pod com imagem, portas e recursos\"]\n    D --\u003e|Criar Service| F[\"Definir Service com porta e selector\"]\n\n    E --\u003e|Adicionar ao estado desejado| G[\"Retorna resposta JSON para o Metacontroller\"]\n    F --\u003e|Adicionar ao estado desejado| G\n\n    G --\u003e|Aplica mudanças| H[\"Kubernetes cria ou atualiza recursos\"]\n    H --\u003e|Estado atualizado| I[\"Aplicação rodando conforme especificado\"]\n\n    classDef highlight fill:#f9f,stroke:#333,stroke-width:2px;\n    class B,C,D,H highlight;\n```\n\n\u003cp align=\"right\"\u003e(\u003ca href=\"#readme-top\"\u003eback to top\u003c/a\u003e)\u003c/p\u003e\n\n# Implementação\n\n## Pré-requisitos\n\nAntes de começar, você precisa ter instalado em sua máquina:\n\n- [Docker](https://docs.docker.com/get-docker/)\n- [Kind](https://kind.sigs.k8s.io/docs/user/quick-start/)\n- [Kubectl](https://kubernetes.io/docs/tasks/tools/install-kubectl/)\n- [Task](https://taskfile.dev/#/installation)\n\n## Passo a Passo\n\nUma vez que temos o código do controlador personalizado, podemos seguir os passos abaixo para testá-lo:\n\n1. **Crie um Cluster Kubernetes com Kind**\n\n```bash\ntask kind:create\n```\n\n2. **Instale o Metacontroller**\n\n```bash\ntask addons:metacontroller\n```\n\n3. **Crie um Custom Resource Definition (CRD)**\n\n```bash\nkubectl apply -f manifests/crd.yaml\n```\n\n5. **Crie um CompositeController**\n\n```bash\nkubectl apply -f manifests/controller.yaml\n```\n\n6. **Teste o Controlador Personalizado**\n\n```bash\nNAMESPACE=\"pocs-kubernetes-metacontroller\"\nkubectl create ns $NAMESPACE\nkubectl create configmap -n $NAMESPACE podservice-controller --from-file=./src/sync.py\nkubectl apply -n $NAMESPACE -f ./src/controller/podservice-controller.yaml\nkubectl get pods -n $NAMESPACE\nkubectl apply -n $NAMESPACE -f ./src/application/podservice.yaml\nkubectl get pods,svc,ingress -n $NAMESPACE\n```\n\n7. **Adicionando IP do Service no /etc/hosts**\n\n\u003e [!WARNING]\n\u003e A função `addhost` é específica do meu ambiente, você deve adicionar manualmente o IP do Service no `/etc/hosts`.\n\n```bash\naddhost 127.0.0.1 podservice.local\n```\n\n8. **Testar o acesso ao serviço**\n\n```bash\ncurl http://podservice.local\n```\n\n9. **Limpeza do Ambiente**\n\n```bash\ntask kind:destroy\n```\n\n\u003cp align=\"right\"\u003e(\u003ca href=\"#readme-top\"\u003eback to top\u003c/a\u003e)\u003c/p\u003e\n\n# Conclusão\n\nUse o Metacontroller, quando:\n\n- Você deseja criar um controlador personalizado sem escrever um controlador em Go.\n- Você quer escrever a lógica do controlador em Python, Node.js ou qualquer linguagem que suporte webhooks.\n- Você precisa estender recursos já existentes sem modificar sua estrutura diretamente.\n\nNão use o Metacontroller, quando:\n\n- Você precisa de controladores com lógica muito complexa e de alta performance (Go pode ser mais eficiente).\n- Você tem necessidade de interação intensiva com a API do Kubernetes.\n\nNo geral, o Metacontroller é uma ferramenta poderosa para simplificar o desenvolvimento de controladores personalizados no Kubernetes, permitindo que você se concentre na lógica de controle em vez de se preocupar com a complexidade da API do Kubernetes.\n\n\u003cp align=\"right\"\u003e(\u003ca href=\"#readme-top\"\u003eback to top\u003c/a\u003e)\u003c/p\u003e\n\n# Referências\n\nLinks relevantes para esse projeto:\n\n- [Metacontroller Docs](https://metacontroller.github.io/metacontroller/intro.html)\n- [What is a Kubernetes Controller?](https://book-v1.book.kubebuilder.io/basics/what_is_a_controller.html)\n\n\u003cp align=\"right\"\u003e(\u003ca href=\"#readme-top\"\u003eback to top\u003c/a\u003e)\u003c/p\u003e\n\n# Contributing\n\nGostaria de contribuir? Isso é ótimo! Temos um guia de contribuição para te ajudar. Clique [aqui](CONTRIBUTING.md) para lê-lo.\n\n\u003cp align=\"right\"\u003e(\u003ca href=\"#readme-top\"\u003eback to top\u003c/a\u003e)\u003c/p\u003e\n\n# Versioning\n\nPara verificar o histórico de mudanças do projeto, acesse o arquivo [**CHANGELOG.md**](CHANGELOG.md).\n\n\u003cp align=\"right\"\u003e(\u003ca href=\"#readme-top\"\u003eback to top\u003c/a\u003e)\u003c/p\u003e\n\n# Troubleshooting\n\nSe você tiver algum problema, [abra uma issue nesse projeto](https://github.com/homelabsz/helm-charts/issues).\n\n\u003cp align=\"right\"\u003e(\u003ca href=\"#readme-top\"\u003eback to top\u003c/a\u003e)\u003c/p\u003e\n\n# Show your support\n\n\u003cdiv align=\"center\"\u003e\n\nDê uma ⭐️ para esse projeto se ele te ajudou!\n\n\u003cimg alt=\"gif-footer\" src=\"https://github.com/lpsm-dev/lpsm-dev/blob/main/.github/assets/yoda.gif\" width=\"225\"/\u003e\n\n\u003cbr\u003e\n\u003cbr\u003e\n\nFeito com 💜 por [mim](https://github.com/lpsm-dev) :wave: inspirado no [readme-md-generator](https://github.com/kefranabg/readme-md-generator)\n\n\u003c/div\u003e\n\n\u003cp align=\"right\"\u003e(\u003ca href=\"#readme-top\"\u003eback to top\u003c/a\u003e)\u003c/p\u003e\n\u003c!-- END_DOCS --\u003e\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Flpsm-dev%2Fkubernetes-metacontroller","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Flpsm-dev%2Fkubernetes-metacontroller","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Flpsm-dev%2Fkubernetes-metacontroller/lists"}