Why you should try to keep your Deployment names to 47 characters (or less)
Most Kubernetes objects, including Deployments, can have names that are ≤ 253 characters in length. You should, however, consider restricting your Deployment names to ≤ 47 characters because of the implications that exceeding this threshold will have on your Pod names.
Pod and ReplicaSet naming
As you likely know, Deployments create ReplicaSets — and those ReplicaSets create Pods. When Deployment names are short (e.g. mydeployment
), the ReplicaSet name is the Deployment name with a suffix of a dash/hyphen followed by the pod-template-hash, which is 9 hexadecimal characters (e.g. mydeployment–548f955bf
). The Pod name is the ReplicaSet name with a suffix of a dash/hyphen followed by 5 random hexadecimal characters (e.g. mydeployment–548f955bf-j8wng
).
This is convenient because it allows you to easily see which Pods correspond to which ReplicaSets as well as which Deployments simply by looking at their names, while at the same time guaranteeing uniqueness of both the Pod and ReplicaSet names.
But what happens when your Deployment name is longer than 47 characters?
A ReplicaSet name can in theory be 253 characters. When a Deployment is used to create a ReplicaSet, however, the ReplicaSet’s name uses only the first 80 characters of the Deployment’s name, and then appends the dash/hyphen and 9-character pod-template-hash suffix (for a maximum length of 90).
Pod names, however, can’t exceed 63 characters.
For ReplicaSets with long names, Kubernetes only uses the first 58 characters of the ReplicaSet and will then append the 5 random hexadecimal characters. without the dash/hyphen. If the ReplicaSet name is 57 characters or less, Kubernetes will include the dash/hyphen prior to the 5 random characters.
What does this mean to you?
When Deployment names are 47 characters or shorter in length, everything is fine...
However, let’s suppose that your Deployment name was longer than 47 characters. We might want to specify a Deployment name of eventhub-universal-billing-schedule-updater-development-v103-blue
— which happens to be 65 characters long. A Deployment name like this would be something that you would consider if you were trying to deploy a number of different Deployments to the same Namespace. You can’t have 2 Deployments in the same Namespace with the same name, and so you would need to add elements to the Deployment name to differentiate them from each other.
The corresponding ReplicaSet name would be something like eventhub-eventhub-universal-billing-schedule-updater-development-v103-blue-548f955bf
. The Pod name(s) would be something like eventhub-universal-billing-schedule-updater-development-v18lrpt
.
Notice that the Pod name has truncated the original Deployment name and does not include the pod-template-hash. This means that Pods from different ReplicaSets are not as easily distinguished from one another, which can be somewhat unfortunate during a number of operational tasks — for example, if you are trying to deal with a rollout that can’t proceed because of a ResourceQuota where you might want to manually delete a Pod or two from the older ReplicaSet to allow a rollout to proceed.
And what happens if you have another Deployment in the same Namespace with a similar name — for example eventhub-universal-billing-schedule-updater-development-v104-green
? The Pod name(s) for this “v104-green” Deployment will be something like eventhub-universal-billing-schedule-updater-development-v17psqn
, which is not distinguishable by name from the Pods created by the “v103-blue” Deployment.
This may not be the end of the world, but it does complicate operational tasks and increases the probability that mistakes will be made.
What can you do?
If for some reason you can’t use Deployment names ≤ 47 characters, Pods associated with ReplicaSets have an ownerReferences stanza in their metadata that includes the name of the “parent” ReplicaSet:
apiVersion: v1
kind: Pod
metadata:
labels:
pod-template-hash: 548f955bf
name: a2345678901234567890123456789012345678901234567-548f955bf-j8wng
ownerReferences:
- apiVersion: apps/v1
blockOwnerDeletion: true
controller: true
kind: ReplicaSet
name: eventhub-universal-billing-schedule-updater-development-v103-blue-548f955bf
...
Similarly, ReplicaSets have an ownerReferences stanza in the metadata that includes the name of the “parent” Deployment:
apiVersion: apps/v1
kind: ReplicaSet
metadata:
name: eventhub-universal-billing-schedule-updater-development-v103-blue-548f955bf
ownerReferences:
- apiVersion: apps/v1
blockOwnerDeletion: true
controller: true
kind: Deployment
name: eventhub-universal-billing-schedule-updater-development-v103-blue
Unfortunately, using kubectl alone you can’t easily select only Pods that have a particular ownerReference. You could potentially pipe the output from kubectl to jq similar to the following:
kubectl get pods -o json | jq -r '.items[] | select(.metadata.ownerReferences[] | select(.name=="eventhub-universal-billing-schedule-updater-development-v103-blue-548f955bf")) | .metadata.name '
But the easiest approach is likely to simply restrict your Deployment names to only 47 characters…
If getting your Deployment names down to 47 characters or less is a challenge, consider using Namespaces. Namespaces are also limited to 63 character names, but if you created one Namespace called eventhub-universal-billing-development-v103-blue
and another calledeventhub-universal-billing-development-v104-green
, you could simply name your Deployment schedule-updater
in each Namespace.
Hopefully this helps you avoid confusion or operational issues! If you find this story helpful, please consider looking through my other stories on Medium or following me.