☁️ 14. 云平台部署
云平台部署是现代Web应用开发的重要环节,它提供了弹性、可扩展和高可用的基础设施。本章将深入探讨主流云平台的Flask应用部署实践,帮助你掌握从传统部署到云原生架构的完整技能。
🚀 14.1 AWS 部署实践
14.1.1 AWS 服务概览
AWS(Amazon Web Services)提供了丰富的服务来支持Flask应用的部署和运行:
14.1.2 EC2 部署实践
步骤1:创建EC2实例
bash
# 使用AWS CLI创建实例
aws ec2 run-instances \
--image-id ami-0abcdef1234567890 \
--count 1 \
--instance-type t3.micro \
--key-name my-key-pair \
--security-group-ids sg-903004f81
2
3
4
5
6
7
2
3
4
5
6
7
步骤2:配置应用环境
bash
# 在EC2实例上安装依赖
sudo yum update -y
sudo yum install python3 python3-pip nginx -y
# 创建应用目录
sudo mkdir -p /var/www/flask-app
sudo chown ec2-user:ec2-user /var/www/flask-app1
2
3
4
5
6
7
2
3
4
5
6
7
步骤3:部署Flask应用
python
# app.py - 生产环境配置
from flask import Flask
import os
app = Flask(__name__)
# 从环境变量读取配置
app.config['SECRET_KEY'] = os.environ.get('SECRET_KEY', 'dev-key')
app.config['DATABASE_URL'] = os.environ.get('DATABASE_URL')
@app.route('/')
def hello():
return {'message': 'Hello from AWS!', 'environment': 'production'}
@app.route('/health')
def health_check():
return {'status': 'healthy'}, 200
if __name__ == '__main__':
app.run(host='0.0.0.0', port=5000)1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
步骤4:配置Gunicorn和Nginx
ini
# gunicorn.conf.py
bind = "127.0.0.1:5000"
workers = 2
worker_class = "sync"
worker_connections = 1000
timeout = 30
keepalive = 2
max_requests = 1000
max_requests_jitter = 1001
2
3
4
5
6
7
8
9
2
3
4
5
6
7
8
9
nginx
# /etc/nginx/conf.d/flask-app.conf
server {
listen 80;
server_name your-domain.com;
location / {
proxy_pass http://127.0.0.1:5000;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
}
location /static {
alias /var/www/flask-app/static;
expires 1y;
add_header Cache-Control "public, immutable";
}
}1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
14.1.3 Elastic Beanstalk 快速部署
Elastic Beanstalk 提供了更简单的部署方式,自动处理容量预配置、负载均衡和自动扩展:
yaml
# .ebextensions/python.config
option_settings:
aws:elasticbeanstalk:container:python:
WSGIPath: application.py
aws:elasticbeanstalk:application:environment:
FLASK_ENV: production
SECRET_KEY: your-secret-key1
2
3
4
5
6
7
2
3
4
5
6
7
python
# application.py - EB入口文件
from app import app as application
if __name__ == '__main__':
application.run()1
2
3
4
5
2
3
4
5
部署命令:
bash
# 初始化EB应用
eb init flask-app --platform python-3.8
# 创建环境并部署
eb create production --single
# 后续更新
eb deploy1
2
3
4
5
6
7
8
2
3
4
5
6
7
8
🌐 14.2 Google Cloud Platform 部署
14.2.1 App Engine 部署
Google App Engine 提供了完全托管的serverless平台:
yaml
# app.yaml
runtime: python39
env_variables:
SECRET_KEY: "your-secret-key"
DATABASE_URL: "postgresql://user:pass@host/db"
automatic_scaling:
min_instances: 1
max_instances: 10
target_cpu_utilization: 0.6
resources:
cpu: 1
memory_gb: 0.5
disk_size_gb: 101
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
python
# main.py - App Engine入口
from flask import Flask
import os
app = Flask(__name__)
@app.route('/')
def hello():
return f'Hello from Google Cloud! Instance: {os.environ.get("GAE_INSTANCE", "local")}'
if __name__ == '__main__':
app.run(host='127.0.0.1', port=8080, debug=False)1
2
3
4
5
6
7
8
9
10
11
12
2
3
4
5
6
7
8
9
10
11
12
部署流程:
bash
# 部署到App Engine
gcloud app deploy
# 查看应用
gcloud app browse
# 查看日志
gcloud app logs tail -s default1
2
3
4
5
6
7
8
2
3
4
5
6
7
8
14.2.2 Cloud Run 容器化部署
dockerfile
# Dockerfile
FROM python:3.9-slim
WORKDIR /app
COPY requirements.txt .
RUN pip install --no-cache-dir -r requirements.txt
COPY . .
EXPOSE 8080
CMD ["gunicorn", "--bind", "0.0.0.0:8080", "--workers", "2", "app:app"]1
2
3
4
5
6
7
8
9
10
11
2
3
4
5
6
7
8
9
10
11
bash
# 构建并部署到Cloud Run
gcloud builds submit --tag gcr.io/PROJECT_ID/flask-app
gcloud run deploy --image gcr.io/PROJECT_ID/flask-app --platform managed1
2
3
2
3
⚡ 14.3 Azure 部署指南
14.3.1 App Service 部署
Azure App Service 提供了类似于AWS Elastic Beanstalk的托管服务:
python
# startup.py - Azure启动脚本
import os
from app import app
if __name__ == '__main__':
app.run(host='0.0.0.0', port=int(os.environ.get('PORT', 8000)))1
2
3
4
5
6
2
3
4
5
6
bash
# 使用Azure CLI部署
az webapp create --resource-group myResourceGroup \
--plan myAppServicePlan \
--name myFlaskApp \
--runtime "PYTHON|3.9"
# 配置启动命令
az webapp config set --resource-group myResourceGroup \
--name myFlaskApp \
--startup-file "startup.py"
# 部署代码
az webapp deployment source config-zip --resource-group myResourceGroup \
--name myFlaskApp \
--src app.zip1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
2
3
4
5
6
7
8
9
10
11
12
13
14
15
⚙️ 14.4 Kubernetes 编排
14.4.1 Kubernetes 部署架构
14.4.2 Kubernetes 配置文件
yaml
# deployment.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: flask-app
labels:
app: flask-app
spec:
replicas: 3
selector:
matchLabels:
app: flask-app
template:
metadata:
labels:
app: flask-app
spec:
containers:
- name: flask-app
image: your-registry/flask-app:latest
ports:
- containerPort: 5000
env:
- name: SECRET_KEY
valueFrom:
secretKeyRef:
name: flask-secrets
key: secret-key
- name: DATABASE_URL
valueFrom:
configMapKeyRef:
name: flask-config
key: database-url
resources:
requests:
memory: "128Mi"
cpu: "100m"
limits:
memory: "256Mi"
cpu: "200m"
livenessProbe:
httpGet:
path: /health
port: 5000
initialDelaySeconds: 30
periodSeconds: 10
readinessProbe:
httpGet:
path: /health
port: 5000
initialDelaySeconds: 5
periodSeconds: 5
---
apiVersion: v1
kind: Service
metadata:
name: flask-service
spec:
selector:
app: flask-app
ports:
- protocol: TCP
port: 80
targetPort: 5000
type: ClusterIP
---
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: flask-ingress
annotations:
kubernetes.io/ingress.class: nginx
cert-manager.io/cluster-issuer: letsencrypt-prod
spec:
tls:
- hosts:
- your-domain.com
secretName: flask-tls
rules:
- host: your-domain.com
http:
paths:
- path: /
pathType: Prefix
backend:
service:
name: flask-service
port:
number: 801
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
部署命令:
bash
# 应用配置
kubectl apply -f deployment.yaml
# 查看部署状态
kubectl get pods -l app=flask-app
kubectl get services
# 扩缩容
kubectl scale deployment flask-app --replicas=51
2
3
4
5
6
7
8
9
2
3
4
5
6
7
8
9
🔥 14.5 Serverless 部署(AWS Lambda)
14.5.1 Lambda 函数适配
Serverless架构适合处理事件驱动和间歇性工作负载:
python
# lambda_function.py
import json
from flask import Flask
from werkzeug.serving import WSGIRequestHandler
import awsgi
app = Flask(__name__)
@app.route('/')
def hello():
return {'message': 'Hello from Lambda!', 'cold_start': False}
@app.route('/api/<path:path>', methods=['GET', 'POST', 'PUT', 'DELETE'])
def api_proxy(path):
# API路由处理
return {'path': path, 'method': request.method}
def lambda_handler(event, context):
return awsgi.response(app, event, context)1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
14.5.2 SAM 模板配置
yaml
# template.yaml
AWSTemplateFormatVersion: '2010-09-09'
Transform: AWS::Serverless-2016-10-31
Globals:
Function:
Timeout: 30
MemorySize: 256
Runtime: python3.9
Resources:
FlaskApi:
Type: AWS::Serverless::Function
Properties:
CodeUri: src/
Handler: lambda_function.lambda_handler
Environment:
Variables:
SECRET_KEY: !Ref SecretKey
DATABASE_URL: !Ref DatabaseUrl
Events:
ApiGateway:
Type: Api
Properties:
Path: /{proxy+}
Method: ANY
RootPath:
Type: Api
Properties:
Path: /
Method: ANY
Parameters:
SecretKey:
Type: String
NoEcho: true
DatabaseUrl:
Type: String
Outputs:
ApiUrl:
Description: "API Gateway endpoint URL"
Value: !Sub "https://${ServerlessRestApi}.execute-api.${AWS::Region}.amazonaws.com/Prod/"1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
部署流程:
bash
# 构建和部署
sam build
sam deploy --guided
# 本地测试
sam local start-api1
2
3
4
5
6
2
3
4
5
6
📈 14.6 CDN 与静态资源优化
14.6.1 CDN 架构设计
14.6.2 Flask 静态资源优化
python
# static_optimizer.py
from flask import Flask, url_for
from flask_assets import Environment, Bundle
import os
app = Flask(__name__)
# 配置静态资源
if app.config.get('ENV') == 'production':
# 生产环境使用CDN
app.config['CDN_DOMAIN'] = 'https://cdn.yourdomain.com'
app.config['SEND_FILE_MAX_AGE_DEFAULT'] = 31536000 # 1年
else:
app.config['CDN_DOMAIN'] = ''
# 资源打包和压缩
assets = Environment(app)
css_bundle = Bundle(
'css/bootstrap.css',
'css/main.css',
filters='cssmin',
output='dist/css/packed.css'
)
js_bundle = Bundle(
'js/jquery.js',
'js/main.js',
filters='jsmin',
output='dist/js/packed.js'
)
assets.register('css_all', css_bundle)
assets.register('js_all', js_bundle)
@app.template_global()
def static_url(filename):
"""生成带CDN的静态资源URL"""
base_url = app.config.get('CDN_DOMAIN', '')
return base_url + url_for('static', filename=filename)
@app.after_request
def add_cache_headers(response):
"""添加缓存头"""
if request.endpoint == 'static':
response.cache_control.max_age = 31536000 # 1年
response.cache_control.public = True
return response1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
14.6.3 CloudFront 配置示例
json
{
"DistributionConfig": {
"CallerReference": "flask-app-cdn",
"Origins": {
"Quantity": 2,
"Items": [
{
"Id": "flask-app-origin",
"DomainName": "your-app.elasticbeanstalk.com",
"CustomOriginConfig": {
"HTTPPort": 80,
"HTTPSPort": 443,
"OriginProtocolPolicy": "https-only"
}
},
{
"Id": "s3-static-origin",
"DomainName": "your-bucket.s3.amazonaws.com",
"S3OriginConfig": {
"OriginAccessIdentity": ""
}
}
]
},
"DefaultCacheBehavior": {
"TargetOriginId": "flask-app-origin",
"ViewerProtocolPolicy": "redirect-to-https",
"CachePolicyId": "managed-caching-optimized"
},
"CacheBehaviors": {
"Quantity": 1,
"Items": [
{
"PathPattern": "/static/*",
"TargetOriginId": "s3-static-origin",
"ViewerProtocolPolicy": "https-only",
"CachePolicyId": "managed-caching-optimized-for-uncompressed-objects"
}
]
}
}
}1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
🎯 部署最佳实践总结
选择合适的部署策略
关键配置检查清单
- ✅ 安全配置:HTTPS证书、安全组/防火墙规则
- ✅ 监控告警:应用性能监控、日志聚合
- ✅ 备份策略:数据库备份、代码版本控制
- ✅ 扩展性:负载均衡、自动扩缩容配置
- ✅ 成本优化:资源标签、预留实例、定时任务
通过本章的学习,你已经掌握了在主流云平台上部署Flask应用的核心技能。下一章我们将深入探讨安全与性能优化,确保你的应用在生产环境中稳定高效运行。
