一、概要

在AI训练云平台中,分布式训练任务是根据不同的系统镜像,利用k8s的statefulset方式在集群内部启动多个能够互相免密通信的容器环境,用户可以在当前任务启动的容器环境中利用显卡进行各种模型框架训练。通过webshell页面交互已无法满足用户的需求。

1.在不构建原有系统镜像的基础上动态解耦挂载部署可视化界面如jupyterlab、vscode等应用组件.
2.解决可视化工具在不同的分布式训练容器如何进行路由访问的问题.

本文在上述两点核心问题上提供了解决方案

二、技术栈

熟悉以下技术有助于理解使用此方案

  • k8s:ingress、service、pod、StatefulSet
  • docker
  • nginx
  • shell

三、网路架构设计

利用k8s的statefulset方式启动pod,可以设置pod副本数量
在这里插入图片描述

四、技术细节

在不构建原有系统镜像的基础上动态解耦挂载部署可视化界面如jupyterlab、vscode等应用组件。

每个pod分别管理了两个容器,同步容器container1,训练容器container2,其中训练容器对用户可见,同步容器对用户不可见,所以可以将vscode、jupyterlab等组件包部署在同步容器中。已知同步容器和训练容器在一个pod中,可以在当前pod启动时建立一个类型为EmptyDir临时共享目录,然后在启动同步容器时将vscode包mv到临时共享目录中,训练容器即可操作vscode组件。

这样处理的好处在于,如果以后需要对vscode等组件进行升级,只需要重新构建同步容器镜像即可。
在这里插入图片描述

五、关键代码

1.动态修改nginx.conf文件

#! /bin/bash
# $1 替换目标路径
# $2 是否是Horovod任务 0:否 其他大于零的数据:是,且表示分布式容器数量

urlPath=$1
containerNum=$2
#定义删除vscode开头的文件方法
deleteVscodeNginxConf() {
  vconfNum=`ls /usr/local/nginx/conf/vscode|grep vscode|grep conf|wc -l`
  if [ $vconfNum -gt 0 ];then
    cd /usr/local/nginx/conf/vscode
    rm -rf vscode*
  fi
}

#创建Horovod分布式任务nginx配置方法
createHorovodVscodeNginxConf() {
  i=0
  num=$containerNum
  while [ $i -lt $num ]
  do
    fileName="/usr/local/nginx/conf/vscode/vscode-$i.conf"
    echo "location /$urlPath-$i/ {" >> $fileName
    echo "    proxy_set_header Host \$http_host;" >> $fileName
    echo "    proxy_set_header X-Forwarded-For \$proxy_add_x_forwarded_for;" >> $fileName
    echo "    proxy_set_header Upgrade \$http_upgrade;" >> $fileName
    echo "    proxy_set_header Connection \"upgrade\";" >> $fileName
    echo "    proxy_pass http://localhost:7001/;" >> $fileName
    echo "}" >> $fileName
    i=$((i+1))
  done
}

#创建非Horovod分布式任务nginx配置方法
createVscodeNginxConf() {
  fileName="/usr/local/nginx/conf/vscode/vscode.conf"
  echo "location /$urlPath/ {" >> $fileName
  echo "    proxy_set_header Host \$http_host;" >> $fileName
  echo "    proxy_set_header X-Forwarded-For \$proxy_add_x_forwarded_for;" >> $fileName
  echo "    proxy_set_header Upgrade \$http_upgrade;" >> $fileName
  echo "    proxy_set_header Connection \"upgrade\";" >> $fileName
  echo "    proxy_pass http://localhost:7001/;" >> $fileName
  echo "}" >> $fileName
}

#-------------------------------下面是脚本执行主代码----------------------
mkdir -p /usr/local/nginx/conf/vscode
deleteVscodeNginxConf
#非Horovod分布式任务
if [ $containerNum -eq 0 ];then
  createVscodeNginxConf 
#Horovod分布式任务
else
  createHorovodVscodeNginxConf 
fi

#启动nginx
nginxNum=`ps -ef|grep nginx|grep -v grep|wc -l`
if [ ! $nginxNum -eq 0 ];then
  /usr/local/nginx/sbin/nginx -s reload
else
  /usr/local/nginx/sbin/nginx
fi

2.同步容器nginx.conf

worker_processes  1;

events {
    worker_connections  1024;
}

http {
    include       mime.types;
    default_type  application/octet-stream;

    sendfile        on;
    keepalive_timeout  65;

    server {
        listen       7000;
        server_name  localhost;

	location /hf/vscode/12345678910111213/ {
            proxy_set_header Host $http_host;
            proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
	        proxy_set_header Upgrade $http_upgrade;
	        proxy_set_header Connection "upgrade";
            proxy_pass http://localhost:7001/;
        }
        
	include vscode/*.conf;
        
	error_page   500 502 503 504  /50x.html;
        location = /50x.html {
            root   html;
        }
    }
}

六、访问测试

通过浏览器访问k8s集群管理的容器中的vscode进程
在这里插入图片描述
并且可以提供一个操作k8s集群容器shell终端
在这里插入图片描述

Logo

K8S/Kubernetes社区为您提供最前沿的新闻资讯和知识内容

更多推荐