Skip to content
Kubernetes Operator able to simplify the deployment of an application (Spring Boot, ...) using a Custom Resource - Component
Go Shell Makefile Dockerfile
Branch: master
Clone or download
Fetching latest commit…
Cannot retrieve the latest commit at this time.
Type Name Latest commit message Commit time
Failed to load latest commit information.
.circleci Bump to version tested which is v0.5.1 Aug 16, 2019
build chore: update Dockerfile Aug 14, 2019
cmd/manager chore: use package Aug 14, 2019
demo fix: update descriptor name Aug 14, 2019
deploy chore: more deploy update Aug 14, 2019
examples Remove double quotes Aug 15, 2019
img Update image of the operator bundle Apr 5, 2019
pkg Add missing contextPath to s2i generate step. Otherwise all the reosu… Aug 16, 2019
scripts chore: use package Aug 14, 2019
test chore: use package Aug 14, 2019
.gitignore chore: mark outdated documentation as deprecated Aug 14, 2019
Makefile chore: more deploy update Aug 14, 2019 fix: typos Jun 6, 2019
go.mod chore: use package Aug 14, 2019
go.sum chore: use package Aug 14, 2019

Halkyon Operator


Table of Contents


Deploying modern micro-services applications that utilize the 12-factor guidelines to Kubernetes is difficult, mainly due to the host of different and complex Kubernetes Resources involved. In such scenarios developer experience becomes very important.

This projects aims to tackle said complexity and vastly simplify the process of deploying micro-service applications to Kubernetes.

