Openpai v1.8.1 部署总结

Note: 微软官方已经停止维护此项目,目前我在我自己的分支维护一些我自己需要的功能,也欢迎PR。

前提

虽然我保留了v1.8.1这个release,但实际我已经添加了许多功能和bug fix,所以和microsoft发布的v1.8.1版本会有一些区别,具体可参考https://github.com/siaimes/pai/pulls?q=is%3Apr

术语

术语 解释
dev-box 集群安装、管理与维护节点,不用的时候可以关机,请不要格式化,否则再也无法维护集群
master 集群主节点
worker 集群计算节点
所有机器 包括dev-box、master和worker在内的所有节点

硬件要求

节点 CPU 内存 系统盘
dev-box 4线程 8GB 40GB
master 8线程 64GB 256GB
worker 6线程/GPU 64GB/GPU 512GB

注1: master,worker必须为物理机器(其实也可以是虚拟机,但是生产环境不建议这样用,还要考虑显卡直通虚拟机的问题也挺麻烦),dev-box可以虚拟机(如果要调试代码或二次开发可能要100G以上硬盘空间),毕竟他只有安装和维护系统的时候才用到,用物理机器太浪费了。

前提条件

  1. 所有机器操作系统为全新的Ubuntu 18.04 LTS server;
  2. 所有机器具有相同用户名和密码的管理员账户;
  3. 所有机器时区为上海;
  4. 所有机器IP在同一网段,一台机器多个IP也是不允许的;
  5. 此文档只支持x86_84架构的机器。

注1: Openpai项目文档建议用Ubuntu 16.04 LTS,但是我在Ubuntu 16.04 LTS遇到了很严重的问题,所以更新到Ubuntu 18.04。

注2:k8s不支持swap,安装系统的时候请不要添加swap分区,否则节点重启就挂了。

初始化

所有机器

关闭自动更新

Ubuntu 18.04 LTS server默认是开启自动更新的,需要关闭,以避免不必要的系统故障。

1
sudo nano /etc/apt/apt.conf.d/20auto-upgrades
1
2
3
4
APT::Periodic::Update-Package-Lists "0";
APT::Periodic::Download-Upgradeable-Packages "0";
APT::Periodic::AutocleanInterval "0";
APT::Periodic::Unattended-Upgrade "0";

参考:Prevent Ubuntu 18.06 And Nvidia Drivers From Updating

切换清华源

https://mirrors.tuna.tsinghua.edu.cn/help/ubuntu/

更新依赖

1
2
sudo apt update
sudo apt upgrade

启动BBR(可选)

拥塞控制算法,比默认的更好。

查看:

1
sudo sysctl net.ipv4.tcp_congestion_control

设置:

1
2
3
sudo bash -c 'echo "net.core.default_qdisc=fq" >> /etc/sysctl.conf'
sudo bash -c 'echo "net.ipv4.tcp_congestion_control=bbr" >> /etc/sysctl.conf'
sudo sysctl -p

验证:

1
sudo sysctl net.ipv4.tcp_congestion_control

安装openssh-server

1
sudo apt install openssh-server

安装ntp

1
sudo apt install ntp

安装docker

https://docs.docker.com/engine/install/ubuntu/

1
sudo apt remove docker docker-engine docker.io containerd runc
1
2
3
4
5
6
7
8
sudo apt update
sudo apt-get install \
apt-transport-https \
ca-certificates \
curl \
gnupg \
lsb-release
curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo gpg --dearmor -o /usr/share/keyrings/docker-archive-keyring.gpg
1
2
3
echo \
"deb [arch=amd64 signed-by=/usr/share/keyrings/docker-archive-keyring.gpg] https://download.docker.com/linux/ubuntu \
$(lsb_release -cs) stable" | sudo tee /etc/apt/sources.list.d/docker.list > /dev/null
1
2
sudo apt update
sudo apt install docker-ce docker-ce-cli containerd.io

删除添加的docker源,因为安装Openpai的时候,Openpai的脚本会再添加一次docker源,会导致源冲突。

1
sudo rm /etc/apt/sources.list.d/docker.list

安装python

按理说Ubuntu默认是有安装python的,但是我在实际操作的时候发现有的机器就是没有python,所以手动确认以下,以避免报错。

1
sudo apt install python

安装nfs客户端

1
sudo apt install nfs-common

安装压缩软件

1
sudo apt install zip

修改daemon

在所有机器的/etc/docker/daemon.json中写入{},可以避免不必要的报错。

如果您局域网地址是172.*.*.*,请参考这个文档Docker-Compose导致ssh连接断开的问题,修改/etc/docker/daemon.json,否则可能出现奇怪的网络问题。即使用下面的daemon文件:

1
2
3
{
"default-address-pools": [{"base":"10.10.0.0/16","size":24}]
}

修改完daemon之后重启一下docker:

1
sudo systemctl restart docker

worker

注1: 下面介绍的是使用NVIDIA显卡的worker节点配置方法,如果使用AMD显卡请自己参考项目文档,由于我没有ADM显卡,所以无法测试。

