Ubuntu20.04 OpenPAI安装

1 参考

2 OpenPAI简介

微软开发的一套针对机器学习的资源调度系统,通常有用户端和管理员端两个入口。管理员端主要用于管理OpenPAI集群,客户端主要提供给用户提交任务。

OpenPAI支持两种调度器,Kubernets default scheduler以及hivedscheduler。hivedscheduler是OpenPAI的默认调度器,它支持虚拟集群划分,拓扑感知的资源保证、以及性能优化的 Gang Scheduling,这些都是 k8s default scheduler 不支持的。对于CPU worker或NVIDIA GPU worker,可以使用k8s default scheduler或hivedscheduler。

3 安装

本文在Ubuntu20.04换机上安装,使用OpenPAI官方的脚本未安装成功,因此尝试先直接使用kubespray安装k8s集群,然后在使用PAI的脚本安装PAI服务。

3.1 主机信息:

  • node1:172.18.18.207
  • node2:172.18.18.208
  • node3:172.18.18.209
  • node4:172.18.18.210
  • node5:172.18.18.206

3.2 准备工作

  • 每台主机安装Nvidia Driver、Docker、Docker-runtime、Anaconda。直接使用ansible playbook安装
  • 其它基本准备命令
sed -i 's/^#PermitRootLogin prohibit-password/PermitRootLogin yes/g' /etc/ssh/sshd_config
systemctl restart sshd

ansible gpu -m shell -a "mkfs.ext4 /dev/sda"
ansible gpu -m shell -a "echo '/dev/sda /data   ext4    defaults    0   0' >> /etc/fstab"
ansible gpu -m shell -a "init 6"
ansible gpu -m shell -a "systemctl stop ufw"
ansible gpu -m shell -a "systemctl disable ufw"
ansible gpu -m shell -a "install nfs-common -y"
ansible gpu -m shell -a "apt update"
systemctl daemon-reload
systemctl restart docker
  • privoxy配置代理,主要用于将http请求转发到配置的socks5的隧道上

3.3 使用kubespray安装k8s

【采坑】:因为版本原因,本文修改group_vars/k8s_cluster/k8s-cluster.yml中kube_version为v1.20.9,而不是1.21.3。kuberspray暂时不支持1.21.3的配置文件格式,所以将k8s的版本降级了。

安装kubespray官方文档执行下面操作:

# Install dependencies from ``requirements.txt``
sudo pip3 install -r requirements.txt

# Copy ``inventory/sample`` as ``inventory/mycluster``
cp -rfp inventory/sample inventory/mycluster

# Update Ansible inventory file with inventory builder
declare -a IPS=(172.18.18.207 172.18.18.208 172.18.18.209)  # 修改为集群IP
CONFIG_FILE=inventory/mycluster/hosts.yaml python3 contrib/inventory_builder/inventory.py ${IPS[@]}

# Review and change parameters under ``inventory/mycluster/group_vars``
cat inventory/mycluster/group_vars/all/all.yml
cat inventory/mycluster/group_vars/k8s_cluster/k8s-cluster.yml 【在该文件中修改k8s的版本,即kube_version为v1.20.9】
catinventory/mycluster/group_vars/k8s_cluster/addons.yml 【在该文件中启动dasshboard,dashboard_enabled: true】

# install 暂时全部使用默认配置
ansible-playbook -i inventory/mycluster/hosts.yaml  --become --become-user=root cluster.yml 【该步骤执行时间较长,同时因为无法访问问题,必须配置docker代理,否则执行会失败。】

3.4 参考openpai仓库中的代码在k8s集群上安装openpai

pai的版本为:pai-1.8.0

pai-1.8.0/contrib/kubespray/config目录下layout.yaml的配置如下:

machine-sku:
  master-machine: # define a machine sku
    mem: 48Gi
    cpu:
      vcore: 24
  gpu-machine:
    computing-device:
      type: nvidia.com/gpu
      model: GeForce RTX 3090
      count: 2
    mem: 48Gi
    cpu:
      vcore: 20

machine-list:
  - hostname: node1 # name of the machine, **do not** use upper case alphabet letters for hostname
    hostip: 172.18.18.207
    machine-type: master-machine # only one master-machine supported
    pai-master: "true"
  - hostname: node2
    hostip: 172.18.18.208
    machine-type: gpu-machine
    pai-worker: "true"
  - hostname: node3
    hostip: 172.18.18.209
    machine-type: gpu-machine
    pai-worker: "true"

pai-1.8.0/contrib/kubespray/config目录下config.yaml除了修改docker_image_tag版本之外,其他不变

user: root
password: schinper
docker_image_tag: v1.8.0
...

使用dev-box:v1.8.0创建容器:

