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
前端

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


浙公网安备 33010602011771号