You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

为何我的Flask应用在AKS中仅单副本时能正常运行?

问题分析

你的问题核心是Flask默认采用内存级会话存储,当部署多副本(多个Pod)时,Kubernetes Service的轮询分发策略会将用户请求分配到不同Pod。登录后的会话仅存在单个Pod的内存中,若后续请求被路由到无会话记录的Pod,就会出现重定向失败、状态时好时坏的现象。

解决方案

1. 切换Flask会话到分布式存储

将Flask的会话存储从本地内存迁移到共享存储(如Redis),实现跨Pod的会话共享。

代码调整示例

先安装依赖:

pip install flask-session redis

修改Flask应用代码:

import os
from flask import Flask, session, redirect, url_for
from flask_session import Session
import redis

app = Flask(__name__)
# 从环境变量读取配置,避免硬编码
app.config['SESSION_TYPE'] = 'redis'
app.config['SESSION_REDIS'] = redis.from_url(os.getenv('REDIS_URL', 'redis://redis:6379'))
# 会话加密密钥,需确保所有副本一致
app.config['SECRET_KEY'] = os.getenv('SECRET_KEY', 'your-strong-secret-key-here')
# 初始化会话组件
Session(app)

# 登录逻辑示例
@app.route('/login', methods=['POST'])
def login():
    # 此处替换为你的用户验证逻辑
    session['user_id'] = 123
    return redirect(url_for('home'))

2. 在AKS内部部署Redis服务

创建Redis的Deployment和Service,为Flask提供共享会话存储:

# redis-deployment.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
  name: redis
spec:
  replicas: 1
  selector:
    matchLabels:
      app: redis
  template:
    metadata:
      labels:
        app: redis
    spec:
      containers:
      - name: redis
        image: redis:alpine
        ports:
        - containerPort: 6379
        # 可选:挂载持久化存储防止数据丢失
        volumeMounts:
        - name: redis-data
          mountPath: /data
      volumes:
      - name: redis-data
        persistentVolumeClaim:
          claimName: redis-pvc
---
# redis-service.yaml
apiVersion: v1
kind: Service
metadata:
  name: redis
spec:
  selector:
    app: redis
  ports:
  - port: 6379
    targetPort: 6379
---
# redis-pvc.yaml(可选,用于持久化Redis数据)
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
  name: redis-pvc
spec:
  accessModes:
    - ReadWriteOnce
  resources:
    requests:
      storage: 1Gi

执行部署命令:

kubectl apply -f redis-deployment.yaml

3. 更新Flask Deployment配置

修改你的Deployment.yaml,调整副本数并注入环境变量:

apiVersion: apps/v1
kind: Deployment
metadata:
  name: frontpage
  namespace: default
spec:
  replicas: 2  # 设置为需要的副本数
  selector:
    matchLabels:
      app: frontpage
  template:
    metadata:
      labels:
        app: frontpage
    spec:
      containers:
      - name: frontpage
        image: ***.azurecr.io/frontpage:latest
        ports:
        - containerPort: 5000
        env:
        - name: REDIS_URL
          value: redis://redis:6379
        - name: SECRET_KEY
          valueFrom:
            secretKeyRef:
              name: flask-secret
              key: SECRET_KEY

先创建存储密钥的Secret:

kubectl create secret generic flask-secret --from-literal=SECRET_KEY="your-strong-secret-key-here"

4. 临时方案:配置会话亲和性(不推荐)

如果暂时无法修改代码,可以通过Service的会话亲和性让同一用户请求固定路由到同一Pod,但此方案会降低负载均衡效果,且Pod重启后会话仍会丢失:

# 修改Service.yaml
apiVersion: v1
kind: Service
metadata:
  name: frontpage
  namespace: default
spec:
  selector:
    app: frontpage
  ports:
  - name: http
    port: 80
    targetPort: 5000
  type: ClusterIP
  sessionAffinity: ClientIP
  sessionAffinityConfig:
    clientIP:
      timeoutSeconds: 10800  # 3小时过期

内容的提问来源于stack exchange,提问作者Rakesh V

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.20 19:02:18