flask k8s websocket连接pod执行

handle.py

 

	...
	def _terminal_start(self, namespace, pod_name, container):
		command = [
			"/bin/sh",
			"-c",
			'TERM=xterm-256color; export TERM; [ -x /bin/bash ] '
			'&& ([ -x /usr/bin/script ] '
			'&& /usr/bin/script -q -c "/bin/bash" /dev/null || exec /bin/bash) '
			'|| exec /bin/sh']

		container_stream = stream(
			self.coreapi.connect_get_namespaced_pod_exec,
			name=pod_name,
			namespace=namespace,
			container=container,
			command=command,
			stderr=True, stdin=True,
			stdout=True, tty=True,
			_preload_content=False
		)

		return container_stream

	def terminal(self, ws, namespace, pod, container):
		'''webconsole'''
		log.info('Try create socket connection')
		try:
			container_stream = self._terminal_start(namespace, pod, container)
		except Exception as err:
			log.error('Connect container error: {}'.format(err))
			ws.close()
			return

		kub_stream = K8SStreamThread(ws, container_stream)
		kub_stream.start()

		log.info('Start terminal')
		try:
			while not ws.closed:
				message = ws.receive()
				if message is not None and message != '__ping__':
					container_stream.write_stdin(message)
			container_stream.write_stdin('exit\r')
		except Exception as err:
			log.error('Connect container error: {}'.format(err))
		finally:
			container_stream.close()
			ws.close()
	...

class K8SStreamThread(Thread):

    def __init__(self, ws, container_stream):
        super(K8SStreamThread, self).__init__()
        self.ws = ws
        self.stream = container_stream

    def run(self):
        while not self.ws.closed:

            if not self.stream.is_open():
                log.info('container stream closed')
                self.ws.close()

            try:
                if self.stream.peek_stdout():
                    stdout = self.stream.read_stdout()
                    self.ws.send(stdout)

                if self.stream.peek_stderr():
                    stderr = self.stream.read_stderr()
                    self.ws.send(stderr)
            except Exception as err:
                log.error('container stream err: {}'.format(err))
                self.ws.close()
                break

  

manage.py

#!/usr/bin/env python
# -*- coding:utf-8 -*-
from flask_migrate import Migrate, MigrateCommand
from flask import request
from app import create_app, db
from flask_sockets import Sockets
from app.common.models import User
from flask_script import Manager, Shell
from gevent import pywsgi
from geventwebsocket.handler import WebSocketHandler
from flask_sqlalchemy import SQLAlchemy, get_debug_queries
from werkzeug import serving
from app.common.log import log
from app.kubernetes.handle import KubernetesAPI, K8SStreamThread
import sys

# 创建app
app = create_app()
migrate = Migrate(app, db)
manager = Manager(app)
sockets = Sockets(app)


def make_shell_context():
    return dict(app=app, db=db, User=User)


# 配置shell在命令行操作测试数据库
manager.add_command("shell", Shell(make_context=make_shell_context))
manager.add_command('db', MigrateCommand)


# 勿删,用来检查 查询数据过慢时是否存在慢查询
# @app.after_request
# def after_request(response):
#     for query in get_debug_queries():
#         print(query.statement,query.duration)
#         if query.duration >= app.config['FLASKY_DB_QUERY_TIMEOUT']:
#              # query.statement:查询的sql
#              # query.duration: 耗时
#              # 打印超时sql和时间
#              print('----慢sql-----\t\nsql:\t\n {sql} \t\n耗时:{duration}'.format(sql=query.statement,duration=query.duration))
#     return response

# socket请求
@sockets.route('/terminal')
def terminal_socket(ws):
    cluster_name = request.args.get('cluster_name')
    namespace = request.args.get('namespace')
    pod = request.args.get('pod')
    container = request.args.get('container')
    log.info(namespace)
    log.info(pod)
    log.info(container)
    log.info('Try create socket connection')
    kub = KubernetesAPI(cluster_name)
    try:
        container_stream = kub.terminal(ws, namespace, pod, container)
    except Exception as err:
        log.error('Connect container error: {}'.format(err))
        ws.close()
        return

    kub_stream = K8SStreamThread(ws, container_stream)
    kub_stream.start()

    log.info('Start terminal')
    try:
        while not ws.closed:
            message = ws.receive()
            if message is not None and message != '__ping__':
                container_stream.write_stdin(message)
        container_stream.write_stdin('exit\r')
    except Exception as err:
        log.error('Connect container error: {}'.format(err))
    finally:
        if container_stream:
            container_stream.close()
        ws.close()


@serving.run_with_reloader
def run_server():
    app.debug = True
    server = pywsgi.WSGIServer(
        listener=('0.0.0.0', 8080),
        application=app,
        handler_class=WebSocketHandler)
    server.serve_forever()


if __name__ == '__main__':
    run_server()

 注意:这样做了之后,uwsgi启动 ws连接不上,需要这样运行

python manage.py runserver

  

前端

 

 

后来发现可以在 模块初始化文件里这样写

 

posted @ 2023-06-02 14:48  醒日是归时  阅读(35)  评论(0)    收藏  举报