Skip to content

Commit 4d8990a

Browse files
committed
Document the max length of instance set names
The name of an instance set goes into the name of a StatefulSet which, in turn, goes into a label value on its Pods. That label value includes a hash generated by Kubernetes. We cannot perform or specify any cross-field validation at this time. Describe the maximum length of these fields in their documentation, instead. Issue: [sc-14068] See: https://issue.k8s.io/64023
1 parent 1604339 commit 4d8990a

File tree

4 files changed

+133
-6
lines changed

4 files changed

+133
-6
lines changed

config/crd/bases/postgres-operator.crunchydata.com_postgresclusters.yaml

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5631,7 +5631,9 @@ spec:
56315631
default: ""
56325632
description: Name that associates this set of PostgreSQL pods.
56335633
This field is optional when only one instance set is defined.
5634-
Each instance set in a cluster must have a unique name.
5634+
Each instance set in a cluster must have a unique name. The
5635+
combined length of this and the cluster name must be 46 characters
5636+
or less.
56355637
pattern: ^([a-z0-9]([-a-z0-9]*[a-z0-9])?)?$
56365638
type: string
56375639
priorityClassName:

docs/content/references/crd.md

Lines changed: 1 addition & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

internal/naming/limitations.md

Lines changed: 114 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,114 @@
1+
<!--
2+
Copyright 2022 Crunchy Data Solutions, Inc.
3+
Licensed under the Apache License, Version 2.0 (the "License");
4+
you may not use this file except in compliance with the License.
5+
You may obtain a copy of the License at
6+
7+
http://www.apache.org/licenses/LICENSE-2.0
8+
9+
Unless required by applicable law or agreed to in writing, software
10+
distributed under the License is distributed on an "AS IS" BASIS,
11+
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12+
See the License for the specific language governing permissions and
13+
limitations under the License.
14+
-->
15+
16+
# Definitions
17+
18+
[k8s-names]: https://docs.k8s.io/concepts/overview/working-with-objects/names/
19+
20+
### DNS subdomain
21+
22+
Most resource types require this kind of name. It must be 253 characters or less,
23+
lowercase, and alphanumeric with hyphens U+002D and dots U+002E allowed in between.
24+
25+
- [k8s.io/apimachinery/pkg/util/validation.IsDNS1123Subdomain](https://pkg.go.dev/k8s.io/apimachinery/pkg/util/validation#IsDNS1123Subdomain)
26+
27+
### DNS label
28+
29+
Some resource types require this kind of name. It must be 63 characters or less,
30+
lowercase, and alphanumeric with hyphens U+002D allowed in between.
31+
32+
Some have a stricter requirement to start with an alphabetic (nonnumerical) character.
33+
34+
- [k8s.io/apimachinery/pkg/util/validation.IsDNS1123Label](https://pkg.go.dev/k8s.io/apimachinery/pkg/util/validation#IsDNS1123Label)
35+
- [k8s.io/apimachinery/pkg/util/validation.IsDNS1035Label](https://pkg.go.dev/k8s.io/apimachinery/pkg/util/validation#IsDNS1035Label)
36+
37+
38+
# Labels
39+
40+
[k8s-labels]: https://docs.k8s.io/concepts/overview/working-with-objects/labels/
41+
42+
Label names must be 317 characters or less. The portion before an optional slash U+002F
43+
must be a DNS subdomain. The portion after must be 63 characters or less.
44+
45+
Label values must be 63 characters or less and can be empty.
46+
47+
Both label names and values must be alphanumeric with hyphens U+002D, underscores U+005F,
48+
and dots U+002E allowed in between.
49+
50+
- [k8s.io/apimachinerypkg/util/validation.IsQualifiedName](https://pkg.go.dev/k8s.io/apimachinery/pkg/util/validation#IsQualifiedName)
51+
- [k8s.io/apimachinerypkg/util/validation.IsValidLabelValue](https://pkg.go.dev/k8s.io/apimachinery/pkg/util/validation#IsValidLabelValue)
52+
53+
54+
# Annotations
55+
56+
[k8s-annotations]: https://docs.k8s.io/concepts/overview/working-with-objects/annotations/
57+
58+
Annotation names must be 317 characters or less. The portion before an optional slash U+002F
59+
must be a DNS subdomain. The portion after must be 63 characters or less and alphanumeric with
60+
hyphens U+002D, underscores U+005F, and dots U+002E allowed in between.
61+
62+
Annotation values may contain anything, but the combined size of *all* names and values
63+
must be 256 KiB or less.
64+
65+
- [https://pkg.go.dev/k8s.io/apimachinery/pkg/api/validation.ValidateAnnotations](https://pkg.go.dev/k8s.io/apimachinery/pkg/api/validation#ValidateAnnotations)
66+
67+
68+
# Specifics
69+
70+
The Kubernetes API validates custom resource metadata.
71+
[Custom resource names are DNS subdomains](https://releases.k8s.io/v1.23.0/staging/src/k8s.io/apiextensions-apiserver/pkg/registry/customresource/validator.go#L60).
72+
It may be possible to limit this further through validation. This is a stated
73+
goal of [CEL expression validation](https://docs.k8s.io/tasks/extend-kubernetes/custom-resources/custom-resource-definitions/#validation-rules).
74+
75+
[ConfigMap names are DNS subdomains](https://releases.k8s.io/v1.23.0/pkg/apis/core/validation/validation.go#L5618).
76+
77+
[CronJob names are DNS subdomains](https://docs.k8s.io/concepts/workloads/controllers/cron-jobs/)
78+
but must be [52 characters or less](https://releases.k8s.io/v1.23.0/pkg/apis/batch/validation/validation.go#L281).
79+
80+
[Deployment names are DNS subdomains](https://releases.k8s.io/v1.23.0/pkg/apis/apps/validation/validation.go#L632).
81+
82+
[Job names are DNS subdomains](https://releases.k8s.io/v1.23.0/pkg/apis/batch/validation/validation.go#L86).
83+
When `.spec.completionMode = Indexed`, the name must be shorter (closer to 61 characters, it depends).
84+
When `.spec.manualSelector` is unset, its Pods get (and must have) a "job-name" label, limiting the
85+
name to 63 characters or less.
86+
87+
[Namespace names are DNS labels](https://releases.k8s.io/v1.23.0/pkg/apis/core/validation/validation.go#L5963).
88+
89+
[PersistentVolumeClaim (PVC) names are DNS subdomains](https://releases.k8s.io/v1.23.0/pkg/apis/core/validation/validation.go#L2066).
90+
91+
[Pod names are DNS subdomains](https://releases.k8s.io/v1.23.0/pkg/apis/core/validation/validation.go#L3443).
92+
The strategy for [generating Pod names](https://releases.k8s.io/v1.23.0/pkg/registry/core/pod/strategy.go#L62) truncates to 63 characters.
93+
The `.spec.hostname` field must be 63 characters or less.
94+
95+
PodDisruptionBudget (PDB)
96+
97+
[ReplicaSet names are DNS subdomains](https://releases.k8s.io/v1.23.0/pkg/apis/apps/validation/validation.go#L655).
98+
99+
Role
100+
101+
RoleBinding
102+
103+
[Secret names are DNS subdomains](https://releases.k8s.io/v1.23.0/pkg/apis/core/validation/validation.go#L5515).
104+
105+
[Service names are DNS labels](https://docs.k8s.io/concepts/services-networking/service/)
106+
that must begin with a letter.
107+
108+
ServiceAccount (subdomain)
109+
110+
[StatefulSet names are DNS subdomains](https://docs.k8s.io/concepts/workloads/controllers/statefulset/),
111+
but its Pods get [hostnames](https://releases.k8s.io/v1.23.0/pkg/apis/core/validation/validation.go#L3561)
112+
so it must be shorter (closer to 61 characters, it depends). Its Pods also get a "controller-revision-hash"
113+
label with [11 characters appended](https://issue.k8s.io/64023), limiting the name to 52 characters or less.
114+

pkg/apis/postgres-operator.crunchydata.com/v1beta1/postgrescluster_types.go

Lines changed: 15 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -393,13 +393,24 @@ type PostgresInstanceSetSpec struct {
393393
// +optional
394394
Metadata *Metadata `json:"metadata,omitempty"`
395395

396-
// This value goes into the name of an appsv1.StatefulSet and the hostname
397-
// of a corev1.Pod. The pattern below is IsDNS1123Label wrapped in "()?" to
398-
// accommodate the empty default.
396+
// This value goes into the name of an appsv1.StatefulSet, the hostname of
397+
// a corev1.Pod, and label values. The pattern below is IsDNS1123Label
398+
// wrapped in "()?" to accommodate the empty default.
399+
//
400+
// The Pods created by a StatefulSet have a "controller-revision-hash" label
401+
// comprised of the StatefulSet name, a dash, and a 10-character hash.
402+
// The length below is derived from limitations on label values:
403+
//
404+
// 63 (max) ≥ len(cluster) + 1 (dash)
405+
// + len(set) + 1 (dash) + 4 (id)
406+
// + 1 (dash) + 10 (hash)
407+
//
408+
// See: https://issue.k8s.io/64023
399409

400410
// Name that associates this set of PostgreSQL pods. This field is optional
401411
// when only one instance set is defined. Each instance set in a cluster
402-
// must have a unique name.
412+
// must have a unique name. The combined length of this and the cluster name
413+
// must be 46 characters or less.
403414
// +optional
404415
// +kubebuilder:default=""
405416
// +kubebuilder:validation:Pattern=`^([a-z0-9]([-a-z0-9]*[a-z0-9])?)?$`

0 commit comments

Comments
 (0)