Notice: Our URL has changed! Please update your bookmarks. Dismiss

KDL a notation to describe Kubernetes application deployments


This guide illustrates a graphical notation for Kubernetes API objects: Kubernetes Deployment Language (in short KDL). Kubernetes API objects can be used to describe how a solution will be deployed in Kubernetes.

There is a need to describe and document how applications will be deployed in Kubernetes, especially when these applications are comprised of several components. To fill this gap, this document defines a simple graphical convention to describe these deployments, so that they can be diagramed, easily whiteboarded, and captured in a document.

To better explain the objective, we can draw a parallel to UML, which had several graphical languages to describe different aspects of an application architecture. In contrasting UML with KDL, the objective to do forward or reverse engineering doesn’t exist (i.e. convert the diagrams in yaml files is not a goal). This way, we have the opportunity to manage how much of the information we want to display in the diagrams. As a general rule of thumb, we will only display architecturally relevant information.

Here you can find a git repo with the latest version of KDL and you can also download a visio stencil for the proposed notation.

Kubernetes API Objects

In general Kubernetes API objects cover the following areas:

Area Color convention Example

OpenShift Cluster


The Kubernetes cluster(s) involved in the solution









Persistent Volume Claim, Persistent Volume

Here is the API object notation convention.

Kubernetes cluster

The Kubernetes cluster is simply represented as a rectangle:

kubernetes template

All the other API objects will live inside the cluster or at its edges. There should never be a need to call out individual nodes of an Kubernetes cluster.

You can represents components outside the cluster and how they connect to components inside the cluster. This graphical convention does not cover components outside the cluster.


The compute objects are the most complex. In general they are represented by a rectangle with badges around it to show additional information. Here is a template:

compute template

The central section of the picture represents a pod. In it we can find one or more containers. Both pod and containers should have a name.

On the left side of the pod we have additional compute information. The top badge specify the type of controller for this pod. Here are the types of controllers and their abbreviations:

Type of controller Abbreviation

Replication Controller


Replica Set




DeploymentConfig (OpenShift only)








Cron Job


On the bottom we have the cardinality of the instances of that pod. This field assumes different meaning and format depending on the type of controller, here is a reference table:

Type Of Controller Format

Replication Controller

A number or a range (ex 3 or 2:5)


A number or a range (ex 3 or 2:5)


A number or a range (ex 3 or 2:5)

DeploymentConfig (OpenShift only)

A number or a range (ex 3 or 2:5)


The node selector: storage-node=true


A number: 3


A number representing the degree of parallelism: 3

Cron Job

A number representing the degree of parallelism: 3

At the top of the pod we have the exposed ports. You can use the little badges to just show the port number or also add the port name. Here is an example:

port example

These badges are in yellow because the represent networking config. You can connect each port with the container that is actually exposing that port if relevant. But in most cases this will not be necessary because most pods have just one container.

At the bottom of the pod we have the attached volumes. The name of the volume should be displayed in the rectangle. In most cases these will be persistent volumes. If the volume type is not persistent volume it may be relevant to show it. Also, sometimes it may be important to also show the mount point. Here are examples of acceptable notation:

volume example

On the right side of the pod with have volumes that pertain to the configuration of the pod: secrets and configmaps. As for the data volumes, the name of the volume should be indicated, usually it is important to distinguish between configmaps and secrets, so also the type of volume should be indicated and if necessary also the mount point can be shown. Here are some examples:

secret example


There are two types of networking objects: services and ingresses (routes in OpenShift).


A service can be represented with an oval as in the following picture:

service template

On the left side there is a badge representing the type of service. Here are the possible abbreviations

Type Abbreviation

Cluster IP


Cluster IP, ClusterIP: None

HS a.k.a. Headless Service

Node Port




External Name (OpenShift only)


External IP


At the top of the service there are the exposed ports. Same convention applies here as for the compute ports.

The service should be connected to a compute object. This will implicitly define the service selector, so there is no need to have it indicated in the picture.

If a service is allows traffic from the outside of the cluster to internal pods (such as for Load Balancer or Node Port or External IP) it should be depicted on the edge of the cluster.

edge service

Same concept applies to services that regulate outbound traffic (such as External Name), although in this case they would probably appear at the bottom of the openshift cluster rectangle.


Ingresses can be indicated with a parallelogram as in the following picture:

ingress template

An ingress shows the ingress name and optionally the host exposed. An ingress will be connected to a service (the same rules apply to OpenShift routes). Ingresses are always shown at the edge of the openshift cluster.

edge ingress


Storage is used to indicate persistent volumes. The color of storage is blues and it’s shape is a bucket deployed as the following picture:

storage template

Storage should indicate the persistent volume name and the storage provider (example NFS, gluster etc…​). Persistent Storage is always depicted at the edge of the cluster because it is a configuration pointing to an externally available storage.  image::./images/edge-storage.png[]

Putting it all together

In this section we will go over an example of how this notation can be used to describe the deployment of an application. Our application is an bank service application that uses a mariadb database as its datastore. Here is the deployment diagram:

mariadb example

Notice that the mariadb pod uses StatefulSet and a persistent volume for its data. This pod is not exposed externally to the cluster, but its service is consumed by the BankService app.
The BankService app is a stateless pod controlled by a deployment config which has a secret with the credentials to access the database. It also has a service and a route so that it can accept inbound connection from outside the cluster.