Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

lbaas-controller leaks floating IP addresses #28

Open
expektorans opened this issue Jun 8, 2022 · 1 comment
Open

lbaas-controller leaks floating IP addresses #28

expektorans opened this issue Jun 8, 2022 · 1 comment

Comments

@expektorans
Copy link

expektorans commented Jun 8, 2022

I've put lbaas under a bit of stress and could observe that it started to "leak" FIPs. "Leak" is here defined as "floating IPs that are allocated by lbaas to an OS project but are no longer actively used by it"

  • two FIPs that were created by lbaas no longer had their lbaas tag (they could be identified by their description)
  • several FIPs had a valid port but were no longer assigned to a k8s service
expektorans pushed a commit to expektorans/ch-k8s-lbaas that referenced this issue Jun 8, 2022
This commit fixes the collection of ports by storing the actual item
instead of the address of the loop variable in the list. An example,
because I find pointers confusing:

Let's say our actual ports are [1, 2, 3]. Previously, GetPorts returned
[3, 3, 3], and now we receive (as expected) [1, 2, 3].

I stumbled over this problem while applying force to lbaas by having a
script create and delete services at random intervals as well as
manually deleting the lbaas and the workload pod. This should resolve
the resource leaks observed in cloudandheat#28. If we're lucky this might also help
with lbaas eating FIPs.
@expektorans expektorans changed the title lbaas-controller leaks floating IP addresses (Draft) lbaas-controller leaks floating IP addresses Jun 8, 2022
@expektorans
Copy link
Author

This is my hack-ish stress script which wasn't cleaned up in any way.

#!/usr/bin/env python3

from functools import partial
from kubernetes import client, config, utils, watch, dynamic
from kubernetes.client import api_client
from threading import Thread
import random
import time

def task(name, port):
    svc_manifest = {
        "apiVersion": "v1",
        "kind": "Service",
        "metadata": {
            "labels": {
            "app": "nginx"
            },
            "name": name
        },
        "spec": {
            "ports": [
            {
                "port": port,
                "protocol": "TCP",
                "targetPort": 80
            }
            ],
            "selector": {
            "app": "nginx"
            },
            "type": "LoadBalancer"
        },
    }

    # Creating a dynamic client
    c = dynamic.DynamicClient(
        api_client.ApiClient(configuration=config.load_kube_config())
    )

    api = c.resources.get(api_version="v1", kind="Service")
    try:
        api.get(name=name, namespace="default")
        api.delete(name=name, namespace="default")
    except:
        print("Nothing to do")

    while True:
        api.create(body=svc_manifest, namespace="default")
        time.sleep(random.randint(0, 20))
        while True:
            svc = api.get(name=name, namespace="default")
            if svc["status"].get('loadBalancer', {}).get('ingress', []):
                print(f"Got an IP")
                break
            time.sleep(random.randint(0, 20))
        print("Deleting")
        time.sleep(random.randint(0, 20))
        api.delete(name=name, namespace="default")

def main():
    config.load_kube_config()
    for i,p in enumerate([80, 81, 80, 81, 80]):
        Thread(target=partial(task, name=f"nginx-{i}", port=p)).start()
    
if __name__ == '__main__':
    main()

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant