Skip to content

Architecture

Overview

bindcar is designed as a sidecar container that runs alongside BIND9, providing a REST API for zone management. It acts as a bridge between Kubernetes/container orchestration and BIND9's rndc control interface.

System Architecture

graph TB subgraph "Kubernetes Pod" subgraph "bindcar Container" API[HTTP API Server] Auth[Authentication Middleware] Handler[Request Handlers] RNDC[RNDC Executor] end subgraph "BIND9 Container" BIND[BIND9 Server] RNDCDaemon[rndc Daemon :953] end SharedVol[Shared Volume<br/>/var/cache/bind] end Client[API Client] K8s[Kubernetes ServiceAccount] Client -->|Bearer Token| API K8s -.->|Provides Token| Client API --> Auth Auth --> Handler Handler --> RNDC Handler -.->|Write Zone Files| SharedVol RNDC -->|rndc commands| RNDCDaemon RNDCDaemon -.->|Manages| BIND BIND -.->|Reads| SharedVol style API fill:#e1f5ff style BIND fill:#ffe1e1 style SharedVol fill:#e8f5e9

Component Breakdown

HTTP API Server (Axum)

  • Handles incoming HTTP requests
  • Provides OpenAPI/Swagger documentation
  • Implements health and readiness probes
  • Routes requests to appropriate handlers
graph LR Request[HTTP Request] --> Router[Axum Router] Router --> Health[Health Endpoints] Router --> Zones[Zone Endpoints] Router --> Server[Server Endpoints] Health --> Response[JSON Response] Zones --> Response Server --> Response

Authentication Middleware

  • Validates Bearer tokens
  • Integrates with Kubernetes ServiceAccount tokens
  • Protects all endpoints except health checks
sequenceDiagram participant Client participant Auth as Auth Middleware participant Handler as Request Handler Client->>Auth: Request + Bearer Token Auth->>Auth: Extract Token alt No Token Auth-->>Client: 401 Unauthorized else Invalid Format Auth-->>Client: 401 Unauthorized else Empty Token Auth-->>Client: 401 Unauthorized else Valid Token Auth->>Handler: Forward Request Handler-->>Auth: Response Auth-->>Client: 200 OK end

RNDC Executor

Executes rndc commands via the system binary.

graph TD A["RNDC Executor"] --> B["tokio::process::Command"] B --> C["/usr/sbin/rndc"] C --> D{"Exit Code"} D -->|"0"| E["Parse stdout"] D -->|"!=0"| F["Parse stderr"] E --> G["Return Success"] F --> H["Return Error"]

Zone File Management

sequenceDiagram participant API participant FS as File System participant RNDC participant BIND9 API->>API: Generate Zone File Content API->>FS: Write /var/cache/bind/zone.zone FS-->>API: Success API->>RNDC: rndc addzone example.com { ... } RNDC->>BIND9: Add zone configuration BIND9->>FS: Read zone file BIND9-->>RNDC: Zone loaded RNDC-->>API: Success

Request Flow

Create Zone Flow

sequenceDiagram autonumber participant Client participant Auth as Auth Middleware participant Handler as Zone Handler participant FS as File System participant RNDC as RNDC Executor participant BIND9 Client->>Auth: POST /api/v1/zones Auth->>Auth: Validate Token Auth->>Handler: Authorized Request Handler->>Handler: Validate Zone Config Handler->>Handler: Generate Zone File Handler->>FS: Write zone.zone FS-->>Handler: File Written Handler->>RNDC: Execute addzone RNDC->>BIND9: rndc addzone BIND9-->>RNDC: Zone Loaded RNDC-->>Handler: Success Handler-->>Auth: 201 Created Auth-->>Client: JSON Response

Delete Zone Flow

sequenceDiagram autonumber participant Client participant Handler as Zone Handler participant RNDC as RNDC Executor participant BIND9 participant FS as File System Client->>Handler: DELETE /api/v1/zones/{name} Handler->>RNDC: Execute delzone RNDC->>BIND9: rndc delzone BIND9-->>RNDC: Zone Removed RNDC-->>Handler: Success Handler->>FS: Delete zone.zone FS-->>Handler: File Deleted Handler-->>Client: 200 OK

Data Flow

Zone Configuration to Zone File

graph LR JSON[JSON Config] --> Parser[Config Parser] Parser --> SOA[SOA Record] Parser --> NS[NS Records] Parser --> RR[Resource Records] SOA --> Builder[Zone File Builder] NS --> Builder RR --> Builder Builder --> File[Zone File] style JSON fill:#e3f2fd style File fill:#f3e5f5

Deployment Architecture

Standalone Docker

graph TB subgraph "Docker Host" subgraph "bind9 Container" BIND[BIND9] end subgraph "bindcar Container" API[bindcar API] end Vol[Docker Volume<br/>zones] end BIND -.->|Reads| Vol API -.->|Writes| Vol API -->|rndc| BIND Client[External Client] -->|:8080| API

Kubernetes Sidecar

graph TB subgraph "Kubernetes Cluster" subgraph "Pod" subgraph "bind9 Container" BIND[BIND9<br/>:53] end subgraph "bindcar Container" API[bindcar<br/>:8080] end Vol[emptyDir Volume] end Service[ClusterIP Service<br/>dns-api] SA[ServiceAccount<br/>dns-operator] end BIND -.->|Reads| Vol API -.->|Writes| Vol API -->|rndc :953| BIND Service -->|Routes| API SA -.->|Provides Token| API Operator[External Operator] -->|Authenticated| Service style Service fill:#fff3e0 style SA fill:#e8f5e9

Security Model

graph TD A[API Request] --> B{Has Auth Header?} B -->|No| C[401 Unauthorized] B -->|Yes| D{Valid Format?} D -->|No| C D -->|Yes| E{Token Present?} E -->|No| C E -->|Yes| F[Process Request] F --> G{Input Validation} G -->|Invalid| H[400 Bad Request] G -->|Valid| I{Execute Operation} I --> J{Success?} J -->|Yes| K[200/201 Response] J -->|No| L{Error Type} L -->|RNDC Error| M[500 Internal Server Error] L -->|Not Found| N[404 Not Found] L -->|Other| O[500 Internal Error]

Error Handling

graph TD Req[Request] --> Val{Validation} Val -->|Invalid Input| E400[400 Bad Request] Val -->|Valid| Auth{Authentication} Auth -->|Failed| E401[401 Unauthorized] Auth -->|Success| Proc[Process Request] Proc --> FS{File Operations} FS -->|Failed| E500[500 Internal Error] FS -->|Success| RNDC{RNDC Command} RNDC -->|Failed| E500[500 Internal Server Error] RNDC -->|Not Found| E404[404 Not Found] RNDC -->|Success| Success[200/201 Success] style E400 fill:#ffebee style E401 fill:#ffebee style E404 fill:#ffebee style E500 fill:#ffebee style E500 fill:#ffebee style Success fill:#e8f5e9

Technology Stack

Layer Technology
HTTP Framework Axum 0.8
Async Runtime Tokio
Serialization Serde + JSON
Logging Tracing + tracing-subscriber
API Documentation utoipa + Swagger UI
RNDC Communication System rndc binary
Container Runtime Docker / containerd
Orchestration Kubernetes (optional)