注2: 如果是CPU计算节点可以跳过这一部分。

安装GPU驱动

https://launchpad.net/~graphics-drivers/+archive/ubuntu/ppa

https://openpai.readthedocs.io/zh_CN/latest/manual/cluster-admin/installation-faqs-and-troubleshooting.html#how-to-check-whether-the-gpu-driver-is-installed

https://howtoinstall.co/en/ubuntu/xenial/xserver-xorg?action=remove

https://chrisalbon.com/code/deep_learning/setup/prevent_nvidia_drivers_from_upgrading/

1
2
3
4
5
6
sudo add-apt-repository ppa:graphics-drivers/ppa
sudo apt update
sudo apt install nvidia-driver-470
sudo apt autoremove xserver-xorg
sudo apt autoremove --purge xserver-xorg
sudo apt-mark hold nvidia-driver-470 # Freeze NVIDIA Drivers

如果上面第一条命令不成功可以用下面这条替代:

1
sudo bash -c 'echo "deb https://launchpad.proxy.ustclug.org/graphics-drivers/ppa/ubuntu bionic main" > /etc/apt/sources.list.d/graphics-drivers-ubuntu-ppa-bionic.list'

安装nvidia-container-runtime

https://github.com/NVIDIA/nvidia-container-runtime#installation

https://openpai.readthedocs.io/zh_CN/latest/manual/cluster-admin/installation-faqs-and-troubleshooting.html#how-to-install-nvidia-container-runtime

先用这个命令ping一下nvidia.github.io看看返回的IP地址是否正常。

1
ping nvidia.github.io

我的网络环境这个域名已经被DNS污染了(DNS返回127.0.0.1),我的解决方案是在/etc/hosts文件中添加一行如下:

1
185.199.110.153 nvidia.github.io

然后继续安装即可

1
2
3
4
5
6
7
8
curl -s -L https://nvidia.github.io/nvidia-container-runtime/gpgkey | \
sudo apt-key add -
distribution=$(. /etc/os-release;echo $ID$VERSION_ID)
curl -s -L https://nvidia.github.io/nvidia-container-runtime/$distribution/nvidia-container-runtime.list | \
sudo tee /etc/apt/sources.list.d/nvidia-container-runtime.list
sudo apt update
sudo apt install nvidia-container-runtime
sudo nano /etc/docker/daemon.json

填入下面的配置文件:

1
2
3
4
5
6
7
8
9
{
"default-runtime": "nvidia",
"runtimes": {
"nvidia": {
"path": "/usr/bin/nvidia-container-runtime",
"runtimeArgs": []
}
}
}

如果有按照上一部分修改daemon,配置文件应该如下:

1
2
3
4
5
6
7
8
9
10
{
"default-runtime": "nvidia",
"runtimes": {
"nvidia": {
"path": "/usr/bin/nvidia-container-runtime",
"runtimeArgs": []
}
},
"default-address-pools": [{"base":"10.10.0.0/16","size":24}]
}

最后重启docker。

1
sudo systemctl restart docker

设置GPU常驻内存

https://linuxeye.com/463.html

设置GPU常驻内存,可将nvidia-smi -pm 1加入/etc/rc.local,重启生效,可解决GPU初始化缓慢、无任务运行但是利用率居高不下、偶尔丢卡等问题。

Ubuntu 18.04 LTS的rc.local逻辑已经改变了,需要自己调整一下。

  1. /lib/systemd/system/rc-local.service文件新增以下内容:
1
2
3
[Install]
WantedBy=multi-user.target
Alias=rc-local.service
  1. 设置rc-local开机自启:
1
sudo systemctl enable rc-local
  1. /etc/rc.local中填入以下内容:
1
2
3
4
5
#!/bin/sh -e

nvidia-smi -pm 1

exit 0
  1. 赋予可执行权限:
1
sudo chmod +x /etc/rc.local

测试驱动是否正常

  1. 重启一下服务器。
1
sudo reboot
  1. 检查显卡驱动以及常驻内存是否生效
1
nvidia-smi
  1. 能正确返回信息即驱动安装成功,Persistence-M的状态为On,则常驻内存配置成功。

检查nvidia-container-runtime是否安装成功。

1
sudo docker run nvidia/cuda:10.0-base nvidia-smi

处理容器内nvidia-smi无法显示占用GPU进程问题

nvidia-smi can not detect the PID of processes using GPU

dev-box

配置免密登录

  1. 生成密钥
1
ssh-keygen
  1. 向远程主机注册密钥
1
ssh-copy-id username@remote_host
  1. 测试是否可免密登录
1
ssh username@remote_host

开始安装

下面都在dev-box中操作

https://openpai.readthedocs.io/en/pai-1.6.y/manual/cluster-admin/installation-guide.html

准备项目

无法clone github项目的,可以为git开一个代理,或者其他电脑clone下来之后上传,这里应该是目前唯一可能遭遇网络问题的地方。

1
2
3
4
git clone -b release-2.11 https://github.com/kubernetes-sigs/kubespray.git ${HOME}/pai-deploy/kubespray
git clone https://github.com/siaimes/pai.git
cd pai
git checkout v1.8.1

