Dekorate: Gerando manifests Kubernetes e OpenShift para projetos Java

O Dekorate, anteriormente conhecido como ap4k que significa annotation processors for Kubernetes, é projetado para tornar simples a geração de manifests para Kubernetes e OpenShift em projetos baseados em Java. O projeto foi renomeado já que o mesmo suporta a geração de manifests sem o uso de anotações, logo o nome ap4k não faz mais sentido para o projeto.
O Dekorate é uma coleção de geradores e decorators em tempo de compilação Java para manifests Kubernetes e OpenShift. Os desenvolvedores não precisam mais editar nenhum XML, JSON ou YAML para customizar os manifests.
Com o Dekorate os desenvolvedores podem gerar ou customizar manifests usando processamento de anotações, arquivos de propriedades de configuração (application.properties), ou ambos. O Dekorate suporta o Kubernetes, OpenShift, Knative, Tekton, Prometheus, Jaeger, Service Catalog, e Halkyon CRD. Além disso, o Dekorate integra com frameworks como o Spring Boot, Quarkus, Thorntail, e também fornece uma ferramenta para projetos Java genéricos que permite que qualquer projeto que use maven, gradle, sbt, e bazel gere os manifests.
Vamos explorar como o Dekorate se integra à uma aplicação Quarkus.
O Quarkus já possui uma extensão Kubernetes que internamente usa o Dekorate para gerar e customizar manifests para o Kubernetes, OpenShift e Knative. Essa extensão permite implantar uma aplicação Quarkus em um cluster Kubernetes aplicando os manifests gerados, ou mesmo criar uma imagem de container e enviar a mesma para um registry antes de implantar a aplicação.
Para adicionar a extensão, basta executar no terminal:
mvn quarkus:add-extension -Dextensions="io.quarkus:quarkus-kubernetes"
Após o término da compilação, os manifests gerados estarão disponíveis em: target/kubernetes/.
O arquivo kubernetes.json será parecido com:
{"apiVersion" : "v1","kind" : "ServiceAccount","metadata" : {"annotations" : {"app.quarkus.io/vcs-url" : "<>","app.quarkus.io/build-timestamp" : "2020-06-04 - 05:13:57 +0000","app.quarkus.io/commit-id" : "<>"},"labels" : {"app.kubernetes.io/name" : "decorate","app.kubernetes.io/version" : "1.0.0-SNAPSHOT"},"name" : "decorate"}}
Até o momento, essa extensão manipula coisas como portas e health checks, sem que seja necessário nenhuma configuração do usuário.
Para uma aplicação Spring Boot, existem dois starters disponíveis, io.dekorate:kubernetes-spring-starter:1.0.0 para o Kubernetes, e io.dekorate:openshift-spring-starter:1.0.0 para o OpenShift.
No Spring Boot, é possível ignorar as anotações fazendo uso de recursos já existentes no framework. Para customizar os manifests gerados, é possível adicionar propriedades do Dekorate no application.yml/application.properties, ou ainda usar anotações junto com o application.yml/application.properties. Por padrão, as configurações definidas nos arquivos de propriedades tem prioridade sobre as configurações definidas via annotation.
Abaixo temos a ordem de prioridade das configurações do Dekorate:
Annotations;
application.properties;
application.yaml;
application.yml;
application-kubernetes.properties;
application-kubernetes.yaml;
application-kubernetes.yml.
Para uma aplicação Thorntail, existem dois starters disponíveis, io.dekorate:kubernetes-thorntail-starter:jar:1.0.0 para o Kubernetes, e io.dekorate:openshift-thorntail-starter:jar:1.0.0 para o OpenShift.
A partir desses starters, é possível usar as anotações do Dekorate, tais como @KubernetesApplication, @OpenShiftApplication, etc.
Para gerar os manifests do Kubernetes para uma aplicação Java genérica, basta adicionar a dependência io.dekorate:kubernetes-annotations:jar:1.0.0 para o Kubernetes, e io.dekorate:openshit-annotations:jar:1.0.0 para o OpenShift.
Então adicionar a anotação @Dekorate, ou @KubernetesApplication, em uma das classes Java.
import io.dekorate.kubernetes.annotation.KubernetesApplication;
@KubernetesApplication
public class Main {public static void main(String[] args) {}}
Após a execução de mvn clean package os manifests estarão disponíveis sob target/classes/META-INF/dekorate.
O kubernetes.yml será parecido com:
apiVersion: "apps/v1"
kind: "Deployment"
metadata:
name: "kubernetes-example"
spec:
replicas: 1
selector:
matchLabels:
app.kubernetes.io/name: "my-gradle-app"
app.kubernetes.io/version: "1.0-SNAPSHOT"
template:
metadata:
labels:
app.kubernetes.io/name: "my-gradle-app"
app.kubernetes.io/version: "1.0-SNAPSHOT"
spec:
containers:- env:- name: "KUBERNETES_NAMESPACE"
valueFrom:
fieldRef:
fieldPath: "metadata.namespace"
image: "default/my-gradle-app:1.0-SNAPSHOT"
imagePullPolicy: "IfNotPresent"
name: "my-gradle-app"
Para gerar os manifests do OpenShift para uma aplicação genérica Java, basta usar a anotação @Dekorate, ou @OpenshiftApplication, que funciona exatamente como a @KubernetesApplication, porém irá gerar o openshift.yml/openshift.json.
O Dekorate traz algumas funcionalidades adicionais além da geração de manifests. Essas funcionalidades incluem coisas como fazer o build, implantar, e testar.
O Dekorate permite que os usuários conectem ferramentas externas (por exemplo, docker ou oc) para acionar construções de imagem de container após o final da compilação, uma vez que o Dekorate não gera arquivos do Docker nem fornece suporte interno para executar construções do docker ou s2i.
Até o momento, como funcionalidade experimental temos o seguinte:
docker build hook (requer o binário do docker, habilitado com -Ddekorate.build=true);
docker push hook (requer o binário do docker, habilitado com -Ddekorate.push=true);
OpenShift s2i build hook (requer o binário do oc, acionado com -Ddekorate.deploy=true).
O Dekorate também traz extensões JUnit 5 para o Kubernetes e Openshift, que permite que os desenvolvedores executem testes de ponta a ponta. Até esse momento as funcionalidades suportadas são condições de ambiente, builds de container, aplicar os manifest gerados em um ambiente específico, e injetar testes com a aplicação/pod cliente.
Maiores detalhes, tais como todas as opções de configuração e exemplos de código (Spring Boot, Thorntail, Vertx, Istio), podem ser encontradas no repositório do GitHub.