【DevOps】尝试flask管理docker容器
尝试写一个flask管理docker的web api,需要使用dockerfile创建自己所需的docker image。在这个docker image中实现了爬虫在docker中运行。
系统环境CentOS 7.9.2009(Py3.7.9)
0x01 创建flask项目
创建项目文件夹和python虚拟环境,激活虚拟环境
$ mkdir flask_api
$ cd flask_api
$ python3 -m venv venv
$ . venv/bin/activate
创建web api 文件app.py
$ touch app.py
$ vim app.py
0x02 实现逻辑
管理方式就是通过 Docker SDK for Python 这个库实现通过python对docker容器的管理,本文中使用的本地的docker环境,命令如下
import docker
# 默认的配置,即连接本地的docker
client = docker.from_env()
编写过程中难点主要是获取容器的name
# 获取当前活动容器,相当于docker ps
client.containers.list()
# 获取所有容器,相当于docker ps -a
client.containers.list(all)
# 想获取容器的名字,需要一个for循环来实现
for container in client.containers.list(all):
print(container.id)
print(container.name)
获取指定的容器,可以通过容器的id或者名字
container = client.containers.get('容器')
而对于指定容器的添加、删除和查询功能在下面的代码视线中有详细的介绍,最主要的是需要在进行操作前对改容器名进行判断,判断是否已存在。
# 判断容器是否存在
def exist_container(name):
for container in client.containers.list(all):
if(container.name==name):
# 容器存在
return True
# 容器不存在
return False
0x03 代码实现
编辑app.py,实现docker管理功能,其中args是参数
from flask import Flask,request,jsonify
import docker
app = Flask(__name__)
# 初始化docker连接
client = docker.from_env()
# 判断容器是否存在
def exist_container(name):
for container in client.containers.list(all):
if(container.name==name):
# 容器存在
return True
# 容器不存在
return False
# 添加容器
@app.route("/add", methods=['POST'])
def add():
args = request.form.get('args')
if(exist_container(args)==False):
client.containers.run('mosoteach',[args],name=args,detach=True)
return jsonify(code=200,msg=args+',任务创建成功')
else:
return jsonify(code=204,msg=args+',任务已存在')
# 删除容器
@app.route('/delete', methods=['POST'])
def delete():
args = request.form.get('args')
if(exist_container(args)==True):
container = client.containers.get(args)
container.stop()
container.remove()
return jsonify(code=200,msg=args+',任务删除成功')
return jsonify(code=204,msg=args+',任务不存在')
# 删除所有容器
@app.route('/delete_all', methods=['POST'])
def delete_all():
security_code = request.form.get('security_code')
if(security_code=='NstevKwt2nMbtdkC'):
for container in client.containers.list(all):
container.stop()
container.remove()
return jsonify(code=200,msg=args+',所有任务删除成功')
return jsonify(code=204,msg='安全码不正确')
# 获取正在运行的所有容器
@app.route('/get_list')
def get_list():
containers_list = []
for container in client.containers.list():
containers_list.append(container.name)
return jsonify(containers_list=containers_list)
# 获取某个容器日志
@app.route('/get_logs', methods=['POST'])
def get_logs():
args = request.form.get('args')
if(exist_container(args)==True):
container = client.containers.get(args)
return container.logs()
else:
return jsonify(code=204,msg=args+',任务不存在')
if __name__ == '__main__':
app.run()
0x04 编写Dockerfile
爬虫需要从docker中启动,编写Dockerfile文件制作docker镜像。
新建Dockerfile
$ touch Dockerfile
$ vim Dockerfile
FROM python:slim-buster
# 创建项目目录/app
RUN mkdir /app
# 复制当前目录下的scapy文件夹中的文件至docker镜像中的/app中
copy scapy/ /app
# 设置工作文件夹为/app
WORKDIR /app
# 安装依赖
RUN ["pip","install","-r","requirements.txt","-i","https://pypi.tuna.tsinghua.edu.cn/simple"]
# 固定参数
ENTRYPOINT ["python", "main.py"]
# 可变参数
CMD ["0","0"]
制作镜像,注意最后有一个 .
$ docker build -t [镜像名] .
启动镜像
$ docker run -d --name=[容器名] [镜像名] [参数1] [参数2]
查看容器日志
$ docker logs [容器名或者容器id]
确认无误后,即可在python中调用命令创建
client.containers.run('mosoteach',启动参数,name=容器名,detach=True)
本作品采用 知识共享署名-相同方式共享 4.0 国际许可协议 进行许可。
评论已关闭