Description
What happened?
When I apply a deployment yaml to modify spec.template.spec.containers[0].ports[1].containerPort
from 8080
to 8081
apiVersion: apps/v1
kind: Deployment
metadata:
name: kube-state-metrics
namespace: kube-system
spec:
replicas: 1
revisionHistoryLimit: 10
selector:
matchLabels:
k8s-app: kube-state-metrics
k8s-submitter: controller
template:
labels:
k8s-app: kube-state-metrics
k8s-submitter: controller
spec:
containers:
- image: myimage
imagePullPolicy: Always
name: kube-state-metrics
ports:
- containerPort: 8181
name: http-metrics
protocol: TCP
hostNetwork: true
restartPolicy: Always
The errors occur:
The Deployment "kube-state-metrics" is invalid: spec.template.spec.containers[0].ports[1].name: Duplicate value: "http-metrics"
What did you expect to happen?
The apply patch should be successfully finished.
Referring to the containerPort attributes:
https://github.com/kubernetes/kubernetes/blob/master/staging/src/k8s.io/api/core/v1/types.go#L2350
// List of ports to expose from the container. Exposing a port here gives
// the system additional information about the network connections a
// container uses, but is primarily informational. Not specifying a port here
// DOES NOT prevent that port from being exposed. Any port which is
// listening on the default "0.0.0.0" address inside a container will be
// accessible from the network.
// Cannot be updated.
// +optional
// +patchMergeKey=containerPort
// +patchStrategy=merge
// +listType=map
// +listMapKey=containerPort
// +listMapKey=protocol
Ports []ContainerPort `json:"ports,omitempty" patchStrategy:"merge" patchMergeKey:"containerPort" protobuf:"bytes,6,rep,name=ports"`
the patchMergeKey is containerPort
, and the listMapKey are containerPort
and protocol
.
And strategicpatch calls mergeSliceWithoutSpecialElements
to merge the maps if a new value stays the same as the original map instead of appending as a new item.
https://github.com/kubernetes/kubernetes/blob/master/staging/src/k8s.io/apimachinery/pkg/util/strategicpatch/patch.go#L1557
How can we reproduce it (as minimally and precisely as possible)?
deploy a deployment yaml with containerPort:
test-deployment.yaml
ports:
- containerPort: 8181
name: http-metrics
protocol: TCP
create the deployment
kubectl create -f test-deployment.yaml
modify containerPort from yaml file:
ports:
- containerPort: 8180
name: http-metrics
protocol: TCP
apply the changes
kubectl apply -f test-deployment.yaml
the error occurs:
The Deployment "kube-state-metrics" is invalid: spec.template.spec.containers[0].ports[1].name: Duplicate value: "http-metrics"
Anything else we need to know?
No response
Kubernetes version
kubernetes GitVersion: v1.20.6
Cloud provider
OS version
# On Linux:
$ cat /etc/os-release
# paste output here
$ uname -a
# paste output here
# On Windows:
C:\> wmic os get Caption, Version, BuildNumber, OSArchitecture
# paste output here