mirror of
https://github.com/k3s-io/kubernetes.git
synced 2025-07-27 13:37:30 +00:00
Do not delete an incorrect pod when replacing a mirror pod
This commit is contained in:
parent
12ff2fe3f5
commit
12713b3ee4
@ -1629,11 +1629,13 @@ func (kl *Kubelet) syncPod(o syncPodOptions) error {
|
|||||||
if mirrorPod.DeletionTimestamp != nil || !kl.podManager.IsMirrorPodOf(mirrorPod, pod) {
|
if mirrorPod.DeletionTimestamp != nil || !kl.podManager.IsMirrorPodOf(mirrorPod, pod) {
|
||||||
// The mirror pod is semantically different from the static pod. Remove
|
// The mirror pod is semantically different from the static pod. Remove
|
||||||
// it. The mirror pod will get recreated later.
|
// it. The mirror pod will get recreated later.
|
||||||
klog.Warningf("Deleting mirror pod %q because it is outdated", format.Pod(mirrorPod))
|
klog.Infof("Trying to delete pod %s %v", podFullName, mirrorPod.ObjectMeta.UID)
|
||||||
if err := kl.podManager.DeleteMirrorPod(podFullName); err != nil {
|
var err error
|
||||||
|
deleted, err = kl.podManager.DeleteMirrorPod(podFullName, &mirrorPod.ObjectMeta.UID)
|
||||||
|
if deleted {
|
||||||
|
klog.Warningf("Deleted mirror pod %q because it is outdated", format.Pod(mirrorPod))
|
||||||
|
} else if err != nil {
|
||||||
klog.Errorf("Failed deleting mirror pod %q: %v", format.Pod(mirrorPod), err)
|
klog.Errorf("Failed deleting mirror pod %q: %v", format.Pod(mirrorPod), err)
|
||||||
} else {
|
|
||||||
deleted = true
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -20,6 +20,7 @@ import (
|
|||||||
"k8s.io/api/core/v1"
|
"k8s.io/api/core/v1"
|
||||||
"k8s.io/apimachinery/pkg/api/errors"
|
"k8s.io/apimachinery/pkg/api/errors"
|
||||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||||
|
"k8s.io/apimachinery/pkg/types"
|
||||||
clientset "k8s.io/client-go/kubernetes"
|
clientset "k8s.io/client-go/kubernetes"
|
||||||
"k8s.io/klog"
|
"k8s.io/klog"
|
||||||
kubecontainer "k8s.io/kubernetes/pkg/kubelet/container"
|
kubecontainer "k8s.io/kubernetes/pkg/kubelet/container"
|
||||||
@ -35,7 +36,7 @@ type MirrorClient interface {
|
|||||||
CreateMirrorPod(pod *v1.Pod) error
|
CreateMirrorPod(pod *v1.Pod) error
|
||||||
// DeleteMirrorPod deletes the mirror pod with the given full name from
|
// DeleteMirrorPod deletes the mirror pod with the given full name from
|
||||||
// the API server or returns an error.
|
// the API server or returns an error.
|
||||||
DeleteMirrorPod(podFullName string) error
|
DeleteMirrorPod(podFullName string, uid *types.UID) (bool, error)
|
||||||
}
|
}
|
||||||
|
|
||||||
// basicMirrorClient is a functional MirrorClient. Mirror pods are stored in
|
// basicMirrorClient is a functional MirrorClient. Mirror pods are stored in
|
||||||
@ -73,21 +74,35 @@ func (mc *basicMirrorClient) CreateMirrorPod(pod *v1.Pod) error {
|
|||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
func (mc *basicMirrorClient) DeleteMirrorPod(podFullName string) error {
|
// DeleteMirrorPod deletes a mirror pod.
|
||||||
|
// It takes the full name of the pod and optionally a UID. If the UID
|
||||||
|
// is non-nil, the pod is deleted only if its UID matches the supplied UID.
|
||||||
|
// It returns whether the pod was actually deleted, and any error returned
|
||||||
|
// while parsing the name of the pod.
|
||||||
|
// Non-existence of the pod or UID mismatch is not treated as an error; the
|
||||||
|
// routine simply returns false in that case.
|
||||||
|
func (mc *basicMirrorClient) DeleteMirrorPod(podFullName string, uid *types.UID) (bool, error) {
|
||||||
if mc.apiserverClient == nil {
|
if mc.apiserverClient == nil {
|
||||||
return nil
|
return false, nil
|
||||||
}
|
}
|
||||||
name, namespace, err := kubecontainer.ParsePodFullName(podFullName)
|
name, namespace, err := kubecontainer.ParsePodFullName(podFullName)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
klog.Errorf("Failed to parse a pod full name %q", podFullName)
|
klog.Errorf("Failed to parse a pod full name %q", podFullName)
|
||||||
return err
|
return false, err
|
||||||
}
|
}
|
||||||
klog.V(2).Infof("Deleting a mirror pod %q", podFullName)
|
klog.V(2).Infof("Deleting a mirror pod %q (uid %#v)", podFullName, uid)
|
||||||
// TODO(random-liu): Delete the mirror pod with uid precondition in mirror pod manager
|
var GracePeriodSeconds int64
|
||||||
if err := mc.apiserverClient.CoreV1().Pods(namespace).Delete(name, metav1.NewDeleteOptions(0)); err != nil && !errors.IsNotFound(err) {
|
GracePeriodSeconds = 0
|
||||||
|
if err := mc.apiserverClient.CoreV1().Pods(namespace).Delete(name, &metav1.DeleteOptions{GracePeriodSeconds: &GracePeriodSeconds, Preconditions: &metav1.Preconditions{UID: uid}}); err != nil {
|
||||||
|
// Unfortunately, there's no generic error for failing a precondition
|
||||||
|
if !(errors.IsNotFound(err) || errors.IsConflict(err)) {
|
||||||
|
// We should return the error here, but historically this routine does
|
||||||
|
// not return an error unless it can't parse the pod name
|
||||||
klog.Errorf("Failed deleting a mirror pod %q: %v", podFullName, err)
|
klog.Errorf("Failed deleting a mirror pod %q: %v", podFullName, err)
|
||||||
}
|
}
|
||||||
return nil
|
return false, nil
|
||||||
|
}
|
||||||
|
return true, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// IsStaticPod returns true if the pod is a static pod.
|
// IsStaticPod returns true if the pod is a static pod.
|
||||||
|
@ -338,7 +338,7 @@ func (pm *basicManager) getOrphanedMirrorPodNames() []string {
|
|||||||
func (pm *basicManager) DeleteOrphanedMirrorPods() {
|
func (pm *basicManager) DeleteOrphanedMirrorPods() {
|
||||||
podFullNames := pm.getOrphanedMirrorPodNames()
|
podFullNames := pm.getOrphanedMirrorPodNames()
|
||||||
for _, podFullName := range podFullNames {
|
for _, podFullName := range podFullNames {
|
||||||
pm.MirrorClient.DeleteMirrorPod(podFullName)
|
pm.MirrorClient.DeleteMirrorPod(podFullName, nil)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -20,6 +20,7 @@ import (
|
|||||||
"sync"
|
"sync"
|
||||||
|
|
||||||
"k8s.io/api/core/v1"
|
"k8s.io/api/core/v1"
|
||||||
|
"k8s.io/apimachinery/pkg/types"
|
||||||
"k8s.io/apimachinery/pkg/util/sets"
|
"k8s.io/apimachinery/pkg/util/sets"
|
||||||
cp "k8s.io/kubernetes/pkg/kubelet/checkpoint"
|
cp "k8s.io/kubernetes/pkg/kubelet/checkpoint"
|
||||||
"k8s.io/kubernetes/pkg/kubelet/checkpointmanager"
|
"k8s.io/kubernetes/pkg/kubelet/checkpointmanager"
|
||||||
@ -52,12 +53,13 @@ func (fmc *FakeMirrorClient) CreateMirrorPod(pod *v1.Pod) error {
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (fmc *FakeMirrorClient) DeleteMirrorPod(podFullName string) error {
|
// TODO (Robert Krawitz): Implement UID checking
|
||||||
|
func (fmc *FakeMirrorClient) DeleteMirrorPod(podFullName string, _ *types.UID) (bool, error) {
|
||||||
fmc.mirrorPodLock.Lock()
|
fmc.mirrorPodLock.Lock()
|
||||||
defer fmc.mirrorPodLock.Unlock()
|
defer fmc.mirrorPodLock.Unlock()
|
||||||
fmc.mirrorPods.Delete(podFullName)
|
fmc.mirrorPods.Delete(podFullName)
|
||||||
fmc.deleteCounts[podFullName]++
|
fmc.deleteCounts[podFullName]++
|
||||||
return nil
|
return true, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (fmc *FakeMirrorClient) HasPod(podFullName string) bool {
|
func (fmc *FakeMirrorClient) HasPod(podFullName string) bool {
|
||||||
|
@ -48,17 +48,17 @@ func (_m *MockManager) CreateMirrorPod(_a0 *v1.Pod) error {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// DeleteMirrorPod provides a mock function with given fields: podFullName
|
// DeleteMirrorPod provides a mock function with given fields: podFullName
|
||||||
func (_m *MockManager) DeleteMirrorPod(podFullName string) error {
|
func (_m *MockManager) DeleteMirrorPod(podFullName string, _ *types.UID) (bool, error) {
|
||||||
ret := _m.Called(podFullName)
|
ret := _m.Called(podFullName)
|
||||||
|
|
||||||
var r0 error
|
var r0 error
|
||||||
if rf, ok := ret.Get(0).(func(string) error); ok {
|
if rf, ok := ret.Get(0).(func(string) error); ok {
|
||||||
r0 = rf(podFullName)
|
return true, rf(podFullName)
|
||||||
} else {
|
} else {
|
||||||
r0 = ret.Error(0)
|
r0 = ret.Error(0)
|
||||||
}
|
}
|
||||||
|
|
||||||
return r0
|
return false, r0
|
||||||
}
|
}
|
||||||
|
|
||||||
// DeleteOrphanedMirrorPods provides a mock function with given fields:
|
// DeleteOrphanedMirrorPods provides a mock function with given fields:
|
||||||
|
Loading…
Reference in New Issue
Block a user