This reference for version: 1.0.0
Moon is an enterprise version of Selenoid using Kubernetes to launch browsers.
1. Getting Started
1.1. Quick Start Guide
-
Prerequisites:
-
Running Kubernetes cluster
-
kubectlclient installed and pointing to the cluster
-
-
Examples of used YAML and JSON files can be found in Example Configuration Files section.
-
Configure your namespace service account to support Aerokube private registry - replace
REGISTRY_USERNAME,REGISTRY_PASSWORDandREGISTRY_EMAILplaceholders with your values:$ kubectl create secret docker-registry registry.aerokube.com --docker-server=registry.aerokube.com --docker-username=REGISTRY_USERNAME --docker-password=REGISTRY-PASSWORD --docker-email=REGISTRY-EMAIL $ kubectl patch serviceaccount default -p '{"imagePullSecrets": [{"name": "registry.aerokube.com"}]}'
See this Kubernetes documentation section for more details.
. Copy test quota to quota directory and initialize browsers configuration:
$ mkdir -p quota $ touch quota/browsers.json # Add contents to file $ kubectl create configmap quota --from-file=quota
-
Start one or more Moon replicas:
$ kubectl create -f moon.yaml
-
Start one or more Moon API replicas:
$ kubectl create -f moon-api.yaml
-
Determine IP addresses or hostnames for
moonandmoon-apiservices. When testing in Minikube this can be done with the following commands:$ minikube service moon --url http://192.168.99.100:30979
$ minikube service moon-api --url http://192.168.99.100:41567
-
Run your tests against
moonservice like you do with regular Selenium:http://192.168.99.100:30979/wd/hub
-
Check that
moon-apireturns statistics:$ http://192.168.99.100:41567/status
A successful request should return a JSON with browser usage statistics.
1.2. Cluster Architecture

