The Pizza Order Controller is a custom Kubernetes controller that forms the core of the Kubernetes Pizza Observability project. It's responsible for watching PizzaOrder custom resources, processing these orders by interacting with the Dominos Pizza API, and updating their status within the Kubernetes cluster. This enables the automated ordering of pizza when specific cluster conditions (like high CPU usage) are met.
The controller is built using Go and the controller-runtime library, adhering to the Kubernetes operator pattern. Its main architectural components are:
PizzaOrderCustom Resource Definition (CRD): Defines thePizzaOrdercustom resource, which represents a pizza order within the Kubernetes cluster. This CRD includes fields for customer details, delivery address, pizza specifications, and payment information.- Reconciler (
pizza-controller.go): Contains the primary reconciliation logic. TheReconcilefunction is triggered whenPizzaOrderresources are created, updated, or deleted. It handles the entire lifecycle of a pizza order. - Dominos API Integration: A set of functions responsible for communicating with the Dominos Pizza API. This includes finding the nearest store, validating the order, pricing the order, and placing the order.
- RBAC Configuration (
pizza-controller-deployment.yaml): Defines the necessaryServiceAccount,ClusterRole, andClusterRoleBindingto grant the controller appropriate permissions to interact with Kubernetes API resources (e.g.,PizzaOrderCRDs,Secrets).
The controller's workflow is as follows:
- Resource Watching: The controller continuously watches for changes to
PizzaOrdercustom resources in the cluster. - Order Processing Trigger: When a new
PizzaOrderresource is created with thespec.placeOrderfield set totrue, or an existing one is updated to this state, the reconciler is invoked. - Order Validation & Preparation:
- Retrieves customer and delivery details from the
PizzaOrderspec. - Fetches payment information from a Kubernetes
Secretreferenced inspec.paymentSecret.name. - Validates the order details with the Dominos API (e.g., address validation, store lookup).
- Retrieves customer and delivery details from the
- Order Placement:
- Prices the order using the Dominos API.
- If validation and pricing are successful, places the order with the Dominos API.
- Status Update: After attempting to place the order, the controller updates the
statussubresource of thePizzaOrderCRD with:orderId: The ID returned by Dominos API upon successful order placement.status: The current status of the order (e.g., "Pending", "Placed", "Failed", "Delivered").price: The total price of the order.lastUpdateTime: Timestamp of the last status update.
- Order Tracking (Future Enhancement): While the current implementation focuses on order placement, a future enhancement could involve periodic polling of the Dominos API to track the order through its various stages (e.g., preparation, baking, out for delivery) and update the
PizzaOrderstatus accordingly.
- A running Kubernetes cluster (e.g., Minikube, Kind, AKS, GKE, EKS).
kubectlconfigured to communicate with your cluster.- The
PizzaOrderCRD must be installed in the cluster. - A Kubernetes
Secretcontaining Dominos payment information must be created. - Docker (if building the image locally).
- Helm 3.x (if deploying via Helm).
If you've made changes to the controller code, you'll need to rebuild the Docker image:
# Navigate to the controller directory
cd kubernetes/controller
# Build the Docker image
docker build -t your-registry/pizza-controller:latest .
# Push to your container registry (e.g., Docker Hub, ACR, GCR)
# docker login your-registry
docker push your-registry/pizza-controller:latestMake sure to update the image path in kubernetes/controller/pizza-controller-deployment.yaml or your Helm values.yaml if you use a custom registry or tag.
This is the easiest way to deploy the controller along with all its dependencies (CRD, RBAC, etc.).
# From the project root directory
helm install k8s-pizza helm/k8s-pizza-observability-chart --namespace k8s-pizzaEnsure your values.yaml for the Helm chart correctly points to the controller image and configures any necessary parameters.
If you prefer manual deployment or are not using Helm:
# 1. Apply the PizzaOrder CRD
kubectl apply -f kubernetes/crds/pizzaorders.yaml
# 2. Create the Dominos Payment Secret (see Configuration section below)
kubectl apply -f kubernetes/dominos-payment-secret.example.yaml # Modify with real data first!
# 3. Deploy the Controller
kubectl apply -f kubernetes/controller/pizza-controller-deployment.yamlThe controller requires payment information to place orders. This is securely stored in a Kubernetes Secret. Create a Secret named dominos-payment-secret in the same namespace as the controller.
Example dominos-payment-secret.yaml:
apiVersion: v1
kind: Secret
metadata:
name: dominos-payment-secret
namespace: k8s-pizza # Or your deployment namespace
type: Opaque
stringData: # Use stringData for base64 auto-encoding by Kubernetes
CardType: "VISA" # e.g., VISA, MASTERCARD, AMEX
Number: "4111111111111111" # Your card number (use a test card for development)
Expiration: "0130" # Format: MMYY (e.g., January 2030)
SecurityCode: "123" # CVV/CVC
PostalCode: "90210" # Billing postal code for the cardApply the secret:
kubectl apply -f dominos-payment-secret.yamlImportant Security Note: Never commit real payment information to your Git repository. Use a placeholder example and create the actual secret directly in your cluster or manage it with a secrets management tool.
To trigger a pizza order, create a PizzaOrder custom resource:
apiVersion: pizza.bilalashraf.xyz/v1
kind: PizzaOrder
metadata:
name: cpu-high-alert-order-1
namespace: k8s-pizza # Or your deployment namespace
spec:
placeOrder: true # Set to true to initiate order placement
customer:
firstName: "Cluster"
lastName: "Admin"
email: "admin@example.com"
phone: "5551234567"
address:
street: "1600 Amphitheatre Parkway"
city: "Mountain View"
region: "CA" # State or Province
postalCode: "94043"
pizzas:
- size: "Large" # e.g., Small, Medium, Large
toppings:
- "Pepperoni"
- "Mushrooms"
- size: "Medium"
toppings:
- "Cheese"
paymentSecret:
name: "dominos-payment-secret" # Name of the K8s Secret containing payment infoApply the PizzaOrder:
kubectl apply -f your-pizza-order.yamlThe controller outputs logs that are crucial for monitoring its activity and troubleshooting issues.
-
View Controller Logs:
# Find the controller pod name kubectl get pods -n k8s-pizza -l app=pizza-controller # Stream logs from the controller pod (replace <pod-name>) kubectl logs -f -n k8s-pizza <pod-name>
-
Check
PizzaOrderStatus:# List all pizza orders kubectl get pizzaorders -n k8s-pizza # Describe a specific pizza order for detailed status kubectl describe pizzaorder cpu-high-alert-order-1 -n k8s-pizza
The
statusfield of thePizzaOrderresource will show theorderId,price, and currentstatus(e.g.,Pending,Processing,Placed,Failed).
- Controller Pod Not Starting/Crashing:
- Check controller logs (
kubectl logs ...) for error messages. - Verify RBAC permissions: Ensure the
ServiceAccountused by the controller has the necessary permissions defined in itsClusterRoleandClusterRoleBindingto accessPizzaOrderCRDs andSecrets. - Ensure the
PizzaOrderCRD is correctly installed (kubectl get crd pizzaorders.pizza.bilalashraf.xyz).
- Check controller logs (
- Order Placement Failing:
- Check controller logs for specific errors from the Dominos API.
- Verify the
dominos-payment-secretexists, is correctly formatted, and contains valid (test) payment details. - Ensure the delivery address is valid and serviceable by Dominos.
- Check for network connectivity issues from the controller pod to the Dominos API endpoints.
PizzaOrderStatus Not Updating:- Confirm the controller has permissions to update the
statussubresource ofPizzaOrderobjects (this is typically included in the RBAC rules). - Check controller logs for any errors during status updates.
- Confirm the controller has permissions to update the
For developing and testing the controller locally (outside the cluster):
-
Ensure Go is installed.
-
Access to a Kubernetes cluster: Your local
kubectlshould be configured to point to a development cluster where thePizzaOrderCRD is installed. -
Environment Variables (Optional): If the controller relies on environment variables for configuration (though typically it uses in-cluster config or command-line flags), set them up in your local environment.
-
Run the controller:
# Navigate to the controller directory cd kubernetes/controller # Run the main Go program go run pizza-controller.go --kubeconfig=/path/to/your/.kube/config
This will start the controller on your local machine, watching for
PizzaOrderresources in the configured Kubernetes cluster.
The controller is designed to be extensible. Potential areas for enhancement include:
- More Pizza Customization: Add support for different crust types, sauces, and a wider variety of toppings in the
PizzaOrderspec. - Advanced Order Tracking: Implement logic to periodically poll the Dominos API for detailed order status updates (e.g., "In the Oven