diff --git a/apis/apps/v1alpha1/well_know_annotations.go b/apis/apps/v1alpha1/well_know_annotations.go new file mode 100644 index 0000000000..68f6b212ba --- /dev/null +++ b/apis/apps/v1alpha1/well_know_annotations.go @@ -0,0 +1,8 @@ +package v1alpha1 + +const ( + // AnnotationUsingEnhancedLiveness indicates that the enhanced liveness probe of pod is enabled. + AnnotationUsingEnhancedLiveness = "apps.kruise.io/using-enhanced-liveness" + // AnnotationUsingEnhancedLiveness indicates the backup probe (json types) of the pod native container livnessprobe configuration. + AnnotationNativeContainerProbeContext = "apps.kruise.io/container-probe-context" +) diff --git a/pkg/features/kruise_features.go b/pkg/features/kruise_features.go index 0d5112f870..45a0fce8e3 100644 --- a/pkg/features/kruise_features.go +++ b/pkg/features/kruise_features.go @@ -113,6 +113,9 @@ const ( // DeletionProtectionForCRDCascadingGate enable deletionProtection for crd Cascading DeletionProtectionForCRDCascadingGate featuregate.Feature = "DeletionProtectionForCRDCascadingGate" + + // Enables a enhanced livenessProbe solution + EnhancedLivenessProbeGate featuregate.Feature = "EnhancedLivenessProbe" ) var defaultFeatureGates = map[featuregate.Feature]featuregate.FeatureSpec{ @@ -135,11 +138,14 @@ var defaultFeatureGates = map[featuregate.Feature]featuregate.FeatureSpec{ SidecarTerminator: {Default: false, PreRelease: featuregate.Alpha}, PodProbeMarkerGate: {Default: true, PreRelease: featuregate.Alpha}, PreDownloadImageForDaemonSetUpdate: {Default: false, PreRelease: featuregate.Alpha}, - CloneSetEventHandlerOptimization: {Default: false, PreRelease: featuregate.Alpha}, - PreparingUpdateAsUpdate: {Default: false, PreRelease: featuregate.Alpha}, - ImagePullJobGate: {Default: false, PreRelease: featuregate.Alpha}, - ResourceDistributionGate: {Default: false, PreRelease: featuregate.Alpha}, - DeletionProtectionForCRDCascadingGate: {Default: false, PreRelease: featuregate.Alpha}, + + CloneSetEventHandlerOptimization: {Default: false, PreRelease: featuregate.Alpha}, + PreparingUpdateAsUpdate: {Default: false, PreRelease: featuregate.Alpha}, + ImagePullJobGate: {Default: false, PreRelease: featuregate.Alpha}, + ResourceDistributionGate: {Default: false, PreRelease: featuregate.Alpha}, + DeletionProtectionForCRDCascadingGate: {Default: false, PreRelease: featuregate.Alpha}, + + EnhancedLivenessProbeGate: {Default: false, PreRelease: featuregate.Alpha}, } func init() { @@ -167,6 +173,7 @@ func SetDefaultFeatureGates() { _ = utilfeature.DefaultMutableFeatureGate.Set(fmt.Sprintf("%s=false", PodUnavailableBudgetUpdateGate)) _ = utilfeature.DefaultMutableFeatureGate.Set(fmt.Sprintf("%s=false", WorkloadSpread)) _ = utilfeature.DefaultMutableFeatureGate.Set(fmt.Sprintf("%s=false", SidecarSetPatchPodMetadataDefaultsAllowed)) + _ = utilfeature.DefaultMutableFeatureGate.Set(fmt.Sprintf("%s=false", EnhancedLivenessProbeGate)) } if !utilfeature.DefaultFeatureGate.Enabled(KruiseDaemon) { _ = utilfeature.DefaultMutableFeatureGate.Set(fmt.Sprintf("%s=false", PreDownloadImageForInPlaceUpdate)) @@ -176,6 +183,7 @@ func SetDefaultFeatureGates() { _ = utilfeature.DefaultMutableFeatureGate.Set(fmt.Sprintf("%s=false", PodProbeMarkerGate)) _ = utilfeature.DefaultMutableFeatureGate.Set(fmt.Sprintf("%s=false", SidecarTerminator)) _ = utilfeature.DefaultMutableFeatureGate.Set(fmt.Sprintf("%s=false", ImagePullJobGate)) + _ = utilfeature.DefaultMutableFeatureGate.Set(fmt.Sprintf("%s=false", EnhancedLivenessProbeGate)) } if utilfeature.DefaultFeatureGate.Enabled(PreDownloadImageForInPlaceUpdate) || utilfeature.DefaultFeatureGate.Enabled(PreDownloadImageForDaemonSetUpdate) { _ = utilfeature.DefaultMutableFeatureGate.Set(fmt.Sprintf("%s=true", ImagePullJobGate)) diff --git a/pkg/webhook/pod/mutating/enhancedlivenessprobe_handler.go b/pkg/webhook/pod/mutating/enhancedlivenessprobe_handler.go new file mode 100644 index 0000000000..602592a0c6 --- /dev/null +++ b/pkg/webhook/pod/mutating/enhancedlivenessprobe_handler.go @@ -0,0 +1,88 @@ +package mutating + +import ( + "context" + "encoding/json" + "fmt" + + admissionv1 "k8s.io/api/admission/v1" + v1 "k8s.io/api/core/v1" + "k8s.io/klog/v2" + "sigs.k8s.io/controller-runtime/pkg/webhook/admission" + + alpha1 "github.com/openkruise/kruise/apis/apps/v1alpha1" + "github.com/openkruise/kruise/pkg/util" +) + +type containerLivenessProbe struct { + Name string `json:"name"` + LivenessProbe v1.Probe `json:"livenessProbe"` +} + +func (h *PodCreateHandler) enhancedLivenessProbeWhenPodCreate(ctx context.Context, req admission.Request, pod *v1.Pod) (skip bool, err error) { + + if len(req.AdmissionRequest.SubResource) > 0 || + req.AdmissionRequest.Operation != admissionv1.Create || + req.AdmissionRequest.Resource.Resource != "pods" { + return true, nil + } + + if !util.IsPodOwnedByKruise(pod) { + return true, nil + } + + if !usingEnhancedLivenessProbe(pod) { + return true, nil + } + + context, err := removeAndBackUpPodContainerLivenessProbe(pod) + if err != nil { + klog.Errorf("Remove pod (%v/%v) container livenessProbe config and backup error: %v", pod.Namespace, pod.Name, err) + return false, err + } + if context == "" { + return true, nil + } + klog.V(3).Infof("Mutating add pod(%s/%s) annotation[%s]=%s", pod.Namespace, pod.Name, alpha1.AnnotationNativeContainerProbeContext, context) + return false, nil +} + +// return two parameters: +// 1. the json string of the pod containers native livenessProbe configurations. +// 2. the error reason of the function. +func removeAndBackUpPodContainerLivenessProbe(pod *v1.Pod) (string, error) { + containersLivenessProbe := []containerLivenessProbe{} + for index := range pod.Spec.Containers { + getContainer := &pod.Spec.Containers[index] + if getContainer.LivenessProbe == nil { + continue + } + containersLivenessProbe = append(containersLivenessProbe, containerLivenessProbe{ + Name: getContainer.Name, + LivenessProbe: *getContainer.LivenessProbe, + }) + getContainer.LivenessProbe = nil + } + + if len(containersLivenessProbe) == 0 { + return "", nil + } + containersLivenessProbeRaw, err := json.Marshal(containersLivenessProbe) + if err != nil { + klog.Errorf("Failed to json marshal %v for pod: %v/%v, err: %v", + containersLivenessProbe, pod.Namespace, pod.Name, err) + return "", fmt.Errorf("Failed to json marshal %v for pod: %v/%v, err: %v", + containersLivenessProbe, pod.Namespace, pod.Name, err) + } + if pod.Annotations == nil { + pod.Annotations = map[string]string{} + } + pod.Annotations[alpha1.AnnotationNativeContainerProbeContext] = string(containersLivenessProbeRaw) + return pod.Annotations[alpha1.AnnotationNativeContainerProbeContext], nil +} + +// return one parameter: +// 1. the native container livenessprobe is enabled when the alpha1.AnnotationUsingEnhancedLiveness is true. +func usingEnhancedLivenessProbe(pod *v1.Pod) bool { + return pod.Annotations[alpha1.AnnotationUsingEnhancedLiveness] == "true" +} diff --git a/pkg/webhook/pod/mutating/enhancedlivenessprobe_handler_test.go b/pkg/webhook/pod/mutating/enhancedlivenessprobe_handler_test.go new file mode 100644 index 0000000000..468d16bad4 --- /dev/null +++ b/pkg/webhook/pod/mutating/enhancedlivenessprobe_handler_test.go @@ -0,0 +1,491 @@ +package mutating + +import ( + "context" + "reflect" + "testing" + + admissionv1 "k8s.io/api/admission/v1" + corev1 "k8s.io/api/core/v1" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/apimachinery/pkg/runtime" + "k8s.io/apimachinery/pkg/util/intstr" + "sigs.k8s.io/controller-runtime/pkg/client/fake" + "sigs.k8s.io/controller-runtime/pkg/webhook/admission" + + alpha1 "github.com/openkruise/kruise/apis/apps/v1alpha1" + clonesetutils "github.com/openkruise/kruise/pkg/controller/cloneset/utils" +) + +var ( + schema *runtime.Scheme +) + +func init() { + schema = runtime.NewScheme() + _ = corev1.AddToScheme(schema) +} + +func TestRemoveAndBackUpPodContainerLivenessProbe(t *testing.T) { + + testCases := []struct { + name string + pod *corev1.Pod + expectResult string + }{ + { + name: "livenessProbe configuration for standard container", + pod: &corev1.Pod{ + ObjectMeta: metav1.ObjectMeta{ + Name: "pod1", + Namespace: "namespace1", + }, + Spec: corev1.PodSpec{ + Containers: []corev1.Container{ + { + Name: "c1", + LivenessProbe: &corev1.Probe{ + FailureThreshold: 3, + InitialDelaySeconds: 3000, + PeriodSeconds: 100, + SuccessThreshold: 1, + TimeoutSeconds: 5, + ProbeHandler: corev1.ProbeHandler{ + HTTPGet: &corev1.HTTPGetAction{ + Path: "/health", + Port: intstr.IntOrString{ + Type: intstr.Int, + IntVal: 7001, + }, + Scheme: corev1.URISchemeHTTP, + }, + }, + }, + }, + }, + }, + }, + expectResult: `[{"name":"c1","livenessProbe":{"httpGet":{"path":"/health","port":7001,"scheme":"HTTP"},"initialDelaySeconds":3000,"timeoutSeconds":5,"periodSeconds":100,"successThreshold":1,"failureThreshold":3}}]`, + }, + { + name: "livenessProbe configuration for multi-standard containers", + pod: &corev1.Pod{ + ObjectMeta: metav1.ObjectMeta{ + Name: "pod2", + Namespace: "sp1", + }, + Spec: corev1.PodSpec{ + Containers: []corev1.Container{ + { + Name: "c1", + LivenessProbe: &corev1.Probe{ + FailureThreshold: 3, + InitialDelaySeconds: 3000, + PeriodSeconds: 100, + SuccessThreshold: 1, + TimeoutSeconds: 5, + ProbeHandler: corev1.ProbeHandler{ + HTTPGet: &corev1.HTTPGetAction{ + Path: "/health", + Port: intstr.IntOrString{ + Type: intstr.Int, + IntVal: 7001, + }, + Scheme: corev1.URISchemeHTTP, + }, + }, + }, + }, + { + Name: "c2", + LivenessProbe: &corev1.Probe{ + FailureThreshold: 3, + InitialDelaySeconds: 3000, + PeriodSeconds: 100, + SuccessThreshold: 1, + TimeoutSeconds: 5, + ProbeHandler: corev1.ProbeHandler{ + Exec: &corev1.ExecAction{ + Command: []string{ + "/home/admin/liveness.sh", + }, + }, + }, + }, + }, + }, + }, + }, + expectResult: `[{"name":"c1","livenessProbe":{"httpGet":{"path":"/health","port":7001,"scheme":"HTTP"},"initialDelaySeconds":3000,"timeoutSeconds":5,"periodSeconds":100,"successThreshold":1,"failureThreshold":3}},{"name":"c2","livenessProbe":{"exec":{"command":["/home/admin/liveness.sh"]},"initialDelaySeconds":3000,"timeoutSeconds":5,"periodSeconds":100,"successThreshold":1,"failureThreshold":3}}]`, + }, + { + name: "different livenssProbe configuration for multi-standard containers", + pod: &corev1.Pod{ + ObjectMeta: metav1.ObjectMeta{ + Name: "pod3", + Namespace: "sp1", + }, + Spec: corev1.PodSpec{ + Containers: []corev1.Container{ + { + Name: "c1", + LivenessProbe: &corev1.Probe{ + FailureThreshold: 3, + InitialDelaySeconds: 3000, + PeriodSeconds: 100, + SuccessThreshold: 1, + TimeoutSeconds: 5, + ProbeHandler: corev1.ProbeHandler{ + HTTPGet: &corev1.HTTPGetAction{ + Path: "/health", + Port: intstr.IntOrString{ + Type: intstr.Int, + IntVal: 7001, + }, + Scheme: corev1.URISchemeHTTP, + }, + }, + }, + }, + { + Name: "c2", + LivenessProbe: &corev1.Probe{ + FailureThreshold: 3, + InitialDelaySeconds: 3000, + PeriodSeconds: 100, + SuccessThreshold: 1, + TimeoutSeconds: 5, + ProbeHandler: corev1.ProbeHandler{ + Exec: &corev1.ExecAction{ + Command: []string{ + "/home/admin/liveness.sh", + }, + }, + }, + }, + }, + { + Name: "c3", + }, + }, + }, + }, + expectResult: `[{"name":"c1","livenessProbe":{"httpGet":{"path":"/health","port":7001,"scheme":"HTTP"},"initialDelaySeconds":3000,"timeoutSeconds":5,"periodSeconds":100,"successThreshold":1,"failureThreshold":3}},{"name":"c2","livenessProbe":{"exec":{"command":["/home/admin/liveness.sh"]},"initialDelaySeconds":3000,"timeoutSeconds":5,"periodSeconds":100,"successThreshold":1,"failureThreshold":3}}]`, + }, + { + name: "no livenessProbe configuration for standard container", + pod: &corev1.Pod{ + ObjectMeta: metav1.ObjectMeta{ + Name: "pod3", + Namespace: "sp1", + }, + Spec: corev1.PodSpec{ + Containers: []corev1.Container{ + { + Name: "c1", + }, + }, + }, + }, + }, + } + + for _, tc := range testCases { + t.Run(tc.name, func(t *testing.T) { + got, err := removeAndBackUpPodContainerLivenessProbe(tc.pod) + if err != nil { + t.Errorf("Test case: %v failed, err: %v", tc.name, err) + } + if !reflect.DeepEqual(got, tc.expectResult) { + t.Errorf("Test case: %v failed, expect: %v, but: %v", + tc.name, tc.expectResult, got) + } + }) + } +} + +func TestUsingEnhancedLivenessProbe(t *testing.T) { + testCases := []struct { + name string + pod *corev1.Pod + expectResult bool + }{ + { + name: "case no exist annotationUsingEnhancedLiveness in pod", + pod: &corev1.Pod{ + ObjectMeta: metav1.ObjectMeta{ + Name: "pod1", + Namespace: "default", + }, + }, + expectResult: false, + }, + { + name: "case exist annotationUsingEnhancedLiveness in pod", + pod: &corev1.Pod{ + ObjectMeta: metav1.ObjectMeta{ + Name: "pod1", + Namespace: "default", + Annotations: map[string]string{ + alpha1.AnnotationUsingEnhancedLiveness: "true", + }, + }, + }, + expectResult: true, + }, + { + name: "case exist reverse annotationUsingEnhancedLiveness in pod", + pod: &corev1.Pod{ + ObjectMeta: metav1.ObjectMeta{ + Name: "pod1", + Namespace: "default", + Annotations: map[string]string{ + alpha1.AnnotationUsingEnhancedLiveness: "false", + }, + }, + }, + expectResult: false, + }, + } + for _, tc := range testCases { + t.Run(tc.name, func(t *testing.T) { + got := usingEnhancedLivenessProbe(tc.pod) + if got != tc.expectResult { + t.Errorf("Test case: %v failed, expect: %v, but: %v", tc.name, tc.expectResult, got) + } + }) + } +} + +func TestRemoveAndBackUpPodContainerLivenessProbeLink(t *testing.T) { + + testCases := []struct { + name string + pod *corev1.Pod + expectPod *corev1.Pod + }{ + { + name: "case1: exist using enhanced liveness probe gate", + pod: &corev1.Pod{ + ObjectMeta: metav1.ObjectMeta{ + Name: "pod1", + Namespace: "sp1", + Annotations: map[string]string{ + alpha1.AnnotationUsingEnhancedLiveness: "true", + }, + ResourceVersion: "v1", + OwnerReferences: []metav1.OwnerReference{{ + APIVersion: clonesetutils.ControllerKind.GroupVersion().String(), + Kind: clonesetutils.ControllerKind.Kind, + Name: "cloneSet1", + UID: "1111-2222", + Controller: func() *bool { v := true; return &v }(), + BlockOwnerDeletion: func() *bool { v := true; return &v }(), + }}, + }, + Spec: corev1.PodSpec{ + Containers: []corev1.Container{ + { + Name: "c1", + LivenessProbe: &corev1.Probe{ + FailureThreshold: 3, + InitialDelaySeconds: 1000, + PeriodSeconds: 100, + SuccessThreshold: 2, + TimeoutSeconds: 5, + ProbeHandler: corev1.ProbeHandler{ + HTTPGet: &corev1.HTTPGetAction{ + Path: "/health", + Port: intstr.IntOrString{ + Type: intstr.Int, + IntVal: 7001, + }, + }, + }, + }, + }, + { + Name: "c2", + LivenessProbe: &corev1.Probe{ + FailureThreshold: 3, + InitialDelaySeconds: 1000, + PeriodSeconds: 100, + SuccessThreshold: 2, + TimeoutSeconds: 5, + ProbeHandler: corev1.ProbeHandler{ + TCPSocket: &corev1.TCPSocketAction{ + Port: intstr.IntOrString{ + Type: intstr.Int, + IntVal: 7001, + }, + }, + }, + }, + }, + }, + }, + }, + expectPod: &corev1.Pod{ + ObjectMeta: metav1.ObjectMeta{ + Name: "pod1", + Namespace: "sp1", + Annotations: map[string]string{ + alpha1.AnnotationUsingEnhancedLiveness: "true", + alpha1.AnnotationNativeContainerProbeContext: `[{"name":"c1","livenessProbe":{"httpGet":{"path":"/health","port":7001},"initialDelaySeconds":1000,"timeoutSeconds":5,"periodSeconds":100,"successThreshold":2,"failureThreshold":3}},{"name":"c2","livenessProbe":{"tcpSocket":{"port":7001},"initialDelaySeconds":1000,"timeoutSeconds":5,"periodSeconds":100,"successThreshold":2,"failureThreshold":3}}]`, + }, + ResourceVersion: "v1", + OwnerReferences: []metav1.OwnerReference{{ + APIVersion: clonesetutils.ControllerKind.GroupVersion().String(), + Kind: clonesetutils.ControllerKind.Kind, + Name: "cloneSet1", + UID: "1111-2222", + Controller: func() *bool { v := true; return &v }(), + BlockOwnerDeletion: func() *bool { v := true; return &v }(), + }}, + }, + Spec: corev1.PodSpec{ + Containers: []corev1.Container{ + { + Name: "c1", + }, + { + Name: "c2", + }, + }, + }, + }, + }, + { + name: "case2: no exist using enhanced liveness probe gate", + pod: &corev1.Pod{ + ObjectMeta: metav1.ObjectMeta{ + Name: "pod1", + Namespace: "sp1", + ResourceVersion: "v1", + OwnerReferences: []metav1.OwnerReference{{ + APIVersion: clonesetutils.ControllerKind.GroupVersion().String(), + Kind: clonesetutils.ControllerKind.Kind, + Name: "cloneSet1", + UID: "1111-2222", + Controller: func() *bool { v := true; return &v }(), + BlockOwnerDeletion: func() *bool { v := true; return &v }(), + }}, + }, + Spec: corev1.PodSpec{ + Containers: []corev1.Container{ + { + Name: "c1", + LivenessProbe: &corev1.Probe{ + FailureThreshold: 3, + InitialDelaySeconds: 1000, + PeriodSeconds: 100, + SuccessThreshold: 2, + TimeoutSeconds: 5, + ProbeHandler: corev1.ProbeHandler{ + HTTPGet: &corev1.HTTPGetAction{ + Path: "/health", + Port: intstr.IntOrString{ + Type: intstr.Int, + IntVal: 7001, + }, + }, + }, + }, + }, + { + Name: "c2", + LivenessProbe: &corev1.Probe{ + FailureThreshold: 3, + InitialDelaySeconds: 1000, + PeriodSeconds: 100, + SuccessThreshold: 2, + TimeoutSeconds: 5, + ProbeHandler: corev1.ProbeHandler{ + TCPSocket: &corev1.TCPSocketAction{ + Port: intstr.IntOrString{ + Type: intstr.Int, + IntVal: 7001, + }, + }, + }, + }, + }, + }, + }, + }, + expectPod: &corev1.Pod{ + ObjectMeta: metav1.ObjectMeta{ + Name: "pod1", + Namespace: "sp1", + ResourceVersion: "v1", + OwnerReferences: []metav1.OwnerReference{{ + APIVersion: clonesetutils.ControllerKind.GroupVersion().String(), + Kind: clonesetutils.ControllerKind.Kind, + Name: "cloneSet1", + UID: "1111-2222", + Controller: func() *bool { v := true; return &v }(), + BlockOwnerDeletion: func() *bool { v := true; return &v }(), + }}, + }, + Spec: corev1.PodSpec{ + Containers: []corev1.Container{ + { + Name: "c1", + LivenessProbe: &corev1.Probe{ + FailureThreshold: 3, + InitialDelaySeconds: 1000, + PeriodSeconds: 100, + SuccessThreshold: 2, + TimeoutSeconds: 5, + ProbeHandler: corev1.ProbeHandler{ + HTTPGet: &corev1.HTTPGetAction{ + Path: "/health", + Port: intstr.IntOrString{ + Type: intstr.Int, + IntVal: 7001, + }, + }, + }, + }, + }, + { + Name: "c2", + LivenessProbe: &corev1.Probe{ + FailureThreshold: 3, + InitialDelaySeconds: 1000, + PeriodSeconds: 100, + SuccessThreshold: 2, + TimeoutSeconds: 5, + ProbeHandler: corev1.ProbeHandler{ + TCPSocket: &corev1.TCPSocketAction{ + Port: intstr.IntOrString{ + Type: intstr.Int, + IntVal: 7001, + }, + }, + }, + }, + }, + }, + }, + }, + }, + } + for _, tc := range testCases { + t.Run(tc.name, func(t *testing.T) { + podIn := tc.pod + decoder, _ := admission.NewDecoder(schema) + client := fake.NewClientBuilder().WithScheme(schema).WithObjects(podIn).Build() + podOut := podIn.DeepCopy() + podHandler := &PodCreateHandler{Decoder: decoder, Client: client} + req := newAdmission(admissionv1.Create, runtime.RawExtension{}, runtime.RawExtension{}, "") + _, err := podHandler.enhancedLivenessProbeWhenPodCreate(context.Background(), req, podOut) + if err != nil { + t.Errorf("enhanced liveness probe when pod create failed, err: %v", err) + } + if !reflect.DeepEqual(tc.expectPod, podOut) { + t.Errorf("pod DeepEqual failed") + } + }) + } +} diff --git a/pkg/webhook/pod/mutating/pod_create_update_handler.go b/pkg/webhook/pod/mutating/pod_create_update_handler.go index 9e1a62cc06..09c1665616 100644 --- a/pkg/webhook/pod/mutating/pod_create_update_handler.go +++ b/pkg/webhook/pod/mutating/pod_create_update_handler.go @@ -21,13 +21,14 @@ import ( "encoding/json" "net/http" - "github.com/openkruise/kruise/pkg/features" - "github.com/openkruise/kruise/pkg/util/controllerfinder" - utilfeature "github.com/openkruise/kruise/pkg/util/feature" corev1 "k8s.io/api/core/v1" "sigs.k8s.io/controller-runtime/pkg/client" "sigs.k8s.io/controller-runtime/pkg/runtime/inject" "sigs.k8s.io/controller-runtime/pkg/webhook/admission" + + "github.com/openkruise/kruise/pkg/features" + "github.com/openkruise/kruise/pkg/util/controllerfinder" + utilfeature "github.com/openkruise/kruise/pkg/util/feature" ) // PodCreateHandler handles Pod @@ -103,6 +104,15 @@ func (h *PodCreateHandler) Handle(ctx context.Context, req admission.Request) ad changed = true } + // EnhancedLivenessProbe enabled + if utilfeature.DefaultFeatureGate.Enabled(features.EnhancedLivenessProbeGate) { + if skip, err := h.enhancedLivenessProbeWhenPodCreate(ctx, req, obj); err != nil { + return admission.Errored(http.StatusInternalServerError, err) + } else if !skip { + changed = true + } + } + if !changed { return admission.Allowed("") } diff --git a/test/e2e/apps/pullimages.go b/test/e2e/apps/pullimages.go index 4a87cc264d..3596e27b72 100644 --- a/test/e2e/apps/pullimages.go +++ b/test/e2e/apps/pullimages.go @@ -26,11 +26,6 @@ import ( "github.com/onsi/ginkgo" "github.com/onsi/gomega" - appsv1alpha1 "github.com/openkruise/kruise/apis/apps/v1alpha1" - kruiseclientset "github.com/openkruise/kruise/pkg/client/clientset/versioned" - "github.com/openkruise/kruise/pkg/controller/imagepulljob" - "github.com/openkruise/kruise/pkg/util" - "github.com/openkruise/kruise/test/e2e/framework" v1 "k8s.io/api/core/v1" "k8s.io/apimachinery/pkg/api/errors" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" @@ -41,6 +36,12 @@ import ( "k8s.io/klog/v2" utilpointer "k8s.io/utils/pointer" "sigs.k8s.io/controller-runtime/pkg/client" + + appsv1alpha1 "github.com/openkruise/kruise/apis/apps/v1alpha1" + kruiseclientset "github.com/openkruise/kruise/pkg/client/clientset/versioned" + "github.com/openkruise/kruise/pkg/controller/imagepulljob" + "github.com/openkruise/kruise/pkg/util" + "github.com/openkruise/kruise/test/e2e/framework" ) var _ = SIGDescribe("PullImage", func() {