这是我参与更文挑战的第25天,活动详情查看: 更文挑战
写在前面
接上一篇 Django REST framework 部署实战 Uwsgi + Nginx 的部署是今天文章的基础,它属于传统部署方式步骤比较繁琐,流程比较复杂,不太适合真实的运维场景,今天就聊一聊真实项目中的部署。
正文开始
随着容器化时代的到来,如今的运维不再是简单的写脚本部署服务,而是使用 K8s + Docker 的方式去部署服务。使得运维更关注服务器,开发人员更注重业务。感兴趣的可以查看相关的文档。
1. Dcokerfile
Docker 是一个开源的应用容器引擎,让开发者可以打包他们的应用以及依赖包到一个可移植的镜像中,然后发布到任何流行的 Linux或Windows 机器上,也可以实现虚拟化。容器是完全使用沙箱机制,相互之间不会有任何接口。
大致介绍一下 Dcokerfile 中用到的语法
- FROM 基础镜像选择
- WORKDIR 工作目录
- COPY 拷贝文件到工作目录
- RUN 需要运行的命令
- EXPOSE 容器对外暴露的端口
- ENTRYPOINT 类似于 CMD 指令,一般用来执行真实的部署脚本
FROM python:3.6
WORKDIR /opt/app
COPY . .
RUN pip install -r requirements.txt -i https://mirrors.aliyun.com/pypi/simple/
EXPOSE 8080
ENTRYPOINT ["sh", "entrypoint.sh"]
复制代码
2. 部署脚本
entrypoint.sh
主要是关于运行的脚本,可以配置部署的逻辑,下面的文件根据环境变量选择是否执行数据库变更(生产环境数据库变更需要执行对应的SQL文件,因为 migrate 存在不确定性,会使生产环境产生不确定性)
# 是否需要执行数据库变更
if [ "$ENABLE_MIGRATE" == "true" ];then
python3 manage.py migrate
fi
echo "start demo web service"
# 根据配置环境指定运行方式
if [ "$ENV" == "local" ];then
exec python3 manage.py runserver 0.0.0.0:8080
else
python3 manage.py collectstatic
exec gunicorn demo.wsgi:application \
--name main_django \
--max-requests 2000 \
--max-requests-jitter 500 \
--bind 0.0.0.0:8080 \
--workers 4 \
--threads 4 \
"$@"
fi
复制代码
这里使用 gunicorn 部署服务,详情可以查看官方文档 Gunicorn 。
Gunicorn是一个unix上被广泛使用的高性能的Python WSGI UNIX HTTP Server。 和大多数的web框架兼容,并具有实现简单,轻量级,高性能等特点。
功能上与 uwsgi 没有太大的区别,主要区别在于网络模型。个人对于这两者的认知总结一下:
gunicorn 使用协程来提供并发支撑, 对于网络IO密集的服务比较有利,优点就是 更稳定,性能高,适用于轻量级部署。
uWSGI uWSGI是使用C写的,通过 python 调用 C 的接口实现转发。支持http协议、wsgi协议等协议。优点是功能很全面,有缓存、队列、 rpc 等功能的支持。
3. Docker 运行
# 构建docker 镜像
docker build -t demo .
# 运行 docker 服务
docker run -dit demo -p 8080:8080 /bin/bash
复制代码
4. Docker Compose
Docker Compose 是用于定义和运行多容器 Docker 应用程序的工具。通过 Compose,您可以使用 YML 文件来配置应用程序需要的所有服务。然后,使用一个命令,就可以从 YML 文件配置中创建并启动所有服务。
version: '2'
services:
nginx:
image: nginx:1.15-alpine
restart: always
ports:
- "8000:8080"
volumes:
- ./docker_nginx.conf:/etc/nginx/conf.d/default.conf:ro
api:
build:
context: .
dockerfile: Dockerfile
restart: always
ports:
-
"8001:8080"
volumes:
- ./:/opt/app:rw
depends_on:
- nginx
复制代码
在此配置文件中共指定了两个容器 一个是 api 服务另一个是 nginx,这就满足开发的基本要求,当然这里还可以指定数据库的容器;这样可以使用docker来配置一个完美的开发环境。
在 docker-compose.yaml 目录下运行服务,如果是前台启动,可以查看到服务的实时日志;如果是后台启动可以指定容器查看日志。具体命令如下
# 前台运行服务
docker-compose up
# 以下是常用的一些命令
# 后台运行服务
docker-compose up -d
# 重新 build + 启动
docker-compose up -d --build
# 查看日志 指定容器
docker-compose logs -f --tail=100 api
复制代码
一些解释:
- yaml 文件中 version 代表语法的版本为 2.0,不同的版本语法会有所差别。
- 各个服务之间的依赖通过 depends_on 指定,构建的时候会先构建依赖项。
- service 中的各服务之间可以通过 yaml 中定义的名称访问(docker-compose 内部的构建的虚拟网络)。
volumes: ./:/opt/app:rw
代表对宿主机目录拥有可读可写的权限,可以根据文件的使用指定不同的权限。