hotfix: restore service target port while leave resource in gvisor mode (#476)

This commit is contained in:
naison
2025-03-16 17:04:55 +08:00
committed by GitHub
parent b5ea7b2016
commit b6f90812f7
5 changed files with 47 additions and 17 deletions

View File

@@ -6,6 +6,7 @@ import (
"time"
log "github.com/sirupsen/logrus"
"k8s.io/apimachinery/pkg/apis/meta/v1/unstructured"
"github.com/wencaiwulue/kubevpn/v2/pkg/config"
"github.com/wencaiwulue/kubevpn/v2/pkg/controlplane"
@@ -38,8 +39,15 @@ func (svr *Server) Leave(req *rpc.LeaveRequest, resp rpc.Daemon_LeaveServer) err
log.Errorf("Failed to get unstructured object: %v", err)
return err
}
u := object.Object.(*unstructured.Unstructured)
templateSpec, _, err := util.GetPodTemplateSpecPath(u)
if err != nil {
log.Errorf("Failed to get template spec path: %v", err)
return err
}
// add rollback func to remove envoy config
err = inject.UnPatchContainer(factory, maps, object, func(isFargateMode bool, rule *controlplane.Rule) bool {
var empty bool
empty, err = inject.UnPatchContainer(factory, maps, object, func(isFargateMode bool, rule *controlplane.Rule) bool {
if isFargateMode {
return svr.connect.IsMe(util.ConvertWorkloadToUid(workload), rule.Headers)
}
@@ -49,6 +57,9 @@ func (svr *Server) Leave(req *rpc.LeaveRequest, resp rpc.Daemon_LeaveServer) err
log.Errorf("Leaving workload %s failed: %v", workload, err)
continue
}
if empty {
err = inject.ModifyServiceTargetPort(resp.Context(), svr.connect.GetClientset(), namespace, templateSpec.Labels, map[int32]int32{})
}
svr.connect.LeavePortMap(workload)
err = util.RolloutStatus(resp.Context(), factory, namespace, workload, time.Minute*60)
}

View File

@@ -43,12 +43,13 @@ func createOutboundPod(ctx context.Context, factory cmdutil.Factory, clientset *
}
var deleteResource = func(ctx context.Context) {
options := metav1.DeleteOptions{}
_ = clientset.AdmissionregistrationV1().MutatingWebhookConfigurations().Delete(ctx, config.ConfigMapPodTrafficManager+"."+namespace, options)
_ = clientset.RbacV1().RoleBindings(namespace).Delete(ctx, config.ConfigMapPodTrafficManager, options)
_ = clientset.RbacV1().Roles(namespace).Delete(ctx, config.ConfigMapPodTrafficManager, options)
_ = clientset.CoreV1().ServiceAccounts(namespace).Delete(ctx, config.ConfigMapPodTrafficManager, options)
_ = clientset.CoreV1().Services(namespace).Delete(ctx, config.ConfigMapPodTrafficManager, options)
_ = clientset.AppsV1().Deployments(namespace).Delete(ctx, config.ConfigMapPodTrafficManager, options)
name := config.ConfigMapPodTrafficManager
_ = clientset.AdmissionregistrationV1().MutatingWebhookConfigurations().Delete(ctx, name+"."+namespace, options)
_ = clientset.RbacV1().RoleBindings(namespace).Delete(ctx, name, options)
_ = clientset.RbacV1().Roles(namespace).Delete(ctx, name, options)
_ = clientset.CoreV1().ServiceAccounts(namespace).Delete(ctx, name, options)
_ = clientset.CoreV1().Services(namespace).Delete(ctx, name, options)
_ = clientset.AppsV1().Deployments(namespace).Delete(ctx, name, options)
}
defer func() {
if err != nil {

View File

@@ -9,6 +9,7 @@ import (
corev1 "k8s.io/api/core/v1"
apierrors "k8s.io/apimachinery/pkg/api/errors"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/apimachinery/pkg/apis/meta/v1/unstructured"
"k8s.io/utils/pointer"
"sigs.k8s.io/yaml"
@@ -95,7 +96,14 @@ func (c *ConnectOptions) LeaveAllProxyResources(ctx context.Context) (err error)
log.Errorf("Failed to get unstructured object: %v", err)
return err
}
err = inject.UnPatchContainer(c.factory, c.clientset.CoreV1().ConfigMaps(c.Namespace), object, func(isFargateMode bool, rule *controlplane.Rule) bool {
u := object.Object.(*unstructured.Unstructured)
templateSpec, _, err := util.GetPodTemplateSpecPath(u)
if err != nil {
log.Errorf("Failed to get template spec path: %v", err)
return err
}
var empty bool
empty, err = inject.UnPatchContainer(c.factory, c.clientset.CoreV1().ConfigMaps(c.Namespace), object, func(isFargateMode bool, rule *controlplane.Rule) bool {
if isFargateMode {
return c.IsMe(util.ConvertWorkloadToUid(workload), rule.Headers)
}
@@ -105,6 +113,9 @@ func (c *ConnectOptions) LeaveAllProxyResources(ctx context.Context) (err error)
log.Errorf("Failed to leave workload %s: %v", workload, err)
continue
}
if empty {
err = inject.ModifyServiceTargetPort(ctx, c.clientset, c.Namespace, templateSpec.Labels, map[int32]int32{})
}
c.LeavePortMap(workload)
}
return err

View File

@@ -108,6 +108,9 @@ func ModifyServiceTargetPort(ctx context.Context, clientset *kubernetes.Clientse
var svc *v1.Service
for _, item := range list.Items {
if item.Spec.Selector == nil {
continue
}
if labels.SelectorFromSet(item.Spec.Selector).Matches(labels.Set(podLabels)) {
svc = &item
break
@@ -117,7 +120,11 @@ func ModifyServiceTargetPort(ctx context.Context, clientset *kubernetes.Clientse
return fmt.Errorf("can not found service with selector: %v", podLabels)
}
for i := range len(svc.Spec.Ports) {
svc.Spec.Ports[i].TargetPort = intstr.FromInt32(m[svc.Spec.Ports[i].Port])
if p, found := m[svc.Spec.Ports[i].Port]; found {
svc.Spec.Ports[i].TargetPort = intstr.FromInt32(p)
} else {
svc.Spec.Ports[i].TargetPort = intstr.FromInt32(svc.Spec.Ports[i].Port)
}
}
_, err = clientset.CoreV1().Services(namespace).Update(ctx, svc, metav1.UpdateOptions{})
return err

View File

@@ -114,12 +114,12 @@ func InjectVPNAndEnvoySidecar(ctx context.Context, f cmdutil.Factory, clientset
return err
}
func UnPatchContainer(factory cmdutil.Factory, mapInterface v12.ConfigMapInterface, object *runtimeresource.Info, isMeFunc func(isFargateMode bool, rule *controlplane.Rule) bool) error {
func UnPatchContainer(factory cmdutil.Factory, mapInterface v12.ConfigMapInterface, object *runtimeresource.Info, isMeFunc func(isFargateMode bool, rule *controlplane.Rule) bool) (bool, error) {
u := object.Object.(*unstructured.Unstructured)
templateSpec, depth, err := util.GetPodTemplateSpecPath(u)
if err != nil {
log.Errorf("Failed to get template spec path: %v", err)
return err
return false, err
}
nodeID := fmt.Sprintf("%s.%s", object.Mapping.Resource.GroupResource().String(), object.Name)
@@ -128,11 +128,11 @@ func UnPatchContainer(factory cmdutil.Factory, mapInterface v12.ConfigMapInterfa
empty, found, err = removeEnvoyConfig(mapInterface, nodeID, isMeFunc)
if err != nil {
log.Errorf("Failed to remove envoy config: %v", err)
return err
return false, err
}
if !found {
log.Infof("Not found proxy resource %s", workload)
return nil
return false, nil
}
log.Infof("Leaving workload %s", workload)
@@ -147,7 +147,7 @@ func UnPatchContainer(factory cmdutil.Factory, mapInterface v12.ConfigMapInterfa
pod := &v1.Pod{ObjectMeta: templateSpec.ObjectMeta, Spec: templateSpec.Spec}
CleanupUselessInfo(pod)
err = CreateAfterDeletePod(factory, pod, helper)
return err
return empty, err
}
log.Debugf("The %s is under controller management", workload)
@@ -162,15 +162,15 @@ func UnPatchContainer(factory cmdutil.Factory, mapInterface v12.ConfigMapInterfa
})
if err != nil {
log.Errorf("Failed to generate json patch: %v", err)
return err
return empty, err
}
_, err = helper.Patch(object.Namespace, object.Name, types.JSONPatchType, bytes, &metav1.PatchOptions{})
if err != nil {
log.Errorf("Failed to patch resource: %s %s: %v", object.Mapping.Resource.Resource, object.Name, err)
return err
return empty, err
}
}
return err
return empty, err
}
func addEnvoyConfig(mapInterface v12.ConfigMapInterface, nodeID string, tunIP util.PodRouteConfig, headers map[string]string, port []controlplane.ContainerPort, portmap map[int32]string) error {