contrib/kubespray/script/environment.sh#L18-L23

1
2
3
4
5
6
echo "Clone kubespray source code from github to ${HOME}/pai-deploy"
sudo rm -rf ${HOME}/pai-deploy/kubespray
git clone -b release-2.11 https://github.com/kubernetes-sigs/kubespray.git ${HOME}/pai-deploy/kubespray

echo "Copy inventory folder, and save it "
cp -rfp ${HOME}/pai-deploy/kubespray/inventory/sample ${HOME}/pai-deploy/kubespray/inventory/pai

改为

1
2
3
4
5
6
7
#echo "Clone kubespray source code from github to ${HOME}/pai-deploy"
#sudo rm -rf ${HOME}/pai-deploy/kubespray
#git clone -b release-2.11 https://github.com/kubernetes-sigs/kubespray.git ${HOME}/pai-deploy/kubespray

echo "Copy inventory folder, and save it "
rm -rf ${HOME}/pai-deploy/kubespray/inventory/pai
cp -rfp ${HOME}/pai-deploy/kubespray/inventory/sample ${HOME}/pai-deploy/kubespray/inventory/pai

离线安装相关文件准备

参考:

https://github.com/siaimes/k8s-share

https://github.com/microsoft/pai/issues/5150

启动服务容器

在dev-box运行如下命令:

1
sudo docker run -itd -p 0.0.0.0:10000:80 --restart always --name k8s_share siaimes/k8s-share:v1.8.1

该命令会在dev-box启动一个容器以提供安装PAI需要的资源文件,现在假设你dev-box的IP为10.10.10.10,后面有提到这个地址的地方自己对照修改。

修改安装脚本

/src/device-plugin/deploy/start.sh.template#L32

1
svn cat https://github.com/NVIDIA/k8s-device-plugin.git/tags/1.0.0-beta4/nvidia-device-plugin.yml \

改为

1
curl "http://10.10.10.10:10000/k8s-share/NVIDIA/k8s-device-plugin/1.0.0-beta4/nvidia-device-plugin.yml" \

即将nvidia-device-plugin.yml资源文件下载地址改为我们自己启动的服务地址。

编写参数文件

参考项目文档编写layout.yaml文件。

参考下面的格式编写config.yaml文件。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
user: username
password: password
docker_registry_namespace: siaimes
docker_image_tag: v1.8.1

openpai_kubespray_extra_var:
kube_image_repo: "siaimes"
gcr_image_repo: "siaimes"
pod_infra_image_repo: "siaimes/pause-{{ image_arch }}"
dnsautoscaler_image_repo: "siaimes/cluster-proportional-autoscaler-{{ image_arch }}"
kubeadm_download_url: "http://10.10.10.10:10000/k8s-share/kubernetes-release/release/{{ kubeadm_version }}/bin/linux/{{ image_arch }}/kubeadm"
hyperkube_download_url: "http://10.10.10.10:10000/k8s-share/kubernetes-release/release/{{ kube_version }}/bin/linux/{{ image_arch }}/hyperkube"
cni_download_url: "http://10.10.10.10:10000/k8s-share/containernetworking/plugins/releases/download/{{ cni_version }}/cni-plugins-linux-{{ image_arch }}-{{ cni_version }}.tgz"
calicoctl_download_url: "http://10.10.10.10:10000/k8s-share/projectcalico/calicoctl/releases/download/{{ calico_ctl_version }}/calicoctl-linux-{{ image_arch }}"

kubelet_custom_flags:
serialize-image-pulls: "false"

安装

1
2
3
cd contrib/kubespray
/bin/bash quick-start-kubespray.sh
/bin/bash quick-start-service.sh

重启服务注意事项

https://github.com/microsoft/pai/issues/5465

项目文档说管理集群要使用/pai/paictl.py,但是该文件默认checkout的是最终版本而非当前版本,所以会导致版本不一致问题。

如果要使用这个脚本的话,每次启动容器都要手动checkout一下,否则可能导致服务无法正常启动。

目前的解决方案是将本地checkout好的项目挂载到容器里面然后直接用那里面的paictl.py。

1
2
3
4
5
6
7
8
9
10
11
12
sudo docker run -itd \
-e COLUMNS=$COLUMNS -e LINES=$LINES -e TERM=$TERM \
-v /var/run/docker.sock:/var/run/docker.sock \
-v ${HOME}/pai-deploy/cluster-cfg:/cluster-configuration \
-v ${HOME}/pai-deploy/kube:/root/.kube \
-v ${HOME}/pai:/mnt/pai \
--pid=host \
--privileged=true \
--net=host \
--name=dev-box \
--restart=always \
siaimes/dev-box:v1.8.1

运行这个命令前确保${HOME}/pai中检出版本与安装版本一致,然后容器中使用/mnt/pai中的paictl.py

后续

成功启动service之后,其他个性化配置过程一般不会有问题,除非配置文件写错了,务必检查清楚。

0%