Browser Controller is a Kubernetes controller for the Selenosis ecosystem.
It manages Browser and BrowserConfig custom resources and is responsible for creating, monitoring, and cleaning up ephemeral browser Pods.
The controller is designed for deterministic browser provisioning with strict lifecycle management.
- Browser — runtime resource representing a single browser instance.
- BrowserConfig — configuration resource defining browser images and pod templates.
- Controller — resolves configuration, creates Pods, tracks their lifecycle, and updates status.
Each Browser resource results in exactly one Pod with the same name.
- Registers
BrowserandBrowserConfigCRDs - Reconciles
Browserresources into Pods - Resolves configuration using
BrowserConfig(template + overrides) - Updates
Browser.statuswith runtime information - Ensures proper cleanup via finalizers
- Exposes health, readiness, and metrics endpoints
- Runs inside a Kubernetes cluster (in-cluster config)
- Uses a ServiceAccount with ClusterRole / ClusterRoleBinding
- RBAC manifests are located in
config/rbac - Examples assume the
defaultnamespace
Apply CRDs, RBAC, and deploy the controller:
kubectl apply -f config/crd
kubectl apply -f config/rbac
kubectl apply -f config/controllerBrowserConfig examples config/examples
Browser is a namespaced CustomResource that defines a desired browser session (browser type and version) and exposes the actual runtime state of the underlying Kubernetes Pod (phase, IP, container details). It is used by the browser-controller to manage the full lifecycle of browser pods.
- Group/Version:
selenosis.io/v1(adjust if your API group differs) - Kind:
Browser - Scope: Namespaced
- Resource:
browsers - Short name:
brw - Categories:
selenosis - Status subresource: enabled (
/status)
The CRD defines additional printer columns for quick inspection:
- Browser:
.spec.browserName - Version:
.spec.browserVersion - Phase:
.status.phase - PodIP:
.status.podIP - StartTime:
.status.startTime - Age:
.metadata.creationTimestamp
Example:
kubectl get browsers
kubectl get brwspec describes the desired browser configuration:
-
browserName (string, required, minLength=1)
Name of the browser to run (for example:chrome,firefox). -
browserVersion (string, required, minLength=1)
Browser version to use (for example:91.0,120.0, orlatestif supported by the controller).
status is populated by the controller and reflects the observed state of the browser pod:
-
podIP (string, optional)
IP address assigned to the pod. -
phase (PodPhase, optional)
Current lifecycle phase of the pod (Pending,Running,Succeeded,Failed,Unknown). -
message (string, optional)
Human-readable description of the current condition. -
reason (string, optional)
Short, machine-friendly reason (for example:Evicted). -
startTime (Time, optional)
Timestamp when the pod was started. -
containerStatuses (array, optional)
Detailed status for each container:- name — container name
- state — current container state (
Pending,Running,Failed) - image — container image
- restartCount — number of restarts
- ports — exposed ports (container/host, protocol, name)
apiVersion: selenosis.io/v1
kind: Browser
metadata:
name: d568aeff-a91a-449b-834b-d79bf2d6d623
namespace: default
spec:
browserName: chrome
browserVersion: "120.0"Apply and inspect:
kubectl apply -f browser.yaml
kubectl get brw
kubectl describe brw d568aeff-a91a-449b-834b-d79bf2d6d623
kubectl get brw d568aeff-a91a-449b-834b-d79bf2d6d623 -o yaml- Based on
spec.browserNameandspec.browserVersion, the controller creates and manages a dedicated browser pod. - Runtime details (IP, phase, start time, container statuses) are continuously published to
.status, allowing UIs and clients to quickly determine browser availability and health.
BrowserConfig is a namespaced CustomResource that defines browser images and pod-level configuration templates used by the browser-controller when creating browser pods.
It allows you to centrally manage defaults (template) and override them per browser name and browser version.
This CRD does not create pods by itself. Instead, it acts as a configuration source consumed by the browser-controller.
- Group/Version:
selenosis.io/v1(adjust if your API group differs) - Kind:
BrowserConfig - Scope: Namespaced
- Status subresource: enabled (
/status)
BrowserConfig provides:
- A global pod template applied to all browsers and versions
- Per-browser and per-version override capabilities
- A deterministic merge strategy (version → browser → template)
- Centralized control over:
- Browser images
- Resources
- Environment variables
- Volumes and mounts
- Sidecars and init containers
- Scheduling and security settings
spec.template defines a base pod configuration applied to all browsers and versions unless explicitly overridden.
Supported fields include:
labels,annotationsenvresourcesvolumes,volumeMountsnodeSelector,affinity,tolerationshostAliasesinitContainerssidecarsprivilegedimagePullSecretsdnsConfigsecurityContextworkingDir
All fields are optional.
spec.browsers is a required map that defines browser-specific and version-specific configuration.
Structure:
browsers:
<browserName>:
<browserVersion>:
image: <container-image>
...Example:
browsers:
chrome:
"120.0":
image: selenium/standalone-chrome:120.0
"121.0":
image: selenium/standalone-chrome:121.0
firefox:
"118.0":
image: selenium/standalone-firefox:118.0Each browser version supports the same override fields as the template.
Configuration is merged in the following order (later overrides earlier):
- Template
- Browser-level version config
- Explicit version overrides
Rules:
nilfields inherit values from the template- Maps and lists are merged, not replaced
- Sidecars and init containers are merged by name
- Environment variables are merged by variable name
This ensures predictable and reusable configuration without duplication.
status reflects metadata about the effective configuration:
- version (string) — current configuration version identifier
- lastUpdated (timestamp) — last update time
apiVersion: selenosis.io/v1
kind: BrowserConfig
metadata:
name: default-browser-config
namespace: default
spec:
template:
resources:
requests:
cpu: "500m"
memory: "1Gi"
env:
- name: TZ
value: UTC
browsers:
chrome:
"120.0":
image: selenium/standalone-chrome:120.0Apply and inspect:
kubectl apply -f browserconfig.yaml
kubectl get browserconfig -n
kubectl describe browserconfig default-browser-config
kubectl get browserconfig default-browser-config -o yamlBrowserConfigis loaded and cached by the controllerBrowserreconciliation:- resolves configuration
- creates a Pod with the same name
- tracks Pod lifecycle
- updates
Browser.status
- Pods are non-restarting and treated as ephemeral
- Failures are terminal and reflected in
Browser.status
This project uses make to generate code, manifests, and build the controller image.
make install-toolsmake generate
make manifestsOr run everything:
make allmake docker-build
make docker-pushOr combined:
make deploy