Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

SidecarSet add upgrade state in pod annotation #1349

Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
54 changes: 54 additions & 0 deletions pkg/control/sidecarcontrol/util.go
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,10 @@

// SidecarSetUpgradable is a pod condition to indicate whether the pod's sidecarset is upgradable
SidecarSetUpgradable corev1.PodConditionType = "SidecarSetUpgradable"

// SidecarSetUpgradeSpec State
SidecarSetHashStateUpdating = "Updating"
SidecarSetHashStateNormal = "Normal"
)

var (
Expand All @@ -81,6 +85,7 @@
SidecarSetName string `json:"sidecarSetName"`
SidecarList []string `json:"sidecarList"` // sidecarSet container list
SidecarSetControllerRevision string `json:"controllerRevision,omitempty"` // sidecarSet controllerRevision name
State string `json:"state"` // enum: Normal, Updating
}

// PodMatchSidecarSet determines if pod match Selector of sidecar.
Expand Down Expand Up @@ -253,11 +258,60 @@
SidecarSetName: sidecarSet.Name,
SidecarList: sidecarList.List(),
SidecarSetControllerRevision: sidecarSet.Status.LatestRevision,
State: SidecarSetHashStateUpdating,
}
newHash, _ := json.Marshal(sidecarSetHash)
pod.Annotations[hashKey] = string(newHash)
}

func IsSiderCarContainersReady(pod *corev1.Pod, containers sets.String) bool {
for _, cs := range pod.Status.ContainerStatuses {
// only check containers set
if !containers.Has(cs.Name) {
continue

Check warning on line 271 in pkg/control/sidecarcontrol/util.go

View check run for this annotation

Codecov / codecov/patch

pkg/control/sidecarcontrol/util.go#L267-L271

Added lines #L267 - L271 were not covered by tests
}
if !cs.Ready {
return false
}

Check warning on line 275 in pkg/control/sidecarcontrol/util.go

View check run for this annotation

Codecov / codecov/patch

pkg/control/sidecarcontrol/util.go#L273-L275

Added lines #L273 - L275 were not covered by tests
}
return true

Check warning on line 277 in pkg/control/sidecarcontrol/util.go

View check run for this annotation

Codecov / codecov/patch

pkg/control/sidecarcontrol/util.go#L277

Added line #L277 was not covered by tests
}

func IsPodFinishSiderCarContainersUpdate(pod *corev1.Pod, sidecarSet *appsv1alpha1.SidecarSet) bool {
sidecars := GetSidecarContainersInPod(sidecarSet)
if _, ok := pod.Annotations[SidecarsetInplaceUpdateStateKey]; ok {
if IsSidecarContainerUpdateCompleted(pod, sets.NewString(sidecarSet.Name), sidecars) && IsSiderCarContainersReady(pod, sidecars) {
return true
}
} else {
if IsSiderCarContainersReady(pod, sidecars) {
return true
}

Check warning on line 289 in pkg/control/sidecarcontrol/util.go

View check run for this annotation

Codecov / codecov/patch

pkg/control/sidecarcontrol/util.go#L280-L289

Added lines #L280 - L289 were not covered by tests
}
return false

Check warning on line 291 in pkg/control/sidecarcontrol/util.go

View check run for this annotation

Codecov / codecov/patch

pkg/control/sidecarcontrol/util.go#L291

Added line #L291 was not covered by tests
}

func GetPodSidecarSetHashState(pod *corev1.Pod, sidecarSet *appsv1alpha1.SidecarSet) string {
hashKey := SidecarSetHashAnnotation
sidecarSetHash := make(map[string]SidecarSetUpgradeSpec)
if err := json.Unmarshal([]byte(pod.Annotations[hashKey]), &sidecarSetHash); err != nil {
klog.Errorf("unmarshal pod(%s/%s) annotations[%s] failed: %s", pod.Namespace, pod.Name, hashKey, err.Error())

// to be compatible with older sidecarSet hash struct, map[string]string
olderSidecarSetHash := make(map[string]string)
if err = json.Unmarshal([]byte(pod.Annotations[hashKey]), &olderSidecarSetHash); err == nil {
for k, v := range olderSidecarSetHash {
sidecarSetHash[k] = SidecarSetUpgradeSpec{
SidecarSetHash: v,
UpdateTimestamp: metav1.Now(),
SidecarSetName: sidecarSet.Name,
}
}

Check warning on line 309 in pkg/control/sidecarcontrol/util.go

View check run for this annotation

Codecov / codecov/patch

pkg/control/sidecarcontrol/util.go#L294-L309

Added lines #L294 - L309 were not covered by tests
}
}
return sidecarSetHash[sidecarSet.Name].State

Check warning on line 312 in pkg/control/sidecarcontrol/util.go

View check run for this annotation

Codecov / codecov/patch

pkg/control/sidecarcontrol/util.go#L312

Added line #L312 was not covered by tests
}

