mirror of
https://github.com/k3s-io/kubernetes.git
synced 2025-08-01 07:47:56 +00:00
Merge pull request #41851 from janetkuo/deployment-duplicate-rs
Automatic merge from submit-queue (batch tested with PRs 38957, 41819, 41851, 40667, 41373) Fix deployment helper - no assumptions on only one new ReplicaSet #40415 **Release note**: ```release-note NONE ``` @kubernetes/sig-apps-bugs
This commit is contained in:
commit
7cca0d1867
@ -61,6 +61,7 @@ go_test(
|
|||||||
"//vendor:k8s.io/apimachinery/pkg/api/equality",
|
"//vendor:k8s.io/apimachinery/pkg/api/equality",
|
||||||
"//vendor:k8s.io/apimachinery/pkg/apis/meta/v1",
|
"//vendor:k8s.io/apimachinery/pkg/apis/meta/v1",
|
||||||
"//vendor:k8s.io/apimachinery/pkg/runtime",
|
"//vendor:k8s.io/apimachinery/pkg/runtime",
|
||||||
|
"//vendor:k8s.io/apimachinery/pkg/types",
|
||||||
"//vendor:k8s.io/apimachinery/pkg/util/intstr",
|
"//vendor:k8s.io/apimachinery/pkg/util/intstr",
|
||||||
"//vendor:k8s.io/client-go/testing",
|
"//vendor:k8s.io/client-go/testing",
|
||||||
],
|
],
|
||||||
|
@ -612,9 +612,13 @@ func EqualIgnoreHash(template1, template2 v1.PodTemplateSpec) bool {
|
|||||||
// FindNewReplicaSet returns the new RS this given deployment targets (the one with the same pod template).
|
// FindNewReplicaSet returns the new RS this given deployment targets (the one with the same pod template).
|
||||||
func FindNewReplicaSet(deployment *extensions.Deployment, rsList []*extensions.ReplicaSet) (*extensions.ReplicaSet, error) {
|
func FindNewReplicaSet(deployment *extensions.Deployment, rsList []*extensions.ReplicaSet) (*extensions.ReplicaSet, error) {
|
||||||
newRSTemplate := GetNewReplicaSetTemplate(deployment)
|
newRSTemplate := GetNewReplicaSetTemplate(deployment)
|
||||||
|
sort.Sort(controller.ReplicaSetsByCreationTimestamp(rsList))
|
||||||
for i := range rsList {
|
for i := range rsList {
|
||||||
if EqualIgnoreHash(rsList[i].Spec.Template, newRSTemplate) {
|
if EqualIgnoreHash(rsList[i].Spec.Template, newRSTemplate) {
|
||||||
// This is the new ReplicaSet.
|
// In rare cases, such as after cluster upgrades, Deployment may end up with
|
||||||
|
// having more than one new ReplicaSets that have the same template as its template,
|
||||||
|
// see https://github.com/kubernetes/kubernetes/issues/40415
|
||||||
|
// We deterministically choose the oldest new ReplicaSet.
|
||||||
return rsList[i], nil
|
return rsList[i], nil
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -629,7 +633,12 @@ func FindOldReplicaSets(deployment *extensions.Deployment, rsList []*extensions.
|
|||||||
// All pods and replica sets are labeled with pod-template-hash to prevent overlapping
|
// All pods and replica sets are labeled with pod-template-hash to prevent overlapping
|
||||||
oldRSs := map[string]*extensions.ReplicaSet{}
|
oldRSs := map[string]*extensions.ReplicaSet{}
|
||||||
allOldRSs := map[string]*extensions.ReplicaSet{}
|
allOldRSs := map[string]*extensions.ReplicaSet{}
|
||||||
newRSTemplate := GetNewReplicaSetTemplate(deployment)
|
requiredRSs := []*extensions.ReplicaSet{}
|
||||||
|
allRSs := []*extensions.ReplicaSet{}
|
||||||
|
newRS, err := FindNewReplicaSet(deployment, rsList)
|
||||||
|
if err != nil {
|
||||||
|
return requiredRSs, allRSs, err
|
||||||
|
}
|
||||||
for _, pod := range podList.Items {
|
for _, pod := range podList.Items {
|
||||||
podLabelsSelector := labels.Set(pod.ObjectMeta.Labels)
|
podLabelsSelector := labels.Set(pod.ObjectMeta.Labels)
|
||||||
for _, rs := range rsList {
|
for _, rs := range rsList {
|
||||||
@ -637,8 +646,8 @@ func FindOldReplicaSets(deployment *extensions.Deployment, rsList []*extensions.
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, nil, fmt.Errorf("invalid label selector: %v", err)
|
return nil, nil, fmt.Errorf("invalid label selector: %v", err)
|
||||||
}
|
}
|
||||||
// Filter out replica set that has the same pod template spec as the deployment - that is the new replica set.
|
// Filter out new replica set
|
||||||
if EqualIgnoreHash(rs.Spec.Template, newRSTemplate) {
|
if newRS != nil && rs.UID == newRS.UID {
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
allOldRSs[rs.ObjectMeta.Name] = rs
|
allOldRSs[rs.ObjectMeta.Name] = rs
|
||||||
@ -647,12 +656,10 @@ func FindOldReplicaSets(deployment *extensions.Deployment, rsList []*extensions.
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
requiredRSs := []*extensions.ReplicaSet{}
|
|
||||||
for key := range oldRSs {
|
for key := range oldRSs {
|
||||||
value := oldRSs[key]
|
value := oldRSs[key]
|
||||||
requiredRSs = append(requiredRSs, value)
|
requiredRSs = append(requiredRSs, value)
|
||||||
}
|
}
|
||||||
allRSs := []*extensions.ReplicaSet{}
|
|
||||||
for key := range allOldRSs {
|
for key := range allOldRSs {
|
||||||
value := allOldRSs[key]
|
value := allOldRSs[key]
|
||||||
allRSs = append(allRSs, value)
|
allRSs = append(allRSs, value)
|
||||||
|
@ -18,7 +18,9 @@ package util
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
|
"math/rand"
|
||||||
"reflect"
|
"reflect"
|
||||||
|
"strconv"
|
||||||
"testing"
|
"testing"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
@ -27,6 +29,7 @@ import (
|
|||||||
apiequality "k8s.io/apimachinery/pkg/api/equality"
|
apiequality "k8s.io/apimachinery/pkg/api/equality"
|
||||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||||
"k8s.io/apimachinery/pkg/runtime"
|
"k8s.io/apimachinery/pkg/runtime"
|
||||||
|
"k8s.io/apimachinery/pkg/types"
|
||||||
"k8s.io/apimachinery/pkg/util/intstr"
|
"k8s.io/apimachinery/pkg/util/intstr"
|
||||||
core "k8s.io/client-go/testing"
|
core "k8s.io/client-go/testing"
|
||||||
"k8s.io/kubernetes/pkg/api"
|
"k8s.io/kubernetes/pkg/api"
|
||||||
@ -161,6 +164,7 @@ func generateRS(deployment extensions.Deployment) extensions.ReplicaSet {
|
|||||||
template := GetNewReplicaSetTemplate(&deployment)
|
template := GetNewReplicaSetTemplate(&deployment)
|
||||||
return extensions.ReplicaSet{
|
return extensions.ReplicaSet{
|
||||||
ObjectMeta: metav1.ObjectMeta{
|
ObjectMeta: metav1.ObjectMeta{
|
||||||
|
UID: randomUID(),
|
||||||
Name: v1.SimpleNameGenerator.GenerateName("replicaset"),
|
Name: v1.SimpleNameGenerator.GenerateName("replicaset"),
|
||||||
Labels: template.Labels,
|
Labels: template.Labels,
|
||||||
},
|
},
|
||||||
@ -172,6 +176,10 @@ func generateRS(deployment extensions.Deployment) extensions.ReplicaSet {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func randomUID() types.UID {
|
||||||
|
return types.UID(strconv.FormatInt(rand.Int63(), 10))
|
||||||
|
}
|
||||||
|
|
||||||
// generateDeployment creates a deployment, with the input image as its template
|
// generateDeployment creates a deployment, with the input image as its template
|
||||||
func generateDeployment(image string) extensions.Deployment {
|
func generateDeployment(image string) extensions.Deployment {
|
||||||
podLabels := map[string]string{"name": image}
|
podLabels := map[string]string{"name": image}
|
||||||
@ -466,9 +474,18 @@ func TestEqualIgnoreHash(t *testing.T) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func TestFindNewReplicaSet(t *testing.T) {
|
func TestFindNewReplicaSet(t *testing.T) {
|
||||||
|
now := metav1.Now()
|
||||||
|
later := metav1.Time{Time: now.Add(time.Minute)}
|
||||||
|
|
||||||
deployment := generateDeployment("nginx")
|
deployment := generateDeployment("nginx")
|
||||||
newRS := generateRS(deployment)
|
newRS := generateRS(deployment)
|
||||||
newRS.Labels[extensions.DefaultDeploymentUniqueLabelKey] = "different-hash"
|
newRS.Labels[extensions.DefaultDeploymentUniqueLabelKey] = "hash"
|
||||||
|
newRS.CreationTimestamp = later
|
||||||
|
|
||||||
|
newRSDup := generateRS(deployment)
|
||||||
|
newRSDup.Labels[extensions.DefaultDeploymentUniqueLabelKey] = "different-hash"
|
||||||
|
newRSDup.CreationTimestamp = now
|
||||||
|
|
||||||
oldDeployment := generateDeployment("nginx")
|
oldDeployment := generateDeployment("nginx")
|
||||||
oldDeployment.Spec.Template.Spec.Containers[0].Name = "nginx-old-1"
|
oldDeployment.Spec.Template.Spec.Containers[0].Name = "nginx-old-1"
|
||||||
oldRS := generateRS(oldDeployment)
|
oldRS := generateRS(oldDeployment)
|
||||||
@ -481,11 +498,17 @@ func TestFindNewReplicaSet(t *testing.T) {
|
|||||||
expected *extensions.ReplicaSet
|
expected *extensions.ReplicaSet
|
||||||
}{
|
}{
|
||||||
{
|
{
|
||||||
test: "Get new ReplicaSet with the same spec but different pod-template-hash value",
|
test: "Get new ReplicaSet with the same template as Deployment spec but different pod-template-hash value",
|
||||||
deployment: deployment,
|
deployment: deployment,
|
||||||
rsList: []*extensions.ReplicaSet{&newRS, &oldRS},
|
rsList: []*extensions.ReplicaSet{&newRS, &oldRS},
|
||||||
expected: &newRS,
|
expected: &newRS,
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
test: "Get the oldest new ReplicaSet when there are more than one ReplicaSet with the same template",
|
||||||
|
deployment: deployment,
|
||||||
|
rsList: []*extensions.ReplicaSet{&newRS, &oldRS, &newRSDup},
|
||||||
|
expected: &newRSDup,
|
||||||
|
},
|
||||||
{
|
{
|
||||||
test: "Get nil new ReplicaSet",
|
test: "Get nil new ReplicaSet",
|
||||||
deployment: deployment,
|
deployment: deployment,
|
||||||
@ -502,13 +525,23 @@ func TestFindNewReplicaSet(t *testing.T) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func TestFindOldReplicaSets(t *testing.T) {
|
func TestFindOldReplicaSets(t *testing.T) {
|
||||||
|
now := metav1.Now()
|
||||||
|
later := metav1.Time{Time: now.Add(time.Minute)}
|
||||||
|
|
||||||
deployment := generateDeployment("nginx")
|
deployment := generateDeployment("nginx")
|
||||||
newRS := generateRS(deployment)
|
newRS := generateRS(deployment)
|
||||||
newRS.Labels[extensions.DefaultDeploymentUniqueLabelKey] = "different-hash"
|
newRS.Labels[extensions.DefaultDeploymentUniqueLabelKey] = "hash"
|
||||||
|
newRS.CreationTimestamp = later
|
||||||
|
|
||||||
|
newRSDup := generateRS(deployment)
|
||||||
|
newRSDup.Labels[extensions.DefaultDeploymentUniqueLabelKey] = "different-hash"
|
||||||
|
newRSDup.CreationTimestamp = now
|
||||||
|
|
||||||
oldDeployment := generateDeployment("nginx")
|
oldDeployment := generateDeployment("nginx")
|
||||||
oldDeployment.Spec.Template.Spec.Containers[0].Name = "nginx-old-1"
|
oldDeployment.Spec.Template.Spec.Containers[0].Name = "nginx-old-1"
|
||||||
oldRS := generateRS(oldDeployment)
|
oldRS := generateRS(oldDeployment)
|
||||||
oldRS.Status.FullyLabeledReplicas = *(oldRS.Spec.Replicas)
|
oldRS.Status.FullyLabeledReplicas = *(oldRS.Spec.Replicas)
|
||||||
|
|
||||||
newPod := generatePodFromRS(newRS)
|
newPod := generatePodFromRS(newRS)
|
||||||
oldPod := generatePodFromRS(oldRS)
|
oldPod := generatePodFromRS(oldRS)
|
||||||
|
|
||||||
@ -542,6 +575,18 @@ func TestFindOldReplicaSets(t *testing.T) {
|
|||||||
},
|
},
|
||||||
expected: []*extensions.ReplicaSet{&oldRS},
|
expected: []*extensions.ReplicaSet{&oldRS},
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
test: "Get old ReplicaSets with two new ReplicaSets, only the oldest new ReplicaSet is seen as new ReplicaSet",
|
||||||
|
deployment: deployment,
|
||||||
|
rsList: []*extensions.ReplicaSet{&oldRS, &newRS, &newRSDup},
|
||||||
|
podList: &v1.PodList{
|
||||||
|
Items: []v1.Pod{
|
||||||
|
newPod,
|
||||||
|
oldPod,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
expected: []*extensions.ReplicaSet{&oldRS, &newRS},
|
||||||
|
},
|
||||||
{
|
{
|
||||||
test: "Get empty old ReplicaSets",
|
test: "Get empty old ReplicaSets",
|
||||||
deployment: deployment,
|
deployment: deployment,
|
||||||
|
@ -68,12 +68,12 @@
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
"ImportPath": "github.com/gogo/protobuf/proto",
|
"ImportPath": "github.com/gogo/protobuf/proto",
|
||||||
"Comment": "v0.2-33-ge18d7aa",
|
"Comment": "v0.2-33-ge18d7aa8",
|
||||||
"Rev": "e18d7aa8f8c624c915db340349aad4c49b10d173"
|
"Rev": "e18d7aa8f8c624c915db340349aad4c49b10d173"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"ImportPath": "github.com/gogo/protobuf/sortkeys",
|
"ImportPath": "github.com/gogo/protobuf/sortkeys",
|
||||||
"Comment": "v0.2-33-ge18d7aa",
|
"Comment": "v0.2-33-ge18d7aa8",
|
||||||
"Rev": "e18d7aa8f8c624c915db340349aad4c49b10d173"
|
"Rev": "e18d7aa8f8c624c915db340349aad4c49b10d173"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
8
staging/src/k8s.io/apiserver/Godeps/Godeps.json
generated
8
staging/src/k8s.io/apiserver/Godeps/Godeps.json
generated
@ -349,12 +349,12 @@
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
"ImportPath": "github.com/docker/distribution/digest",
|
"ImportPath": "github.com/docker/distribution/digest",
|
||||||
"Comment": "v2.4.0-rc.1-38-gcd27f17",
|
"Comment": "v2.4.0-rc.1-38-gcd27f179",
|
||||||
"Rev": "cd27f179f2c10c5d300e6d09025b538c475b0d51"
|
"Rev": "cd27f179f2c10c5d300e6d09025b538c475b0d51"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"ImportPath": "github.com/docker/distribution/reference",
|
"ImportPath": "github.com/docker/distribution/reference",
|
||||||
"Comment": "v2.4.0-rc.1-38-gcd27f17",
|
"Comment": "v2.4.0-rc.1-38-gcd27f179",
|
||||||
"Rev": "cd27f179f2c10c5d300e6d09025b538c475b0d51"
|
"Rev": "cd27f179f2c10c5d300e6d09025b538c475b0d51"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@ -402,12 +402,12 @@
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
"ImportPath": "github.com/gogo/protobuf/proto",
|
"ImportPath": "github.com/gogo/protobuf/proto",
|
||||||
"Comment": "v0.2-33-ge18d7aa",
|
"Comment": "v0.2-33-ge18d7aa8",
|
||||||
"Rev": "e18d7aa8f8c624c915db340349aad4c49b10d173"
|
"Rev": "e18d7aa8f8c624c915db340349aad4c49b10d173"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"ImportPath": "github.com/gogo/protobuf/sortkeys",
|
"ImportPath": "github.com/gogo/protobuf/sortkeys",
|
||||||
"Comment": "v0.2-33-ge18d7aa",
|
"Comment": "v0.2-33-ge18d7aa8",
|
||||||
"Rev": "e18d7aa8f8c624c915db340349aad4c49b10d173"
|
"Rev": "e18d7aa8f8c624c915db340349aad4c49b10d173"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
@ -100,12 +100,12 @@
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
"ImportPath": "github.com/docker/distribution/digest",
|
"ImportPath": "github.com/docker/distribution/digest",
|
||||||
"Comment": "v2.4.0-rc.1-38-gcd27f17",
|
"Comment": "v2.4.0-rc.1-38-gcd27f179",
|
||||||
"Rev": "cd27f179f2c10c5d300e6d09025b538c475b0d51"
|
"Rev": "cd27f179f2c10c5d300e6d09025b538c475b0d51"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"ImportPath": "github.com/docker/distribution/reference",
|
"ImportPath": "github.com/docker/distribution/reference",
|
||||||
"Comment": "v2.4.0-rc.1-38-gcd27f17",
|
"Comment": "v2.4.0-rc.1-38-gcd27f179",
|
||||||
"Rev": "cd27f179f2c10c5d300e6d09025b538c475b0d51"
|
"Rev": "cd27f179f2c10c5d300e6d09025b538c475b0d51"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@ -161,12 +161,12 @@
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
"ImportPath": "github.com/gogo/protobuf/proto",
|
"ImportPath": "github.com/gogo/protobuf/proto",
|
||||||
"Comment": "v0.2-33-ge18d7aa",
|
"Comment": "v0.2-33-ge18d7aa8",
|
||||||
"Rev": "e18d7aa8f8c624c915db340349aad4c49b10d173"
|
"Rev": "e18d7aa8f8c624c915db340349aad4c49b10d173"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"ImportPath": "github.com/gogo/protobuf/sortkeys",
|
"ImportPath": "github.com/gogo/protobuf/sortkeys",
|
||||||
"Comment": "v0.2-33-ge18d7aa",
|
"Comment": "v0.2-33-ge18d7aa8",
|
||||||
"Rev": "e18d7aa8f8c624c915db340349aad4c49b10d173"
|
"Rev": "e18d7aa8f8c624c915db340349aad4c49b10d173"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
@ -100,12 +100,12 @@
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
"ImportPath": "github.com/docker/distribution/digest",
|
"ImportPath": "github.com/docker/distribution/digest",
|
||||||
"Comment": "v2.4.0-rc.1-38-gcd27f17",
|
"Comment": "v2.4.0-rc.1-38-gcd27f179",
|
||||||
"Rev": "cd27f179f2c10c5d300e6d09025b538c475b0d51"
|
"Rev": "cd27f179f2c10c5d300e6d09025b538c475b0d51"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"ImportPath": "github.com/docker/distribution/reference",
|
"ImportPath": "github.com/docker/distribution/reference",
|
||||||
"Comment": "v2.4.0-rc.1-38-gcd27f17",
|
"Comment": "v2.4.0-rc.1-38-gcd27f179",
|
||||||
"Rev": "cd27f179f2c10c5d300e6d09025b538c475b0d51"
|
"Rev": "cd27f179f2c10c5d300e6d09025b538c475b0d51"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@ -153,12 +153,12 @@
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
"ImportPath": "github.com/gogo/protobuf/proto",
|
"ImportPath": "github.com/gogo/protobuf/proto",
|
||||||
"Comment": "v0.2-33-ge18d7aa",
|
"Comment": "v0.2-33-ge18d7aa8",
|
||||||
"Rev": "e18d7aa8f8c624c915db340349aad4c49b10d173"
|
"Rev": "e18d7aa8f8c624c915db340349aad4c49b10d173"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"ImportPath": "github.com/gogo/protobuf/sortkeys",
|
"ImportPath": "github.com/gogo/protobuf/sortkeys",
|
||||||
"Comment": "v0.2-33-ge18d7aa",
|
"Comment": "v0.2-33-ge18d7aa8",
|
||||||
"Rev": "e18d7aa8f8c624c915db340349aad4c49b10d173"
|
"Rev": "e18d7aa8f8c624c915db340349aad4c49b10d173"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
Loading…
Reference in New Issue
Block a user