首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >docker容器化python服务部署(supervisor-gunicorn-flask)

docker容器化python服务部署(supervisor-gunicorn-flask)

作者头像
用户7225427
发布2020-09-03 11:17:09
2.2K0
发布2020-09-03 11:17:09
举报
文章被收录于专栏:厚积薄发厚积薄发厚积薄发

docker容器化python服务部署(supervisor-gunicorn-flask)

本文系作者原创,转载请注明出处: https://cloud.tencent.com/developer/article/1691352

目录

  • 实现目标
  • docker vs virtual machine(虚拟机)
  • 实战(python 服务镜像制作,本地镜像仓库创建,移植)
  • 遇到的问题以及解决办法

  • 实现目标

在局域网内机器上部署 python 服务(在某台机器上部署完成后,生成镜像,上传到本地镜像仓库,其他机器下载镜像,一键部署服务);

开机自启动(物理机启动->容器自启动->服务自启动)

  • docker vs virtual machine(虚拟机)

啥也不说,先上docker官方网站的两张图。

VM(虚拟机)

优点:在于隔离性,各个虚拟环境之间是完全隔离的。

缺点:每个虚拟环境类似于一个独立的机器,有独立的操作系统,所以占用内存比较大,一台物理机器最多也就能同时开启虚拟环境 10+,

      另外,部署在虚拟环境下服务不太好移植。

docker

优点:有虚拟机隔离性的特点,解决了传统 VM 占用内存较大,服务不太好移植的问题。

关于 vm 和 docker 的详细区别,这里就不赘述了,网络上铺天盖地,大家随便百度一下。

  • 实战(python 服务镜像制作,本地镜像仓库创建,移植)

我的操作系统linux centos7,通过命令 cat /etc/os-release 查看

> docker 安装

注:宿主机 centos 版本最好是 7 以上,在 6 上安装 docker 遇到坑比较多。

yum install -y docker

> 获取基础镜像

docker pull centos

