-
Notifications
You must be signed in to change notification settings - Fork 41.6k
Description
What happened?
I created a Deployment manifest that contains a PodSpec with only one port :
ports:
- name: dns-udp
containerPort: 5353
protocol: UDP
I applied it.
Afterwards, I added the TCP equivalent of this port to my manifest :
- name: dns-tcp
containerPort: 5353
protocol: TCP
I diffed it with the cluster and the diff appeared empty.
What did you expect to happen?
I expected the diff to show the difference I added to the manifest.
How can we reproduce it (as minimally and precisely as possible)?
Using the following manifest (and commented out port) :
---
apiVersion: apps/v1
kind: Deployment
metadata:
name: coredns-forwarder
namespace: coredns-forwarder
spec:
replicas: 1
selector:
matchLabels:
app.kubernetes.io/name: coredns-forwarder
app.kubernetes.io/instance: coredns-forwarder
template:
metadata:
labels:
app.kubernetes.io/name: coredns-forwarder
app.kubernetes.io/instance: coredns-forwarder
spec:
containers:
- name: coredns-forwarder
image: "coredns/coredns:1.9.0"
imagePullPolicy: IfNotPresent
args:
- -conf
- /etc/coredns/Corefile
- -logtostderr
- -v
- "10"
ports:
- name: dns-udp
containerPort: 5353
protocol: UDP
# - name: dns-tcp
# containerPort: 5353
# protocol: TCP
volumeMounts:
- mountPath: /etc/coredns
name: coredns-forwarder-config
volumes:
- configMap:
defaultMode: 420
items:
- key: Corefile
path: Corefile
name: coredns-forwarder-config
name: coredns-forwarder-config
---
apiVersion: v1
kind: ConfigMap
metadata:
name: coredns-forwarder-config
namespace: coredns-forwarder
data:
Corefile: |
.:5353 {
errors
ready
health
forward . 1.1.1.1
cache 30
reload
loadbalance
}
Anything else we need to know?
This might seem like a benign bug however as for a lot of things exposed by APIs, people tend to assume things should be there.
As indicated here (
| // List of ports to expose from the container. Exposing a port here gives |
//Exposing a port here
// the system additional information about the network connections a
// container uses, but is primarily informational.
However this breaks in several scenarios :
- If you use service with named ports, the diff won't be applied and thus this won't work.
- If some service LoadBalancer implementation assumes this information to be correct (and this is the case for Azure Load Balancer), this makes the LoadBalancer non working.
- In some cases if you have some security / networking software that uses this information, this may also break.
The problem here being patchMergeKey:"containerPort" if I understand the code correctly. This does not distinguish protocols. (I discovered this while installing a DNS server, but this might also happen for modern reverse proxies with things like http3 using UDP for instance).
This might be both a client and server version bug.
Kubernetes version
$ kubectl version
Client Version: version.Info{Major:"1", Minor:"21", GitVersion:"v1.21.6", GitCommit:"d921bc6d1810da51177fbd0ed61dc811c5228097", GitTreeState:"archive", BuildDate:"1980-01-01T00:00:00Z", GoVersion:"go1.16.8", Compiler:"gc", Platform:"linux/amd64"}
Server Version: version.Info{Major:"1", Minor:"21", GitVersion:"v1.21.2", GitCommit:"802eff1fe87ad2dd737ebbe891f30500b88beb00", GitTreeState:"clean", BuildDate:"2021-11-15T08:35:41Z", GoVersion:"go1.16.5", Compiler:"gc", Platform:"linux/amd64"}Also :
Client Version: version.Info{Major:"1", Minor:"21", GitVersion:"v1.21.6", GitCommit:"d921bc6d1810da51177fbd0ed61dc811c5228097", GitTreeState:"archive", BuildDate:"1980-01-01T00:00:00Z", GoVersion:"go1.16.8", Compiler:"gc", Platform:"linux/amd64"}
Server Version: version.Info{Major:"1", Minor:"22", GitVersion:"v1.22.3+k3s1", GitCommit:"61a2aab25eeb97c26fa3f2b177e4355a7654c991", GitTreeState:"clean", BuildDate:"2021-11-21T00:00:00Z", GoVersion:"go1.16.9", Compiler:"gc", Platform:"linux/amd64"}
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 hereInstall tools
Container runtime (CRI) and and version (if applicable)
Related plugins (CNI, CSI, ...) and versions (if applicable)
I'm interested in helping to solve this bug, I've never touched k8s internals though so pointers would be greatly appreciated.