By providing several, easy-to-use Kubernetes Custom Resources - CR and an Operator to handle them, the Halkyon project provides the following features:

  • Install micro-services (components in Halkyon's parlance) utilizing runtimes such as Spring Boot, Vert.x, Thorntail, Quarkus or Nodejs, serving as base building blocks for your application
  • Manage the relations between the different components of the using a link CR allowing one micro-service for example to consume a REST endpoint provided by another
  • Deploy various infrastructure services like a database which are bound to a component via the capability CR.

Custom resources contains metadata about the framework/language to be used to either:

  • Configure the strategy that we want to adopt to deploy the application: Development mode or Building/Prod mode
  • Select the container image to be used to launch the application: java for Spring Boot, Eclipse Vert.x, Thorntail; node for nodejs
  • Configure the component in order to inject env var, secret, ...
  • Create a service or capability such as database

To add a micro-service to your application is, if a URL should be created to access it from outside of the cluster or simply to specify some ENV vars to be used by the container's image when the pod is created, then create a component.yaml file such as the following:

kind: Component
  name: spring-boot-demo
  # Strategy used by the operator to install the Kubernetes resources using :
  # 1) the Dev mode where we can push the uber jar file of the microservices
  # compiled locally or 
  # 2) Build Mode where we want to delegate to the operator the responsibility
  # to build the code from the git repository and to push to a local
  # docker registry the image
  deploymentMode: dev
  # Runtime type that the operator will map with a docker image (java, nodejs, ...)
  runtime: spring-boot
  version: 2.1.16
  # To been able to create a Kubernetes Ingress resource or OpenShift Route
  exposeService: true
    value: openshift-catalog


  • The Halkyon Operator runs top of Kubernetes >= 1.13 or OpenShift >= 3.11.
  • You can find more information about the Custom Resources and their fields under this folder pkg/apis/component/v1alpha2 like also the others CRs supported : link and capability


In order to use the Halkyon Operator and the CRs, it is needed to install Tekton Pipelines and KubeDB Operators. We assume that you have installed a K8s cluster as of starting from Kubernetes version 1.13.

Local cluster using Minikube

Install using Homebrew on macOS the following software:

brew cask install minikube
brew install kubernetes-cli
brew install kubernetes-helm

Next, create a Kubernetes cluster where ingress and dashboard addons are enabled

minikube config set vm-driver virtualbox
minikube config set cpus 4
minikube config set kubernetes-version v1.14.0
minikube config set memory 6000
minikube addons enable ingress
minikube addons enable dashboard
minikube addons enable registry
minikube start

When minikube has started, initialize Helm to install on the cluster Tiller

helm init
until kubectl get pods -n kube-system -l name=tiller | grep 1/1; do sleep 1; done
kubectl create clusterrolebinding tiller-cluster-admin --clusterrole=cluster-admin --serviceaccount=kube-system:default

Next, edit the /etc/hosts file of minikube vm in order to specify the IP address of the docker registry daemon as the docker client, when it will fetch from the docker registry images pushed, will use name kube-registry.kube-system to call the docker server

kc get svc/registry -n kube-system -o jsonpath={.spec.clusterIP}
minikube ssh
echo '<IP_ADDRESS> kube-registry.kube-system kube-registry.kube-system.svc kube-registry.kube-system.svc.cluster.local' | sudo tee -a /etc/hosts

Install Tekton Pipelines technology

kubectl apply -f

Install the KubeDB operator and its PostgreSQL catalog supporting different database versions

helm repo add appscode
helm repo update
helm install appscode/kubedb --name kubedb-operator --version ${KUBEDB_VERSION} \
  --namespace kubedb --set apiserver.enableValidatingWebhook=false,apiserver.enableMutatingWebhook=false

Wait till the Operator has started before to install the Catalog

until kubectl get crd || [[ ${TIMER} -eq 60 ]]; do
  sleep 5
  TIMER=$((TIMER + 1))

Install the PostgreSQL catalog.

helm install appscode/kubedb-catalog --name kubedb-catalog --version ${KUBEDB_VERSION} \
  --namespace kubedb --set catalog.postgres=true,catalog.elasticsearch=false,catalog.etcd=false,catalog.memcached=false,catalog.mongo=false,catalog.mysql=false,catalog.redis=false

Installation of the Halkyon Operator

Deploy the Cluster Role, Role Binding, CRDs, ServiceAccount and Operator within the namespace operators

kubectl create ns operators
kubectl apply -n operators -f deploy/sa.yaml
kubectl apply -f deploy/cluster-role.yaml
kubectl apply -f deploy/user-rbac.yaml
kubectl apply -f deploy/cluster-role-binding.yaml
kubectl apply -f deploy/crds/capability.yaml
kubectl apply -f deploy/crds/component.yaml
kubectl apply -f deploy/crds/link.yaml
kubectl apply -n operators -f deploy/operator.yaml

Wait till the Operator's pod is ready and running before to continue

until kubectl get pods -n operators -l name=halkyon-operator | grep 1/1; do sleep 1; done

Control if the operator is running correctly

pod_id=$(kubectl get pods -n operators -l name=halkyon-operator -o=name)
kubectl logs $pod_id -n operators

Enjoy the Halkyon Operator!

How to play with it

The process is pretty simple and is about creating a custom resource, one by micro-service or runtime to be deployed. So create first a demo namespace

kubectl create ns demo

and next create using your favorite editor, create a component resource with the following information:

kind: Component
  name: spring-boot
  runtime: spring-boot
  deploymentMode: dev

Deploy it

kubectl apply -n demo -f my-component.yaml

Verify if the component has been well created by executing the following kubectl command

kubectl get components -n demo
NAME          RUNTIME       VERSION   AGE   MODE   STATUS    MESSAGE                                                            REVISION
spring-boot   spring-boot             14s   dev    Pending   pod is not ready for component 'spring-boot' in namespace 'demo'                        

Remark Don't worry about the status which is reported the first time as downloading the first time the needed images from external docker registry could take time !

kubectl get components -n demo   
spring-boot   spring-boot             2m19s   dev    Ready              

When, the Halkyon operator will read the content of the Custom Resource Component, then it will create several K8s resources that you can discover if you execute the following command

kubectl get pods,services,deployments,pvc -n demo
NAME                              READY   STATUS    RESTARTS   AGE
pod/spring-boot-6d9475f4c-c9w2z   1/1     Running   0          4m18s

NAME                  TYPE        CLUSTER-IP     EXTERNAL-IP   PORT(S)    AGE
service/spring-boot   ClusterIP   <none>        8080/TCP   4m18s

NAME                                READY   UP-TO-DATE   AVAILABLE   AGE
deployment.extensions/spring-boot   1/1     1            1           4m18s

NAME                                        STATUS   VOLUME                                     CAPACITY   ACCESS MODES   STORAGECLASS   AGE
persistentvolumeclaim/m2-data-spring-boot   Bound    pvc-dab00dfe-a2f6-11e9-98d1-08002798bb5f   1Gi        RWO            standard       4m18s

You can now cleanup the project as we will not deploy a Java micro-services or delegate the build to the Operator. So cleanup the project installed (component)

kubectl delete component --all -n demo 

A Real demo

To play with a real example and discover the different features currently supported, we have created within the directory demo a project containing 2 micro-services: a Spring Boot REST client calling a Service exposed by a Spring Boot backend application which access a postgresql database.

So jump here in order to see in action How we enhance the Developer Experience on Kubernetes ;-)

Cleanup the Operator resources

To clean the operator deployed on your favorite Kubernetes cluster, then execute the following kubectl commands:

kubectl delete -n operators -f deploy/sa.yaml
kubectl delete -f deploy/cluster-role.yaml
kubectl delete -f deploy/user-rbac.yaml
kubectl delete -f deploy/cluster-role-binding.yaml
kubectl delete -f deploy/crds/capability.yaml
kubectl delete -f deploy/crds/component.yaml
kubectl delete -f deploy/crds/link.yaml
kubectl delete -n operators -f deploy/operator.yaml
You can’t perform that action at this time.