0% found this document useful (0 votes)
17 views3 pages

Kubernetes Java Operators Cheatsheet2

This cheat sheet describes how to create a Kubernetes operator in Java using Quarkus that watches for Pizza custom resources. It involves: 1. Defining a CRD for the Pizza resource and example resource. 2. Creating Java classes to parse the Pizza resource specification and status. 3. Registering the CRD and creating clients to interact with Kubernetes and custom resources. 4. Implementing the operator logic to create a pod running the pizza-maker image when a Pizza resource is observed.

Uploaded by

Aa
Copyright
© © All Rights Reserved
Available Formats
Download as PDF, TXT or read online on Scribd
Download as pdf or txt
0% found this document useful (0 votes)
17 views3 pages

Kubernetes Java Operators Cheatsheet2

This cheat sheet describes how to create a Kubernetes operator in Java using Quarkus that watches for Pizza custom resources. It involves: 1. Defining a CRD for the Pizza resource and example resource. 2. Creating Java classes to parse the Pizza resource specification and status. 3. Registering the CRD and creating clients to interact with Kubernetes and custom resources. 4. Implementing the operator logic to create a pod running the pizza-maker image when a Pizza resource is observed.

Uploaded by

Aa
Copyright
© © All Rights Reserved
Available Formats
Download as PDF, TXT or read online on Scribd
Download as pdf or txt
Download as pdf or txt
You are on page 1/ 3

CHEAT SHEET

Writing a Kubernetes Operator in Java

This cheat sheet covers how to create a Kubernetes Operator in Java using Quarkus.
mvn "io.quarkus:quarkus-maven-plugin:1.4.0.Final:create" \
-DprojectGroupId="org.acme" \
-DprojectArtifactId="pizza-operator" \
-DprojectVersion="1.0-SNAPSHOT" \
-Dextensions="kubernetes, kubernetes-client" \

Tip You can generate the project in https://code.quarkus.io/ and selecting kubernetes and kubernetes-client extensions.

@JsonProperty("sauce")
DEFINING THE CRD private String sauce;
// getters/setters
First, you need to create a CRD de ning the custom resource: }
apiVersion: apiextensions.k8s.io/v1beta1 @JsonDeserialize
kind: CustomResourceDefinition public class PizzaResourceStatus {}
metadata: @JsonDeserialize
name: pizzas.mykubernetes.acme.org public class PizzaResource extends CustomResource {
labels: private PizzaResourceSpec spec;
app: pizzamaker private PizzaResourceStatus status;
mylabel: stuff // getters/setters
spec: }
group: mykubernetes.acme.org @JsonSerialize
scope: Namespaced public class PizzaResourceList extends
version: v1beta2 CustomResourceList<PizzaResource> {}
names:
kind: Pizza public class PizzaResourceDoneable extends
listKind: PizzaList CustomResourceDoneable<PizzaResource> {
plural: pizzas public PizzaResourceDoneable(PizzaResource resource,
singular: pizza Function<PizzaResource, PizzaResource>
shortNames: function)
- pz { super(resource, function);}
}
An example of a pizza resource:
apiVersion: mykubernetes.acme.org/v1beta2
kind: Pizza Registering the CRD in Kubernetes Client
metadata:
public class KubernetesClientProducer {
name: alexmeats
spec:
@Produces
toppings:
@Singleton
- mozzarella
@Named("namespace")
- pepperoni
String findMyCurrentNamespace() throws
- sausage
IOException {
- bacon
return new
sauce: extra
String(Files.readAllBytes(Paths.get("/
var/run/secrets/kubernetes.io/
DEFINING THE JAVA CODE serviceaccount/namespace")));
}
@Produces
Parsing of the pizza resource
@Singleton
KubernetesClient
You need to create a parser for reading the content of pizza resource.
makeDefaultClient(@Named("namespace") String
@JsonDeserialize namespace) {
public class PizzaResourceSpec { return new
@JsonProperty("toppings") DefaultKubernetesClient().inNamespace(namespace);
private List<String> toppings = new ArrayList<>(); }

some task with / description of what that would do


Build here. Go any where. developers.redhat.com | @RHdevelopers 1
CHEAT SHEET

@Produces final ContainerBuilder containerBuilder =


@Singleton new ContainerBuilder().withName("pizza-
MixedOperation<PizzaResource, PizzaResourceList, maker")
PizzaResourceDoneable, Resource<PizzaResource, .withImage("quay.io/lordofthejars/
PizzaResourceDoneable>> pizza-maker:1.0.0").withCommand("/work/
application")
makeCustomHelloResourceClient(KubernetesClient .withArgs("--sauce=" + sauce, "--
defaultClient) { toppings=" + String.join(",",toppings));

KubernetesDeserializer.registerCustomKind("mykuberne final PodSpecBuilder podSpecBuilder = new


tes.acme.org/v1beta2", "Pizza", PodSpecBuilder().withContainers
PizzaResource.class); (containerBuilder.build())
CustomResourceDefinition crd = .withRestartPolicy("Never");
defaultClient.customResourceDefinitions().
list().getItems().stream().findFirst() final PodBuilder podBuilder = new
.orElseThrow(RuntimeException::new); PodBuilder().withMetadata
return defaultClient.customResources(crd, (objectMetaBuilder.build())
PizzaResource.class, PizzaResourceList.class, .withSpec(podSpecBuilder.build());
PizzaResourceDoneable.class);
} final Pod pod = podBuilder.build();
} defaultClient.resource(pod)
.createOrReplace();
}
Implement the Operator
}

Operator is the logic that is executed when the custom resource (pizza) is
@Override
applied. In this case, a pod is instantiated with pizza-maker image. public void onClose(KubernetesClientException e)
public class PizzaResourceWatcher { {
}
@Inject });
KubernetesClient defaultClient; }
}
@Inject
MixedOperation<PizzaResource, PizzaResourceList,
Deploy Operator
PizzaResourceDoneable, Resource<PizzaResource,
PizzaResourceDoneable>> crClient;
You need to package and create a container with all the operator code and
deploy it to the cluster.
void onStartup(@Observes StartupEvent event) {
apiVersion: rbac.authorization.k8s.io/v1
crClient.watch(new Watcher<PizzaResource>() { kind: ClusterRole
@Override metadata:
public void eventReceived(Action action, name: quarkus-operator-example
PizzaResource resource) { rules:
if (action == Action.ADDED) { - apiGroups:
final String app = resource.getMetadata() - ''
.getName(); resources:
final String sauce = resource.getSpec() - pods
.getSauce(); verbs:
final List<Stri ng> toppings = - get
resource.getSpec().getToppings(); - list
- watch
final Map<String, String> labels = new - create
HashMap<>();labels.put("app", app); - update
- delete
final ObjectMetaBuilder objectMetaBuilder = - patch
new ObjectMetaBuilder().withName(app + "- - apiGroups:
pod") - apiextensions.k8s.io
.withNamespace(resource.getMetadata() resources:
.getNamespace()).withLabels(labels); - customresourcedefinitions
verbs:
- list

Build here. Go any where. developers.redhat.com | @RHdevelopers 2


CHEAT SHEET

- watch
---
apiVersion: v1
kind: ServiceAccount
metadata:
name: quarkus-operator-example
---
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRoleBinding
metadata:
name: quarkus-operator-example
subjects:
- kind: ServiceAccount
name: quarkus-operator-example
namespace: default
roleRef:
kind: ClusterRole
name: quarkus-operator-example
apiGroup: rbac.authorization.k8s.io
---
apiVersion: apps/v1
kind: Deployment
metadata:
name: quarkus-operator-example
spec:
selector:
matchLabels:
app: quarkus-operator-example
replicas: 1
template:
metadata:
labels:
app: quarkus-operator-example
spec:
serviceAccountName: quarkus-operator-example
containers:
- image: quay.io/lordofthejars/pizza-operator:1.0.0
name: quarkus-operator-example
imagePullPolicy: IfNotPresent

Run the kubectl apply -f pizza-crd.yaml command to register the CRD


in the cluster. Run the kubectl apply -f deploy.yaml command to
register the operator.

Running the example

Apply the custom resource by running: kubectl apply -f meat-pizza.yaml


and check the output of kubectl get pods command.

Author Alex Soto


Java Champion, Working at Red Hat

Build here. Go any where. developers.redhat.com | @RHdevelopers 2

You might also like