Flask 个人站 iProfile 上线笔记(k3s + Nginx + Let‘s Encrypt)

一、技术栈全景

层 选型 说明
Web 框架 Flask 3.0 + Jinja2 零构建,模板直出 HTML
前端 Bootstrap 5 + Bootstrap Icons + Google Fonts CDN 引入,无需打包
WSGI Gunicorn 2 worker,0.0.0.0:8000
容器 Docker (python:3.12-slim) 非 root 运行,多阶段缓存依赖
编排 k3s + Kubernetes 清单 无状态,NodePort 30081 暴露
反代 Nginx 静态资源直出 + gzip + 反代 8000
证书 Let's Encrypt (certbot) 自动续期 HTTPS
邮件提醒 smtplib (SMTP_SSL) 询盘实时发邮件,未配置则静默跳过

二、服务整体编排结构

复制代码
                        ┌────────────────────────────┐
   浏览器(HTTPS 443) ──►│  Nginx 反向代理            │
                        │  - 静态 /static/ 直接返回    │
                        │  - 动态 / 转发到 upstream    │
                        └────────────┬───────────────┘
                                     │ proxy_pass
                                     ▼
                         ┌──────────────────────────┐
                         │ k3s NodePort :30081       │
                         │ ┌──────────────────────┐ │
                         │ │ Service iprofile-web  │ │
                         │ └──────────┬───────────┘ │
                         │            │  selector    │
                         │ ┌──────────▼───────────┐ │
                         │ │ Deployment           │ │
                         │ │  iprofile-web:latest │ │
                         │ │  replicas=1          │ │
                         │ │  probes: 就绪+存活    │ │
                         │ └──────────┬───────────┘ │
                         │            │             │
                         │   Secret: SECRET_KEY ◄──┘ (env 注入)
                         └──────────────────────────┘

  邮件(SMTP_SSL): 环境变量 MAIL_HOST/PORT/USER/PASSWORD/TO

三、关键设计点

1. 配置全走环境变量,代码零硬编码

复制代码
app.secret_key = os.environ.get('SECRET_KEY', os.urandom(24))
# SMTP 未配置时静默降级,不影响站点可用性
if not (host and user and password and to):
    print('[mail] SMTP not configured; skipping')
    return False

2. 容器安全

  • python:3.12-slim 精简镜像
  • PYTHONDONTWRITEBYTECODE / PYTHONUNBUFFERED 生产优化
  • 新建 appuser 非 root 运行
  • .dockerignore 排除敏感/冗余目录

3. k8s 清单三段式(Namespace / Secret / Deployment+Service)

  • Secret 用 stringData 注入 SECRET_KEY
  • Deployment 配了 readinessProbe 和 livenessProbe(GET /)
  • RollingUpdate :maxSurge:1, maxUnavailable:0 滚动无中断
  • 资源限制 :request 50m/64Mi,limit 500m/256Mi(一台小 VPS 也能扛)
  • Service 用 NodePort 30081(和已有服务 30080 同一套暴露模式)

4. Nginx 双层配置(上线顺序的关键)

  • init.conf:先上 HTTP 版,跑完 certbot 拿到证书
  • web.liousa.site.conf:再切换 HTTPS 版,带完整 SSL + 安全头 + gzip

5. Nginx 性能细节

  • 静态资源 expires 30d 强缓存 + gzip
  • proxy_http_version 1.1 + keepalive 8 连接复用
  • 安全头:X-Frame-Options / X-Content-Type-Options / Referrer-Policy

四、部署步骤

复制代码
# 1. 构建镜像(k3s 节点本地)
docker build -t iprofile-web:latest .

# 2. 应用 k8s 清单(自动建 ns/secret/deploy/svc)
kubectl apply -f k8s/iprofile.yaml

# 3. 验证
kubectl -n iprofile get pods,svc

# 4. Nginx 先上 HTTP 引导配置
sudo cp deploy/nginx/web.liousa.site.init.conf /etc/nginx/sites-available/web.liousa.site
sudo ln -sf /etc/nginx/sites-available/web.liousa.site /etc/nginx/sites-enabled/
sudo nginx -t && sudo systemctl reload nginx

# 5. 申请证书(免费 HTTPS)
sudo certbot --nginx -d web.liousa.site

# 6. 切换正式 HTTPS 配置
sudo cp deploy/nginx/web.liousa.site.conf /etc/nginx/sites-available/web.liousa.site
sudo nginx -t && sudo systemctl reload nginx

五、上线遇到的问题

  1. 容器内 vs 宿主机端口要分清 :Gunicorn 在容器里监听 0.0.0.0:8000,k8s 再映射到 NodePort 30081,最终 Nginx 反代到 30081。三层端口别搞混。
  2. SSL 必须先 HTTP 引导再切 HTTPS:certbot 需要先用 HTTP 验证域名,所以上线脚本里 init.conf 和最终 conf 是两份。
  3. 探针救了服务 :加了 readinessProbe 后,容器没起来前 k8s 不会把流量打给它,避免"502 风暴"。

项目演示地址:https://iprofile.liousa.site(https://iprofile.liousa.site)

相关推荐
Li_RuiQi8 小时前
DAgger方法演进_独立学习笔记
笔记·学习·计算机视觉
Li_RuiQi13 小时前
DAgger与交互式模仿学习_ACT学习笔记
笔记·学习
He BianGu13 小时前
【笔记】C# 中BindingFlags的详细作用
笔记·c#
AI视觉网奇13 小时前
turtle 入门教程笔记
笔记
跨知易知识产权14 小时前
美国专利确权是什么,和专利诉讼有什么不一样?
笔记
杨逢昌工厂6S管理14 小时前
126-杨逢昌6S三环体系:越做越乱的现场熵增机理与基准化治理——一线现场诊断笔记
经验分享·笔记·职场和发展·学习方法
悟道书生14 小时前
若依 RBAC 权限控制学习笔记
java·网络·笔记·sql·学习·vue
陈哈哈111115 小时前
折腾了半天,总算把 Vim 9.2 装明白了
笔记
陈哈哈111115 小时前
折腾了半天,总算把 OpenGL 的开发环境给装明白了
笔记
深圳老胡15 小时前
STM32F103 硬件 SPI 与软件 IO 模拟 SPI 最高速度差异详解
笔记·stm32·单片机·代码规范·1024程序员节