mirror of
https://github.com/k3s-io/kubernetes.git
synced 2025-11-01 14:22:17 +00:00
kubeadm: sort pod Volumes and VolumeMounts
Order of Volumes and VolumeMounts in the pod objects created by
kubeadm is undefined as they're represended as maps in the
controlPlaneHostPathMounts struct.
This influences 'kubeadm upgrade' logic in a way that even when
manifest of the component is not changed kubeadm tries to upgrade
it because most of the time current and new pods are not equal
due to the different order of Volumes and VolumeMounts.
For example 'kubeadm apply diff' almost always shows difference
in Volumes and VolumeMounts because of this:
volumeMounts:
+ - mountPath: /etc/kubernetes/pki
+ name: k8s-certs
+ readOnly: true
- mountPath: /etc/ssl/certs
name: ca-certs
+ readOnly: true
+ - mountPath: /etc/pki
+ name: etc-pki
+ readOnly: true
+ - mountPath: /usr/share/ca-certificates
+ name: usr-share-ca-certificates
readOnly: true
- mountPath: /etc/ca-certificates
name: etc-ca-certificates
readOnly: true
- - mountPath: /etc/pki
- name: etc-pki
- readOnly: true
- - mountPath: /etc/kubernetes/pki
- name: k8s-certs
- readOnly: true
- - mountPath: /usr/share/ca-certificates
- name: usr-share-ca-certificates
- readOnly: true
Sorting Volumes and VolumeMounts should fix this issue and help
to avoid unnecessary upgrades.
This commit is contained in:
@@ -22,6 +22,7 @@ import (
|
||||
"net"
|
||||
"net/url"
|
||||
"os"
|
||||
"sort"
|
||||
"strings"
|
||||
|
||||
"k8s.io/api/core/v1"
|
||||
@@ -147,6 +148,10 @@ func VolumeMapToSlice(volumes map[string]v1.Volume) []v1.Volume {
|
||||
v = append(v, vol)
|
||||
}
|
||||
|
||||
sort.Slice(v, func(i, j int) bool {
|
||||
return strings.Compare(v[i].Name, v[j].Name) == -1
|
||||
})
|
||||
|
||||
return v
|
||||
}
|
||||
|
||||
@@ -158,6 +163,10 @@ func VolumeMountMapToSlice(volumeMounts map[string]v1.VolumeMount) []v1.VolumeMo
|
||||
v = append(v, volMount)
|
||||
}
|
||||
|
||||
sort.Slice(v, func(i, j int) bool {
|
||||
return strings.Compare(v[i].Name, v[j].Name) == -1
|
||||
})
|
||||
|
||||
return v
|
||||
}
|
||||
|
||||
|
||||
@@ -481,13 +481,19 @@ func TestVolumeMapToSlice(t *testing.T) {
|
||||
"foo": {
|
||||
Name: "foo",
|
||||
},
|
||||
"bar": {
|
||||
Name: "bar",
|
||||
},
|
||||
}
|
||||
volumeSlice := VolumeMapToSlice(testVolumes)
|
||||
if len(volumeSlice) != 1 {
|
||||
if len(volumeSlice) != 2 {
|
||||
t.Errorf("Expected slice length of 1, got %d", len(volumeSlice))
|
||||
}
|
||||
if volumeSlice[0].Name != "foo" {
|
||||
t.Errorf("Expected volume name \"foo\", got %s", volumeSlice[0].Name)
|
||||
if volumeSlice[0].Name != "bar" {
|
||||
t.Errorf("Expected first volume name \"bar\", got %s", volumeSlice[0].Name)
|
||||
}
|
||||
if volumeSlice[1].Name != "foo" {
|
||||
t.Errorf("Expected second volume name \"foo\", got %s", volumeSlice[1].Name)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -496,13 +502,19 @@ func TestVolumeMountMapToSlice(t *testing.T) {
|
||||
"foo": {
|
||||
Name: "foo",
|
||||
},
|
||||
"bar": {
|
||||
Name: "bar",
|
||||
},
|
||||
}
|
||||
volumeMountSlice := VolumeMountMapToSlice(testVolumeMounts)
|
||||
if len(volumeMountSlice) != 1 {
|
||||
if len(volumeMountSlice) != 2 {
|
||||
t.Errorf("Expected slice length of 1, got %d", len(volumeMountSlice))
|
||||
}
|
||||
if volumeMountSlice[0].Name != "foo" {
|
||||
t.Errorf("Expected volume mount name \"foo\", got %s", volumeMountSlice[0].Name)
|
||||
if volumeMountSlice[0].Name != "bar" {
|
||||
t.Errorf("Expected first volume mount name \"bar\", got %s", volumeMountSlice[0].Name)
|
||||
}
|
||||
if volumeMountSlice[1].Name != "foo" {
|
||||
t.Errorf("Expected second volume name \"foo\", got %s", volumeMountSlice[1].Name)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user