microfrontends-controller
This repository is a (GO) re-implementation of the [Kubernetes Controller] pattern over custom resources specifying front-end web components to be dynamically integrated into a user interface application shell, using operator-sdk. It is heavily inspired by https://github.com/milung/ufe-controller. The project is of educational nature.
This is an experimental concept design of micro-frontends architecture, considering declarative definition of micro-frontends as part of the Kubernetes API custom resource definitions, and leveraging the web components technology. This enables us to approach the development of particular micro-frontends in a similar way as is done with the development of cloud-native microservices.
Description
The original ufe-controller was implemented in Prolog using the Kubernetes (k8s) client to read the Custom Resources (CRs) called web components. It then aggregates the CRs to a frontend config structure which is then served via a REST endpoint. This config is then used to inject the web components to a frontend application container.
The aim of this project is to use operator-sdk and Golang to recreate what was done in the ufe-controller. It was created as a learning experience to understand how the k8s operators work and how to implement one.
There are two main components in the application: WebComponentController and an API server serving the fe-config.
WebComponentController is reconciling the WebComponent CRs. Currently, it is applying the following logic on a WebComponent:
- Check if the WebComponent still exists.
- If WebComponent does not contain finalizers it adds one so that the controller does its cleanup before the k8s removes the WebComponent.
- It converts the WebComponent to internal MicroFrontendConfig model which in turn is converted to TransferObject and stored in memory to be served through the fe-config endpoint.
- If WebComponent is set to be deleted it removes it also from the in-memory storage so it is no longer a part of fe-config response.
The API server simply takes the last snapshot of the in-memory storage and returns it to the frontend.
Example Front End using the WebComponents
The original repo of ufe-controller contained both backend and an sample web ui. For this project we decided to separate UI and backend into two separate projects. The UI sample using this backend is located here: https://github.com/SevcikMichal/microfrontends-webui
Configuration
You can use environment variables to configure the following parameters:
Env. Variable |
Default Value |
Description |
BASE_URL |
/ |
Base URL of the server, all absolute links are prefixed with this address |
OBSERVE_NAMESPACES |
|
Comma separated list of namespaces in which to look for webcomponents to be served by this instance |
USER_ID_HEADER |
x-forwarded-email |
incomming request`s header name (lowercase) specifying the user identifier, typically email |
USER_NAME_HEADER |
x-forwarded-user |
incomming request`s header name (lowercase) specifying the user name |
USER_ROLES_HEADER |
x-forwarded-groups |
incomming request`s header name (lowercase) specifying the list of user roles (or groups) |
HTTP_PORT |
80 |
port on which the HTTP server listens |
SW_VERSION |
v1 |
Version of the service worker, used to force the browser to update the service worker |
SW_SKIP_FETCH |
|
Comma separated list of regular expressions against request paths which should not be fetched by the service worker. All paths that contains /api/ string, or requests to other domains are implicitly skipped reagrdless of this setting. All other requests, including requests toward web components are served with cache-first startegy |
PASS_THROUGH_SERVER |
http://localhost:8082 |
Address to which everything that cannot be served by this server will be passed on. This is typically the address of the frontend application shell. |
Getting Started
You’ll need a Kubernetes cluster to run against. You can use KIND to get a local cluster for testing, or run against a remote cluster.
Your controller will automatically use the current context in your kubeconfig file (i.e. whatever cluster kubectl cluster-info
shows).
Controller is currently expecting ingess-nginx to be installed in the cluster. This is used to create the ingress for the controller. If you have different ingress controller you can modify the controller to use that one in config/manager/ingress.yaml.
Running locally
This will still require a cluster where the CRs will be stored only the processing part will run from your code. Allowing debuging etc.
- Install CRD into your local cluster
kubectl apply -k config/crd
- Install Instances of Custom Resources:
kubectl apply -k config/samples/
- Or if you want to test the namespace observation you can apply namespaced version of the samples:
kubect apply -k config/samples/namespaced
-
Run a debug session using included debug configurations in .vscode/launch.json
there is one for observing all namespaces and one where you can limit the observed namespaces.
-
Call localhost:<port-default-80>\fe-config
to get the MicroFrontendConfigurations created from the CRs.
Delete CRs
To delete the CRs from the cluster and see the delete logic in the controller:
kubectl delete -k config/samples
or if you used the namespaced sample:
kubectl delete -k config/samples/namespaced
Uninstall CRDs
To delete the CRDs from the cluster:
kubectl delete -k config/crd
Running on the cluster
. Install CRD into your local cluster
kubectl apply -k config/crd
- Install Instances of Custom Resources:
kubectl apply -k config/samples/
- Or if you want to test the namespace observation you can apply namespaced version of the samples:
kubect apply -k config/samples/namespaced
- Build and push your image to the location specified by
IMG
:
make docker-build docker-push IMG=<some-registry>/microfrontends-controller:tag
- Deploy the controller to the cluster with the image specified by
IMG
:
make deploy IMG=<some-registry>/microfrontends-controller:tag
Uninstall CRDs
To delete the CRDs from the cluster:
make uninstall
Undeploy controller
UnDeploy the controller from the cluster:
make undeploy
How it works
This project aims to follow the Kubernetes Operator pattern.
It uses Controllers,
which provide a reconcile function responsible for synchronizing resources until the desired state is reached on the cluster.
Modifying the API definitions
If you are editing the API definitions, generate the manifests such as CRs or CRDs using:
make manifests
NOTE: Run make --help
for more information on all potential make
targets
More information can be found via the Kubebuilder Documentation
License
Copyright 2023.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.