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
-
kubectl
client 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_PASSWORD
andREGISTRY_EMAIL
placeholders 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
moon
andmoon-api
services. 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
moon
service like you do with regular Selenium:http://192.168.99.100:30979/wd/hub
-
Check that
moon-api
returns 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
moon
application 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-api
application containers. This API collects and returns various data about running browsers.moon-api
is usually exposed as Kubernetes service available on HTTP port (e.g.80
or8080
). -
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 usertest
to work properly you should createtest.json
file. -
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