Light Dark Auto

Deploy a Mesh

Deploy a mesh using the operator


Clone the GitHub repo

Clone the operator from

Generate Kubernetes Manifests

Kubernetes manifests are templated in pkg/cuemodule. The CUE CLI must be invoked from this directory.

cd pkg/cuemodule/core
cue eval -c ./k8s/outputs --out text -e operator_manifests_yaml > manifests.yaml

The manifests were generated with default options. If you'd like to use these options jump to Install the Mesh, or continue with customization.



  • spire(Boolean) - Toggle SPIRE for mTLS across the data plane.
  • auto_apply_mesh(Boolean) - Toggle auto-apply of the mesh CRD, this can be used to modify configuration before creating the mesh
  • openshift - Toggle Openshift-specific presets including SCCs for permissioning.

Manual modification

Directly modify manifests.yaml. For example, you can set options in the overrides-cue ConfigMap.

kind: ConfigMap
  overrides.cue: |-
    package only

    config: {
      spire: false
      auto_apply_mesh: true


You can customize the manifests, at creation time, by passing -t tags to cue eval. Multiple tags can be used at the same time.

cue eval -c ./k8s/outputs --out text -e operator_manifests_yaml -t <tag-field>=<tag-value>

For example, if you wanted SPIRE and to disable automatic mesh creation, do the following.

cue eval -c ./k8s/outputs --out text -e operator_manifests_yaml -t spire=true -t auto_apply_mesh=false > manifests.yaml

Install the Mesh

kubectl apply -f manifests.yaml

You should see the following resources created in your cluster.

  • A mesh CRD, registered in the Kubernetes API for creating a mesh
  • A gm-operator namespace where the operator's StatefulSet and resulting pods will live
  • A gm-operator StatefulSet and accompanying overrides-cue ConfigMap
  • A gm-webhook Service and necessary mutating and validating webhook configurations
  • Additional RBAC roles, bindings, and service accounts used by the operator

Create the Container Registry Secret

After applying the generated installation manifests, you must also create a secret containing your Grey Matter Docker Registry credentials. This will allow the operator to pull container images for deploying core Grey Matter services.

kubectl create secret docker-registry gm-docker-secret \ \
  -n gm-operator

If the operator pod is in a CrashLoopBackoff state, you may need to delete the pod so a new pod can use the newly created secret.

kubectl delete pod gm-operator-0 -n gm-operator

Verify mesh installation

List the core Grey Matter pods.

kubectl get pods -n greymatter
NAME                            READY   STATUS    RESTARTS   AGE
catalog-8699dfbf6b-tlc6k        2/2     Running   0          2m
controlensemble-0               3/3     Running   1          2m
dashboard-658d46b98d-9nl8s      2/2     Running   0          2m
edge-54df68bbb8-nbntv           1/1     Running   0          2m
redis-0                         2/2     Running   0          2m

During the initialization process, the Grey Matter control plane networks the data plane for its own internal communication. It will take 1-2 minutes for all core components to initialize.

Access the Grey Matter application

The operator creates a LoadBalancer Service for access to the Grey Matter application.

Get the external IP of the service.

kubectl get service edge -n greymatter
NAME   TYPE           CLUSTER-IP     EXTERNAL-IP     PORT(S)                 AGE
edge   LoadBalancer   {cluster-ip}   {external-ip}   10808:{node-port}/TCP   2m

The Grey Matter application will be accessible from http://{external-ip}:10808.

Next Steps