云容器实例原生支持Kubernetes API,相比从控制台创建负载,使用API的粒度更细一 些。
Kubernetes中,运行容器的最小资源单位是Pod,一个Pod封装一个或多个容器、存储 资源、一个独立的网络IP等。实际使用中很少直接创建Pod,而是使用Kubernetes中称 为Controller的抽象层来管理Pod实例,例如Deployment和StatefulSet。另外在 Kubernetes中使用Service定义一系列Pod以及访问这些Pod的策略的资源对象,使用 Ingress管理外部访问的资源对象。 如果您对Kubernetes的资源不熟悉,请参见《云容 器实例开发指南》了解各资源的关系。
对于Wordpress应用,可以按照下图调用API创建一系列资源。
● MySQL:创建一个Deployment部署mysql,创建一个Service定义mysql的访问策 略。
● Wordpress:创建一个Deployment部署wordpress,创建Service和Ingress定义 wordpress的访问策略。
最佳实践 3 使用多种方法创建工作负载
Namespace
步骤1 调用创建Namespace接口创建命名空间,并指定使用命名空间的类型。
{ "apiVersion": "v1", "kind": "Namespace", "metadata": {
"name": "namespace-test", "annotations": {
"namespace.kubernetes.io/flavor": "gpu-accelerated"
} }, "spec": { "finalizers": [ "kubernetes"
最佳实践 3 使用多种方法创建工作负载
] } }
步骤2 调用创建Network接口创建网络,与VPC与子网关联。
{ "apiVersion": "networking.cci.io/v1beta1", "kind": "Network",
"metadata": { "annotations": {
"network.alpha.kubernetes.io/default-security-group": "{{security-group-id}}", "network.alpha.kubernetes.io/domain-id": "{{domain-id}}",
"network.alpha.kubernetes.io/project-id": "{{project-id}}"
},
"name": "test-network"
}, "spec": {
"availableZone": "cnnorth-1a", "cidr": "192.168.0.0/24", "attachedVPC": "vpc-id", "networkID": "network-id", "networkType": "underlay_neutron", "subnetID": "subnet-id"
{ "apiVersion": "apps/v1", "kind": "Deployment", "metadata": {
}, "kind": "Service", "metadata": {
● 使用wordpress:latest镜像。
● 设置容器环境变量WORDPRESS_DB_PASSWORD为“********”,请替换为您设置 的密码。此处的密码必须与MySQL的MYSQL_ROOT_PASSWORD一致。
{ "apiVersion": "apps/v1", "kind": "Deployment", "metadata": {
"metadata": {
{ "apiVersion": "extensions/v1beta1", "kind": "Ingress",
"metadata": {
"kubernetes.io/elb.id": "2d48d034-6046-48db-8bb2-53c67e8148b5", "kubernetes.io/elb.ip": "10.10.10.10",
} ] } }
----结束
最佳实践 3 使用多种方法创建工作负载
4 使用 Tensorflow 训练神经网络
执行docker build -t tensorflow/tensorflow:v1 . 命令制作镜像(.表示当前目录,即 Dockerfile文件所在目录)。
镜像制作好后需要上传到容器镜像服务,具体步骤请参见https://
support.huaweicloud.com/usermanual-swr/swr_01_0009.html。
最佳实践 4 使用 Tensorflow 训练神经网络
创建 Tensorflow 负载
步骤1 登录云容器实例管理控制台。
步骤2 创建GPU型命名空间,填写命名空间名称,设置好VPC和子网网段后,单击“创 建”。
图4-1 GPU 型命名空间
步骤3 左侧导航栏中选择“工作负载 > 无状态(Deployment)”,在右侧页面中单击“创建 无状态负载”。
步骤4 配置负载信息。
1. 填写基本信息,选择步骤2创建的命名空间,Pod数量选择为“1”,选择Pod规格 为“GPU加速型”,显卡的驱动版本选择“418.126”,如下所示。
GPU Pod的详细规格和显卡驱动的说明请参见Pod规格。
图4-2 选择 GPU 容器规格
2. 选择需要的容器镜像,这里选择的上传到镜像容器仓库的tensorflow镜像。
3. 在容器设置下面的高级设置中,挂载一个NFS类型的文件存储卷,用于保存训练 后的数据。
图4-3 挂载 NFS 存储
最佳实践 4 使用 Tensorflow 训练神经网络
– 可执行命令:/bin/bash – 参数1:-c
– 参数2:python /home/project/gpu-demo/cifar10/
cifar10_multi_gpu_train.py --num_gpus=1 --data_dir=/home/project/gpu-demo/cifar10/data --max_steps=10000 --train_dir=/tmp/sfs0/train_data;
while true; do sleep 10; done
此处 --train_dir 表示训练结果存储路径,其前缀 /tmp/sfs0 需要与步骤4.3 中设置的NFS“容器内挂载路径”路径保持一致,否则训练结果无法写入NFS
步骤2 进入到工程所在目录,执行python classify_image.py --model_dir=model命令,可以
# python classify_image.py --model_dir=model --image_file=/home/project/gpu-demo/
airplane.jpg
…2019-01-02 08:05:24.891201: I tensorflow/core/common_runtime/gpu/gpu_device.cc:1084] Created TensorFlow device (/job:localhost/replica:0/task:0/device:GPU:0 with 15131 MB memory) -> physical GPU (device: 0, name: Tesla P100-PCIE-16GB, pci bus id: 0000:00:0a.0, compute capability: 6.0) airliner (score = 0.84250)
wing (score = 0.03228) space shuttle (score = 0.02524) warplane, military plane (score = 0.00691) airship, dirigible (score = 0.00664)
这里通过--image_file指定了要分类的图片,图片如下。执行结果最后几行是分类的
giant panda, panda, panda bear, coon bear, Ailuropoda melanoleuca (score = 0.89107)
indri, indris, Indri indri, Indri brevicaudatus (score = 0.00779) lesser panda, red panda, panda, bear cat, cat bear, Ailurus fulgens (score = 0.00296)
custard apple (score = 0.00147) earthstar (score = 0.00117)
执行结果显示模型认为这是一只大熊猫。
----结束
使用训练的图片分类模型
tensorflow官网中给了一个深度卷积网络的模型代码和训练数据:CIFAR-10。这是个 简化的图片分类模型,将图片分成以下10类:airplane, automobile, bird, cat, deer, dog, frog, horse, ship和truck。当然喂给模型的图,也就是训练数据,也是这10种类 型的图片。
步骤1 单击负载名称,进入负载详情界面,选择“Pod列表>终端”Tab页,使用代码中提供 的cifar10_eval.py校验模型的准确性,这里的checkpoint_dir指定使用刚刚训练出来的 模型进行准确性校验。
# cd /home/project/gpu-demo/cifar10
# python cifar10_eval.py --data_dir=data --checkpoint_dir=/tmp/sfs0/train_data --run_once
…2019-01-02 08:25:43.914186: precision @1 = 0.817
步骤2 继续使用上面的飞机图片进行测试,这里的checkpoint_dir指定使用刚刚训练出来的模 型进行图片分类,test_file指定用哪张图片测试。
# python label_image.py --checkpoint_dir=/tmp/sfs0/train_data --test_file=/home/project/gpu-demo/
airplane.jpg …
2019-01-02 08:36:42.149700: I tensorflow/core/common_runtime/gpu/gpu_device.cc:1084] Created TensorFlow device (/job:localhost/replica:0/task:0/device:GPU:0 with 15131 MB memory) -> physical GPU (device: 0, name: Tesla P100-PCIE-16GB, pci bus id: 0000:00:0a.0, compute capability:
6.0)
airplane (score = 4.28143) ship (score = 1.92319) cat (score = 0.03095)
可见它准确识别出图中是架飞机。label_image.py是使用刚刚训练的模型来进行图片分 类的代码。
同时,在“Pod列表>监控”Tab页中,可以看到各种资源的使用率。
最佳实践 4 使用 Tensorflow 训练神经网络
----结束
最佳实践 4 使用 Tensorflow 训练神经网络
5 CCI 使用 Nvidia-smi 工具
为了支持查看GPU使用情况的场景,需要在镜像中注入nvidia-smi工具,根据购买的专 属节点GPU驱动版本选择不同的nvidia-smi二进制文件。
步骤1 nvidia-smi获取方式。
该二进制文件可以在nvidia官网,根据CUDA Toolkit版本选择下载对应版本的nvidia驱 动包。
图5-1 NVIDIA 驱动程序下载
以CUDA 10.1为例,可以下载得到对应版本的驱动包NVIDIA-Linux-x86_64-418.126.run文件,执行如下命令解压缩:
sh NVIDIA-Linux-x86_64-418.126.run -x
在解压缩后的目录下即可找到官方提供的nvidia-smi工具二进制文件。
步骤2 注入nvidia-smi工具。
将步骤1中得到的nvidia-smi二进制文件放在Dockerfile所在目录下,然后在同目录下 的Dockerfile中新增注入语句:
# inject nvidia-smi tool COPY nvidia-smi /usr/bin/
RUN chmod +x /usr/bin/nvidia-smi
最佳实践 5 CCI 使用 Nvidia-smi 工具
COPY命令会从Dockerfile文件所在的当前目录下去寻找名为nvidia-smi的文件,然后 拷贝到镜像的/usr/bin/目录下。
----结束
最佳实践 5 CCI 使用 Nvidia-smi 工具
6 CCI 使用 AOM 查看 Pod 监控
步骤1 点击Pod列表的“监控”列表,点击“查看更多”。
图6-1 Pod 列表
步骤2 此时,跳转至AOM服务页面, 点击图中序号为3图标。
图6-2 AOM 服务
步骤3 添加指标图表,例如:选择“CPU使用率”,点击确定。
最佳实践 6 CCI 使用 AOM 查看 Pod 监控
图6-3 添加指标图表
步骤4 视图详情即可查看POD监控数据。
图6-4 监控视图
----结束
最佳实践 6 CCI 使用 AOM 查看 Pod 监控
7 CCI 应用进行优雅滚动升级
使用场景
用户在CCI中部署工作负载时,应用发布成了LoadBalance类型的Service或Ingress且对 接的独享型ELB,经过ELB的访问流量支持直通到容器中;当应用进行滚动升级或者弹 性扩缩容,通过配置容器探针,最短就绪时间等可以做到优雅升级,从而实现优雅弹 性扩缩容(在升级或者扩缩容过程中业务不会出现5xx的错误响应)。
操作步骤
在此以nginx的无状态工作负载为例,提供了CCI中应用进行优雅滚动升级或者弹性扩 缩容最佳实践。
步骤1 在CCI控制台,单击左侧栏目树中的“工作负载 > 无状态 Deployment”,单击右上角
“创建无状态负载”。
图7-1 创建无状态负载
步骤2 在“容器设置”,单击展开“高级设置 > 健康检查 > 应用业务探针”,如下图设置工 作负载业务探针。
最佳实践 7 CCI 应用进行优雅滚动升级
图7-2 配置应用业务探针
说明
该配置是检查用户业务是否就绪,不就绪则不转发流量到当前实例。
步骤3 单击展开“生命周期”,配置容器的“停止前处理”,保证容器在退出过程中能够对 外提供服务。
图7-3 配置生命周期
说明
该配置是保证业务容器在退出过程中能够对外提供服务。
步骤4 单击“下一步:访问设置”,如图7-5。
最佳实践 7 CCI 应用进行优雅滚动升级
图7-4 配置访问类型及端口一
图7-5 配置访问类型及端口二
步骤5 单击“下一步”完成工作负载的创建。
步骤6 配置最短就绪时间。
最短就绪时间,用于指定新创建的Pod在没有任意容器崩溃情况下的最小就绪时间,只 有超出这个时间Pod才被视为可用。
“最短就绪时间”需在右上角的“YAML编辑”进行配置。如图7-6:
最佳实践 7 CCI 应用进行优雅滚动升级
图7-6 配置最短就绪时间
说明
● 推荐的配置minReadySeconds时长,为业务容器的启动预期时间加上ELB服务下发member 到生效的时间。
● minReadySeconds的时长需要小于sleep时长,保证旧的容器停止并退出之前,新的容器已 经准备就绪。
步骤7 配置完成后,对应用进行升级和弹性扩缩容的打流测试。
准备一台集群外的客户端节点,预置检测脚本detection_script.sh,内容如下,其中
最佳实践 7 CCI 应用进行优雅滚动升级
● 100.85.125.90:7552为service的公网访问地址。
步骤8 运行检测脚本:bash detection_script.sh,并在CCI界面触发应用的滚动升级,如图 7-7修改了容器规格,触发了应用的滚动升级。
图7-7 修改容器规格
滚动升级的过程中,应用的访问并未中断,并且返回的请求都是“200OK”,说明升 级过程是优雅升级,没有中断的。
----结束
最佳实践 7 CCI 应用进行优雅滚动升级