<p>In Kubernetes <code>CustomResourceDefinitions</code> (CRDs), we can specify <code>additionalPrinterColumns</code>, which (for example) are used for <code>kubectl get</code> with a CRD. The value for a column is usually extracted from the status of a CRD using a <code>jsonPath</code>. From the <a href="https://kubernetes.io/docs/tasks/extend-kubernetes/custom-resources/custom-resource-definitions/#type" rel="nofollow noreferrer">Kubernetes docs</a>, we can also see that timestamps are rendered in a user friendly way (e.g., <em>5m</em> or <em>2h</em>, representing the duration from this timestamp to now):</p>
<pre class="lang-yaml prettyprint-override"><code>additionalPrinterColumns:
  - name: Duration
    type: date
    jsonPath: .status.completitionTimestamp
</code></pre>
<p>The Kubernetes <em>Job</em> resource is an example for a resource, which does not only show since when it exists, but also <a href="https://kubernetes.io/docs/tasks/job/automated-tasks-with-cron-jobs/" rel="nofollow noreferrer">for long it was running</a>:</p>
<pre><code>NAME               COMPLETIONS   DURATION   AGE
hello-4111706356   0/1                      0s
hello-4111706356   0/1           0s         0s
hello-4111706356   1/1           5s         5s
</code></pre>
<p>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 <code>.status.startTimestamp</code> and <code>.status.completitionTimestamp</code> evaluated and formatted by Kubernetes.</p>
<p>As exactly the same thing is done in the <em>Job</em> resource, I'm wondering if this is somehow possible or if this is special behavior built into <code>kubectl</code>?</p>

Sören Henning
<p>I will answer on your question partially so you have some understanding and ideas on what/how/where.</p>
<hr />
<p><strong>kubectl get</strong></p>
<p>When <code>kubectl get jobs</code> is executed, <code>kubernetes API server</code> decides which fields to provide in response:</p>
<blockquote>
<p>The <code>kubectl</code> tool relies on server-side output formatting. Your
cluster's API server decides which columns are shown by the <code>kubectl get</code> command</p>
</blockquote>
<p>See <a href="https://kubernetes.io/docs/tasks/extend-kubernetes/custom-resources/custom-resource-definitions/#additional-printer-columns" rel="nofollow noreferrer">here</a>.</p>
<p><code>Duration</code> field for <code>jobs</code> is also calculated on the server's side. This happens because <code>job</code> is a well-known resource for kubernetes server and it's built into the code &quot;How to print the response&quot;. See <a href="https://github.com/kubernetes/kubernetes/blob/d1a5513cb044ad805007cbea6327bdfb1cc73aab/pkg/printers/internalversion/printers.go#L1031-L1046" rel="nofollow noreferrer">JobDuration - printer</a>.</p>
<p>This also can be checked by running regular command:</p>
<pre><code>kubectl get job job-name --v=8
</code></pre>
<p>And then using <a href="https://kubernetes.io/docs/reference/kubectl/overview/#server-side-columns" rel="nofollow noreferrer"><code>server-print</code></a> flag set to <code>false</code> (default is <code>true</code> for human-readable reasons):</p>
<pre><code>kubectl get job job-name --v=8 --server-print=false
</code></pre>
<p>With last command only general information will be returned and <code>name</code> and <code>age</code> will be shown in output.</p>
<hr />
<p><strong>What can be done</strong></p>
<p>Let's start with <a href="https://kubernetes.io/docs/concepts/extend-kubernetes/api-extension/custom-resources/#custom-controllers" rel="nofollow noreferrer">CRDs and controllers</a>:</p>
<blockquote>
<p>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.</p>
<p>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.</p>
</blockquote>
<p>Moving forward to <a href="https://kubernetes.io/docs/reference/command-line-tools-reference/feature-gates/#feature-gates" rel="nofollow noreferrer"><code>feature gates</code></a>. We're interested in <code>CustomResourceSubresources</code>:</p>
<blockquote>
<p>Enable <code>/status</code> and <code>/scale</code> subresources on resources created from
<code>CustomResourceDefinition</code>.</p>
</blockquote>
<p>This <code>feature gate</code> is enabled by default starting from kubernetes <code>1.16</code>.</p>
<p>Therefore custom field like <code>duration-execution</code> could be created within CRD <code>subresource</code>'s status and custom controller could update the value of the given field whenever the value is changed using <code>watch update funtion</code>.</p>
<p><strong>Part 2</strong></p>
<p>There's a <a href="https://kubernetes.io/docs/tasks/extend-kubernetes/custom-resources/custom-resource-definitions/#controlling-pruning" rel="nofollow noreferrer"><code>controller prunning</code></a> that should be taken into consideration:</p>
<blockquote>
<p>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
<code>x-kubernetes-preserve-unknown-fields: true</code> in the <a href="https://kubernetes.io/docs/tasks/extend-kubernetes/custom-resources/custom-resource-definitions/#specifying-a-structural-schema" rel="nofollow noreferrer">structural OpenAPI
v3 validation schema</a>.</p>
</blockquote>
<p>Here's a very similar <a href="https://stackoverflow.com/a/66766843/15537201">answer</a> about custom field and <code>additionalPrinterColumns</code>.</p>