Moon cluster consists of several important components:
-
Kubernetes configuration map to store browser quota information and various runtime settings.
-
One or more
moonapplication containers. Their main purpose is to start and stop browser containers. These replicas are usually exposed as Kubernetes service available on standard Selenium port4444. You should run all the tests against this service. -
One or more
moon-apiapplication containers. This API collects and returns various data about running browsers.moon-apiis usually exposed as Kubernetes service available on HTTP port (e.g.80or8080). -
Running browser containers. Moon is using exactly the same containers as Selenoid.
Basic browser startup functionality is completely stateless and does not require any external database to be running.
2. Configuration
2.1. Configuring Available Browsers
-
Moon is using exactly the same JSON format as Selenoid. An example file can be found in Example Configuration Files section. Because everything in Kubernetes is being run in containers - you cannot specify path to webdriver binary, only container with browser. To be available across the cluster all configuration data is stored in ConfigMap.
-
Moon supports multiple users, so you need to create one file for each user named
<username>.json. For example for usertestto work properly you should createtest.jsonfile. -
All JSON files should be stored in the same directory because in that case you can update configuration with just one command.
2.1.1. Updating Browsers List
To add or remove browsers:
-
Having configuration files stored in directory update Moon configuration:
$ kubectl update configmap quota --from-file=quota
-
Gracefully restart Moon service:
$ kubectl update -f moon.yaml
All running user sessions will continue to work without any interruption.
Appendix A: Example Configuration Files
browsers.json file contents{
"firefox": {
"default": "55.0",
"versions": {
"55.0": {
"image": "selenoid/vnc:firefox_55.0",
"port": "4444",
"path": "/wd/hub"
},
"54.0": {
"image": "selenoid/vnc:firefox_54.0",
"port": "4444",
"path": "/wd/hub"
},
"53.0": {
"image": "selenoid/vnc:firefox_53.0",
"port": "4444",
"path": "/wd/hub"
},
"52.0": {
"image": "selenoid/vnc:firefox_52.0",
"port": "4444",
"path": "/wd/hub"
},
"51.0": {
"image": "selenoid/vnc:firefox_51.0",
"port": "4444",
"path": "/wd/hub"
},
"50.0": {
"image": "selenoid/vnc:firefox_50.0",
"port": "4444",
"path": "/wd/hub"
},
"49.0": {
"image": "selenoid/vnc:firefox_49.0",
"port": "4444",
"path": "/wd/hub"
},
"48.0": {
"image": "selenoid/vnc:firefox_48.0",
"port": "4444",
"path": "/wd/hub"
},
"47.0": {
"image": "selenoid/vnc:firefox_47.0",
"port": "4444",
"path": "/wd/hub"
},
"46.0": {
"image": "selenoid/vnc:firefox_46.0",
"port": "4444",
"path": "/wd/hub"
},
"45.0": {
"image": "selenoid/vnc:firefox_45.0",
"port": "4444",
"path": "/wd/hub"
},
"44.0": {
"image": "selenoid/vnc:firefox_44.0",
"port": "4444",
"path": "/wd/hub"
},
"43.0": {
"image": "selenoid/vnc:firefox_43.0",
"port": "4444",
"path": "/wd/hub"
},
"42.0": {
"image": "selenoid/vnc:firefox_42.0",
"port": "4444",
"path": "/wd/hub"
},
"41.0": {
"image": "selenoid/vnc:firefox_41.0",
"port": "4444",
"path": "/wd/hub"
},
"40.0": {
"image": "selenoid/vnc:firefox_40.0",
"port": "4444",
"path": "/wd/hub"
},
"39.0": {
"image": "selenoid/vnc:firefox_39.0",
"port": "4444",
"path": "/wd/hub"
},
"38.0": {
"image": "selenoid/vnc:firefox_38.0",
"port": "4444",
"path": "/wd/hub"
},
"37.0": {
"image": "selenoid/vnc:firefox_37.0",
"port": "4444",
"path": "/wd/hub"
},
"36.0": {
"image": "selenoid/vnc:firefox_36.0",
"port": "4444",
"path": "/wd/hub"
},
"35.0": {
"image": "selenoid/vnc:firefox_35.0",
"port": "4444",
"path": "/wd/hub"
},
"34.0": {
"image": "selenoid/vnc:firefox_34.0",
"port": "4444",
"path": "/wd/hub"
},
"33.0": {
"image": "selenoid/vnc:firefox_33.0",
"port": "4444",
"path": "/wd/hub"
},
"32.0": {
"image": "selenoid/vnc:firefox_32.0",
"port": "4444",
"path": "/wd/hub"
},
"31.0": {
"image": "selenoid/vnc:firefox_31.0",
"port": "4444",
"path": "/wd/hub"
},
"30.0": {
"image": "selenoid/vnc:firefox_30.0",
"port": "4444",
"path": "/wd/hub"
},
"29.0": {
"image": "selenoid/vnc:firefox_29.0",
"port": "4444",
"path": "/wd/hub"
},
"28.0": {
"image": "selenoid/vnc:firefox_28.0",
"port": "4444",
"path": "/wd/hub"
},
"27.0": {
"image": "selenoid/vnc:firefox_27.0",
"port": "4444",
"path": "/wd/hub"
},
"26.0": {
"image": "selenoid/vnc:firefox_26.0",
"port": "4444",
"path": "/wd/hub"
},
"25.0": {
"image": "selenoid/vnc:firefox_25.0",
"port": "4444",
"path": "/wd/hub"
},
"24.0": {
"image": "selenoid/vnc:firefox_24.0",
"port": "4444",
"path": "/wd/hub"
},
"23.0": {
"image": "selenoid/vnc:firefox_23.0",
"port": "4444",
"path": "/wd/hub"
},
"22.0": {
"image": "selenoid/vnc:firefox_22.0",
"port": "4444",
"path": "/wd/hub"
},
"21.0": {
"image": "selenoid/vnc:firefox_21.0",
"port": "4444",
"path": "/wd/hub"
},
"20.0": {
"image": "selenoid/vnc:firefox_20.0",
"port": "4444",
"path": "/wd/hub"
},
"19.0": {
"image": "selenoid/vnc:firefox_19.0",
"port": "4444",
"path": "/wd/hub"
},
"18.0": {
"image": "selenoid/vnc:firefox_18.0",
"port": "4444",
"path": "/wd/hub"
},
"17.0": {
"image": "selenoid/vnc:firefox_17.0",
"port": "4444",
"path": "/wd/hub"
},
"16.0": {
"image": "selenoid/vnc:firefox_16.0",
"port": "4444",
"path": "/wd/hub"
},
"15.0": {
"image": "selenoid/vnc:firefox_15.0",
"port": "4444",
"path": "/wd/hub"
},
"14.0": {
"image": "selenoid/vnc:firefox_14.0",
"port": "4444",
"path": "/wd/hub"
},
"13.0": {
"image": "selenoid/vnc:firefox_13.0",
"port": "4444",
"path": "/wd/hub"
},
"12.0": {
"image": "selenoid/vnc:firefox_12.0",
"port": "4444",
"path": "/wd/hub"
},
"11.0": {
"image": "selenoid/vnc:firefox_11.0",
"port": "4444",
"path": "/wd/hub"
},
"10.0": {
"image": "selenoid/vnc:firefox_10.0",
"port": "4444",
"path": "/wd/hub"
},
"9.0": {
"image": "selenoid/vnc:firefox_9.0",
"port": "4444",
"path": "/wd/hub"
},
"8.0": {
"image": "selenoid/vnc:firefox_8.0",
"port": "4444",
"path": "/wd/hub"
},
"7.0": {
"image": "selenoid/vnc:firefox_7.0",
"port": "4444",
"path": "/wd/hub"
},
"6.0": {
"image": "selenoid/vnc:firefox_6.0",
"port": "4444",
"path": "/wd/hub"
},
"5.0": {
"image": "selenoid/vnc:firefox_5.0",
"port": "4444",
"path": "/wd/hub"
},
"4.0": {
"image": "selenoid/vnc:firefox_4.0",
"port": "4444",
"path": "/wd/hub"
},
"3.6": {
"image": "selenoid/vnc:firefox_3.6",
"port": "4444",
"path": "/wd/hub"
}
}
},
"chrome": {
"default": "60.0",
"versions": {
"60.0": {
"image": "selenoid/vnc:chrome_60.0",
"port": "4444"
},
"59.0": {
"image": "selenoid/vnc:chrome_59.0",
"port": "4444"
},
"58.0": {
"image": "selenoid/vnc:chrome_58.0",
"port": "4444"
},
"57.0": {
"image": "selenoid/vnc:chrome_57.0",
"port": "4444"
},
"56.0": {
"image": "selenoid/vnc:chrome_56.0",
"port": "4444"
},
"55.0": {
"image": "selenoid/vnc:chrome_55.0",
"port": "4444"
},
"54.0": {
"image": "selenoid/vnc:chrome_54.0",
"port": "4444"
},
"53.0": {
"image": "selenoid/vnc:chrome_53.0",
"port": "4444"
},
"52.0": {
"image": "selenoid/vnc:chrome_52.0",
"port": "4444"
},
"51.0": {
"image": "selenoid/vnc:chrome_51.0",
"port": "4444"
},
"50.0": {
"image": "selenoid/vnc:chrome_50.0",
"port": "4444"
},
"49.0": {
"image": "selenoid/vnc:chrome_49.0",
"port": "4444"
},
"48.0": {
"image": "selenoid/vnc:chrome_48.0",
"port": "4444"
}
}
},
"opera": {
"default": "47.0",
"versions": {
"47.0": {
"image": "selenoid/vnc:opera_47.0",
"port": "4444"
},
"46.0": {
"image": "selenoid/vnc:opera_46.0",
"port": "4444"
},
"45.0": {
"image": "selenoid/vnc:opera_45.0",
"port": "4444"
},
"44.0": {
"image": "selenoid/vnc:opera_44.0",
"port": "4444"
},
"43.0": {
"image": "selenoid/vnc:opera_43.0",
"port": "4444"
},
"42.0": {
"image": "selenoid/vnc:opera_42.0",
"port": "4444"
},
"41.0": {
"image": "selenoid/vnc:opera_41.0",
"port": "4444"
},
"40.0": {
"image": "selenoid/vnc:opera_40.0",
"port": "4444"
},
"39.0": {
"image": "selenoid/vnc:opera_39.0",
"port": "4444"
},
"38.0": {
"image": "selenoid/vnc:opera_38.0",
"port": "4444"
},
"37.0": {
"image": "selenoid/vnc:opera_37.0",
"port": "4444"
},
"36.0": {
"image": "selenoid/vnc:opera_36.0",
"port": "4444"
},
"35.0": {
"image": "selenoid/vnc:opera_35.0",
"port": "4444"
},
"34.0": {
"image": "selenoid/vnc:opera_34.0",
"port": "4444"
},
"33.0": {
"image": "selenoid/vnc:opera_33.0",
"port": "4444"
},
"12.1": {
"image": "selenoid/vnc:opera_12.1",
"port": "4444",
"path": "/wd/hub"
}
}
}
}
moon.yaml file contentskind: Service
apiVersion: v1
metadata:
name: moon
spec:
selector:
app: moon
ports:
- protocol: TCP
port: 4444
type: NodePort
---
apiVersion: apps/v1beta1
kind: Deployment
metadata:
name: moon
spec:
replicas: 3
template:
metadata:
labels:
app: moon
spec:
containers:
- name: moon
image: registry.aerokube.com/moon/moon:1.0.0
ports:
- containerPort: 4444
volumeMounts:
- name: quota
mountPath: /quota
volumes:
- name: quota
configMap:
name: quota
moon-api.yaml file contentskind: Service
apiVersion: v1
metadata:
name: moon-api
spec:
selector:
app: moon-api
ports:
- protocol: TCP
port: 8080
type: NodePort
---
apiVersion: apps/v1beta1
kind: Deployment
metadata:
name: moon-api
spec:
replicas: 1
template:
metadata:
labels:
app: moon-api
spec:
containers:
- name: moon-api
image: registry.aerokube.com/moon/moon-api:1.0.0
ports:
- containerPort: 8080
volumeMounts:
- name: quota
mountPath: /quota
volumes:
- name: quota
configMap:
name: quota