会自动在官网(https://hub.docker.com/)获取 centos:latest 镜像。

查看所有镜像(-a : all):

docker image ls -a

> 容器创建

docker container run -it -p 8888:8080 -v /opt/app:/opt/app --name=python-server 470671670cac bash

命令文档查看:docker container run --help

-it : 交互式终端(interactive terminal) ,也就是创建容器后进入容器。

-p 8888:8080 : 端口映射(port),将容器端口映射到宿主机端口(8888:宿主机端口,8080:容器端口),宿主机端口 8888 确认能被外网访问。

-v /opt/app:/opt/app:数据卷(volumn),将宿主机的数据(应用程序代码,配置文件等等)挂载到容器指定路径下,实现数据存储的持久化(如果没有数据挂载的话,容器销毁,容器中的数据会自动消失)。

--name=python-server: 新的容器的名称

470671670cac:镜像ID(imageID),当然也可以是 imageName + tag(docker.io/centos:latest)

bash:跟 -it 命令结合在一起操作,使容器创建后处于前端,一般是 /bin/bash,我这是bash。

表示容器已创建完成,并已进入容器,容器ID:5de4e81a2e20

可以通过 Ctrl+p,Ctrl+q 退出容器,但容器还是处于运行状态(Up)。

查看正在运行容器的状态:docker container ls 也可以是 docker ps

查看所有容器的状态(包含正在运行 up 和停止 exit):docker container ls -a == docker ps -a

退出容器后再进入容器,有两种方式(前提是该容器必须处于运行状态):

方式一:docker container exec -it 5de4e81a2e20(containerID) bash

方式二:ssh 172.17.0.4(容器ip)

查看容器ip(需要退出容器查看)

docker container inspect 5de4e81a2e20(containerID)

容器其他相关操作命令:

容器启动(交互式):docker container start -i containerID

关闭容器:docker container stop containerID

容器重启动:docker container restart containerID

删除容器(-f : force 强制删除,能删除处于运行状态的容器):docker container rm -f containerID

查看所有容器的容器ID:docker container ls -a -q

删除所有容器:docker contianer rm $(docker container ls -a -q)

在交互式容器中退出,退出启动容器: Ctrl + d

在交互式容器中退出,但是不退出启动容器:先按 Ctrl + p 后 Ctrl + q

使用 -d 启动容器并一直在后台运行 SSH作为第一进程启动:docker container run -d -p 50001:22 imageID /usr/sbin/sshd -D

安装 SSH:

SSH作用:

  1. 出现问题方便进入容器调试;
  2. 作为 python 服务的守护程序,防止容器闪退(一直夯在容器中);

安装命令: yum install -y openssh-server

ssh 配置文件 sshd_config 路径: /etc/ssh/

ssh 启动文件路径:/usr/sbin/

安装 passwd(设置密码): yum install -y passwd

设置密码:passwd root

new password: 12345678

启动 SSH: /usr/sbin/sshd

查看容器 ip(退出容器,在宿主机上,最好另起一个客户端): docker container inspect 1427087a62a7(containerID)

从宿主机进入容器:ssh 172.17.0.5 ,输入密码:12345678

安装 python3:

一般只需安装 pip3即可,但是为了服务调试,这里安装了python3,python3中包含了pip。

安装命令:yum install -y python3

安装完成后,查看版本:python3 -V

这里的python服务是关于深度学习的,所以需要添加库opencv,flask,interval,matplotlib,Pillow,gunicorn,gevent,supervisor。

安装 python 相关库

通过pip3安装,最好加上国内镜像源,防止网络的原因无法下载。

国内常用镜像源:

阿里云 http://mirrors.aliyun.com/pypi/simple/

中国科技大学 https://pypi.mirrors.ustc.edu.cn/simple/

豆瓣(douban) http://pypi.douban.com/simple/

清华大学 https://pypi.tuna.tsinghua.edu.cn/simple/

中国科学技术大学 http://pypi.mirrors.ustc.edu.cn/simple/

opencv:

pip3 install opencv-python-headless==4.2.0.32 -i http://pypi.douban.com/simple --trusted-host pypi.douban.com

flask:

pip3 install Flask==1.1.2 -i http://pypi.douban.com/simple --trusted-host pypi.douban.com

interval:

pip3 install interval==1.0.0 -i http://pypi.douban.com/simple --trusted-host pypi.douban.com

matplotlib:

pip3 install matplotlib==3.2.1 -i http://pypi.douban.com/simple --trusted-host pypi.douban.com

gunicorn

pip3 install gunicorn==20.0.4 -i http://pypi.douban.com/simple --trusted-host pypi.douban.com

supervisor

pip3 install supervisor==4.0.0 -i http://pypi.douban.com/simple --trusted-host pypi.douban.com

gevent:

pip3 install gevent==20.6.0 -i http://pypi.douban.com/simple --trusted-host pypi.douban.com

当然也可以通过 requirements.txt 一键安装所有相关库:

将 python 相关库写入 requirements.txt中:

cat > requirements.txt <<EOF

certifi==2020.4.5.2

chardet==3.0.4

click==7.1.2

cycler==0.10.0

Flask==1.1.2

gevent==20.6.0

gpg==1.10.0

greenlet==0.4.16

gunicorn==20.0.4

idna==2.9

interval==1.0.0

itsdangerous==1.1.0

Jinja2==2.11.2

kiwisolver==1.2.0

MarkupSafe==1.1.1

matplotlib==3.2.1

meld3==2.0.1

numpy==1.18.5

opencv-python-headless==4.2.0.32

Pillow==7.1.2

pyparsing==2.4.7

python-dateutil==2.8.1

requests==2.23.0

rpm==4.14.2

six==1.15.0

supervisor==4.0.0

urllib3==1.25.9

Werkzeug==1.0.1

zope.event==4.4

zope.interface==5.1.0

EOF

查看:cat requirements.txt

一键安装:pip3 install -r requirements.txt

如果已安装完所有库,需要移植到其他机器中,打包所有 python 库:pip3 freeze > requirements.txt

supervisor & gunicorn 配置

gunicorn 可以理解为 WSGI 协议的一个实例,WSGI(Web Server Gateway Interface):就是一个网关,是 web 服务器与应用程序之间通信的协议接口。

supervisor 提供了统一的方式来控制(start,stop,restart)进程,类似于 systemctl(在 docker 容器中 systemctl 命令是无效的)。

注意:宿主机当前路径为 /opt/app/darknet_captcha,容器中代码文件(不包含 darknet_captcha)放在 /opt/app 下

生成 supervisord.conf

echo_supervisord_conf > /etc/supervisord.conf

修改 supervisord.conf 配置

vi /etc/supervisord.conf

在文件最底部,去掉 include , files 注释,并将 files 修改为

include

files = /etc/supervisor/\*.conf

添加 gunicorn.conf

创建路径:mkdir /etc/supervisor

创建配置文件 gunicorn.conf:vi /etc/supervisor/gunicorn.conf

内容为:

program:gunicorn

command = gunicorn -c /opt/app/gunicorn.conf.py wsgi:application

autostart = true

startsecs = 5

autorestart = true

startretries = 3

redirect_stderr = true

stdout_logfile=/opt/logs/gunicorn.log

配置文件生效:supervisorctl update

先测试 gunicorn 启动 flask 服务

gunicorn -c /opt/app/gunicorn.conf.py wsgi:application

psc -ef|grep gunicorn

说明启动正常

删除 gunicorn 进程,改由 supervisord 启动

kill -9 55

用 supervisord 启动 gunicorn

supervisord -c /etc/supervisord.conf

如果出现如下问题,说明已有进程启动,占用了端口号。

解决办法:删除已启动进程即可

ps -ef|grep supervisord

kill -9 pid

启动后,查看 gunicorn 是否启动。

ps -ef|grep gunicorn

如果服务启动失败,在日志里查看原因。

日志查看:vi /opt/app/logs/gunicorn.log

后面就可以使用如下命令操作gunicorn

supervisorctl start gunicorn

supervisorctl stop gunicorn

supervisorctl restart gunicorn

到此,在单机上 docker 容器下 flask 服务部署已完成,接下来就是

基本镜像的制作,通过 dockerfile 创建最终镜像,本地镜像仓库创建,镜像 push 到本地仓库,局域网内其他机器 pull 镜像,一键部署服务。

> 基本镜像制作

退出容器,但容器需处于运行(up)状态:Ctrl + p,Ctrl + q

查看容器ID: docker container ls

制作镜像(镜像名称:weixw/python-server-mirror:v1):docker commit c96c249cf2bd weixw/python-server-mirror:v1

用 docker image ls 查看新镜像是否已存在

> 通过 dockerfile 创建最终镜像

为什么还要通过 dockerfile 制作镜像呢,因为上面生成的基础镜像只能保存静态文件,资源,不能保存动态命令,比如 shell 相关命令,应用程序命令,

而这些命令可以通过 dockerfile 写入进来,从而达到一键创建容器就能自动启动服务的目的。

创建 Dockerfile (规范名称必须是 Dockerfile 或 dockerfile)

在应用程序服务的根目录下创建 Dockerfile :

cd /opt/app/darknet_captcha

vi Dockerfile

Dockerfile 内容

FROM: 基础镜像

WORKDIR: 指定当前路径

COPY: 复制文件

ADD : 添加文件,有 COPY 功能,还有解压,从网站下载文件作用

EXPOSE: 暴露容器端口

CMD : shell 以及 应用程序命令

init.sh()

CMD 一般只能运行一条命令,对于多个命令,采用脚本方式运行。

创建最终镜像

cd /opt/app/darknet_captcha

docker image build -t weixw/python-server-mirror:v1.2 ./

注:Dockerfile 在 /opt/app/darknet_captcha 下,"./" 表示选择当前路径下的 Dockerfile 或 dockerfile文件。

查看:docker image ls

> 本地镜像仓库创建(其他端口不太行,需要开启外网访问端口5000):

下载 registry 镜像

docker pull registry

启动registry容器:docker run -d -p 5000:5000 --restart=always --name registry -v /opt/registry/:/var/lib/registry registry

--restart=always : docker 启动,容器自启动

修改docker 配置文件 daemon.json

vim /etc/docker/daemon.json

{

"registry-mirrors":"https://uoggbpok.mirror.aliyuncs.com",

"insecure-registries":"120.132.8.180:5000"

}

本地仓库加安全认证

生成密码:username: root password: 123456

yum install httpd-tools -y

mkdir /opt/registry-auth/ -p

htpasswd -Bbn root 123456 > /opt/registry-auth/htpasswd

修改密码:

cd /opt/registry-auth/

vim htpasswd

重新启动带有秘钥功能的registry容器

docker rm -f containerID

docker run -d -p 5000:5000 -v /opt/registry-auth/:/auth/ -v /opt/registry:/var/lib/registry --restart=always --name register-auth -e "REGISTRY_AUTH=htpasswd" -e "REGISTRY_AUTH_HTPASSWD_REALM=Registry Realm" -e "REGISTRY_AUTH_HTPASSWD_PATH=/auth/htpasswd" registry

规范本地镜像名称:docker tag imageID 120.132.8.180:5000/weixw/captcha

docker tag weixw/python-server-mirror:v1 120.132.8.180:5000/weixw/python-server-mirror:v1.2

登录(一定要先登录校验,否则无法 push):

docker login 120.132.8.180:5000

username: root

password: 123456

上传镜像到本地仓库(端口5000能被外网访问):docker push 120.132.8.180:5000/weixw/python-server-mirror:v1.2

有一个 harbor 服务用来可视化管理镜像的,大家感兴趣的话可以玩玩,因为我的Linux宿主机本来就是虚拟机,配置比较低,这里就不安装了。

> 另外一台机器获取镜像( 120.132.8.180:5000)步骤:

修改docker 配置文件 daemon.json

vim /etc/docker/daemon.json

{

"registry-mirrors":"https://uoggbpok.mirror.aliyuncs.com",

"insecure-registries":"120.132.8.180:5000"

}

重启 docker : systemctl restart docker

登录(pull 一般不需要登录,可以直接下载):

docker login 120.132.8.180:5000

username: root

password: 123456

向镜像仓库(120.132.8.180:5000)获取镜像: docker pull 120.132.8.180:5000/weixw/python-server-mirror

一键启动服务:docker container run -d -p 80:8080 --restart=always --name=captcha_server 120.132.8.180:5000/weixw/python-server-mirror

-d: 表示在后台启动

-p: 表示端口映射(80:宿主机端口,8080:容器端口)

--restart=always:表示开机自启动容器

启动容器后查看 flask 服务是否启动:ps -ef|grep gunicorn

用 curl 或 postman 向 120.132.8.180:80/服务名称 发送请求,查看结果。

如果服务没有起来,查看日志/opt/app/logs/gunicorn.log 定位问题,然后解决问题。

  • 遇到的问题以及解决办法

> 无法强制删除镜像

原因:该镜像下有容器创建,有可能不是运行状态(exit),所以需要先删除容器,再删除镜像。

解决方案:

查找所有容器:dokcer container ls -a

删除该镜像下所有容器:docker container rm -f containerID

删除镜像:docker image rm -f imageID

> 镜像也可以保存成文件,然后将文件导入

将镜像保存在本地:docker save -o 本地名字 image/name

例如: docker save -o python-server.tar 120.132.8.180:5000/weixw/python-server-mirror

将本地镜像文件加载进docker: docker load -i python-server.tar

不要让懒惰占据你的大脑,不要让妥协拖垮了你的人生。青春就是一张票,能不能赶上时代的快车,你的步伐就掌握在你的脚下。

本文参与 腾讯云自媒体分享计划,分享自作者个人站点/博客。
原始发表:2020-07-04 ,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • docker容器化python服务部署(supervisor-gunicorn-flask)
    • 目录
    相关产品与服务
    容器镜像服务
    容器镜像服务(Tencent Container Registry,TCR)为您提供安全独享、高性能的容器镜像托管分发服务。您可同时在全球多个地域创建独享实例,以实现容器镜像的就近拉取,降低拉取时间,节约带宽成本。TCR 提供细颗粒度的权限管理及访问控制,保障您的数据安全。
    领券
    问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档