mirror of
https://github.com/k3s-io/kubernetes.git
synced 2025-07-26 05:03:09 +00:00
Merge pull request #4915 from yujuhong/hostport
kubelet: record an event with a clear reason on host port conflict
This commit is contained in:
commit
cc3c4414f8
@ -1387,15 +1387,35 @@ func updateBoundPods(changed []api.BoundPod, current []api.BoundPod) []api.Bound
|
|||||||
return updated
|
return updated
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type podsByCreationTime []api.BoundPod
|
||||||
|
|
||||||
|
func (s podsByCreationTime) Len() int {
|
||||||
|
return len(s)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s podsByCreationTime) Swap(i, j int) {
|
||||||
|
s[i], s[j] = s[j], s[i]
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s podsByCreationTime) Less(i, j int) bool {
|
||||||
|
return s[i].CreationTimestamp.Before(s[j].CreationTimestamp)
|
||||||
|
}
|
||||||
|
|
||||||
// filterHostPortConflicts removes pods that conflict on Port.HostPort values
|
// filterHostPortConflicts removes pods that conflict on Port.HostPort values
|
||||||
func filterHostPortConflicts(pods []api.BoundPod) []api.BoundPod {
|
func filterHostPortConflicts(pods []api.BoundPod) []api.BoundPod {
|
||||||
filtered := []api.BoundPod{}
|
filtered := []api.BoundPod{}
|
||||||
ports := map[int]bool{}
|
ports := map[int]bool{}
|
||||||
extract := func(p *api.Port) int { return p.HostPort }
|
extract := func(p *api.Port) int { return p.HostPort }
|
||||||
|
|
||||||
|
// Respect the pod creation order when resolving conflicts.
|
||||||
|
sort.Sort(podsByCreationTime(pods))
|
||||||
|
|
||||||
for i := range pods {
|
for i := range pods {
|
||||||
pod := &pods[i]
|
pod := &pods[i]
|
||||||
if errs := validation.AccumulateUniquePorts(pod.Spec.Containers, ports, extract); len(errs) != 0 {
|
if errs := validation.AccumulateUniquePorts(pod.Spec.Containers, ports, extract); len(errs) != 0 {
|
||||||
glog.Warningf("Pod %q: HostPort is already allocated, ignoring: %v", GetPodFullName(pod), errs)
|
glog.Warningf("Pod %q: HostPort is already allocated, ignoring: %v", GetPodFullName(pod), errs)
|
||||||
|
record.Eventf(pod, "hostPortConflict", "Cannot start the pod due to host port conflict.")
|
||||||
|
// TODO: Set the pod status to fail.
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
filtered = append(filtered, *pod)
|
filtered = append(filtered, *pod)
|
||||||
|
@ -3086,3 +3086,38 @@ func TestPortForward(t *testing.T) {
|
|||||||
t.Fatalf("stream: expected %v, got %v", e, a)
|
t.Fatalf("stream: expected %v, got %v", e, a)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Tests that upon host port conflict, the newer pod is removed.
|
||||||
|
func TestFilterHostPortConflicts(t *testing.T) {
|
||||||
|
// Reuse the pod spec with the same port to create a conflict.
|
||||||
|
spec := api.PodSpec{Containers: []api.Container{{Ports: []api.Port{{HostPort: 80}}}}}
|
||||||
|
var pods = []api.BoundPod{
|
||||||
|
{
|
||||||
|
ObjectMeta: api.ObjectMeta{
|
||||||
|
UID: "123456789",
|
||||||
|
Name: "newpod",
|
||||||
|
Namespace: "foo",
|
||||||
|
},
|
||||||
|
Spec: spec,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
ObjectMeta: api.ObjectMeta{
|
||||||
|
UID: "987654321",
|
||||||
|
Name: "oldpod",
|
||||||
|
Namespace: "foo",
|
||||||
|
},
|
||||||
|
Spec: spec,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
// Make sure the BoundPods are in the reverse order of creation time.
|
||||||
|
pods[1].CreationTimestamp = util.NewTime(time.Now())
|
||||||
|
pods[0].CreationTimestamp = util.NewTime(time.Now().Add(1 * time.Second))
|
||||||
|
filteredPods := filterHostPortConflicts(pods)
|
||||||
|
if len(filteredPods) != 1 {
|
||||||
|
t.Fatalf("Expected one pod. Got pods %#v", filteredPods)
|
||||||
|
}
|
||||||
|
if filteredPods[0].Name != "oldpod" {
|
||||||
|
t.Fatalf("Expected pod %#v. Got pod %#v", pods[1], filteredPods[0])
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
@ -44,6 +44,11 @@ func Now() Time {
|
|||||||
return Time{time.Now()}
|
return Time{time.Now()}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Before reports whether the time instant t is before u.
|
||||||
|
func (t Time) Before(u Time) bool {
|
||||||
|
return t.Time.Before(u.Time)
|
||||||
|
}
|
||||||
|
|
||||||
// Unix returns the local time corresponding to the given Unix time
|
// Unix returns the local time corresponding to the given Unix time
|
||||||
// by wrapping time.Unix.
|
// by wrapping time.Unix.
|
||||||
func Unix(sec int64, nsec int64) Time {
|
func Unix(sec int64, nsec int64) Time {
|
||||||
|
Loading…
Reference in New Issue
Block a user