Merge pull request #113041 from saschagrunert/kubelet-pods-creation-time

Sort kubelet pods by their creation time
This commit is contained in:
Kubernetes Prow Robot 2022-10-18 09:17:19 -07:00 committed by GitHub
commit 843ad71cac
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 44 additions and 0 deletions

View File

@ -169,6 +169,8 @@ type Pod struct {
// The name and namespace of the pod, which is readable by human.
Name string
Namespace string
// Creation timestamps of the Pod in nanoseconds.
CreatedAt uint64
// List of containers that belongs to this pod. It may contain only
// running containers, or mixed with dead ones (when GetPods(true)).
Containers []*Container

View File

@ -21,6 +21,7 @@ import (
"fmt"
"os"
"path/filepath"
"sort"
"time"
cadvisorapi "github.com/google/cadvisor/info/v1"
@ -364,6 +365,7 @@ func (m *kubeGenericRuntimeManager) GetPods(all bool) ([]*kubecontainer.Pod, err
continue
}
p.Sandboxes = append(p.Sandboxes, converted)
p.CreatedAt = uint64(s.GetCreatedAt())
}
containers, err := m.getKubeletContainers(all)
@ -403,6 +405,15 @@ func (m *kubeGenericRuntimeManager) GetPods(all bool) ([]*kubecontainer.Pod, err
result = append(result, pod)
}
// There are scenarios where multiple pods are running in parallel having
// the same name, because one of them have not been fully terminated yet.
// To avoid unexpected behavior on container name based search (for example
// by calling *Kubelet.findContainer() without specifying a pod ID), we now
// return the list of pods ordered by their creation time.
sort.SliceStable(result, func(i, j int) bool {
return result[i].CreatedAt > result[j].CreatedAt
})
return result, nil
}

View File

@ -17,6 +17,7 @@ limitations under the License.
package kuberuntime
import (
"fmt"
"path/filepath"
"reflect"
"sort"
@ -473,6 +474,7 @@ func TestGetPods(t *testing.T) {
ID: types.UID("12345678"),
Name: "foo",
Namespace: "new",
CreatedAt: uint64(fakeSandbox.CreatedAt),
Containers: []*kubecontainer.Container{containers[0], containers[1]},
Sandboxes: []*kubecontainer.Container{sandbox},
},
@ -486,6 +488,35 @@ func TestGetPods(t *testing.T) {
}
}
func TestGetPodsSorted(t *testing.T) {
fakeRuntime, _, m, err := createTestRuntimeManager()
assert.NoError(t, err)
pod := &v1.Pod{ObjectMeta: metav1.ObjectMeta{Name: "foo", Namespace: "bar"}}
createdTimestamps := []uint64{10, 5, 20}
fakeSandboxes := []*apitest.FakePodSandbox{}
for i, createdAt := range createdTimestamps {
pod.UID = types.UID(fmt.Sprint(i))
fakeSandboxes = append(fakeSandboxes, makeFakePodSandbox(t, m, sandboxTemplate{
pod: pod,
createdAt: int64(createdAt),
state: runtimeapi.PodSandboxState_SANDBOX_READY,
}))
}
fakeRuntime.SetFakeSandboxes(fakeSandboxes)
actual, err := m.GetPods(false)
assert.NoError(t, err)
assert.Len(t, actual, 3)
// Verify that the pods are sorted by their creation time (newest/biggest timestamp first)
assert.Equal(t, uint64(createdTimestamps[2]), actual[0].CreatedAt)
assert.Equal(t, uint64(createdTimestamps[0]), actual[1].CreatedAt)
assert.Equal(t, uint64(createdTimestamps[1]), actual[2].CreatedAt)
}
func TestKillPod(t *testing.T) {
fakeRuntime, _, m, err := createTestRuntimeManager()
assert.NoError(t, err)