func newProxyCtnEnvArgs(ports *[]corev1.ServicePort, clusterIP string) *[]corev1.EnvVar {
	var builder strings.Builder
	for _, port := range *ports {
		builder.WriteString(clusterIP)
		builder.WriteString(constant.EnvArgSplitter)
		builder.WriteString(strconv.Itoa(int(port.Port)))
		builder.WriteString(constant.EnvArgSplitter)
		builder.WriteString(strconv.Itoa(int(port.Port)))
		builder.WriteString(constant.EnvArgSplitter)
		builder.WriteString(strings.ToLower(string(port.Protocol)))
		builder.WriteString(constant.EnvArgSplitter)
	}
	return &[]corev1.EnvVar{{
		Name:  "PROXY_ARGS",
		Value: builder.String(),
	}}
}
The only env variable is `PROXY_ARGS`
`PROXY_ARGS` is 4-tuple parameters split by space: <SVC_IP POD_PORT SVC_PORT SVC_PROTO>
package lb
import (
	"context"
	"os"
	"sort"
	"strconv"
	"strings"
	"github.com/kubesphere/porterlb/pkg/constant"
	"github.com/kubesphere/porterlb/pkg/util"
	"github.com/kubesphere/porterlb/pkg/validate"
	appsv1 "k8s.io/api/apps/v1"
	corev1 "k8s.io/api/core/v1"
	"k8s.io/apimachinery/pkg/api/errors"
	metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
	"k8s.io/apimachinery/pkg/runtime"
	"k8s.io/apimachinery/pkg/types"
	ctrl "sigs.k8s.io/controller-runtime"
	"sigs.k8s.io/controller-runtime/pkg/client"
	"sigs.k8s.io/controller-runtime/pkg/controller/controllerutil"
)
func isProxyResc(obj metav1.Object) bool {
	return obj.GetNamespace() == envNamespace() && strings.HasPrefix(obj.GetName(), constant.NodeProxyWorkloadPrefix)
}
func envNamespace() string {
	ns := os.Getenv(constant.EnvPorterNamespace)
	if ns == "" {
		return constant.PorterNamespace
	}
	return ns
}
func proxyRescName(svcName, svcNs string) string {
	return constant.NodeProxyWorkloadPrefix + svcName + constant.NameSeparator + svcNs
}
func svcName(rescName, svcNs string) string {
	return rescName[len(constant.NodeProxyWorkloadPrefix) : len(rescName)-len(svcNs)-len(constant.NameSeparator)]
}
func (r *ServiceReconciler) shouldReconcileDeDs(e metav1.Object) bool {
	if !isProxyResc(e) {
		return false
	}
	svc := &corev1.Service{}
	ns, ok := e.GetAnnotations()[constant.NodeProxyTypeAnnotationKey]
	if !ok {
		return false
	}
	err := r.Get(context.TODO(), types.NamespacedName{Namespace: ns, Name: svcName(e.GetName(), ns)}, svc)
	if err != nil {
		return !errors.IsNotFound(err)
	}
	return IsPorterNPService(svc)
}
func newProxyResc(svc *corev1.Service) *runtime.Object {
	var proxyResc runtime.Object
	switch svc.Annotations[constant.NodeProxyTypeAnnotationKey] {
	case constant.NodeProxyTypeDeployment:
		proxyResc = newProxyDe(svc)
	case constant.NodeProxyTypeDaemonSet:
		proxyResc = newProxyDs(svc)
	}
	return &proxyResc
}
func newProxyDe(svc *corev1.Service) *appsv1.Deployment {
	return &appsv1.Deployment{
		ObjectMeta: *newProxyRescOM(svc),
		Spec: appsv1.DeploymentSpec{
			Selector: newProxyRescSel(svc),
			Template: *newProxyPoTepl(svc),
		},
	}
}
func newProxyDs(svc *corev1.Service) *appsv1.DaemonSet {
	return &appsv1.DaemonSet{
		ObjectMeta: *newProxyRescOM(svc),
		Spec: appsv1.DaemonSetSpec{
			Selector: newProxyRescSel(svc),
			Template: *newProxyPoTepl(svc),
		},
	}
}
func newProxyRescAnno(svc *corev1.Service) *map[string]string {
	return &map[string]string{
		constant.PorterAnnotationKey:        constant.PorterAnnotationValue,
		constant.NodeProxyTypeAnnotationKey: svc.Namespace,
	}
}
func newProxyRescOM(svc *corev1.Service) *metav1.ObjectMeta {
	return &metav1.ObjectMeta{
		Name:        proxyRescName(svc.Name, svc.Namespace),
		Namespace:   envNamespace(),
		Annotations: *newProxyRescAnno(svc),
	}
}
func newProxyRescSel(svc *corev1.Service) *metav1.LabelSelector {
	return &metav1.LabelSelector{
		MatchLabels: map[string]string{
			"name": proxyRescName(svc.Name, svc.Namespace),
		},
	}
}
func newProxyPoTepl(svc *corev1.Service) *corev1.PodTemplateSpec {
	res := &corev1.PodTemplateSpec{
		ObjectMeta: metav1.ObjectMeta{
			Labels: map[string]string{"name": proxyRescName(svc.Name, svc.Namespace)},
		},
		Spec: corev1.PodSpec{
			Containers:     []corev1.Container{*newProxyCtn(svc)},
			InitContainers: []corev1.Container{*newForwardCtn(svc.Name)},
			Affinity: &corev1.Affinity{
				NodeAffinity: &corev1.NodeAffinity{
					RequiredDuringSchedulingIgnoredDuringExecution: &corev1.NodeSelector{
						NodeSelectorTerms: []corev1.NodeSelectorTerm{{
							MatchExpressions: []corev1.NodeSelectorRequirement{{
								Key:      constant.LabelNodeProxyExcludeNode,
								Operator: corev1.NodeSelectorOpDoesNotExist,
							}},
						}},
					},
					PreferredDuringSchedulingIgnoredDuringExecution: []corev1.PreferredSchedulingTerm{
						{
							Weight: 10,
							Preference: corev1.NodeSelectorTerm{
								MatchExpressions: []corev1.NodeSelectorRequirement{{
									Key:      constant.LabelNodeProxyExternalIPPreffered,
									Operator: corev1.NodeSelectorOpExists,
								}},
							},
						},
					},
				},
			},
			Tolerations: []corev1.Toleration{{
				Key:      constant.KubernetesMasterLabel,
				Operator: corev1.TolerationOpExists,
				Effect:   corev1.TaintEffectNoSchedule,
			}},
		},
	}
	return res
}