func GetSidecarContainersInPod(sidecarSet *appsv1alpha1.SidecarSet) sets.String {
names := sets.NewString()
for _, sidecarContainer := range sidecarSet.Spec.Containers {
Expand Down
54 changes: 54 additions & 0 deletions pkg/controller/sidecarset/sidecarset_processor.go
Original file line number Diff line number Diff line change
Expand Up @@ -103,6 +103,13 @@
return reconcile.Result{RequeueAfter: time.Second}, nil
}

// check if pod finish sidecar container upgrade
for _, pod := range pods {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Maybe we should make updatePodsSidecarHashState after line-99 because some pods that already ready should be update state to Noamal.

if sidecarcontrol.IsPodFinishSiderCarContainersUpdate(pod, sidecarSet) && sidecarcontrol.GetPodSidecarSetHashState(pod, sidecarSet) != "Normal" {
p.updatePodSidecarHashState(control, pod)
}
}

// 3. If sidecar container hot upgrade complete, then set the other one(empty sidecar container) image to HotUpgradeEmptyImage
if isSidecarSetHasHotUpgradeContainer(sidecarSet) {
var podsInHotUpgrading []*corev1.Pod
Expand Down Expand Up @@ -189,6 +196,53 @@
return nil
}

func (p *Processor) updatePodSidecarHashState(control sidecarcontrol.SidecarControl, pod *corev1.Pod) error {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Need some e2e tests?

podClone := &corev1.Pod{}
sidecarSet := control.GetSidecarset()
err := retry.RetryOnConflict(retry.DefaultBackoff, func() error {
if err := p.Client.Get(context.TODO(), types.NamespacedName{Namespace: pod.Namespace, Name: pod.Name}, podClone); err != nil {
klog.Errorf("sidecarset(%s) error getting updated pod %s/%s from client", control.GetSidecarset().Name, pod.Namespace, pod.Name)
}

Check warning on line 206 in pkg/controller/sidecarset/sidecarset_processor.go

View check run for this annotation

Codecov / codecov/patch

pkg/controller/sidecarset/sidecarset_processor.go#L205-L206

Added lines #L205 - L206 were not covered by tests
hashKey := sidecarcontrol.SidecarSetHashAnnotation
sidecarSetHash := make(map[string]sidecarcontrol.SidecarSetUpgradeSpec)
if err := json.Unmarshal([]byte(pod.Annotations[hashKey]), &sidecarSetHash); err != nil {
klog.Errorf("unmarshal pod(%s/%s) annotations[%s] failed: %s", pod.Namespace, pod.Name, hashKey, err.Error())

// to be compatible with older sidecarSet hash struct, map[string]string
olderSidecarSetHash := make(map[string]string)
if err = json.Unmarshal([]byte(pod.Annotations[hashKey]), &olderSidecarSetHash); err == nil {
for k, v := range olderSidecarSetHash {
sidecarSetHash[k] = sidecarcontrol.SidecarSetUpgradeSpec{
SidecarSetHash: v,
UpdateTimestamp: metav1.Now(),
SidecarSetName: sidecarSet.Name,
}
}
}

Check warning on line 222 in pkg/controller/sidecarset/sidecarset_processor.go

View check run for this annotation

Codecov / codecov/patch

pkg/controller/sidecarset/sidecarset_processor.go#L211-L222

Added lines #L211 - L222 were not covered by tests
}

sidecarSetHash[sidecarSet.Name] = sidecarcontrol.SidecarSetUpgradeSpec{
UpdateTimestamp: metav1.Now(),
SidecarSetHash: sidecarSetHash[sidecarSet.Name].SidecarSetHash,
SidecarSetName: sidecarSetHash[sidecarSet.Name].SidecarSetName,
SidecarList: sidecarSetHash[sidecarSet.Name].SidecarList,
SidecarSetControllerRevision: sidecarSetHash[sidecarSet.Name].SidecarSetControllerRevision,
State: sidecarcontrol.SidecarSetHashStateNormal,
}
newHash, _ := json.Marshal(sidecarSetHash)
podClone.Annotations[hashKey] = string(newHash)
// update pod in store
return p.Client.Update(context.TODO(), podClone)
})

if err != nil {
return err
}

Check warning on line 242 in pkg/controller/sidecarset/sidecarset_processor.go

View check run for this annotation

Codecov / codecov/patch

pkg/controller/sidecarset/sidecarset_processor.go#L241-L242

Added lines #L241 - L242 were not covered by tests
return nil
}

func (p *Processor) updatePodSidecarAndHash(control sidecarcontrol.SidecarControl, pod *corev1.Pod) error {
podClone := &corev1.Pod{}
sidecarSet := control.GetSidecarset()
Expand Down
8 changes: 8 additions & 0 deletions pkg/webhook/pod/mutating/sidecarset.go
Original file line number Diff line number Diff line change
Expand Up @@ -450,6 +450,14 @@ func buildSidecars(isUpdated bool, pod *corev1.Pod, oldPod *corev1.Pod, matchedS
sidecarSetHash[sidecarSet.Name] = setUpgrade1
sidecarSetHashWithoutImage[sidecarSet.Name] = setUpgrade2
}
sidecarSetHash[sidecarSet.Name] = sidecarcontrol.SidecarSetUpgradeSpec{
UpdateTimestamp: metav1.Now(),
SidecarSetHash: sidecarSetHash[sidecarSet.Name].SidecarSetHash,
SidecarSetName: sidecarSet.Name,
SidecarList: sidecarList.List(),
SidecarSetControllerRevision: sidecarSetHash[sidecarSet.Name].SidecarSetControllerRevision,
State: sidecarcontrol.SidecarSetHashStateUpdating,
}
}

// store sidecarset hash in pod annotations
Expand Down
Loading