LAB07: Building Own Operator

LAB70 Building Own Operator (CRDs)

This lab implements custom controller which watch ingress object with specific annotation and creates the HAProxy config

Below is a high-level architecture diagram

High-Level Architecture Diagram (Text + Visual Logic)

                    ┌───────────────────────────────────────────┐
                    │            Your VPC / Network              │
                    └───────────────────────────────────────────┘


                         ┌─────────────────────┐
                         │  HAProxy Server     │
                         │  (External VM)      │
                         │  /etc/haproxy/...   │
                         └─────────────────────┘

                                     │ updates via Ansible

                       ┌─────────────────────────────────┐
                       │  HAProxy Config Operator (Pod)   │
                       │  - Watches Ingress objects       │
                       │  - Extracts rules                │
                       │  - Resolves NodePorts + NodeIPs  │
                       │  - Renders HAProxy blocks        │
                       │  - Calls ansible-playbook        │
                       └─────────────────────────────────┘

                                     │ watches

                       ┌─────────────────────────────────┐
                       │        Kubernetes API Server     │
                       │----------------------------------│
                       │ • Ingress (w/ annotation)        │
                       │ • Services (NodePort)            │
                       │ • Endpoints                      │
                       │ • Nodes (InternalIP)             │
                       └─────────────────────────────────┘

                        routes via   │ NodePort

          ┌──────────────────────────────────────────────────────────────────┐
          │                            Worker Nodes                          │
          │──────────────────────────────────────────────────────────────────│
          │    ┌────────────────────┐      ┌────────────────────┐           │
          │    │  hello-app Pod     │      │ nginx-demo Pod     │           │
          │    └────────────────────┘      └────────────────────┘           │
          │         ^     ^                      ^     ^                    │
          │         │     │                      │     │                    │
          │  NodePort SVC │              NodePort SVC │                    │
          │  hello-app-svc│              nginx-demo-svc│                   │
          └──────────────────────────────────────────────────────────────────┘

The Flow Explained (Short + Clear)

1. Developer creates an Ingress

With annotation:

Example host:

  • hello-app.demo.local


2. Operator notices the annotated Ingress

It extracts:

  • host

  • path

  • service name

  • service port


3. Operator fetches service details

If service is NodePort:

  • Collects all Node Internal IPs

  • Gets assigned NodePort (e.g., 31625)


4. Operator generates HAProxy config

Example:


5. Operator pushes config using Ansible

ansible-playbook -i <haproxy_ip>,

  • Inserts block into /etc/haproxy/haproxy.cfg

  • Validates

  • Reloads HAProxy


6. External user request

User hits:

HAProxy forwards the traffic to a random node:

<node-ip>:31625hello-app Pod


Controller Implementation

::: spoiler Python controller using Kopf requirements.txt

controller.py

Dockerfile

:::

Deployment Manifests

  1. 00-namespace.yaml

  1. 02-rbac.yaml

  1. 03-deployment.yaml

  1. 04-ssh-secret.yaml

  1. 05-playbook-configmap.yaml

Test

  1. nginx-deployment.yaml

  1. ingress.yaml

  1. service.yaml

Last updated