基于阿里云ECS与ACR的Python微服务镜像构建、部署与接口访问
基本要求
- 掌握使用Dockerfile构建容器镜像的基本方法
- 掌握阿里云云服务器ECS与容器镜像服务ACR的相关操作
- 理解HTTP协议基本概念,熟练掌握HTTP调试工具的使用
- 理解网络服务API的基本概念、分类,重点掌握HTTP RESTful API的定义原则、应用模式
- 理解并掌握基于Python Requests库撰写代码访问RESTful API的基本方法
实验过程
环境搭建
在本地安装Python3
在本地开发环境安装Python3,以便本地测试微服务范例程序:
(local)$ sudo apt install python3
准备云服务器ECS(略)
基于阿里云容器镜像服务ACR配置镜像仓库
访问容器镜像服务ACR产品首页-阿里云,点击“管理控制台”进入实例列表,创建使用个人实例。随后根据页面提示:
- 设置访问密码
- 创建命名空间
exp_pyms1
- 创建镜像仓库
exp_pyms_api_demo
,且“代码源”选择本地仓库。
配置完成后,可在ACR控制台的镜像仓库基本信息中查看登录ACR,以及从镜像仓库拉取或推送镜像的提示信息。
在本地开发环境测试微服务示例程序
在本地开发环境启动微服务范例,体验HTTP RESTful API接口。
本微服务范例在8000
端口监听,启动命令为:
./exp_pyms_api_demo ./device.csv
# ./exp_pyms_api_demo <csv_file>,csv_file为存储设备信息的CSV文件路径。若该路径中CSV文件已存在,则从CSV读取设备信息;否则自动创建5条设备信息,生成CSV文件。
此时访问http://localhost:8000/docs
,页面如下:
且当前目录将产生device.csv
文件:
测试完毕,输入CTR+C
关闭微服务示例程序。
在阿里云ECS以容器方式部署微服务范例
构建微服务范例镜像(本地)
创建Dockerfile
文件:
vim Dockerfile
内容如下:
# 使用Ubuntu 22.04作为基础镜像
FROM ubuntu:22.04
LABEL maintainer="<邮箱>"
# 指定工作目录为/app
WORKDIR /app
# 将主机文件系统中的exp_pyms_api_demo复制到镜像中
COPY exp_pyms_api_demo exp_pyms_api_demo
# 暴露服务端口8000
EXPOSE 8000
# 指定容器的启动命令,device.csv将存储在容器的/var/lib/exp_pyms_data/目录下,因此该目录应持久化
CMD ["/app/exp_pyms_api_demo","/var/lib/exp_pyms_data/device.csv"]
确保工作目录中仅有Dockerfile
与exp_pyms_api_demo
文件。
使用docker build
命令构建容器镜像,并为镜像设置名为exp_pyms_api_demo:1.0
的标签:
[!NOTE]
注:本地环境需要首先安装好Docker!
# -t,tag:后跟镜像名称(REPOSITORY:TAG)
# exp_pyms_api_demo:1.0:自定义镜像名称
# .:PATH,执行命令的上下文路径,构造过程中可以引用该上下文路径中的任何文件
docker build -t exp_pyms_api_demo:1.0 .
(local)$ docker images
(local)$
上传镜像至镜像仓库(本地)
在本地开发环境登录阿里云容器镜像服务ACR。
(local)$ docker login --username=沙里院的雪 crpi-exr3j7gox2plovb8.cn-heyuan.personal.cr.aliyuncs.com
(local)$
随后为本地exp_pyms_api_demo:1.0
镜像设置带有阿里云镜像仓库标记的标签。
(local)$ docker tag exp_pyms_api_demo:1.0 crpi-exr3j7gox2plovb8.cn-heyuan.personal.cr.aliyuncs.com/exp_pyms1/exp_pyms_api_demo:1.0
(local)$ docker push crpi-exr3j7gox2plovb8.cn-heyuan.personal.cr.aliyuncs.com/exp_pyms1/exp_pyms_api_demo:1.0
(local)$
[!NOTE]
注:如果中途遇到权限问题,而账户已经登陆,可以尝试重启docker服务。
访问阿里云ACR控制台页面,在镜像仓库exp_pyms_api_demo
的“镜像版本”页面,可以看见刚推送的镜像exp_pyms_api_demo:1.0。
拉取镜像并部署服务(ECS)
以SSH方式登录阿里云ECS,从ECS登录阿里云ACR拉取镜像。
(ecs)$ docker login --username=沙里院的雪 crpi-exr3j7gox2plovb8.cn-heyuan.personal.cr.aliyuncs.com
(ecs)$ docker pull crpi-exr3j7gox2plovb8.cn-heyuan.personal.cr.aliyuncs.com/exp_pyms1/exp_pyms_api_demo:1.0
(ecs)$ docker images
在ECS工作目录(自行指定)创建一持久化目录exp_pyms_data
,用于在ECS存储容器内服务生成的业务数据文档,即设备信息数据,随后运行微服务范例程序容器镜像。
[!WARNING]
需要首先在阿里云ECS的安全组开放服务器8000端口!
(ecs)$ mkdir exp_pyms_data
(ecs)$ docker run -d --restart=always \
--name exp_pyms_api_demo \
-p 8000:8000 \
-v ./exp_pyms_data/:/var/lib/exp_pyms_data/ \
crpi-exr3j7gox2plovb8.cn-heyuan.personal.cr.aliyuncs.com/exp_pyms1/exp_pyms_api_demo:1.0
查看容器运行日志,可确认服务已成功启动。
(ecs)$ docker logs exp_pyms_api_demo
(ecs)$ ls exp_pyms_data/
device.csv
使用OpenAPI查看微服务接口
微服务范例提供两种OpenAPI文档页面,分别为Redocly文档和Swagger。
Redocly文档提供清晰、完整、详尽的接口与参数信息。通过该文档,可了解服务包含哪些接口、接口请求与响应消息体等内容。Redocly文档地址为
<ecs_ip>:8000/docs
。Swagger文档除了类似Redocly提供接口与参数信息意以外,还提供最基础的调试功能。Swagger文档地址为
<ecs_ip>:8000/docs/swagger
。
使用Requests库编码访问微服务范例接口(本地)
配置Python虚拟环境
Python虚拟环境可实现为不同项目设置独立的依赖库,以实现在同一系统中不同项目所需软件包的隔离。
例如开发环境中两个项目依赖同一个软件包,但依赖的版本不同,或者一些依赖是相互冲突的,那么使用Python虚拟环境就能为不同项目创建独立的虚拟环境。
在本地开发环境创建工作目录exp_pyms_cli
,进入该目录安装启用Python虚拟环境exp_venv
。
(local)$ python3 -m venv exp_venv
(local)$ source exp_venv/bin/activate
(local)(exp_venv)$
随后使用pip install
命令在虚拟环境中安装Python Requests库。
(local)(exp_venv)$ pip install requests
...
(local)(exp_venv)$
安装完成Requests库后,可在Python交互式界面中初步验证。
(local)(exp_venv)$ python3
>>> import requests
>>> requests.__version__
>>> exit()
(local)(exp_venv)$
体验“查询设备”接口
在ECS工作目录中,查看先前创建的exp_pyms_data
目录,可以找到微服务范例程序启动时自动生成的CSV文件,查看文件内容,可发现五条设备信息数据。
(ecs)$ cat exp_pyms_data/device.csv
以ID7719024672
的设备为例,通过Requests库访问“查询设备”接口,可基于设备编号获取设备信息。
(local)(exp_venv)$ python3
>>> import requests
>>> resp = requests.get("http://<ecs_ip>:8000/v1/devices",json={"id":"7719024672"})
>>> resp
>>> resp.status_code
>>> resp.text
>>> resp.json()
这一查询接口还支持另一种查询方式:以设备“序号SN-类型”的组合信息为基准进行设备查询。
>>> resp = requests.get("http://<ecs_ip>:8000/v1/devices",json={"sn":"NDAKw","model":"x86 PC"})
>>> resp.status_code
>>> resp.json()
体验“删除设备”接口
删除接口的消息体是一个设备编号列表,微服务范例程序将根据客户端提交的“删除设备编号列表”进行删除操作,并将实际删除的设备编号列表返回。
下面练习该接口访问。删除设备编号为7719024672
,6132632285
,1234567890
的三台设备,其中最后一台设备并不存在。观察返回结果。
>>> resp = requests.delete("http://<ecs_ip>:8000/v1/devices",json={"ids":["7719024672","6132632285","1234567890"]})
>>> resp.json()
此时登录ECS查看device.csv文件,设备编号为7719024672
,6132632285
的设备信息已被删除。
(ecs)$ cat exp_pyms_data/device.csv
体验“添加设备”接口
添加设备的接口输入参数与获取设备信息相比,只缺少了设备编号,即id
字段。设备编号信息将在成功添加设备后由云端微服务范例程序生成。
下面练习“添加设备”接口访问。
>>> resp = requests.post("http://<ecs_ip>:8000/v1/devices",json={"name": "test-name","type": "controller","hardware": {"model": "test-model", "sn": "test-sn"},"software": {"version": "0.1", "last_update": "2023-08-06 20:00:00"},"nic": [{"type": "wifi","mac": "12:34:56:78:9a:bc","ipv4": "192.168.1.2"}],"status": "online"})
>>> resp.json()
此时登录ECS查看device.csv
,发现已增加了一条设备编号为0366286629
的设备,其数据与刚才访问接口执行添加操作的数据一致。
(ecs)$ cat exp_pyms_data/device.csv
体验“更新设备信息”接口
微服务范例程序允许更新“设备名称、设备类型、设备硬件型号、设备硬件序号、软件版本、软件上次更新时间、设备状态信息”,在请求体中组织JSON形式的参数时,以上字段的JSON嵌套方式与“添加设备”接口的JSON规范一致。此外,调用“更新设备信息”接口要求必须指定设备编号,否则无法定位具体设备。
下面练习“更新设备信息”接口。
>>> resp = requests.put("http://<ecs_ip>:8000/v1/devices",json={"id": "1449204488","name": "new-name","software": {"version": "0.5", "last_update": "2023-08-06 10:00:00"},"status": "offline"})
>>> resp.json()
此时到ECS查看device.csv文件,数据已经成功修改:
(ecs)$ cat exp_pyms_data/device.csv