CRIU实现热迁移

介绍CRIU

CRIU(Checkpoint/Restore In Userspace)是Linux上的一个软件。它可以用来暂停运行中的容器或者是进程,根据CRIU暂停生成的文件从断点恢复容器或者是进程,然后继续执行。

环境安装

实验涉及两台电脑(虚拟机)因此两台电脑间的通信使用NFS(network file system)。

容器就使用docker 17.06.0。

CRIU的版本选择3.14。

两台虚拟机的操作系统选择Ubuntu16,尝试了Ubuntu20感觉不行。

安装NFS

服务器IP:192.168.40.132

客户端IP:192.168.40.134

首先说明服务器端安装nfs的过程。使用apt-get下载完成nfs-kernel-server之后,将要挂载到客户端的目录添加到/etc/exports文件中。

# config host network
sudo apt-get install nfs-kernel-server -y
# config NFS
sudo gedit /etc/exports
# Add the below line to exports file:
# /home       192.168.40.134(rw,sync,no_root_squash,no_subtree_check)
# Then restart nfs-kernel-server service
sudo systemctl restart nfs-kernel-server

在实验过程中根据需要,在服务器exports文件中加入了/home/proc和/home/container目录,分别储存进程迁移、容器迁移的相关文件。

完成上述配置之后,对防火墙进行配置。其中要允许客户端(IP为192.168.40.134)的访问。

# config firewall
# First, check firewall status
sudo ufw status
# If ufw is inactive, use the below command to enable ufw:
sudo ufw enable
# Make ufw allow incoming and outgoing:
sudo ufw default allow incoming
sudo ufw default allow outgoing
# Make client server can access host server
sudo ufw allow from 192.168.40.134 to any port nfs

配置客户端的代码如下。其中只挂载了/home目录,其他的目录挂载可以根据需要调整。

#!/bin/bash
# install nfs

sudo cp /etc/apt/sources.list /etc/apt/sources.list.bak
sudo rm -f /etc/apt/sources.list
sudo cp ./sources.txt /etc/apt/sources.list
echo "finish changing source"
sudo apt update
sudo apt upgrade -y -f

# config host network
sudo apt-get install nfs-common -y
# mount the host /home
sudo mkdir -p /nfs/home
sudo mount 192.168.40.132:/home /nfs/home
# check mount status
sudo df -h

安装Docker

docker同样使用apt安装,而非源码编译。首先将docker(和CRIU)所需要的支持软件全部安装好,代码如下:

#build dependent
sudo apt install build-essential -f -y
sudo apt install pkg-config -f -y
sudo apt install libnet-dev python-yaml libaio-dev -f -y
sudo apt install libprotobuf-dev libprotobuf-c-dev protobuf-c-compiler protobuf-compiler python-protobuf libnl-3-dev libcap-dev libbsd-dev -f -y
sudo apt-get install \
    apt-transport-https \
    ca-certificates \
    curl \
    gnupg-agent \
    software-properties-common -y -f

之后将docker加入sources.list,并且下载对应版本的docker。此处下载的docker版本为17.06.0,下载旧版本的docker是为了保证checkpoint不出现bug(使用apt-cache madison docker-ce指令查看全部可下载版本)。最后如果成功下载hello-world并且运行则说明安装成功。

# install docker
# remove docker
sudo apt-get remove docker docker-engine docker.io containerd runc 
curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo apt-key add -
# add repo
sudo add-apt-repository \
   "deb [arch=amd64] https://download.docker.com/linux/ubuntu \
   $(lsb_release -cs) \
   stable"
# update and install 
sudo apt-get update
sudo apt-get install docker-ce=17.06.0~ce-0~ubuntu -y
# check 
sudo docker run hello-world

安装完成docker之后需要开启experiment属性,代码如下:

# add experiment to docker
sudo echo "{\"experimental\": true}" >> /etc/docker/daemon.json
sudo systemctl restart docker

安装CRIU

CRIU的安装使用源码编译安装的方式。下载的CRIU版本为最新的3.14版。编译源代码时可能会要求安装其他的依赖软件,可以根据提示添加。最后如果criu check输出结果为Looks good.说明没有产生问题。

# criu install
curl -O -sSL http://download.openvz.org/criu/criu-3.14.tar.bz2
tar xjf criu-3.14.tar.bz2
cd criu-3.14
make
sudo cp ./criu/criu /usr/local/bin
# check
sudo criu check

进程热迁移

进程热迁移首先要在服务器上创建要被迁移的进程test.h(该进程会不断输出时间戳)由于CRIU进程热迁移的进程不能依赖当前的shell窗口,因此需要使用setsid指令将time.sh独立出去,同时将输出和输入重定向。指令如下。运行该指令之后可以看到test.out中不断被写入时间戳,可以时候tail指令查看。

$ setsid ./test.sh </dev/null &>$PWD/test.out

脚本test.sh内容如下:

#! /bin/bash

while (true)
do
	time=$(date +%s.%N)
    echo $time
	sleep 10e-4
done

在服务器上暂停进程要确定进程的pid,因此使用ps aux查看进程的pid。之后使用CRIU的dump执行暂停进程。

id=$(ps -ef | grep time| grep -v grep | awk '{print $2}')
criu dump --tree $id --images-dir $PWD

服务器暂停进程之后,在客户端中回复进程,由于目录没有产生变化,因此直接指定–images-dir为当前目录($PWD)即可。

criu restore --images-dir $PWD

CRIU在热迁移进程的大致思路为:在服务器上暂停进程,之后在客户端上使用CRIU恢复出进程。使用tail指令查看test.out文件会发现使用CRIU暂停进程之后test.out不会有新的输入,在客户端上恢复之后又会往test.out中输入时间戳。全部过程都发生在服务器的/home/proc目录中,该目录会挂载到客户端的/home/proc目录中。注意一定要把文件的路径在两台虚拟机上都创建成一样的,否则不能成功

容器热迁移

容器热迁移和进程热迁移类似,只需要加入docker的操作即可。基本的思路是在服务器上创建容器,然后暂停容器,查看运行的输出。在客户端恢复容器之后查看输出,如果运行的输出是紧接服务器输出即说明热迁移成功。整个过程都发生在服务器的/home/container目录下,客户端将服务器的/home/container目录挂载到本地的/home/container下。

首先使用docker创建容器looper2,该程序递增地输出i,每个一秒输出一次。

docker run -d --name looper2 --security-opt seccomp:unconfined busybox /bin/sh -c 'i=0; while true; do echo $i; i=$(expr $i + 1); sleep 1; done'

等待输出一段时间后中断程序,中断程序后会产生对应的目录,存储容器的运行状态,给恢复容器时使用。

sudo docker checkpoint create --checkpoint-dir=/home/container/ looper2 checkpoint2

查看logs如下:

sudo docker logs looper2

服务器容器运行结果

在客户端上使用docker恢复容器,注意这里–checkpoint-dir只需要指定到checkpoints目录即可,不需要进一步制定checkpoint2(已经由–checkpoint指定)

docker create --name looper-clone --security-opt seccomp:unconfined busybox /bin/sh -c 'i=0; while true; do echo $i; i=$(expr $i + 1); sleep 1; done'
docker start --checkpoint-dir=/home/container/1101bde4f985176cab26a3fae2957763c35be3c8d0c27f0fa9e469c1a4ff5928/checkpoints/ --checkpoint=checkpoint2 looper-clone

回复容器后可以使用同样的指令查看运行结果。如下:

客户端恢复结果

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值