consider the indirect owner-relationship between pod and workload (#48)

Signed-off-by: mingzhou.swx <mingzhou.swx@alibaba-inc.com>

Co-authored-by: mingzhou.swx <mingzhou.swx@alibaba-inc.com>
This commit is contained in:
Wei-Xiang Sun 2022-06-28 10:32:18 +08:00 committed by GitHub
parent 149e5a48da
commit 68b1c9eea9
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
5 changed files with 53 additions and 21 deletions

View File

@ -215,7 +215,6 @@ func (c *StatefulSetLikeController) countUpdatedReadyPods(updateRevision string)
updatedReadyReplicas++
}
}
klog.V(3).Infof("BatchRelease(%v) observed %d updatedReadyReplicas")
return updatedReadyReplicas, nil
}

View File

@ -278,7 +278,7 @@ func (r *ControllerFinder) getStatefulSetLikeWorkload(namespace string, ref *rol
func (r *ControllerFinder) getLatestCanaryDeployment(stable *apps.Deployment) (*apps.Deployment, error) {
canaryList := &apps.DeploymentList{}
selector, _ := metav1.LabelSelectorAsSelector(&metav1.LabelSelector{MatchLabels: map[string]string{CanaryDeploymentLabel: stable.Name}})
err := r.List(context.TODO(), canaryList, &client.ListOptions{LabelSelector: selector}, utilclient.DisableDeepCopy)
err := r.List(context.TODO(), canaryList, &client.ListOptions{LabelSelector: selector, Namespace: stable.Namespace}, utilclient.DisableDeepCopy)
if err != nil {
return nil, err
} else if len(canaryList.Items) == 0 {

View File

@ -8,7 +8,6 @@ import (
utilclient "github.com/openkruise/rollouts/pkg/util/client"
appsv1 "k8s.io/api/apps/v1"
v1 "k8s.io/api/core/v1"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/apimachinery/pkg/types"
"k8s.io/klog/v2"
"sigs.k8s.io/controller-runtime/pkg/client"
@ -86,7 +85,7 @@ func ListOwnedPods(c client.Client, object client.Object) ([]*v1.Pod, error) {
}
podLister := &v1.PodList{}
err = c.List(context.TODO(), podLister, &client.ListOptions{LabelSelector: selector}, utilclient.DisableDeepCopy)
err = c.List(context.TODO(), podLister, &client.ListOptions{LabelSelector: selector, Namespace: object.GetNamespace()}, utilclient.DisableDeepCopy)
if err != nil {
return nil, err
}
@ -96,8 +95,12 @@ func ListOwnedPods(c client.Client, object client.Object) ([]*v1.Pod, error) {
if IsCompletedPod(pod) {
continue
}
owner := metav1.GetControllerOf(pod)
if owner == nil || owner.UID != object.GetUID() {
// we should find their indirect owner-relationship,
// such as pod -> replicaset -> deployment
owned, err := IsOwnedBy(c, pod, object)
if err != nil {
return nil, err
} else if !owned {
continue
}
pods = append(pods, pod)

View File

@ -72,6 +72,7 @@ const (
var (
knownWorkloadGVKs = []*schema.GroupVersionKind{
&ControllerKindRS,
&ControllerKindDep,
&ControllerKindSts,
&ControllerKruiseKindCS,
@ -231,10 +232,12 @@ func GetEmptyWorkloadObject(gvk schema.GroupVersionKind) client.Object {
return nil
}
switch gvk.Kind {
case ControllerKindDep.Kind:
switch gvk {
case ControllerKindRS:
return &apps.ReplicaSet{}
case ControllerKindDep:
return &apps.Deployment{}
case ControllerKruiseKindCS.Kind:
case ControllerKruiseKindCS:
return &appsv1alpha1.CloneSet{}
default:
unstructuredObject := &unstructured.Unstructured{}
@ -507,32 +510,53 @@ func IsSupportedWorkload(gvk schema.GroupVersionKind) bool {
return false
}
// GetOwnerWorkload return the top-level workload that is controlled by rollout,
// if the object has no owner, just return nil
func GetOwnerWorkload(r client.Reader, object client.Object) (client.Object, error) {
if object == nil {
return nil, nil
}
owner := metav1.GetControllerOf(object)
if owner == nil {
// We just care about the top-level workload that is referred by rollout
if owner == nil || len(object.GetAnnotations()[InRolloutProgressingAnnotation]) > 0 {
return nil, nil
}
ownerGvk := schema.FromAPIVersionAndKind(owner.APIVersion, owner.Kind)
ownerKey := types.NamespacedName{Namespace: object.GetNamespace(), Name: owner.Name}
if ownerGvk.Group == ControllerKindRS.Group && ownerGvk.Kind == ControllerKindRS.Kind {
replicaset := &apps.ReplicaSet{}
err := r.Get(context.TODO(), ownerKey, replicaset)
if err != nil {
return nil, err
}
return GetOwnerWorkload(r, replicaset)
}
ownerObj := GetEmptyWorkloadObject(ownerGvk)
if ownerObj == nil {
return nil, nil
}
err := r.Get(context.TODO(), ownerKey, ownerObj)
if err != nil {
if client.IgnoreNotFound(err) != nil {
return nil, err
}
return ownerObj, nil
return GetOwnerWorkload(r, ownerObj)
}
// IsOwnedBy will return true if the child is owned by parent directly or indirectly.
func IsOwnedBy(r client.Reader, child, parent client.Object) (bool, error) {
if child == nil {
return false, nil
}
owner := metav1.GetControllerOf(child)
if owner == nil {
return false, nil
} else if owner.UID == parent.GetUID() {
return true, nil
}
ownerGvk := schema.FromAPIVersionAndKind(owner.APIVersion, owner.Kind)
ownerKey := types.NamespacedName{Namespace: child.GetNamespace(), Name: owner.Name}
ownerObj := GetEmptyWorkloadObject(ownerGvk)
if ownerObj == nil {
return false, nil
}
err := r.Get(context.TODO(), ownerKey, ownerObj)
if client.IgnoreNotFound(err) != nil {
return false, err
}
return IsOwnedBy(r, ownerObj, parent)
}
func IsWorkloadType(object client.Object, t WorkloadType) bool {

View File

@ -65,6 +65,12 @@ var _ = SIGDescribe("Rollout", func() {
cloneSet := &appsv1alpha1.CloneSetList{}
k8sClient.List(context.TODO(), cloneSet, client.InNamespace(namespace))
fmt.Println(util.DumpJSON(cloneSet))
sts := &apps.StatefulSetList{}
k8sClient.List(context.TODO(), sts, client.InNamespace(namespace))
fmt.Println(util.DumpJSON(sts))
asts := &appsv1beta1.StatefulSetList{}
k8sClient.List(context.TODO(), asts, client.InNamespace(namespace))
fmt.Println(util.DumpJSON(asts))
}
CreateObject := func(object client.Object, options ...client.CreateOption) {