From 74e64b312a15250c757ae729b6f280ae5fb634c7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E2=80=9CNaeel=E2=80=9D?= Date: Fri, 10 Jul 2026 23:46:28 +0400 Subject: [PATCH] =?UTF-8?q?fix:=20kube-vip=20leader=20election=20+=20Gunic?= =?UTF-8?q?orn=20gevent,=20bump=201.0.8=E2=86=921.0.9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- History/2026-07-10-combined-fix.md | 37 ++++++++++++++++++++++++++++++ requirements.txt | 1 + site/app.py | 25 ++++++++++++++++++-- 3 files changed, 61 insertions(+), 2 deletions(-) create mode 100644 History/2026-07-10-combined-fix.md diff --git a/History/2026-07-10-combined-fix.md b/History/2026-07-10-combined-fix.md new file mode 100644 index 0000000..2942b78 --- /dev/null +++ b/History/2026-07-10-combined-fix.md @@ -0,0 +1,37 @@ +# 2026-07-10 — Комбинированный фикс + +## Два корня +1. kube-vip ARP без лидера → флаппинг между 4 нодами при каждом новом TCP +2. Werkzeug всегда `Connection: close` → новый TCP на каждый запрос + +По отдельности не чинят. Вместе должны. + +## План +### 1. kube-vip: vip_leaderelection=true +```bash +kubectl set env ds/shturval-vip -n kube-vip vip_leaderelection=true +``` + +### 2. Flask: Gunicorn + gevent +```python +# app.py +if __name__ == '__main__': + import gunicorn.app.base + class StandaloneApp(gunicorn.app.base.BaseApplication): + def __init__(self, app, options=None): + self.application = app; self.options = options or {} + super().__init__() + def load_config(self): + for k, v in self.options.items(): self.cfg.set(k, v) + def load(self): return self.application + StandaloneApp(app, { + 'bind': '0.0.0.0:5000', 'workers': 2, + 'worker_class': 'gevent', 'timeout': 120, 'keepalive': 75, + }).run() +``` + +### 3. requirements.txt +flask, gunicorn, gevent + +### 4. ingress +proxy_request_buffering: off (уже) diff --git a/requirements.txt b/requirements.txt index e4a286c..f51d321 100644 --- a/requirements.txt +++ b/requirements.txt @@ -1,2 +1,3 @@ flask gunicorn +gevent diff --git a/site/app.py b/site/app.py index 598ccbf..3b63b24 100644 --- a/site/app.py +++ b/site/app.py @@ -4,7 +4,7 @@ from flask import Flask, render_template, request app = Flask(__name__) -VERSION = '1.0.8' +VERSION = '1.0.9' @app.route('/') @@ -51,4 +51,25 @@ def upload(): if __name__ == '__main__': - app.run(host='0.0.0.0', port=5000, debug=False, threaded=True) + import gunicorn.app.base + + class StandaloneApp(gunicorn.app.base.BaseApplication): + def __init__(self, app, options=None): + self.application = app + self.options = options or {} + super().__init__() + + def load_config(self): + for k, v in self.options.items(): + self.cfg.set(k, v) + + def load(self): + return self.application + + StandaloneApp(app, { + 'bind': '0.0.0.0:5000', + 'workers': 2, + 'worker_class': 'gevent', + 'timeout': 120, + 'keepalive': 75, + }).run()