Search code examples
flaskflask-socketiokubernetes-python-client

Using flask socketio to follow kubernetes pod


I am trying to send kubernetes pod logs using socketio websocket to client, I can see the print(line_str) but socket cannot connect and cannot recieve anything under log_line event

@socketio.on('connect', namespace='/ws-connect')
def handle_connect():
    # Access the query parameters using the `request` object
    namespace = request.args.get('namespace')
    pod = request.args.get('pod')
    print('Following this pod -> ', namespace, pod)
    
    # Get the Kubernetes client and stream the pod logs
    v1 = client.CoreV1Api()

    stream = v1.read_namespaced_pod_log(name=pod, namespace=namespace, follow=True, _preload_content=False, tail_lines=20)
    
    # Send the log lines to the client
    for line in stream:
        # Decode the line from bytes to string
        line_str = line.decode('utf-8').strip()
        print(line_str)
        # Send the line to the client
        socketio.emit('log_line', {'line': line_str}, namespace='/ws-connect',broadcast=True)

request -> ws://localhost:5005/ws-connect?namespace=<ns>&pod=<pod_name>

Thread is not blocked I can still use flask for other endpoints, I just cannot connect through websocket. Any help is appreciated


Solution

  • Instead of doing every step in connect event, just parsed between events. Solution below works for me.

    # Global variables passed between flask methods
    is_disconnected = False
    pod= None
    namespace = None
    
    def follow_pod():
        global is_disconnected, pod, namespace
        # Get the Kubernetes client and stream the pod logs
        v1 = client.CoreV1Api()
    
        stream = v1.read_namespaced_pod_log(name=pod, namespace=namespace, follow=True, _preload_content=False, tail_lines=5)
        
        # Send the log lines to the client
        for line in stream:
            if is_disconnected:
                break
            # Decode the line from bytes to string
            line_str = line.decode('utf-8').strip()
            print(line_str)
            # Send the line to the client
            socketio.emit('log_line', {'line': line_str}, namespace='/ws-connect',broadcast=True)
    
        print("End Of following")
    
    @socketio.on('connect', namespace='/ws-connect')
    def handle_connect():
        global namespace, pod
        namespace = request.args.get('namespace')
        pod = request.args.get('pod')
    
    @socketio.on('follow_pod', namespace='/ws-connect')
    def handle_follow_pod(request):
        global is_disconnected
        is_disconnected=False
        follow_pod()
    
    @socketio.on('disconnect', namespace='/ws-connect')
    def handle_disconnect_pod(request):
        global is_disconnected
        is_disconnected = True