2

In Kubernetes CustomResourceDefinitions (CRDs), we can specify additionalPrinterColumns, which (for example) are used for kubectl get with a CRD. The value for a column is usually extracted from the status of a CRD using a jsonPath. From the Kubernetes docs, we can also see that timestamps are rendered in a user friendly way (e.g., 5m or 2h, representing the duration from this timestamp to now):

additionalPrinterColumns:
  - name: Duration
    type: date
    jsonPath: .status.completitionTimestamp

The Kubernetes Job resource is an example for a resource, which does not only show since when it exists, but also for long it was running:

NAME               COMPLETIONS   DURATION   AGE
hello-4111706356   0/1                      0s
hello-4111706356   0/1           0s         0s
hello-4111706356   1/1           5s         5s

I'm looking for building something similar for my CRD, that is: Showing the duration between two timestamps in the same way. More specific, I would like to get the duration between two status fields such as .status.startTimestamp and .status.completitionTimestamp evaluated and formatted by Kubernetes.

As exactly the same thing is done in the Job resource, I'm wondering if this is somehow possible or if this is special behavior built into kubectl?

Wytrzymały Wiktor
  • 11,492
  • 5
  • 29
  • 37
Sören Henning
  • 326
  • 4
  • 16
  • So now I can only answer partially: this is a `kubectl` behaviour. You can check it by `kubectl proxy --port=8080 &` and then get the details about job directly `curl localhost:8080/apis/batch/v1/namespaces/default/jobs/pi`. There are both fields you have mentioned. I will try to find more details how exactly it happens. By the way, which version of `kubectl` are you going to use? – moonkotte Jan 05 '22 at 15:18
  • @SörenHenning. So I was wrong about first comment, please find an answer below. – moonkotte Jan 12 '22 at 15:02

1 Answers1

1

I will answer on your question partially so you have some understanding and ideas on what/how/where.


kubectl get

When kubectl get jobs is executed, kubernetes API server decides which fields to provide in response:

The kubectl tool relies on server-side output formatting. Your cluster's API server decides which columns are shown by the kubectl get command

See here.

Duration field for jobs is also calculated on the server's side. This happens because job is a well-known resource for kubernetes server and it's built into the code "How to print the response". See JobDuration - printer.

This also can be checked by running regular command:

kubectl get job job-name --v=8

And then using server-print flag set to false (default is true for human-readable reasons):

kubectl get job job-name --v=8 --server-print=false

With last command only general information will be returned and name and age will be shown in output.


What can be done

Let's start with CRDs and controllers:

On their own, custom resources let you store and retrieve structured data. When you combine a custom resource with a custom controller, custom resources provide a true declarative API.

The Kubernetes declarative API enforces a separation of responsibilities. You declare the desired state of your resource. The Kubernetes controller keeps the current state of Kubernetes objects in sync with your declared desired state. This is in contrast to an imperative API, where you instruct a server what to do.

Moving forward to feature gates. We're interested in CustomResourceSubresources:

Enable /status and /scale subresources on resources created from CustomResourceDefinition.

This feature gate is enabled by default starting from kubernetes 1.16.

Therefore custom field like duration-execution could be created within CRD subresource's status and custom controller could update the value of the given field whenever the value is changed using watch update funtion.

Part 2

There's a controller prunning that should be taken into consideration:

By default, all unspecified fields for a custom resource, across all versions, are pruned. It is possible though to opt-out of that for specific sub-trees of fields by adding x-kubernetes-preserve-unknown-fields: true in the structural OpenAPI v3 validation schema.

Here's a very similar answer about custom field and additionalPrinterColumns.

moonkotte
  • 3,661
  • 2
  • 10
  • 25
  • Thank you very much for the detailed explanation and your suggested workarounds! Needed some time to read through this and the provided links. Especially the linked SO answer was really helpful. – Sören Henning Jan 14 '22 at 15:21
  • Just to be clear: With `watch update funtion` you mean something like a custom controller, which `watch`es for changes of the CR and updates the state and nothing which runs on the server side, right? – Sören Henning Jan 14 '22 at 15:25
  • @SörenHenning Sorry for delayed answer. If this is a controller, I'd say it's already meant by server-side. If this is an [operator](https://kubernetes.io/docs/concepts/extend-kubernetes/operator/), then it's not server-side. It depends on actual implementation and architecture. – moonkotte Jan 18 '22 at 10:36