F5Networks / k8s-bigip-ctlr

Repository for F5 Container Ingress Services for Kubernetes & OpenShift.
Apache License 2.0
362 stars 195 forks source link

syn configmap using the old way to query api server in Hub Mode #3568

Open kylinsoong opened 1 month ago

kylinsoong commented 1 month ago

syn configmap using the old way to query api server in Hub Mode

While syn configmap, the service usually resident the watched namespce, and had appInf bounded, however getServicesForHubMode stilll use the old way, this can further enhance to performance.

func (appMgr *Manager) getServicesForHubMode(selector, namespace string, isTenantNameServiceNamespace bool) ([]v1.Service, error) {
    var svcItems []v1.Service
    if isTenantNameServiceNamespace {
        if appInf, infFound := appMgr.getNamespaceInformer(namespace); infFound {
            svcInformer := appInf.svcInformer
            svcLister := listerscorev1.NewServiceLister(svcInformer.GetIndexer())
            ls, _ := createLabel(selector)
            svcListed, _ := svcLister.Services(namespace).List(ls)

            for n, _ := range svcListed {
                svcItems = append(svcItems, *svcListed[n])
            }
            log.Debugf("[CORE] Extract service via watch-list informer '%s'", namespace)
            return svcItems, nil
        }
    }
    // Leaving the old way for hubMode for now.
    svcListOptions := metav1.ListOptions{
        LabelSelector: selector,
    }
    services, err := appMgr.kubeClient.CoreV1().Services(v1.NamespaceAll).List(context.TODO(), svcListOptions)

    if err != nil {
        log.Errorf("[CORE] Error getting service list. %v", err)
        return nil, err
    }
    svcItems = services.Items
    log.Debugf("[CORE] Query service via '%v'", selector)
    return svcItems, nil
}

The invocation of this function in syncConfigMaps looks:

members, err := appMgr.getEndpoints(selector, sKey.Namespace, false)
kylinsoong commented 1 month ago

Samiliar requirements in getEndpointForHub:

func (appMgr *Manager) getEndpointsForHubMode(svcName, svcNamespace string, isTenantNameServiceNamespace bool) (*v1.Endpoints, error) {
    var eps *v1.Endpoints
    if isTenantNameServiceNamespace {
        if appInf, infFound := appMgr.getNamespaceInformer(svcNamespace); infFound {
            if item, found, _ := appInf.endptInformer.GetStore().GetByKey(svcNamespace + "/" + svcName); found {
                eps, _ = item.(*v1.Endpoints)
            }
            return eps, nil
        }
    }
    // Leaving the old way for hubMode for now.
    endpointsList, err := appMgr.kubeClient.CoreV1().Endpoints(svcNamespace).List(context.TODO(),
        metav1.ListOptions{
            FieldSelector: "metadata.name=" + svcName,
        },
    )
    if err != nil {
        return nil, err
    }
    if len(endpointsList.Items) == 0 {
        return eps, nil
    }
    eps = &endpointsList.Items[0]
    return eps, nil
}
vklohiya commented 1 month ago

@kylinsoong , As in the hubmode services can exist in any namespace other-than the configMap namespace hence, we need to query using kube-api server, as informer may or may not exist for the namespace, where service is residing.

If you use isTenantNameServiceNamespace label, it will use the informers and if informers are not found than fall back to kube-api server query.

kylinsoong commented 1 month ago

Thanks @vklohiya, can we use the similar logic in appMgr's syncConfigMaps?

Currently only AS3 Manager get GetEndpoints use the IsTenantNameServiceNamespace, however the APP Manager get GetEndpoints passed false, which thoughts the IsTenantNameServiceNamespace is not set.

On the other side, periodicly syn virtual server are always against the service that has watched with informer referenced.

members, err := appMgr.getEndpoints(selector, sKey.Namespace, false)

The below is getEndpoints in AS3 Manager

                if val, ok := rscCfgMap.Label[IsTenantNameServiceNamespace]; ok && val == TrueLabel {
                    eps, err = rscCfgMap.GetEndpoints(am.getSelector(tnt, app, pn), string(tnt), true)
                } else {
                    eps, err = rscCfgMap.GetEndpoints(am.getSelector(tnt, app, pn), rscCfgMap.Namespace, false)
                }
trinaths commented 3 weeks ago

Created [CONTCNTR-4952] for internal tracking.