|
| 1 | +# Linode Cloud Controller Manager - AI Coding Assistant Instructions |
| 2 | + |
| 3 | +## Project Overview |
| 4 | +This is the Kubernetes Cloud Controller Manager for Linode infrastructure. It integrates Kubernetes clusters with Linode's cloud services, managing load balancers (NodeBalancers), firewalls (Cloud Firewalls), nodes, networking routes, and IP allocation. |
| 5 | + |
| 6 | +## Architecture & Core Components |
| 7 | + |
| 8 | +### Cloud Provider Interface |
| 9 | +- `cloud/linode/cloud.go` - Main cloud provider implementation following Kubernetes CloudProvider interface |
| 10 | +- Implements 4 controllers: Node, Service, Route, and NodeIPAM controllers |
| 11 | +- All controllers run as goroutines initialized in `Initialize()` method |
| 12 | + |
| 13 | +### Controllers Structure |
| 14 | +- **Node Controller** (`node_controller.go`) - Manages node metadata, addresses, and lifecycle |
| 15 | +- **Service Controller** (`service_controller.go`) - Handles service deletions and cleanup |
| 16 | +- **Route Controller** (`route_controller.go`) - Manages VPC routes and pod networking |
| 17 | +- **NodeIPAM Controller** (`nodeipamcontroller.go`) - Allocates pod CIDRs to nodes |
| 18 | + |
| 19 | +### Load Balancer Types |
| 20 | +Two distinct implementations: |
| 21 | +1. **NodeBalancer** (`loadbalancers.go`) - Traditional Linode NodeBalancers |
| 22 | +2. **Cilium BGP** (`cilium_loadbalancers.go`) - BGP-based IP sharing |
| 23 | + |
| 24 | +## Development Patterns |
| 25 | + |
| 26 | +### Client Abstraction |
| 27 | +- `cloud/linode/client/client.go` - Interface wrapping Linode API |
| 28 | +- `client_with_metrics.go` - Prometheus metrics decorator using generated code |
| 29 | +- Use `//go:generate` with gowrap for automatic client instrumentation |
| 30 | + |
| 31 | +### Testing Strategy |
| 32 | +- Extensive use of gomock for Linode API client mocking |
| 33 | +- `fake_linode_test.go` - In-memory fake implementation for integration tests |
| 34 | +- Table-driven tests pattern throughout codebase |
| 35 | +- Mock generation: `//go:generate go run github.com/golang/mock/mockgen` |
| 36 | + |
| 37 | +### Configuration Management |
| 38 | +- `Options` global struct in `cloud.go` for CLI flags and environment variables |
| 39 | +- Annotation-driven service configuration via `cloud/annotations/annotations.go` |
| 40 | +- All annotations prefixed with `service.beta.kubernetes.io/linode-loadbalancer-` |
| 41 | + |
| 42 | +## Key Development Workflows |
| 43 | + |
| 44 | +### Building & Testing |
| 45 | +```bash |
| 46 | +# Use devbox for development environment |
| 47 | +devbox shell |
| 48 | + |
| 49 | +# Build binary |
| 50 | +make build |
| 51 | + |
| 52 | +# Run tests with coverage |
| 53 | +make test-coverage |
| 54 | + |
| 55 | +# Generate mocks (run after changing client interface) |
| 56 | +make mockgen |
| 57 | +``` |
| 58 | + |
| 59 | +### Adding New Annotations |
| 60 | +1. Add constant to `cloud/annotations/annotations.go` |
| 61 | +2. Update `docs/configuration/annotations.md` documentation |
| 62 | +3. Implement parsing logic in relevant controller |
| 63 | +4. Add validation and tests |
| 64 | + |
| 65 | +### Working with Load Balancers |
| 66 | +- Check `loadbalancers.go` for NodeBalancer implementation patterns |
| 67 | +- Use `portConfigAnnotation` struct for JSON port configurations |
| 68 | +- VPC integration uses `getVPCCreateOptions()` for subnet selection |
| 69 | +- Health check configuration follows annotation-driven pattern |
| 70 | + |
| 71 | +## Project-Specific Conventions |
| 72 | + |
| 73 | +### Error Handling |
| 74 | +- Custom error types: `invalidProviderIDError`, `lbNotFoundError` |
| 75 | +- Use `ignoreLinodeAPIError()` helper for handling expected API errors |
| 76 | +- Sentry integration for error reporting in production |
| 77 | + |
| 78 | +### Logging Patterns |
| 79 | +- Use `klog` package throughout (Kubernetes standard) |
| 80 | +- Log levels: Info for normal operations, Error for failures, V(3) for debug |
| 81 | +- Include context like service names, node names in log messages |
| 82 | + |
| 83 | +### Resource Management |
| 84 | +- Provider ID format: `linode://12345` (instance ID) |
| 85 | +- Node caching with TTL in `k8sNodeCache` for performance |
| 86 | +- Workqueue pattern for asynchronous controller processing |
| 87 | + |
| 88 | +### Deployment |
| 89 | +- DaemonSet deployment on control plane nodes only |
| 90 | +- Uses `hostNetwork: true` for API access |
| 91 | +- Requires `LINODE_API_TOKEN` and `LINODE_REGION` environment variables |
| 92 | +- RBAC permissions defined in `deploy/ccm-linode-template.yaml` |
| 93 | + |
| 94 | +## Integration Points |
| 95 | + |
| 96 | +### Kubernetes APIs |
| 97 | +- Implements standard CloudProvider interface from `k8s.io/cloud-provider` |
| 98 | +- Node informers for real-time node updates |
| 99 | +- Service informers for load balancer lifecycle management |
| 100 | + |
| 101 | +### Linode API Integration |
| 102 | +- Wrapped via `linodego` client library |
| 103 | +- Rate limiting and retry logic built into client wrapper |
| 104 | +- Prometheus metrics automatically generated for all API calls |
| 105 | + |
| 106 | +### Cilium Integration |
| 107 | +- BGP mode requires Cilium CNI with BGP peering |
| 108 | +- Creates CiliumLoadBalancerIPPool resources for IP management |
| 109 | +- Uses node selectors for BGP-enabled nodes |
| 110 | + |
| 111 | +## Common Gotchas |
| 112 | +- NodeBalancer backends require VPC configuration when `Options.VPCNames` is set |
| 113 | +- Node exclusion annotation: `node.k8s.linode.com/exclude-from-nb` |
| 114 | +- Port configurations must be valid JSON in annotations |
| 115 | +- Health check types depend on protocol (UDP vs TCP/HTTP) |
| 116 | +- Instance cache is global and shared across controllers |
| 117 | + |
| 118 | +## Documentation |
| 119 | +- Keep `docs/configuration/annotations.md` synchronized with code changes |
| 120 | +- All new features require documentation in `docs/` directory |
| 121 | +- Examples in `docs/examples/` should reflect real-world usage patterns |
0 commit comments