ARTICLE DETAIL

资讯详情

深耕编程入门与网站建设的一线实战洞察。

Cookiecutter Django K8s 部署实战:4 步把 Compose 生产栈搬进 Kubernetes 集群

Cookiecutter Django K8s 部署实战:4 步把 Compose 生产栈搬进 Kubernetes 集群 Cookiecutter Django K8s 部署实战4 步把 Compose 生产栈搬进 Kubernetes 集群【免费下载链接】cookiecutter-djangoCookiecutter Django is a framework for jumpstarting production-ready Django projects quickly.项目地址: https://gitcode.com/GitHub_Trending/co/cookiecutter-djangoDocker Compose 单机跑得挺顺但机器一挂服务全挂想横向扩容也没抓手。你已经用 Cookiecutter Django 生成了生产栈现在要做的是把容器化部署迁到 Kubernetes 集群。这篇文章按镜像 → 有状态服务 → 流量入口 → 自愈的决策链展开帮你一次搞定迁移。复用 Compose 生产镜像多阶段 Dockerfile 已经为集群做好准备很多人以为上 K8s 要重写 Dockerfile其实不用。模板里的 compose/production/django/Dockerfile 本身就是为生产设计的多阶段构建node 阶段编译前端uv 阶段锁定依赖装进 venv运行阶段只带python:3.14-slim和必要的系统库而且全程以非 root 的 django 用户运行。镜像的入口逻辑藏在两个脚本里值得花两分钟看懂# compose/production/django/entrypoint wait-for-it ${POSTGRES_HOST}:${POSTGRES_PORT} -t 30 exec $ # compose/production/django/start节选 python /app/manage.py collectstatic --noinput exec gunicorn config.wsgi --bind 0.0.0.0:5000 --chdir/appwait-for-it等数据库就绪再起进程/start先收静态文件再用 gunicorn 监听5000 端口——后面配 Ingress 和探针都用得到这个端口号。再看配置怎么进容器。打开 config/settings/base.py 会看到数据库和缓存全部走环境变量# config/settings/base.py节选 if os.getenv(DATABASE_URL): DATABASES {default: env.db(DATABASE_URL)} # ... REDIS_URL env(REDIS_URL, defaultredis://redis:6379/0)镜像本身无状态所有运行时配置全靠环境变量注入。这意味着迁移时镜像原样推进镜像仓库即可Deployment 里只改 env一行 Python 代码都不用动。PostgreSQL 与 Redis 有状态服务把 DATABASE_URL 和 REDIS_URL 指到 K8s ServiceCompose 里的postgres服务是官方镜像加一套维护脚本backup / restore / rmbackup 都在 compose/production/postgres/maintenance/redis直接跑docker.io/redis:7.2。到了集群里这两者不该再跟 Django 挤在同一批 Pod 里PostgreSQL 用 StatefulSet PVC或直接换云厂商托管数据库Redis 同理小项目用一个 StatefulSet 就够大项目上托管实例。关键优势是模板没有把任何主机名写死DATABASES优先读DATABASE_URL兜底读POSTGRES_HOST等变量REDIS_URL默认值redis://redis:6379/0里的redis只是 Compose 的服务名。K8s Service 本质就是集群内 DNS把这两个值换成 Service 名就行env: - name: DATABASE_URL valueFrom: { secretKeyRef: { name: db-secret, key: database-url } } - name: REDIS_URL valueFrom: { secretKeyRef: { name: db-secret, key: redis-url } }两种部署的唯一区别就是这两个变量指向的主机名不同。密码、密钥一律放 Secret别硬编码。另外注意 config/settings/production.py 里CONN_MAX_AGE默认 60 秒gunicorn 多 worker 会复用连接池这在集群里是好事不用改。上集群后先进 Pod 跑一次迁移验证连通性kubectl exec -it django-pod -- python /app/manage.py migrate去掉集群内的 TraefikIngress 管路由cert-manager 管证书Compose 方案里的 traefik 服务负责 80/443 端口和 Lets Encrypt 的 httpChallenge见 compose/production/traefik/traefik.yml。上 K8s 后这套东西可以整体退役Ingress 管路由cert-manager 负责证书自动续期集群里不需要再自己养一个反向代理。好消息是 Django 侧的前面有代理配置模板已经替你写好了# config/settings/production.py节选 SECURE_PROXY_SSL_HEADER (HTTP_X_FORWARDED_PROTO, https) SECURE_SSL_REDIRECT env.bool(DJANGO_SECURE_SSL_REDIRECT, defaultTrue)只要 Ingress 正确传递了X-Forwarded-ProtoHTTPS 强制跳转会自动生效。Ingress 最小配置metadata: name: myapp annotations: cert-manager.io/cluster-issuer: letsencrypt-prod spec: tls: - hosts: [example.com] secretName: myapp-tls两个容易踩的坑ALLOWED_HOSTS读的是DJANGO_ALLOWED_HOSTS环境变量新域名必须加进去否则全站 400原 traefik.yml 里有个hostsProxyHeaders: [X-CSRFToken]的 CSRF 中间件换 Ingress 后记得加等价的 header 透传否则带 CSRF Token 的 AJAX 请求会被拒。3 行探针 YAMLgunicorn 卡死后 K8s 集群自动重启 Pod探针是集群派给每个容器的自动体检仪liveness 失败就重启容器readiness 失败就从 Service 摘流量。模板没有独立的/health/路由所以直接用首页做就绪检查存活检查用 TCP 端口即可readinessProbe: httpGet: { path: /, port: 5000 } initialDelaySeconds: 10 livenessProbe: tcpSocket: { port: 5000 } periodSeconds: 10就绪探针查首页、存活探针查 TCP 5000两者都别填 80 端口——那是 Ingress 层的事Pod 只监听 5000。再给容器加上resources的 requests/limits流量高峰时 HPA 就能依据 CPU 指标自动加副本这就是 Compose 给不了的弹性。上线前建议先在集群里跑一轮容器化测试确认视图、API、缓存读写全部通过kubectl exec -it django-pod -- python /app/manage.py test上线前检查清单逐条打勾再放流量镜像已推入仓库Deployment 里的 tag 与 Compose 验证过的一致DATABASE_URL/REDIS_URL指向集群内 Service 名而非 localhostDJANGO_ALLOWED_HOSTS已包含实际对外域名探针端口是 5000Pod 能在 1 分钟内进入 Readymigrate和collectstatic都已执行成功静态资源可访问访问 HTTP 域名会被 301 到 HTTPSSECURE_SSL_REDIRECT生效CPU / 内存的 requests 与 limits 已设置HPA 目标值合理Compose 编排的细节可以再对照 docs/3-deployment/deployment-with-docker.rst 里的说明。清单全部打勾后切 DNS 到 Ingress然后删掉那台单机——集群剩下的事它会自己管。【免费下载链接】cookiecutter-djangoCookiecutter Django is a framework for jumpstarting production-ready Django projects quickly.项目地址: https://gitcode.com/GitHub_Trending/co/cookiecutter-django创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
返回列表