在Google Cloud Run上部署容器化应用
Google Cloud Run让你无需管理服务器即可运行容器。只需部署Docker镜像,Cloud Run会自动处理扩缩容、HTTPS和基础设施。本教程将带你构建一个Python Flask REST API,将其容器化并部署到Cloud Run。
前置条件
- 已启用计费的Google Cloud账户
- 已安装并认证
gcloudCLI - 本地已安装Docker
- Python 3.11+
步骤1:创建Flask应用
创建项目目录并设置应用:
mkdir cloud-run-demo && cd cloud-run-demo
python -m venv venv && source venv/bin/activate
pip install flask gunicorn google-cloud-firestore
创建app.py:
import os
from flask import Flask, jsonify, request
from google.cloud import firestore
app = Flask(__name__)
db = firestore.Client()
@app.route('/health')
def health():
return jsonify({'status': 'healthy', 'service': 'cloud-run-demo'})
@app.route('/api/items', methods=['GET'])
def list_items():
items_ref = db.collection('items')
docs = items_ref.stream()
items = [{'id': doc.id, **doc.to_dict()} for doc in docs]
return jsonify({'items': items, 'count': len(items)})
@app.route('/api/items', methods=['POST'])
def create_item():
data = request.get_json()
if not data or 'name' not in data:
return jsonify({'error': 'name is required'}), 400
item = {
'name': data['name'],
'description': data.get('description', ''),
'created_at': firestore.SERVER_TIMESTAMP
}
doc_ref = db.collection('items').add(item)
return jsonify({'id': doc_ref[1].id, 'message': 'created'}), 201
@app.route('/api/items/<item_id>', methods=['DELETE'])
def delete_item(item_id):
db.collection('items').document(item_id).delete()
return jsonify({'message': 'deleted'}), 200
if __name__ == '__main__':
port = int(os.environ.get('PORT', 8080))
app.run(host='0.0.0.0', port=port, debug=False)
创建requirements.txt:
flask==3.0.0
gunicorn==21.2.0
google-cloud-firestore==2.14.0
步骤2:编写Dockerfile
使用多阶段构建创建精简的生产镜像:
# 构建阶段
FROM python:3.11-slim AS builder
WORKDIR /app
COPY requirements.txt .
RUN pip install --no-cache-dir --prefix=/install -r requirements.txt
# 生产阶段
FROM python:3.11-slim
WORKDIR /app
COPY --from=builder /install /usr/local
COPY . .
ENV PORT=8080
EXPOSE 8080
CMD exec gunicorn --bind :$PORT --workers 2 --threads 4 --timeout 120 app:app
步骤3:本地测试
docker build -t cloud-run-demo .
docker run -p 8080:8080 -e PORT=8080 cloud-run-demo
curl http://localhost:8080/health
步骤4:部署到Google Cloud Run
export PROJECT_ID=your-project-id
gcloud config set project $PROJECT_ID
# 启用所需API
gcloud services enable run.googleapis.com \
containerregistry.googleapis.com \
cloudbuild.googleapis.com \
firestore.googleapis.com
# 使用Cloud Build构建并推送
gcloud builds submit --tag gcr.io/$PROJECT_ID/cloud-run-demo
# 部署到Cloud Run
gcloud run deploy cloud-run-demo \
--image gcr.io/$PROJECT_ID/cloud-run-demo \
--platform managed \
--region asia-northeast1 \
--allow-unauthenticated \
--memory 256Mi \
--cpu 1 \
--min-instances 0 \
--max-instances 10
步骤5:配置自动扩缩容
gcloud run services update cloud-run-demo \
--region asia-northeast1 \
--concurrency 80 \
--min-instances 1 \
--max-instances 50
关键扩缩参数:
步骤6:配置自定义域名
gcloud run domain-mappings create \
--service cloud-run-demo \
--domain api.yourdomain.com \
--region asia-northeast1
步骤7:使用Cloud Build实现CI/CD
创建cloudbuild.yaml:
steps:
- name: 'gcr.io/cloud-builders/docker'
args: ['build', '-t', 'gcr.io/$PROJECT_ID/cloud-run-demo:$COMMIT_SHA', '.']
- name: 'gcr.io/cloud-builders/docker'
args: ['push', 'gcr.io/$PROJECT_ID/cloud-run-demo:$COMMIT_SHA']
- name: 'gcr.io/google.com/cloudsdktool/cloud-sdk'
entrypoint: gcloud
args: ['run', 'deploy', 'cloud-run-demo', '--image', 'gcr.io/$PROJECT_ID/cloud-run-demo:$COMMIT_SHA', '--region', 'asia-northeast1', '--platform', 'managed']
步骤8:监控和日志
gcloud logging read "resource.type=cloud_run_revision \
AND resource.labels.service_name=cloud-run-demo" \
--limit 50 --format json
添加结构化日志:
import json, sys
def log(severity, message, **kwargs):
entry = {'severity': severity, 'message': message, **kwargs}
print(json.dumps(entry), file=sys.stdout if severity != 'ERROR' else sys.stderr)
成本优化建议
1. 开发环境将min-instances设为0——只在有请求时计费
2. 启用CPU节流减少空闲期成本
3. 内存从256Mi起步,按需增加
4. 使用--cpu-boost加速冷启动
5. 将concurrency设高(80-100)最大化每个实例的请求处理量
总结
Google Cloud Run是介于无服务器函数和完整Kubernetes之间的强大平台。它兼具容器的灵活性和无服务器的简洁性——无需集群管理、自动HTTPS、按使用付费。非常适合API、微服务以及需要高效扩展的Web应用。