主要是想搭设几台服务器,希望用户环境能隔离,相互安装和配置环境不影响,也希望不至于发生有了sudo权限就把别人的都删了的情况。同时也希望所有用户都能使用服务器上的硬件设备如GPU,且都能上网。
如果采用虚拟机技术,则硬件只能独占,不能共享,且开销大,另外一旦确定了所需分配的资源就成了固定开销,无论虚拟机中资源利用率如何。而另一方面,容器技术的特点则是资源共享,基本不占用硬件资源,所以考虑使用容器技术来实现用户环境隔离。
目前最流行的容器技术还是Docker,但Docker更适合于单个应用环境的部署,对于用户来说,希望在相互隔离时候也能用到服务器资源,更希望是一个虚拟机,而不是一个应用环境。目前Linux上主要有LXC和LXD,Docker以前就是用的LXC的Runtime,而LXD也只是一个提供了REST API的LXC容器管理器而已,其仓库地址在此。因此打算使用LXD来搭建这个服务器。
初始化
首先是下载LXD容器,如果是Ubuntu16.04里的apt软件仓库,最高应该是2.x的版本,如果要支持LXD容器内GPU的数据处理,至少版本为3.0.好在从16.04时候引进了另一个软件包管理工具,之前一篇文章有所介绍,即使用snap软件包管理工具。
查看版本:
可以看到已经到3.6了,直接下载就行snap install lxd
。
安装好后应该就可以直接使用了,第一部是初始化LXD的环境,使用lxd init
。如果出现permission denied
之类的问题,可以加sudo
,嫌麻烦可以将当前用户加入LXD组内:
然后注销重新登录就行了。
在初始化之前,需要安装几个工具,一个是ZFS,是LXD默认的后端存储工具,另一个是Bridge管理工具,LXD自身也带网桥创建功能,默认创建网桥会自动创建局域网私有地址并分配DHCP地址至虚拟网卡。
初始化过程如下:
所有提示注意一下是否创建网桥时候选择no就行,其余基本可以使用默认配置。如果不用管外网远程登录,可以直接全选默认。
然后拉取一个镜像,如:
拉取成功启动了就可以使用lxc list
看到容器了。使用lxc exec test -- ${command}
命令在容器内执行命令。如:
这时可以进入容器内的bash。
然后通过配置好第一个容器,将其作为模板,制作出多个虚拟主机。
显卡配置
在此之前,需要宿主机上安装显卡驱动和CUDA,具体过程不做赘述。
先关闭容器lxc stop test
,然后将显卡设备添加到容器中:
该命令是添加所有显卡,也可以手动指定显卡id。
然后启动容器,安装显卡驱动:
可以直接参考宿主机的显卡驱动,查看一下宿主机显卡驱动版本,可以使用nvidia-smi
或者sudo dpkg -l |grep nvidia
查看,然后回到容器,使用apt install nvidia-XXX-dev
安装。
如果安装成功,即可以使用nvidia命令查看显卡。
CUDA版本和TensorFlow版本由用户自己选择,默认不安装。
网络配置
这个是最麻烦的,如果需要访问外网的话。目前个人方法如下:
lxc创建网桥
先使用lxc创建一个网桥,网桥地址应该与本地电脑在一个网段,这样桥接后本地其他电脑才可以远程访问该容器。假如本地各电脑IP为192.168.1.xxx
,则:
其他可使用默认配置,具体各项参数见官方说明。
然后使用bridge管理工具将网桥连接至本地网卡,假如本地网卡为enp1s0,则:
添加之后可以使用brctl show
命令查看。
宿主机路由
这时可能出现宿主机无法上网的问题,原因是访问网络时,数据包都默认转发到新建网桥地址,而不是默认网关地址,所以需要添加一条路由表:
可以解决本地宿主机上网问题。
重新初始化
关闭容器后再次使用lxd init
初始化容器环境,主要是为容器选择默认网桥,这时只用修改一项配置Would you like to configure LXD to use an existing bridge or host interface? (yes/no) [default=no]
,改为yes,然后输入新建网桥名lxd0
即可。
分配静态地址
然后重新启动容器并进入bash,修改网络配置文件:
添加
重启网络服务
如果IP还不变,那就重启宿主机。
修改DNS
通常到上一步已经可以上网了,默认域名解析服务地址是网桥地址,你也可以改为自定义的DNS地址,如114.114.114.114
。最通常的方法是修改/etc/resolv.conf
文件中的nameserver
。但重启后会失效。以下是永久修改DNS的方法,通常在搭建过程中不需要用到。
修改Resolvconf配置
修改/etc/resolvconf/resolv.conf.d
目录下的base,在里面修改DNS服务器地址即可。
修改DHCP配置
另一个方法是修改DHCP配置文件,
可以看到,
去掉前面的#,将域名服务器改成自己的就可以了。
ssh配置
如果希望用户能远程访问容器,除了网络配置之外,还需要修改一下ssh配置。默认禁止root用户登录,容器创建默认用户也是root用户,里面有个ubuntu用户,未初始化。既然虚拟主机交给用户,即把root也给用户了,所以先设置允许root用户登录,如不需要可以让用户自行更改。
将其中的PermitRootLogin prohibit-password
改为PermitRootLogin yes
,以及ChallengeResponseAuthentication no
改为ChallengeResponseAuthentication yes
。
然后为root用户设置密码:
另外可以编辑ssh登录用户的欢迎信息,通过编辑/etc/update-motd.d/
目录下的00-header
和01-hepler-text
中的内容即可完成。
最后,重启ssh服务,
挂载共享目录
最后需要在主机上创建一个文件夹,用于各个容器与主机共享,文件传输之类,虽然主机lxc已经有pull和push方法从主机和容器之间拷贝文件,但共享目录会显得更为方便,即便在容器之间也可以相互访问。
其中,path
和source
的地址可以自己定义。
到这里,基本结束。