目前,使用docker部署机器学习或深度学习模型正在成为企业大规模部署的一种常规操作。基于目前工作的情况,刚好可以使用现成的模型尝试使用docker进行部署。主要有以下

1. 什么是docker
2. 个性化环境的定制开发-Dockerfile的制作
3. docker常用命令
4. 模型部署

什么是docker

Docker 是一个开源的应用容器引擎,基于 Go 语言 并遵从Apache2.0协议开源。
Docker 可以让开发者打包他们的应用以及依赖包到一个轻量级、可移植的容器中,然后发布到任何流行的 Linux 机器上,也可以实现虚拟化。
容器是完全使用沙箱机制,相互之间不会有任何接口(类似 iPhone 的 app),更重要的是容器性能开销极低。
它有以下几点优势:

  1. 更快速的交付和部署 ;Docker在整个开发周期都可以完美的辅助你实现快速交付。Docker允许开发者在装有应用和服务本地容器做开发。可以直接集成到可持续开发流程中。例如:开发者可以使用一个标准的镜像来构建一套开发容器,开发完成之后,运维人员可以直接使用这个容器来部署代码。 Docker 可以快速创建容器,快速迭代应用程序,并让整个过程全程可见,使团队中的其他成员更容易理解应用程序是如何创建和工作的。 Docker 容器很轻很快!容器的启动时间是秒级的,大量地节约开发、测试、部署的时间。
  2. 高效的部署和扩容;Docker 容器几乎可以在任意的平台上运行,包括物理机、虚拟机、公有云、私有云、个人电脑、服务器等。 这种兼容性可以让用户把一个应用程序从一个平台直接迁移到另外一个。Docker的兼容性和轻量特性可以很轻松的实现负载的动态管理。你可以快速扩容或方便的下线的你的应用和服务,这种速度趋近实时。
  3. 更高的资源利用率;Docker 对系统资源的利用率很高,一台主机上可以同时运行数千个 Docker 容器。容器除了运行其中应用外,基本不消耗额外的系统资源,使得应用的性能很高,同时系统的开销尽量小。传统虚拟机方式运行 10 个不同的应用就要起 10 个虚拟机,而Docker 只需要启动 10 个隔离的应用即可。
  4. 更简单的管理;使用 Docker,只需要小小的修改,就可以替代以往大量的更新工作。所有的修改都以增量的方式被分发和更新,从而实现自动化并且高效的管理。

个性化环境的定制开发-Dockerfile的制作

针对常见业务场景,每个人电脑开发的开发环境都不一样,要不就是python版本不一样,要不就是TensorFlow版本不一样,避免出现我的代码只能在自己机器上跑的尴尬局面出现,因此建立一个统一的开发部署环境就成为必然。Dockerfile正是为此而诞生。Dockerfile的常用命令有以下几种

  1. FROM,获取基础镜像
  2. COPY,复制本机文件到docker容器的指定目录中
  3. ADD,复制(并解压)文件到docker容器的指定目录中
  4. RUN,运行linux命令,用于创建必要的开发环境
  5. WORKDIR,设置工作目录
  6. ENV,
  7. USER

其他的一些如EXPOSE,LABEL,STOPSIGNAL,VOLUME等命令在现阶段还没用上。
目前自己的定制化Dockerfile如下

# base image
FROM ubuntu:18.04
# MAINTAINER

# 安装相应依赖
RUN apt-get update \
    && apt-get install wget curl vim gcc zlib1g-dev bzip2 -y \
    && apt-get install zlib1g.dev \
    # 安装libssl1.0-dev解决pip安装时md5模块无法导入问题
    && apt-get install openssl libssl1.0-dev -y \
    && apt-get install g++ build-essential -y \
    # && apt-get install python-tk -y \
    # && apt-get install tk-dev -y \
    && mkdir /usr/local/source \
# 设置工作目录
WORKDIR /usr/local/source

RUN wget https://www.python.org/ftp/python/2.7.12/Python-2.7.12.tgz \
    && tar xvf Python-2.7.12.tgz && cd Python-2.7.12 \
    && ./configure --prefix=/usr/local/python27 && make && make altinstall \
    # 备份旧版本
    && mv /usr/bin/python /usr/bin/python27_old \
    # 配置默认python
    && ln -s /usr/local/python27/bin/python /usr/bin/python \
    && ln -s /usr/local/python27/bin/python-config /usr/bin/python-config \
    # 下载安装pip
    && curl https://bootstrap.pypa.io/get-pip.py -o get-pip.py \
    && python get-pip.py \
    # 备份旧pip
    # && mv /usr/bin/pip /usr/bin/pip_old 
    # 建立连接
    && ln -s /usr/local/python27/bin/pip  /usr/bin/pip \
    # 安装包
    && cd /usr/local/source \ 
    && pip install Cython==0.29.7 \
    && pip install pyyaml==5.1 \
    && pip install numpy==1.16.3 \
    && pip install pandas==0.23.2 \
    && pip install scipy==1.2.1 \
    && pip install scikit-learn==0.20.3 \
    && pip install matplotlib==2.1.0 \
    && pip install lightgbm==2.2.2 \
    && pip install catboost==0.13.1 \
    && pip install grpcio==1.20.1 \
    && pip install grpcio-tools==1.20.1 \

docker常用命令

Dockerfile制作完成后,就可以使用以下命令创建一个docker镜像

sudo docker build -it mydocker:v1 .  /bin/bash

请记住末尾有个 .(空格+.),后面/bin/bash的目的是镜像创建后直接开启一个并进入容器,进入命令行模式。
我们可以从主机复制东西到容器中,或者从容器复制东西到主机中,使用下列命令

sudo docker cp 主机文件路径 容器ID:容器路径     ## 从主机复制文件到容器
docker cp 容器ID:要拷贝的文件在容器里面的路径       要拷贝到宿主机的相应路径

其他常用命令

docker images    ## 查看本机镜像
docker image ls  ## 查看本机镜像
docker ps -a     ## 查看本机创建的所有容器
docker rmi 镜像ID(或镜像名称标签)   ## 删除镜像
docker rm 容器ID  ## 删除容器

先这些,想到再加,不懂的google或看官网文档

模型部署

既然容器环境已经创建好了,那就需要把模型文件拷贝进容器,为了部署方便,创建Dockerfile的时候也可以直接把模型复制进去(导致的后果就是镜像过大,占用过多的空间)。为了调用模型,除了基本的调用API接口外,还需要额外包装一层通信网络层,基本过程就是外部或其他容器发送请求数据给模型容器,模型容器接受到数据后,进行基本的特征工程和预测服务后,返回给发送端预测结果。本人在项目中,先后调研并测试过现成的rpc框架,分别是以下三种

  1. zerorpc,Python第三方开源库,安装简单,使用方便,缺点是速度慢,对于性能要求不高的可以尝试
  2. Thrift,Facebook开源RPC框架,使用稍微复杂,支持跨语言传输,速度快,在测试过程中发现数据的传输不是随着数据量的递增呈线性增长,而是指数增长,适用于单次数据量较少的情况
  3. grpc,Google开源RPC框架,使用方法和难度和Thrift一样,速度比Thrift慢,也支持跨多种语言传输,因为TensorFlow生态支持grpc,所以最后在性能满足要求的情况下,选择了grpc

上诉两种大公司的开源RPC框架都需要自定义传输数据格式,并使用其特定的编译器生成接口文件,调用这些接口函数即可,并以此创建自己的API接口,完成数据预处理、特征工程、模型预测服务。所有这些注意性能的变化。
关于Thriftgrpc框架的使用后期再来做个总结。