docker run -itd \
    -v /var/run/docker.sock:/var/run/docker.sock \
    -v /opt/pai-deploy/cluster-cfg:/cluster-configuration  \
    -v /opt/pai-deploy/kube:/root/.kube \
    -v /opt/software/pai-1.8.0:/mnt/pai \
    --pid=host \
    --privileged=true \
    --net=host \
    --name=dev-box-quick-start \
    openpai/dev-box:v1.8.0
  • /opt/pai-deploy/cluster-cfg,该目录下保存了kubespray中的layout.yaml和config.yaml文件,脚本会根据这两个文件生成services-configuration.yaml文件。
  • /opt/pai-deploy/kube 创建该目录,并从k8s任意一台集群上拷贝~/.kube/*到该目录下,同时将config文件中127.0.0.1的地址替换为k8s主机节点地址。
  • /opt/software/pai-1.8.0 PAI的源码

dev-box容器相关操作

docker stop dev-box-quick-start && docker rm dev-box-quick-start  # 停止并删除容器
docker exec -it dev-box-quick-start bash    # 进入容器
docker exec dev-box-quick-start kubectl get node   # 获取k8s集群节点,判断能否连接到k8s的api-server
docker exec -w /mnt/pai dev-box-quick-start /bin/bash ./contrib/kubespray/script/start-service-in-dev-box.sh  # 启动dev-box服务

tart-service-in-dev-box.sh脚本的主要功能:

  • python3 ./contrib/kubespray/script/openpai_generator.py -l ./contrib/kubespray/config/layout.yaml -c ./contrib/kubespray/config/config.yaml -o /cluster-configuration 生成PAI服务配置yaml,即生成services-configuration.yaml文件。
  • ./paictl.py config push -p /cluster-configuration -m service < cluster-id 将配置文件写入k8s。
  • ./paictl.py service start < cluster-id 启动pai服务。

修改生成的services-configuration.yaml,启动openpai的web的端的https访问

pylon:
    port: 80
    uri: "http://172.18.18.207:80"
    ssl:
      crt_name: schinper-pai.crt
      crt_path: /open-pai-ssl/schinper-pai.crt
      key_name: schinper-pai.key
      key_path: /open-pai-ssl/schinper-pai.key

** /open-pai-ssl/schinper-pai.crt和 /open-pai-ssl/schinper-pai.crt参考自签证书 **

脚本执行步骤如下:

echo  "pai" > cluster-id
python3 ./contrib/kubespray/script/openpai_generator.py -l ./contrib/kubespray/config/layout.yaml -c ./contrib/kubespray/config/config.yaml -o /cluster-configuration # 生成PAI服务配置yaml
./paictl.py config push -p /cluster-configuration -m service < cluster-id  # 将配置文件写入k8s
./paictl.py service start < cluster-id # 启动pai服务

重启PAI服务的方法:

./paictl.py service start PAI-ID
./paictl.py service start PAI-ID

浏览PAI的界面:

  • http 浏览地址:http://172.18.18.207:9286/
  • https 浏览地址:https://172.18.18.207/
  • pai的默认用户名和密码:admin/admin-password

4 添加一个NFS存储到k8s并在PAI中使用

安装nfs-common并验证NFS服务器是否能够正常访问【这里的NFS我已经搭建好】

apt-get install nfs-common -y  # 挂载nfs
showmount -e 172.18.18.245  # 查看共享地址
mount -t nfs 172.18.18.245:/volume1/schinper-nfs/pai-data /schinper-nfs/ -o rw -o user=schinper -o vers=4.1 #挂载
umount /schinper-nfs/   # 取消挂载

创建PV和PVC,nfs-storage.yaml文件内容如下:

# NFS Persistent Volume
apiVersion: v1
kind: PersistentVolume
metadata:
  name: nfs-storage-pv
  labels:
    name: nfs-storage
spec:
  capacity:
    storage: 500Gi
  volumeMode: Filesystem
  accessModes:
    - ReadWriteMany
  persistentVolumeReclaimPolicy: Retain
  mountOptions:
    - nfsvers=4.1
  nfs:
    path: /volume1/schinper-nfs/pai-data
    server: 172.18.18.245
---
# NFS Persistent Volume Claim
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
  name: nfs-storage
spec:
  accessModes:
    - ReadWriteMany
  volumeMode: Filesystem
  resources:
    requests:
      storage: 500Gi    # 不要超过上面PV的capacity
  selector:
    matchLabels:
      name: nfs-storage # 和上面PV的label相对应

执行nfs-storage.yaml文件:

kubectl apply -f nfs-storage.yaml

由于k8s中的资源和分组是绑定的,必须绑定上分组之后,在当前分组中的用户才可以使用。
在openpai中使用添加的卷资源,

  • ① 从openpai用户信息中获取token,【在openpai的页面上获取即可】
  • ② 获取分组信息,openpai api开发手册
curl -i -X GET "https://172.18.18.207/rest-server/api/v2/groups/default" \
     -H "Authorization: Bearer TOKEN" --insecure
  • ③ 根据分组信息组装数据包,更新分组信息。
curl -i -X PUT "https://172.18.18.207/rest-server/api/v2/groups" \
     -H "Authorization: Bearer TOKEN" \
     -H "Content-Type: application/json" \
     -d '{
  "data": {
    "groupname": "default",
    "extension": {
      "acls": {
        "storageConfigs": ["nfs-storage"],
        "admin": false,
        "virtualClusters": ["default"]
      }
    }
  },
  "patch": true
}'  --insecure

openpai开发接口:https://developer.box.com/reference/get-groups-id/

执行完毕,在openpai的用户信息中即可看到新创建的卷。

5 配OpenPAI中加载K8S的Dashboard

安装K8S时,需要在group_vars/k8s_cluster/addons.yml 中启动dasshboard,即将dashboard_enabled: true

检测是否安装dashboard服务

kubectl -n kube-system get service kubernetes-dashboard

pai中需要使用https才能访问k8s的dashboard,因此需要参考openpai的https配置。在open-pai的中修改一下内容:services-configuration.yaml,添加内容如下,

pylon:
    port: 80
    uri: "http://172.18.18.207:80"
    ssl:
      crt_name: schinper-pai.crt
      crt_path: /open-pai-ssl/schinper-pai.crt
      key_name: schinper-pai.key
      key_path: /open-pai-ssl/schinper-pai.key

** /open-pai-ssl/schinper-pai.crt和 /open-pai-ssl/schinper-pai.crt参考自签证书**

停止、配置以及启动pylon服务

./paictl.py service stop -n pylon  # 停止pylon服务
./paictl.py config pull -o /cluster-configuration  # 获取集群当前的配置
vim /cluster-configuration/services-configuration.yaml  # 边界当前的配置信息,将pylon信息填入该文件
./paictl.py config push -p /cluster-configuration -m service  # 将新的配置信息写入到pai中。
./paictl.py service start -n pylon  # 启动pylon服务

此时可以通过pai的web界面加载kubernetes-dashboard,但需要用户认证,这里通过用户令牌认证。首先,在k8s中创建用户,admin-user.yaml文件内容如下:

apiVersion: v1
kind: ServiceAccount
metadata:
  name: admin-user
  namespace: kube-system
---
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRoleBinding
metadata:
  name: admin-user
roleRef:
  apiGroup: rbac.authorization.k8s.io
  kind: ClusterRole
  name: cluster-admin
subjects:
- kind: ServiceAccount
  name: admin-user
  namespace: kube-system

执行yaml

kubectl apply -f admin-user.yaml

获取token

kubectl -n kube-system describe secret $(kubectl -n kube-system get secret | grep admin-user | awk '{print $1}')

用获取到的令牌登录k8s的dashboard。

其他

K8S集群管理

安装集群

ansible-playbook -i inventory/mycluster/hosts.yaml  --become --become-user=root cluster.yml

卸载集群

ansible-playbook -i inventory/mycluster/hosts.yaml reset.yml

移除集群中的节点

ansible-playbook -i inventory/mycluster/hosts.yaml remove-node.yml 

OpenPAI集群管理

Worker机器【踩的第一个坑,环境检查一直不通过】

worker机器必须安装的nvidia-container-runtime,且docker的配置文件daemon.json中,必须添加如下runtime相关的内容

{
    "insecure-registries": [
        "172.18.18.222:5000",
        "http://172.18.18.204:30500"
    ],
    "registry-mirrors": [
        "http://172.18.18.204:30500",
        "https://docker.mirrors.ustc.edu.cn"
    ],
    "data-root": "/www/docker",
    "default-runtime": "nvidia",
    "runtimes": {
        "nvidia": {
            "path": "/usr/bin/nvidia-container-runtime",
            "runtimeArgs": []
        }
    }
}

坑2:PAI安装手册中给出的kubeadm下载地址无法访问

kubeadm和hyperkube

获取最新版k8s:https://storage.googleapis.com/kubernetes-release/release/stable.txt
https://storage.googleapis.com/kubernetes-release/release/v1.15.11/bin/linux/amd64/kubeadm
https://storage.googleapis.com/kubernetes-release/release/v1.15.11/bin/linux/amd64/hyperkube

docker run --rm -it --mount type=bind,source=/opt/kubespray-2.16.0/inventory/sample,dst=/inventory \
  --mount type=bind,source=/root/.ssh/id_rsa,dst=/root/.ssh/id_rsa \
  quay.io/kubespray/kubespray:v2.16.0 bash

v1.15.11 是脚本中默认使用的版本,这里直接使用。我直接把这两个文件下载下来,然后配置了一个web服务器,直接从我自己的web服务器中下载。

PAI环境准备

  • dev box机器:172.18.18.248
    • 用于安装、维护和卸载,需要指定唯一一台dev box机器
    • 可以访问Docker Hub
  • master机器:172.18.18.204
    • 用于运行核心Kubernetes组件和OpenPAI服务,目前OpenPAI还不支持高可用
    • 内存需要40G以上,可以访问Docker Hub
    • NTP已被成功开启。 您可以用命令apt install ntp来检查。
  • worker机器(NVIDIA GPU Worker):172.18.18.206

参考

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 203,547评论 6 477
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 85,399评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 150,428评论 0 337
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,599评论 1 274
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,612评论 5 365
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,577评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,941评论 3 395
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,603评论 0 258
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,852评论 1 297
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,605评论 2 321
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,693评论 1 329
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,375评论 4 318
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,955评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,936评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,172评论 1 259
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 43,970评论 2 349
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,414评论 2 342

推荐阅读更多精彩内容