栏目分类:
子分类:
返回
终身学习网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
终身学习网 > IT > 软件开发 > 后端开发 > Java

云计算:KVM和Docker的管理

Java 更新时间:发布时间: 百科书网 趣学号

云计算应该是现如今最火的领域,什么东西沾点云计算都感觉相当的Sophisticated,但真正学了以后发现没那么邪乎,虽然这项技术,或者说这个概念相当牛逼,但是只要这门课有课设,就说明这东西是能被当代大学生做出来(虽然做课设相当头疼)

那么,一个人,一个混子的故事就此开启。两台电脑,无数个日夜,终于将这个作业完成。

下面,全体观众,请欣赏 云计算Ultra Plus Pro Max(都没有)系列

SystemManager类  该模块主要用于全局管理,包括提供KVM和Docker的IP地址等信息

package manager;

import entity.Container;
import entity.Image;
import entity.VM;
import org.json.simple.JSONObject;
import org.json.simple.parser.JSONParser;
import org.json.simple.parser.ParseException;
import org.libvirt.*;
import utils.DockerUtils;
import utils.XMLUtils;
import utils.ZKClient;

import java.io.FileReader;
import java.io.IOException;
import java.math.RoundingMode;
import java.text.DecimalFormat;
import java.util.*;

public class SystemManager {

    private static final Map vmTable;//name-domain
    private static final Map vmInfoTable;//name-vm
    private static final Map connectTable;//ip-connect
    private static final Map ipStateTable;//ip-bool
    private static final Map dnTable;//nodeIp-dn
    private static final Map volTable;//name-vol
    private static final Map pwdTable;//name-vol
    private static final Map> ctTable;//name-container
    private static final Map> imageTable;//p:v-image
    public static final double B2GB = 1 << 30;
    public static final double KB2GB = 1 << 20;
    public static final String POOL = "pool01";
    public static final String POOL_PATH = "/opt/kvm/images";
    public static final String LINUX_USER_NAME = "root";
    public static final String LINUX_PASSWORD = "ldw20000702";
    public static final String NET_CONF_PATH = "/etc/sysconfig/network-scripts/ifcfg-ens3";
    public static final String HOSTNAME_PATH = "/etc/hostname";
    public static final String NFS_SERVER_IP = "192.168.43.130";
    public static final String REGISTRY_IP = "192.168.43.130";
    public static final int REGISTRY_PORT = 5000;
    public static JSONObject NET_CONF;
    public static final DecimalFormat round2 = new DecimalFormat("0.00");
    public static final DecimalFormat round4 = new DecimalFormat("0.0000");
//    public static Connect NFS_SERVER = null;

    static {
        round2.setRoundingMode(RoundingMode.HALF_UP);
        round4.setRoundingMode(RoundingMode.HALF_UP);
        vmTable = new HashMap<>();
        vmInfoTable = new HashMap<>();
        connectTable = new HashMap<>();
        ipStateTable = new TreeMap<>();
        dnTable = new TreeMap<>();
        volTable = new HashMap<>();
        pwdTable = new HashMap<>();
        ctTable = new HashMap<>();
        imageTable = new HashMap<>();
        try {
            //解析JSON文件的内容
            JSONParser jsonParser = new JSONParser();
            String path = Objects.requireNonNull(SystemManager.class.getClassLoader().getResource("ifcfg-ens3.json")).getPath();
            NET_CONF = (JSONObject) jsonParser.parse(new FileReader(path));
        } catch (ParseException | IOException e) {
            e.printStackTrace();
        }
        refreshVM();
        refreshDocker();
    }

    public static void refreshVM() {
        vmTable.clear();
        vmInfoTable.clear();
        connectTable.clear();
        ipStateTable.clear();
        dnTable.clear();
        volTable.clear();
        pwdTable.clear();
        try {
            for (int i = 128; i < 255; i++) {
                ipStateTable.put("192.168.43." + i, false);
            }
            ZKClient zkClient = new ZKClient();
            Map ip4PM = zkClient.listIP4PM();
            pwdTable.putAll(zkClient.listPSW4PM());
            for (Map.Entry entry : ip4PM.entrySet()) {
                String hostname = entry.getKey();
                String nodeIp = entry.getValue();
                String uri = "qemu+tcp://" + nodeIp + ":16509/system";
                Connect connect = new Connect(uri);
                connectTable.put(nodeIp, connect);
                dnTable.put(nodeIp, hostname);
                ipStateTable.put(nodeIp, true);

                int[] ids = connect.listDomains();
                String[] names = connect.listDefinedDomains();
                List nameList = new LinkedList<>();
                for (int id : ids) {
                    String name = connect.domainLookupByID(id).getName();
                    nameList.add(name);
                }
                nameList.addAll(Arrays.asList(names));

                for (String domainName : nameList) {
                    Domain domain = connect.domainLookupByName(domainName);
                    long memory = (long) (domain.getInfo().memory / SystemManager.KB2GB);
                    int vcpu = domain.getInfo().nrVirtCpu;
                    int state = domain.isActive();
                    String ip = zkClient.getIP4VM(hostname, domainName);
                    String volPath = XMLUtils.getVolPath(domain.getXMLDesc(0));
                    StoragePool pool = connect.storagePoolLookupByName(SystemManager.POOL);
                    pool.refresh(0);
                    StorageVol vol = connect.storageVolLookupByPath(volPath);
                    long capacity = (long) (vol.getInfo().capacity / SystemManager.B2GB);
                    VM vm = new VM(nodeIp, domainName, state, ip, memory, vcpu, capacity, domain.isPersistent() == 1);
                    vmTable.put(domainName, domain);
                    vmInfoTable.put(domainName, vm);
                    volTable.put(domainName, vol);
                    ipStateTable.put(ip, true);
                }
            }
            zkClient.close();
        } catch (Exception e) {
            e.printStackTrace();
        }

    }

    public static void refreshDocker() {
        imageTable.clear();
        ctTable.clear();
        dnTable.clear();
        pwdTable.clear();
        try {
            ZKClient zkClient = new ZKClient();
            pwdTable.putAll(zkClient.listPSW4PM());
            Map ip4PM = zkClient.listIP4PM();
            for (Map.Entry entry : ip4PM.entrySet()) {
                String hostname = entry.getKey();
                String nodeIp = entry.getValue();
                dnTable.put(nodeIp, hostname);
                DockerUtils dockerUtils = new DockerUtils(nodeIp);
                imageTable.put(nodeIp, new HashMap<>());
                ctTable.put(nodeIp, new HashMap<>());
                for (Image image : dockerUtils.listImages()) {
                    imageTable.get(nodeIp).put(image.getName(), image);
                }
                for (Container container : dockerUtils.listContainer()) {
                    ctTable.get(nodeIp).put(container.getName(), container);
                }
            }
            zkClient.close();
        } catch (Exception e) {
            e.printStackTrace();
        }
    }


    public static String chooseNodeIP() {
        String ip = null;
        double bestScore = 0;
        try {
            for (Map.Entry entry : connectTable.entrySet()) {

                Connect connect = entry.getValue();
                StoragePool pool = connect.storagePoolLookupByName(SystemManager.POOL);
                if (pool.getInfo().state != StoragePoolInfo.StoragePoolState.VIR_STORAGE_POOL_RUNNING)
                    continue;
                long freeMem = connect.getFreeMemory();
                int maxVcpu = connect.getMaxVcpus("kvm");
                long curVcpu = 0;
                long curMem = 0;

                int[] ids = connect.listDomains();
                for (int id : ids) {
                    Domain domain = connect.domainLookupByID(id);
                    if (domain.isActive() == 1) {
                        curVcpu += domain.getInfo().nrVirtCpu;
                        curMem += domain.getInfo().memory;
                    }
                }
                double curScore = freeMem + maxVcpu - curMem - curVcpu;
                if (curScore > bestScore) {
                    bestScore = curScore;
                    ip = entry.getKey();
                }
            }
        } catch (LibvirtException e) {
            e.printStackTrace();
        }
        return ip;
    }

//    public static String chooseIP() {
//        for (Map.Entry entry : ipStateTable.entrySet()) {
//            if (!entry.getValue())
//                return entry.getKey();
//        }
//        return null;
//    }

    public static Map getVmTable() {
        return vmTable;
    }

    public static Map getVmInfoTable() {
        return vmInfoTable;
    }

    public static Map getConnectTable() {
        return connectTable;
    }

    public static Map getIpStateTable() {
        return ipStateTable;
    }

    public static Map getVolTable() {
        return volTable;
    }

    public static Map getDnTable() {
        return dnTable;
    }

    public static Map getPwdTable() {

        return pwdTable;
    }

    public static Map> getCtTable() {
        return ctTable;
    }

    public static Map> getImageTable() {
        return imageTable;
    }
}

Image类  同上,就不多写了

package entity;

public class Image {
    private String id;
    private String name;
    private String nodeIp;
    private String size;

    public String getId() {
        return this.id;
    }

    public String getName() {
        return this.name;
    }

    public String getNodeIp() {
        return this.nodeIp;
    }

    public String getSize() {
        return this.size;
    }

    public void setId(String id) {
        this.id = id;
    }

    public void setName(String name) {
        this.name = name;
    }

    public void setNodeIp(String nodeIp) {
        this.nodeIp = nodeIp;
    }

    public void setSize(String size) {
        this.size = size;
    }

    public boolean equals(Object o) {
        if (o == this) {
            return true;
        } else if (!(o instanceof Image)) {
            return false;
        } else {
            Image other = (Image)o;
            if (!other.canEqual(this)) {
                return false;
            } else {
                label59: {
                    Object this$id = this.getId();
                    Object other$id = other.getId();
                    if (this$id == null) {
                        if (other$id == null) {
                            break label59;
                        }
                    } else if (this$id.equals(other$id)) {
                        break label59;
                    }

                    return false;
                }

                Object this$name = this.getName();
                Object other$name = other.getName();
                if (this$name == null) {
                    if (other$name != null) {
                        return false;
                    }
                } else if (!this$name.equals(other$name)) {
                    return false;
                }

                Object this$nodeIp = this.getNodeIp();
                Object other$nodeIp = other.getNodeIp();
                if (this$nodeIp == null) {
                    if (other$nodeIp != null) {
                        return false;
                    }
                } else if (!this$nodeIp.equals(other$nodeIp)) {
                    return false;
                }

                Object this$size = this.getSize();
                Object other$size = other.getSize();
                if (this$size == null) {
                    if (other$size != null) {
                        return false;
                    }
                } else if (!this$size.equals(other$size)) {
                    return false;
                }

                return true;
            }
        }
    }

    protected boolean canEqual(Object other) {
        return other instanceof Image;
    }

    public int hashCode() {
        int PRIME = true;
        int result = 1;
        Object $id = this.getId();
        int result = result * 59 + ($id == null ? 43 : $id.hashCode());
        Object $name = this.getName();
        result = result * 59 + ($name == null ? 43 : $name.hashCode());
        Object $nodeIp = this.getNodeIp();
        result = result * 59 + ($nodeIp == null ? 43 : $nodeIp.hashCode());
        Object $size = this.getSize();
        result = result * 59 + ($size == null ? 43 : $size.hashCode());
        return result;
    }

    public String toString() {
        return "Image(id=" + this.getId() + ", name=" + this.getName() + ", nodeIp=" + this.getNodeIp() + ", size=" + this.getSize() + ")";
    }

    public Image() {
    }

    public Image(String id, String name, String nodeIp, String size) {
        this.id = id;
        this.name = name;
        this.nodeIp = nodeIp;
        this.size = size;
    }
}

VM类

package entity;

public class VM {
    private String nodeIp;
    private String domainName;
    private int state;
    private String ip;
    private long memory;
    private int vcpu;
    private long capacity;
    private boolean persistent;

    public String getNodeIp() {
        return this.nodeIp;
    }

    public String getDomainName() {
        return this.domainName;
    }

    public int getState() {
        return this.state;
    }

    public String getIp() {
        return this.ip;
    }

    public long getMemory() {
        return this.memory;
    }

    public int getVcpu() {
        return this.vcpu;
    }

    public long getCapacity() {
        return this.capacity;
    }

    public boolean isPersistent() {
        return this.persistent;
    }

    public void setNodeIp(String nodeIp) {
        this.nodeIp = nodeIp;
    }

    public void setDomainName(String domainName) {
        this.domainName = domainName;
    }

    public void setState(int state) {
        this.state = state;
    }

    public void setIp(String ip) {
        this.ip = ip;
    }

    public void setMemory(long memory) {
        this.memory = memory;
    }

    public void setVcpu(int vcpu) {
        this.vcpu = vcpu;
    }

    public void setCapacity(long capacity) {
        this.capacity = capacity;
    }

    public void setPersistent(boolean persistent) {
        this.persistent = persistent;
    }

    public boolean equals(Object o) {
        if (o == this) {
            return true;
        } else if (!(o instanceof VM)) {
            return false;
        } else {
            VM other = (VM)o;
            if (!other.canEqual(this)) {
                return false;
            } else {
                Object this$nodeIp = this.getNodeIp();
                Object other$nodeIp = other.getNodeIp();
                if (this$nodeIp == null) {
                    if (other$nodeIp != null) {
                        return false;
                    }
                } else if (!this$nodeIp.equals(other$nodeIp)) {
                    return false;
                }

                Object this$domainName = this.getDomainName();
                Object other$domainName = other.getDomainName();
                if (this$domainName == null) {
                    if (other$domainName != null) {
                        return false;
                    }
                } else if (!this$domainName.equals(other$domainName)) {
                    return false;
                }

                if (this.getState() != other.getState()) {
                    return false;
                } else {
                    Object this$ip = this.getIp();
                    Object other$ip = other.getIp();
                    if (this$ip == null) {
                        if (other$ip != null) {
                            return false;
                        }
                    } else if (!this$ip.equals(other$ip)) {
                        return false;
                    }

                    if (this.getMemory() != other.getMemory()) {
                        return false;
                    } else if (this.getVcpu() != other.getVcpu()) {
                        return false;
                    } else if (this.getCapacity() != other.getCapacity()) {
                        return false;
                    } else if (this.isPersistent() != other.isPersistent()) {
                        return false;
                    } else {
                        return true;
                    }
                }
            }
        }
    }

    protected boolean canEqual(Object other) {
        return other instanceof VM;
    }

    public int hashCode() {
        int PRIME = true;
        int result = 1;
        Object $nodeIp = this.getNodeIp();
        int result = result * 59 + ($nodeIp == null ? 43 : $nodeIp.hashCode());
        Object $domainName = this.getDomainName();
        result = result * 59 + ($domainName == null ? 43 : $domainName.hashCode());
        result = result * 59 + this.getState();
        Object $ip = this.getIp();
        result = result * 59 + ($ip == null ? 43 : $ip.hashCode());
        long $memory = this.getMemory();
        result = result * 59 + (int)($memory >>> 32 ^ $memory);
        result = result * 59 + this.getVcpu();
        long $capacity = this.getCapacity();
        result = result * 59 + (int)($capacity >>> 32 ^ $capacity);
        result = result * 59 + (this.isPersistent() ? 79 : 97);
        return result;
    }

    public String toString() {
        return "VM(nodeIp=" + this.getNodeIp() + ", domainName=" + this.getDomainName() + ", state=" + this.getState() + ", ip=" + this.getIp() + ", memory=" + this.getMemory() + ", vcpu=" + this.getVcpu() + ", capacity=" + this.getCapacity() + ", persistent=" + this.isPersistent() + ")";
    }

    public VM() {
    }

    public VM(String nodeIp, String domainName, int state, String ip, long memory, int vcpu, long capacity, boolean persistent) {
        this.nodeIp = nodeIp;
        this.domainName = domainName;
        this.state = state;
        this.ip = ip;
        this.memory = memory;
        this.vcpu = vcpu;
        this.capacity = capacity;
        this.persistent = persistent;
    }
}

#########################################################################################
package entity;

import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;

@Data
@NoArgsConstructor
@AllArgsConstructor
public class VM {
    private String nodeIp;
    private String domainName;
    private int state;
    private String ip;
    private long memory;
    private int vcpu;
    private long capacity;
    private boolean persistent;
}

VMInfo类  该模块用于获取KVM的基础信息

package entity;

import lombok.Data;
import lombok.NoArgsConstructor;
import manager.SystemManager;

@Data
@NoArgsConstructor
public class VMInfo {
    private int nVcpu;
    private double cpuRate;

    private double memRate;
    private double memTotal;

    private double diskAllocation;
    private double diskTotal;

    public VMInfo(int nVcpu, double cpuRate, double diskAllocation, double diskTotal, double memTotal, double memAvailable) {

        this.nVcpu = nVcpu;
        this.cpuRate = Double.parseDouble(SystemManager.round4.format(cpuRate));
        this.diskAllocation = Double.parseDouble(SystemManager.round2.format(diskAllocation));
        this.diskTotal = Double.parseDouble(SystemManager.round2.format(diskTotal));
        this.memTotal = Double.parseDouble(SystemManager.round2.format(memTotal));
        this.memRate = Double.parseDouble(SystemManager.round2.format(1 - memAvailable / memTotal));
    }

    @Override
    public String toString() {
        return "VMInfo{" +
                "nVcpu=" + nVcpu +
                ", cpuRate=" + cpuRate +
                ", memRate=" + memRate +
                ", memTotal=" + memTotal +
                ", diskAllocation=" + diskAllocation +
                ", diskTotal=" + diskTotal +
                '}';
    }
}

Container类  该模块用于

package entity;

public class Container {
    private String id;
    private String image;
    private boolean running;
    private String ip;
    private String nodeIp;
    private String name;

    public String getId() {
        return this.id;
    }

    public String getImage() {
        return this.image;
    }

    public boolean isRunning() {
        return this.running;
    }

    public String getIp() {
        return this.ip;
    }

    public String getNodeIp() {
        return this.nodeIp;
    }

    public String getName() {
        return this.name;
    }

    public void setId(String id) {
        this.id = id;
    }

    public void setImage(String image) {
        this.image = image;
    }

    public void setRunning(boolean running) {
        this.running = running;
    }

    public void setIp(String ip) {
        this.ip = ip;
    }

    public void setNodeIp(String nodeIp) {
        this.nodeIp = nodeIp;
    }

    public void setName(String name) {
        this.name = name;
    }

    public boolean equals(Object o) {
        if (o == this) {
            return true;
        } else if (!(o instanceof Container)) {
            return false;
        } else {
            Container other = (Container)o;
            if (!other.canEqual(this)) {
                return false;
            } else {
                //判断id是否相等
                label75: {
                    Object this$id = this.getId();
                    Object other$id = other.getId();
                    if (this$id == null) {
                        if (other$id == null) {
                            break label75;
                        }
                    } else if (this$id.equals(other$id)) {
                        break label75;
                    }

                    return false;
                }
                //判断存储图片是否相等
                Object this$image = this.getImage();
                Object other$image = other.getImage();
                if (this$image == null) {
                    if (other$image != null) {
                        return false;
                    }
                } else if (!this$image.equals(other$image)) {
                    return false;
                }

                if (this.isRunning() != other.isRunning()) {
                    return false;
                } else {
                    label60: {
                        //判断IP是否相等
                        Object this$ip = this.getIp();
                        Object other$ip = other.getIp();
                        if (this$ip == null) {
                            if (other$ip == null) {
                                break label60;
                            }
                        } else if (this$ip.equals(other$ip)) {
                            break label60;
                        }

                        return false;
                    }
                    //判断nodeIP是否相等
                    Object this$nodeIp = this.getNodeIp();
                    Object other$nodeIp = other.getNodeIp();
                    if (this$nodeIp == null) {
                        if (other$nodeIp != null) {
                            return false;
                        }
                    } else if (!this$nodeIp.equals(other$nodeIp)) {
                        return false;
                    }
                    //判断名字是否相等
                    Object this$name = this.getName();
                    Object other$name = other.getName();
                    if (this$name == null) {
                        if (other$name != null) {
                            return false;
                        }
                    } else if (!this$name.equals(other$name)) {
                        return false;
                    }

                    return true;
                }
            }
        }
    }

    protected boolean canEqual(Object other) {
        return other instanceof Container;
    }

    //用哈希表存储
    public int hashCode() {
        int PRIME = true;
        int result = 1;
        Object $id = this.getId();
        int result = result * 59 + ($id == null ? 43 : $id.hashCode());
        Object $image = this.getImage();
        result = result * 59 + ($image == null ? 43 : $image.hashCode());
        result = result * 59 + (this.isRunning() ? 79 : 97);
        Object $ip = this.getIp();
        result = result * 59 + ($ip == null ? 43 : $ip.hashCode());
        Object $nodeIp = this.getNodeIp();
        result = result * 59 + ($nodeIp == null ? 43 : $nodeIp.hashCode());
        Object $name = this.getName();
        result = result * 59 + ($name == null ? 43 : $name.hashCode());
        return result;
    }

    public String toString() {
        return "Container(id=" + this.getId() + ", image=" + this.getImage() + ", running=" + this.isRunning() + ", ip=" + this.getIp() + ", nodeIp=" + this.getNodeIp() + ", name=" + this.getName() + ")";
    }

    public Container(String id, String image, boolean running, String ip, String nodeIp, String name) {
        this.id = id;
        this.image = image;
        this.running = running;
        this.ip = ip;
        this.nodeIp = nodeIp;
        this.name = name;
    }

    public Container() {
    }
}

######################################################################################
package entity;

import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;

@Data
@AllArgsConstructor
@NoArgsConstructor
public class Container {
    private String id;
    private String image;
    private boolean running;
    private String ip;
    private String nodeIp;
    private String name;
    // docker run -d --name mpi01 --privileged=true centos_mpi:v1 /usr/sbin/init

}

VMServlet类  用于获取前端指令,调用后端函数

package controller;

import entity.Container;
import entity.Image;
import net.sf.json.JSONArray;
import net.sf.json.JSONObject;
import service.CTService;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.nio.charset.StandardCharsets;
import java.util.List;
import java.util.logging.Logger;

public class CTServlet extends HttpServlet {
    private final CTService service = new CTService();
    private final Logger logger = Logger.getLogger("CTServlet");

    public static JSONObject receivePost(HttpServletRequest request) throws IOException {

        // 读取请求内容
        BufferedReader reader = new BufferedReader(new InputStreamReader(request.getInputStream(), StandardCharsets.UTF_8));
        String line;
        StringBuilder stringBuilder = new StringBuilder();
        while ((line = reader.readLine()) != null) {
            stringBuilder.append(line);
        }
        //将json字符串转换为json对象
        return JSONObject.fromObject(stringBuilder.toString());
    }

    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        doPost(req, resp);
    }

    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        req.setCharacterEncoding("utf-8");
        resp.setCharacterEncoding("utf-8");

        JSONObject parameter = receivePost(req);
        String type = String.valueOf(parameter.get("type"));
        System.out.println(type);
        PrintWriter writer = resp.getWriter();
        boolean success = false;
        JSONObject jsonObject = new JSONObject();
        switch (type) {
            case "list":
                List vmList = service.listCT();
                String jsonArray = JSONArray.fromObject(vmList).toString();
                jsonObject.put("ctList", jsonArray);
                success = true;
                break;
            case "create":
                String name = String.valueOf(parameter.get("name"));
                String imageName = String.valueOf(parameter.get("imageName"));
                String nodeIp = String.valueOf(parameter.get("nodeIp"));
                Container ct = service.createCT(nodeIp, name, imageName);
                success = ct != null;
                jsonObject.put("ct", ct);
                break;
            case "open":
                name = String.valueOf(parameter.get("name"));
                nodeIp = String.valueOf(parameter.get("nodeIp"));
                ct = service.openCT(nodeIp, name);
                success = ct != null;
                jsonObject.put("ct", ct);
                break;
            case "close":
                name = String.valueOf(parameter.get("name"));
                nodeIp = String.valueOf(parameter.get("nodeIp"));
                success = service.closeCT(nodeIp, name);
                break;
            case "delete":
                name = String.valueOf(parameter.get("name"));
                nodeIp = String.valueOf(parameter.get("nodeIp"));
                success = service.deleteCT(nodeIp, name);
                break;
            case "commit":
                name = String.valueOf(parameter.get("name"));
                nodeIp = String.valueOf(parameter.get("nodeIp"));
                String author = String.valueOf(parameter.get("author"));
                String describe = String.valueOf(parameter.get("describe"));
                String repository = String.valueOf(parameter.get("repository"));
                String tag = String.valueOf(parameter.get("tag"));
                Image image = service.commitCT(nodeIp, name, author, describe, repository, tag);
                success = image != null;
                jsonObject.put("image", image);
                break;
        }
        jsonObject.put("success", success);
        writer.append(jsonObject.toString());
        logger.info(jsonObject.toString());
    }
}

CTServlet类  同上,但是面对Docker

package controller;

import entity.Container;
import entity.Image;
import net.sf.json.JSONArray;
import net.sf.json.JSONObject;
import service.CTService;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.nio.charset.StandardCharsets;
import java.util.List;
import java.util.logging.Logger;

public class CTServlet extends HttpServlet {
    private final CTService service = new CTService();
    private final Logger logger = Logger.getLogger("CTServlet");

    public static JSONObject receivePost(HttpServletRequest request) throws IOException {

        // 读取请求内容
        BufferedReader reader = new BufferedReader(new InputStreamReader(request.getInputStream(), StandardCharsets.UTF_8));
        String line;
        StringBuilder stringBuilder = new StringBuilder();
        while ((line = reader.readLine()) != null) {
            stringBuilder.append(line);
        }
        //将json字符串转换为json对象
        return JSONObject.fromObject(stringBuilder.toString());
    }

    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        doPost(req, resp);
    }

    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        req.setCharacterEncoding("utf-8");
        resp.setCharacterEncoding("utf-8");

        JSONObject parameter = receivePost(req);
        String type = String.valueOf(parameter.get("type"));
        System.out.println(type);
        PrintWriter writer = resp.getWriter();
        boolean success = false;
        JSONObject jsonObject = new JSONObject();
        switch (type) {
            case "list":
                List vmList = service.listCT();
                String jsonArray = JSONArray.fromObject(vmList).toString();
                jsonObject.put("ctList", jsonArray);
                success = true;
                break;
            case "create":
                String name = String.valueOf(parameter.get("name"));
                String imageName = String.valueOf(parameter.get("imageName"));
                String nodeIp = String.valueOf(parameter.get("nodeIp"));
                Container ct = service.createCT(nodeIp, name, imageName);
                success = ct != null;
                jsonObject.put("ct", ct);
                break;
            case "open":
                name = String.valueOf(parameter.get("name"));
                nodeIp = String.valueOf(parameter.get("nodeIp"));
                ct = service.openCT(nodeIp, name);
                success = ct != null;
                jsonObject.put("ct", ct);
                break;
            case "close":
                name = String.valueOf(parameter.get("name"));
                nodeIp = String.valueOf(parameter.get("nodeIp"));
                success = service.closeCT(nodeIp, name);
                break;
            case "delete":
                name = String.valueOf(parameter.get("name"));
                nodeIp = String.valueOf(parameter.get("nodeIp"));
                success = service.deleteCT(nodeIp, name);
                break;
            case "commit":
                name = String.valueOf(parameter.get("name"));
                nodeIp = String.valueOf(parameter.get("nodeIp"));
                String author = String.valueOf(parameter.get("author"));
                String describe = String.valueOf(parameter.get("describe"));
                String repository = String.valueOf(parameter.get("repository"));
                String tag = String.valueOf(parameter.get("tag"));
                Image image = service.commitCT(nodeIp, name, author, describe, repository, tag);
                success = image != null;
                jsonObject.put("image", image);
                break;
        }
        jsonObject.put("success", success);
        writer.append(jsonObject.toString());
        logger.info(jsonObject.toString());
    }
}

ImageServlet类  老样子

package controller;

import entity.Image;
import net.sf.json.JSONArray;
import net.sf.json.JSONObject;
import service.ImageService;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.nio.charset.StandardCharsets;
import java.util.List;
import java.util.logging.Logger;

public class ImageServlet extends HttpServlet {
    private final ImageService service = new ImageService();
    private final Logger logger = Logger.getLogger("ImageServlet");

    public static JSONObject receivePost(HttpServletRequest request) throws IOException {

        // 读取请求内容
        BufferedReader reader = new BufferedReader(new InputStreamReader(request.getInputStream(), StandardCharsets.UTF_8));
        String line;
        StringBuilder stringBuilder = new StringBuilder();
        while ((line = reader.readLine()) != null) {
            stringBuilder.append(line);
        }
        //将json字符串转换为json对象
        return JSONObject.fromObject(stringBuilder.toString());
    }

    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        doPost(req, resp);
    }

    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        req.setCharacterEncoding("utf-8");
        resp.setCharacterEncoding("utf-8");

        JSONObject parameter = receivePost(req);
        String type = String.valueOf(parameter.get("type"));
        System.out.println(type);
        PrintWriter writer = resp.getWriter();
        boolean success = false;
        JSONObject jsonObject = new JSONObject();
        switch (type) {
            case "list":
                List vmList = service.listImage();
                String jsonArray = JSONArray.fromObject(vmList).toString();
                jsonObject.put("imageList", jsonArray);
                success = true;
                break;
            case "pull":
                String name = String.valueOf(parameter.get("name"));
                String nodeIp = String.valueOf(parameter.get("nodeIp"));
                Image image = service.pullImage(nodeIp, name);
                success = image != null;
                jsonObject.put("image", image);
                break;
            case "delete":
                name = String.valueOf(parameter.get("name"));
                nodeIp = String.valueOf(parameter.get("nodeIp"));
                success = service.deleteImage(nodeIp, name);
                break;
            case "push":
                name = String.valueOf(parameter.get("name"));
                nodeIp = String.valueOf(parameter.get("nodeIp"));
                success = service.pushImage(nodeIp, name);
                break;
        }
        jsonObject.put("success", success);
        writer.append(jsonObject.toString());
        logger.info(jsonObject.toString());
    }
}

VMService类  该模块用于实现KVM的创建、管理、删除的行为

package service;

import entity.VM;
import entity.VMInfo;
import manager.SystemManager;
import org.apache.log4j.Logger;
import org.json.simple.JSONObject;
import org.libvirt.*;
import utils.LinuxConnection;
import utils.RandomCreator;
import utils.XMLUtils;
import utils.ZKClient;

import java.io.*;
import java.util.ArrayList;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;

public class VMService {
    private final Logger logger = Logger.getLogger("VMService");

    public List listVM() {
        SystemManager.refreshVM();
        List vmList = new LinkedList<>();
        for (Map.Entry entry : SystemManager.getVmInfoTable().entrySet()) {
            vmList.add(entry.getValue());
        }
        return vmList;
    }

    public VM createVM(String domainName, long capacity, long memory, int vcpu, String ip, String nodeIp) {
        if (nodeIp == null)
            nodeIp = SystemManager.chooseNodeIP();
        String nodeHostname = SystemManager.getDnTable().get(nodeIp);
        String poolName = SystemManager.POOL;
        String poolPath = SystemManager.POOL_PATH;
        Connect connect = SystemManager.getConnectTable().get(nodeIp);
        String volName = domainName + "_" + System.currentTimeMillis();
        String volPath = poolPath + "/" + volName;
        String volXML = XMLUtils.createVolXML(volPath, volName, capacity);
        String mac = RandomCreator.createMac();
        String domainXML = XMLUtils.createDomainXML(domainName, memory, vcpu, volPath, mac);
        try {
            StoragePool pool = connect.storagePoolLookupByName(poolName);
            StorageVol vol = pool.storageVolCreateXML(volXML, 0);
            Domain domain = connect.domainDefineXML(domainXML);
            domain.setAutostart(false);
            VM vm = new VM(nodeIp, domainName, 0, ip, memory, vcpu, capacity, domain.isPersistent() == 1);
            SystemManager.getVmInfoTable().put(domainName, vm);
            SystemManager.getVmTable().put(domainName, domain);
            SystemManager.getVolTable().put(domainName, vol);
            SystemManager.getIpStateTable().put(ip, true);
            ZKClient zkClient = new ZKClient();
            zkClient.createIP4VM(nodeHostname, domainName, ip);
            zkClient.close();
            return vm;
        } catch (LibvirtException e) {
            e.printStackTrace();
            return null;
        }
    }

    public VMInfo getStatistic(String domainName) {
        VM vm = SystemManager.getVmInfoTable().get(domainName);
        Domain domain = SystemManager.getVmTable().get(domainName);
        StorageVol vol = SystemManager.getVolTable().get(domainName);

        try {
            //cpu信息
            long start = System.currentTimeMillis();
            long cpuTime1 = domain.getInfo().cpuTime;
            Thread.sleep(1000);
            long cpuTime2 = domain.getInfo().cpuTime;
            long end = System.currentTimeMillis();
            int nrVirtCpu = domain.getInfo().nrVirtCpu;
            System.out.println(cpuTime2 - cpuTime1);
            System.out.println(end - start);
            double cpuRate = Math.min(1.0, (cpuTime2 - cpuTime1) / ((end - start) * nrVirtCpu * 1e6));
            System.out.println(cpuRate);

            //磁盘信息
            double capacity = vol.getInfo().capacity / SystemManager.B2GB;
            double allocation = vol.getInfo().allocation / SystemManager.B2GB;

            //内存信息
            LinuxConnection linuxConnection = new LinuxConnection(vm.getIp(), SystemManager.LINUX_USER_NAME, SystemManager.LINUX_PASSWORD);
            InputStream inputStream = new ByteArrayInputStream(linuxConnection.execute("cat /proc/meminfo").getBytes());
            InputStreamReader inputStreamReader = new InputStreamReader(inputStream);
            BufferedReader bufferedReader = new BufferedReader(inputStreamReader);
            double memTotal = Long.parseLong(bufferedReader.readLine().split("\s+")[1]) / SystemManager.KB2GB;
            bufferedReader.readLine();
            double memAvailable = Long.parseLong(bufferedReader.readLine().split("\s+")[1]) / SystemManager.KB2GB;
            VMInfo vmInfo = new VMInfo(nrVirtCpu, cpuRate, allocation, capacity, memTotal, memAvailable);
            System.out.println(vmInfo);
            linuxConnection.close();
            return vmInfo;
        } catch (Exception e) {
            e.printStackTrace();
            return null;
        }
    }

    public boolean closeVM(String domainName) {
        try {
            Domain domain = SystemManager.getVmTable().get(domainName);
            VM vm = SystemManager.getVmInfoTable().get(domainName);
            String hostname = SystemManager.getDnTable().get(vm.getNodeIp());
            domain.destroy();
            vm.setState(0);
            if (!vm.isPersistent()) {
                SystemManager.getVmTable().remove(domainName);
                SystemManager.getVmInfoTable().remove(domainName);
                SystemManager.getVolTable().remove(domainName);
                ZKClient zkClient = new ZKClient();
                zkClient.deleteIP4VM(hostname, vm.getDomainName());
                zkClient.close();
            }
            return true;
        } catch (LibvirtException e) {
            e.printStackTrace();
            return false;
        }
    }

    public boolean deleteVM(String domainName) {
        try {
            VM vm = SystemManager.getVmInfoTable().get(domainName);
            String hostname = SystemManager.getDnTable().get(vm.getNodeIp());
            Domain domain = SystemManager.getVmTable().get(domainName);
            StorageVol vol = SystemManager.getVolTable().get(domainName);
            if (domain.isActive() == 1)
                domain.destroy();
            domain.undefine();
            vol.wipe();
            vol.delete(0);
            SystemManager.getVmTable().remove(domainName);
            SystemManager.getVmInfoTable().remove(domainName);
            SystemManager.getVolTable().remove(domainName);
            SystemManager.getIpStateTable().put(vm.getIp(), false);
            ZKClient zkClient = new ZKClient();
            zkClient.deleteIP4VM(hostname, vm.getDomainName());
            zkClient.close();
            return true;
        } catch (LibvirtException e) {
            e.printStackTrace();
            return false;
        }
    }

    public VM cloneVM(String srcDomainName, String destDomainName, String ip, String nodeIp) {
        try {
            //获取原domain所在的连接
            VM vm1 = SystemManager.getVmInfoTable().get(srcDomainName);
            Domain domain1 = SystemManager.getVmTable().get(srcDomainName);
            if (domain1.isActive() == 1) {
                closeVM(srcDomainName);
            }
            if (nodeIp == null)
                nodeIp = vm1.getNodeIp();
            Connect connect = SystemManager.getConnectTable().get(nodeIp);
            Connect nfsConnection = SystemManager.getConnectTable().get(SystemManager.NFS_SERVER_IP);
            long mem = vm1.getMemory();
            int vcpu = vm1.getVcpu();
            //获取克隆vol
            StorageVol srcVol = SystemManager.getVolTable().get(srcDomainName);
            long capacity = (long) (srcVol.getInfo().capacity / SystemManager.B2GB);
            //分配,只能本地克隆
            String hostname = SystemManager.getDnTable().get(nodeIp);
            //按时间戳取名
            String destVolName = destDomainName + "_" + System.currentTimeMillis();
            String destVolPath = SystemManager.POOL_PATH + "/" + destVolName;
            //创建vol,注意单位转换
            String volXML = XMLUtils.createVolXML(destVolPath, destVolName, capacity);
            StoragePool nfsPool = nfsConnection.storagePoolLookupByName(SystemManager.POOL);
            //本地克隆
            StorageVol destVol = nfsPool.storageVolCreateXMLFrom(volXML, srcVol, 0);
            String mac = RandomCreator.createMac();
            String domainXML = XMLUtils.createDomainXML(destDomainName, mem, vcpu, destVol.getPath(), mac);
            //远程刷新
            StoragePool destPool = connect.storagePoolLookupByName(SystemManager.POOL);
            destPool.refresh(0);
            //创建domain
            Domain domain = connect.domainDefineXML(domainXML);
            domain.setAutostart(false);
            //修改全集变量
            VM vm2 = new VM(nodeIp, destDomainName, 0, ip, mem, vcpu, capacity, domain.isPersistent() == 1);
            SystemManager.getVmInfoTable().put(destDomainName, vm2);
            SystemManager.getVmTable().put(destDomainName, domain);
            SystemManager.getVolTable().put(destDomainName, destVol);
            SystemManager.getIpStateTable().put(ip, true);
            ZKClient zkClient = new ZKClient();
            zkClient.createIP4VM(hostname, destDomainName, ip);
            zkClient.close();

            openVM(destDomainName);
            Thread.sleep(60000);
            LinuxConnection linuxConnection;
            while (true) {
                try {
                    linuxConnection = new LinuxConnection(vm1.getIp(), SystemManager.LINUX_USER_NAME, SystemManager.LINUX_PASSWORD);
                    break;
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
            JSONObject conf = (JSONObject) SystemManager.NET_CONF.clone();
            conf.put("IPADDR", ip);
            StringBuilder stringBuilder = new StringBuilder();
            try {
                stringBuilder.append("rm -f " + SystemManager.HOSTNAME_PATH).append(" && ")
                        .append("touch " + SystemManager.HOSTNAME_PATH).append(" && ").append("echo ")
                        .append(destDomainName).append(">>").append(SystemManager.HOSTNAME_PATH).append(" && ")
                        .append("rm -f " + SystemManager.NET_CONF_PATH).append(" && ")
                        .append("touch " + SystemManager.NET_CONF_PATH).append(" && ");
                for (Object key : conf.keySet()) {
                    String attr = key.toString();
                    String val = conf.get(attr).toString();
                    stringBuilder.append("echo ").append(attr).append("=").append(val).append(">>").append(SystemManager.NET_CONF_PATH).append(" && ");
                }
                stringBuilder.append("reboot");
                linuxConnection.execute(stringBuilder.toString());
                vm2.setState(1);
            } catch (Exception e) {
                e.printStackTrace();
                vm2.setState(-1);
            } finally {
                linuxConnection.close();
            }
            return vm2;
        } catch (LibvirtException | InterruptedException e) {
            e.printStackTrace();
            return null;
        }
    }


    public boolean openVM(String domainName) {
        try {
            VM vm = SystemManager.getVmInfoTable().get(domainName);
            Domain domain = SystemManager.getVmTable().get(domainName);
            domain.create();
            vm.setState(1);
            return true;
        } catch (LibvirtException e) {
            e.printStackTrace();
            return false;
        }
    }


    public VM migrateVM(String srcDomainName, String destDomainName, String nodeIp) {
        String linuxIP = SystemManager.getVmInfoTable().get(srcDomainName).getNodeIp();
        String srcHostname = SystemManager.getDnTable().get(linuxIP);
        String destHostname = SystemManager.getDnTable().get(nodeIp);
        String passwd = SystemManager.getPwdTable().get(srcHostname);
        String usrName = SystemManager.LINUX_USER_NAME;

        LinuxConnection linuxConnection = null;
        try {
            linuxConnection = new LinuxConnection(linuxIP, usrName, passwd);
        } catch (IOException e) {
            e.printStackTrace();
        }
        StringBuilder stringBuilder = new StringBuilder();

        stringBuilder.append("virsh migrate --live ").append(srcDomainName)
                .append(" --dname ").append(destDomainName)
                .append(" qemu+tcp://").append(nodeIp).append("/system ")
                .append("tcp://").append(nodeIp).append(" --unsafe");
        logger.info(stringBuilder.toString());
        // 执行命令
        try {
            linuxConnection.execute(stringBuilder.toString());
            ZKClient zkClient = new ZKClient();
            VM vm = SystemManager.getVmInfoTable().get(srcDomainName);
            if (!vm.isPersistent()) {
                SystemManager.getVmTable().remove(srcDomainName);
                SystemManager.getVmInfoTable().remove(srcDomainName);
                SystemManager.getVolTable().remove(srcDomainName);
                zkClient.deleteIP4VM(srcHostname, vm.getDomainName());
            }
//            removeVM(srcDomainName);

            VM vm2 = new VM(nodeIp, destDomainName, 1, vm.getIp(), vm.getMemory(), vm.getVcpu(), vm.getCapacity(), false);

            StorageVol vol = SystemManager.getVolTable().get(srcDomainName);
            Connect connect = SystemManager.getConnectTable().get(nodeIp);
            Domain domain2 = connect.domainLookupByName(destDomainName);

            SystemManager.getVmInfoTable().put(destDomainName, vm2);
            SystemManager.getVmTable().put(destDomainName, domain2);
            SystemManager.getVolTable().put(destDomainName, vol);
            zkClient.createIP4VM(destHostname, destDomainName, vm2.getIp());
            zkClient.close();
            return vm2;
        } catch (Exception e) {
            e.printStackTrace();
            return null;
        } finally {
            linuxConnection.close();
        }
    }

    public List listIP() {
        List ipList = new ArrayList<>();
        for (Map.Entry entry : SystemManager.getIpStateTable().entrySet()) {
            if (!entry.getValue()) {
                ipList.add(entry.getKey());
            }
        }
        return ipList;
    }

    public List listNodeIP() {
        return new ArrayList<>(SystemManager.getDnTable().keySet());
    }

}

CTService类

package service;

import entity.Container;
import entity.Image;
import manager.SystemManager;
import utils.DockerUtils;

import java.util.LinkedList;
import java.util.List;
import java.util.Map;

public class CTService {
    public List listCT() {
        SystemManager.refreshDocker();
        List ctList = new LinkedList<>();
        for (Map.Entry> mapEntry : SystemManager.getCtTable().entrySet()) {
            for (Map.Entry entry : mapEntry.getValue().entrySet()) {
                ctList.add(entry.getValue());
            }
        }
        return ctList;
    }

    public Container createCT(String nodeIp, String name,String imageName) {
        DockerUtils docker = new DockerUtils(nodeIp);
        try {
            docker.run(name, imageName);
            Container container = docker.getCTByName(name);
            SystemManager.getCtTable().get(nodeIp).put(name, container);
            return container;
        } catch (Exception e) {
            e.printStackTrace();
            return null;
        }
    }


    public boolean closeCT(String nodeIp, String name) {
        DockerUtils docker = new DockerUtils(nodeIp);
        try {
            docker.stop(name);
            Container container = SystemManager.getCtTable().get(nodeIp).get(name);
            container.setRunning(false);
            container.setIp("");
            return true;
        } catch (Exception e) {
            e.printStackTrace();
            return false;
        }
    }

    public boolean deleteCT(String nodeIp, String name) {
        DockerUtils docker = new DockerUtils(nodeIp);
        try {
            docker.rm(name);
            SystemManager.getCtTable().remove(name);
            return true;
        } catch (Exception e) {
            e.printStackTrace();
            return false;
        }
    }

    public Image commitCT(String nodeIp, String name, String author, String describe, String repository, String tag) {
        DockerUtils docker = new DockerUtils(nodeIp);
        try {
            docker.commit(name, author, describe, repository, tag);
            SystemManager.refreshDocker();
            return SystemManager.getImageTable().get(nodeIp).get(repository + ":" + tag);
        } catch (Exception e) {
            e.printStackTrace();
            return null;
        }
    }


    public Container openCT(String nodeIp, String name) {
        DockerUtils docker = new DockerUtils(nodeIp);
        try {
            docker.start(name);
            Container container = SystemManager.getCtTable().get(nodeIp).get(name);
            container.setIp(docker.getIP(name));
            container.setRunning(true);
            return container;
        } catch (Exception e) {
            e.printStackTrace();
            return null;
        }
    }
}

ImgService类  该模块用于镜像

package service;

import entity.Image;
import manager.SystemManager;
import utils.DockerUtils;

import java.util.LinkedList;
import java.util.List;
import java.util.Map;

public class ImageService {

    public List listImage() {
        SystemManager.refreshDocker();
        List imageList = new LinkedList<>();
        for (Map.Entry> mapEntry : SystemManager.getImageTable().entrySet()) {
            for (Map.Entry entry : mapEntry.getValue().entrySet()) {
                imageList.add(entry.getValue());
            }
        }
        return imageList;
    }

    public boolean deleteImage(String nodeIp, String name) {
        DockerUtils docker = new DockerUtils(nodeIp);
        try {
            docker.rmi(name);
            SystemManager.getImageTable().remove(name);
            return true;
        } catch (Exception e) {
            e.printStackTrace();
            return false;
        }
    }

    public Image pullImage(String nodeIp, String name) {
        DockerUtils docker = new DockerUtils(nodeIp);
        try {
            if (!SystemManager.getImageTable().get(nodeIp).containsKey(name))
                docker.pull(name);
            SystemManager.refreshDocker();
            return SystemManager.getImageTable().get(nodeIp).get(name);
        } catch (Exception e) {
            e.printStackTrace();
            return null;
        }
    }


    public boolean pushImage(String nodeIp, String name) {
        DockerUtils docker = new DockerUtils(nodeIp);
        try {
            docker.push(name, SystemManager.REGISTRY_IP, SystemManager.REGISTRY_PORT);
            return true;
        } catch (Exception e) {
            e.printStackTrace();
            return false;
        }
    }
}

DockerUtil类  该模块用于接收并转换Docker的相关指令

package manager;

import entity.Container;
import entity.Image;
import entity.VM;
import org.json.simple.JSONObject;
import org.json.simple.parser.JSONParser;
import org.json.simple.parser.ParseException;
import org.libvirt.*;
import utils.DockerUtils;
import utils.XMLUtils;
import utils.ZKClient;

import java.io.FileReader;
import java.io.IOException;
import java.math.RoundingMode;
import java.text.DecimalFormat;
import java.util.*;

public class SystemManager {

    private static final Map vmTable;//name-domain
    private static final Map vmInfoTable;//name-vm
    private static final Map connectTable;//ip-connect
    private static final Map ipStateTable;//ip-bool
    private static final Map dnTable;//nodeIp-dn
    private static final Map volTable;//name-vol
    private static final Map pwdTable;//name-vol
    private static final Map> ctTable;//name-container
    private static final Map> imageTable;//p:v-image
    public static final double B2GB = 1 << 30;
    public static final double KB2GB = 1 << 20;
    public static final String POOL = "pool01";
    public static final String POOL_PATH = "/opt/kvm/images";
    public static final String LINUX_USER_NAME = "root";
    public static final String LINUX_PASSWORD = "ldw20000702";
    public static final String NET_CONF_PATH = "/etc/sysconfig/network-scripts/ifcfg-ens3";
    public static final String HOSTNAME_PATH = "/etc/hostname";
    public static final String NFS_SERVER_IP = "192.168.43.130";
    public static final String REGISTRY_IP = "192.168.43.130";
    public static final int REGISTRY_PORT = 5000;
    public static JSONObject NET_CONF;
    public static final DecimalFormat round2 = new DecimalFormat("0.00");
    public static final DecimalFormat round4 = new DecimalFormat("0.0000");
//    public static Connect NFS_SERVER = null;

    static {
        round2.setRoundingMode(RoundingMode.HALF_UP);
        round4.setRoundingMode(RoundingMode.HALF_UP);
        vmTable = new HashMap<>();
        vmInfoTable = new HashMap<>();
        connectTable = new HashMap<>();
        ipStateTable = new TreeMap<>();
        dnTable = new TreeMap<>();
        volTable = new HashMap<>();
        pwdTable = new HashMap<>();
        ctTable = new HashMap<>();
        imageTable = new HashMap<>();
        try {
            //解析JSON文件的内容
            JSONParser jsonParser = new JSONParser();
            String path = Objects.requireNonNull(SystemManager.class.getClassLoader().getResource("ifcfg-ens3.json")).getPath();
            NET_CONF = (JSONObject) jsonParser.parse(new FileReader(path));
        } catch (ParseException | IOException e) {
            e.printStackTrace();
        }
        refreshVM();
        refreshDocker();
    }

    public static void refreshVM() {
        vmTable.clear();
        vmInfoTable.clear();
        connectTable.clear();
        ipStateTable.clear();
        dnTable.clear();
        volTable.clear();
        pwdTable.clear();
        try {
            for (int i = 128; i < 255; i++) {
                ipStateTable.put("192.168.43." + i, false);
            }
            ZKClient zkClient = new ZKClient();
            Map ip4PM = zkClient.listIP4PM();
            pwdTable.putAll(zkClient.listPSW4PM());
            for (Map.Entry entry : ip4PM.entrySet()) {
                String hostname = entry.getKey();
                String nodeIp = entry.getValue();
                String uri = "qemu+tcp://" + nodeIp + ":16509/system";
                Connect connect = new Connect(uri);
                connectTable.put(nodeIp, connect);
                dnTable.put(nodeIp, hostname);
                ipStateTable.put(nodeIp, true);

                int[] ids = connect.listDomains();
                String[] names = connect.listDefinedDomains();
                List nameList = new LinkedList<>();
                for (int id : ids) {
                    String name = connect.domainLookupByID(id).getName();
                    nameList.add(name);
                }
                nameList.addAll(Arrays.asList(names));

                for (String domainName : nameList) {
                    Domain domain = connect.domainLookupByName(domainName);
                    long memory = (long) (domain.getInfo().memory / SystemManager.KB2GB);
                    int vcpu = domain.getInfo().nrVirtCpu;
                    int state = domain.isActive();
                    String ip = zkClient.getIP4VM(hostname, domainName);
                    String volPath = XMLUtils.getVolPath(domain.getXMLDesc(0));
                    StoragePool pool = connect.storagePoolLookupByName(SystemManager.POOL);
                    pool.refresh(0);
                    StorageVol vol = connect.storageVolLookupByPath(volPath);
                    long capacity = (long) (vol.getInfo().capacity / SystemManager.B2GB);
                    VM vm = new VM(nodeIp, domainName, state, ip, memory, vcpu, capacity, domain.isPersistent() == 1);
                    vmTable.put(domainName, domain);
                    vmInfoTable.put(domainName, vm);
                    volTable.put(domainName, vol);
                    ipStateTable.put(ip, true);
                }
            }
            zkClient.close();
        } catch (Exception e) {
            e.printStackTrace();
        }

    }

    public static void refreshDocker() {
        imageTable.clear();
        ctTable.clear();
        dnTable.clear();
        pwdTable.clear();
        try {
            ZKClient zkClient = new ZKClient();
            pwdTable.putAll(zkClient.listPSW4PM());
            Map ip4PM = zkClient.listIP4PM();
            for (Map.Entry entry : ip4PM.entrySet()) {
                String hostname = entry.getKey();
                String nodeIp = entry.getValue();
                dnTable.put(nodeIp, hostname);
                DockerUtils dockerUtils = new DockerUtils(nodeIp);
                imageTable.put(nodeIp, new HashMap<>());
                ctTable.put(nodeIp, new HashMap<>());
                for (Image image : dockerUtils.listImages()) {
                    imageTable.get(nodeIp).put(image.getName(), image);
                }
                for (Container container : dockerUtils.listContainer()) {
                    ctTable.get(nodeIp).put(container.getName(), container);
                }
            }
            zkClient.close();
        } catch (Exception e) {
            e.printStackTrace();
        }
    }


    public static String chooseNodeIP() {
        String ip = null;
        double bestScore = 0;
        try {
            for (Map.Entry entry : connectTable.entrySet()) {

                Connect connect = entry.getValue();
                StoragePool pool = connect.storagePoolLookupByName(SystemManager.POOL);
                if (pool.getInfo().state != StoragePoolInfo.StoragePoolState.VIR_STORAGE_POOL_RUNNING)
                    continue;
                long freeMem = connect.getFreeMemory();
                int maxVcpu = connect.getMaxVcpus("kvm");
                long curVcpu = 0;
                long curMem = 0;

                int[] ids = connect.listDomains();
                for (int id : ids) {
                    Domain domain = connect.domainLookupByID(id);
                    if (domain.isActive() == 1) {
                        curVcpu += domain.getInfo().nrVirtCpu;
                        curMem += domain.getInfo().memory;
                    }
                }
                double curScore = freeMem + maxVcpu - curMem - curVcpu;
                if (curScore > bestScore) {
                    bestScore = curScore;
                    ip = entry.getKey();
                }
            }
        } catch (LibvirtException e) {
            e.printStackTrace();
        }
        return ip;
    }

//    public static String chooseIP() {
//        for (Map.Entry entry : ipStateTable.entrySet()) {
//            if (!entry.getValue())
//                return entry.getKey();
//        }
//        return null;
//    }

    public static Map getVmTable() {
        return vmTable;
    }

    public static Map getVmInfoTable() {
        return vmInfoTable;
    }

    public static Map getConnectTable() {
        return connectTable;
    }

    public static Map getIpStateTable() {
        return ipStateTable;
    }

    public static Map getVolTable() {
        return volTable;
    }

    public static Map getDnTable() {
        return dnTable;
    }

    public static Map getPwdTable() {

        return pwdTable;
    }

    public static Map> getCtTable() {
        return ctTable;
    }

    public static Map> getImageTable() {
        return imageTable;
    }
}

ZKClient类

package utils;

import org.apache.zookeeper.CreateMode;
import org.apache.zookeeper.KeeperException;
import org.apache.zookeeper.ZooDefs;
import org.apache.zookeeper.ZooKeeper;
import org.apache.zookeeper.data.Stat;

import java.io.IOException;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

public class ZKClient {
    private ZooKeeper zooKeeper;
    private final static String IP_PARENT = "/ip";
    private final static String PSW_PARENT = "/psw";
    private final static String connectionString = "192.168.43.130:2181,192.168.43.128:2181";

    public ZKClient() {
        try {
            zooKeeper = new ZooKeeper(connectionString, 15000, watchedEvent -> {
            });
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    public String getIP4PM(String hostname) {
        try {
            String path = IP_PARENT + "/" + hostname;
            return new String(zooKeeper.getData(path, true, new Stat()));
        } catch (KeeperException | InterruptedException e) {
            e.printStackTrace();
            return null;
        }
    }

    public String getIP4VM(String hostname, String domainName) {
        try {
            String path = IP_PARENT + "/" + hostname + "/" + domainName;
            return new String(zooKeeper.getData(path, true, new Stat()));
        } catch (KeeperException | InterruptedException e) {
            e.printStackTrace();
            return null;
        }
    }

    public Map listIP4PM() {
        Map ipTable = new HashMap<>();
        try {
            List children = zooKeeper.getChildren(IP_PARENT, true);
            for (String child : children) {
                String ip = (new String(zooKeeper.getData(IP_PARENT + "/" + child, true, new Stat())));
                ipTable.put(child, ip);
            }
        } catch (KeeperException | InterruptedException e) {
            e.printStackTrace();
        }
        return ipTable;
    }

    public Map listPSW4PM() {
        Map pwdTable = new HashMap<>();
        try {
            List children = zooKeeper.getChildren(PSW_PARENT, true);
            for (String child : children) {
                String pwd = (new String(zooKeeper.getData(PSW_PARENT + "/" + child, true, new Stat())));
                pwdTable.put(child, pwd);
            }
        } catch (KeeperException | InterruptedException e) {
            e.printStackTrace();
        }
        return pwdTable;
    }


    public Map listIP4VM() {
        Map ipTable = new HashMap<>();
        try {
            List children = zooKeeper.getChildren(IP_PARENT, true);
            for (String child : children) {
                String pmPath = IP_PARENT + "/" + child;
                List children2 = zooKeeper.getChildren(pmPath, true);
                for (String child2 : children2) {
                    String vmPath = pmPath + "/" + child2;
                    String ip = (new String(zooKeeper.getData(vmPath, true, new Stat())));
                    ipTable.put(child2, ip);
                }
            }
        } catch (KeeperException | InterruptedException e) {
            e.printStackTrace();
        }
        return ipTable;
    }


    public void createIP4PM(String hostname, String ip) {
        try {
            String path = IP_PARENT + "/" + hostname;
            zooKeeper.create(path, ip.getBytes(), ZooDefs.Ids.OPEN_ACL_UNSAFE, CreateMode.PERSISTENT);
        } catch (KeeperException | InterruptedException e) {
            e.printStackTrace();
        }
    }

    public void createIP4VM(String hostname, String domainName, String ip) {
        try {
            String path = IP_PARENT + "/" + hostname + "/" + domainName;
            zooKeeper.create(path, ip.getBytes(), ZooDefs.Ids.OPEN_ACL_UNSAFE, CreateMode.PERSISTENT);
        } catch (KeeperException | InterruptedException e) {
            e.printStackTrace();
        }
    }

    public void deleteIP4PM(String hostname) {
        try {
            String path = IP_PARENT + "/" + hostname;
            List children = zooKeeper.getChildren(path, true);
            for (String child : children) {
                zooKeeper.delete(path + "/" + child, -1);
            }
            zooKeeper.delete(path, -1);
        } catch (KeeperException | InterruptedException e) {
            e.printStackTrace();
        }
    }

    public void deleteIP4VM(String hostname, String domainName) {
        try {
            String path = IP_PARENT + "/" + hostname + "/" + domainName;
            zooKeeper.delete(path, -1);
        } catch (KeeperException | InterruptedException e) {
            e.printStackTrace();
        }
    }

    public boolean existsIP(String path) {
        try {
            Stat exists = zooKeeper.exists(path, true);
            return exists != null;
        } catch (KeeperException | InterruptedException e) {
            e.printStackTrace();
        }
        return false;
    }

    public void close() {
        try {
            zooKeeper.close();
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }
}

XMLUtil类

package utils;

import org.dom4j.*;
import org.dom4j.io.SAXReader;

import java.io.*;
import java.util.Objects;
import java.util.logging.Logger;

public class XMLUtils {
    private static final String volXMLT = "storage-volume.xml";
    private static final String poolXMLT = "storage-pool.xml";
    private static final String domainXMLT = "domain.xml";
    private static final Logger logger = Logger.getLogger("XMLCreator");

    public static String createVolXML(String volPath, String volName, long capacity) {
        try {
            SAXReader saxReader = new SAXReader();
            String path = Objects.requireNonNull(XMLUtils.class.getClassLoader().getResource(volXMLT)).getPath();
            Document document = saxReader.read(new File(path));
            Node node = document.selectSingleNode("//volume/name");//确保节点是真的唯一
            System.out.println(document.asXML());
            node.setText(volName);
            node = document.selectSingleNode("//volume/capacity");
            node.setText(Long.toString(capacity));
            node = document.selectSingleNode("//volume/target/path");
            node.setText(volPath);
            logger.info(document.asXML());
            logger.info(document.asXML());
            return document.asXML();
        } catch (IOException | DocumentException e) {
            e.printStackTrace();
            return "";
        }
    }

    public static String createPoolXML(String poolName, int capacity, String poolPath) {
        try {
            SAXReader saxReader = new SAXReader();
            String path = Objects.requireNonNull(XMLUtils.class.getClassLoader().getResource(poolXMLT)).getPath();
            Document document = saxReader.read(new File(path));
            Node node = document.selectSingleNode("//pool/name");//确保节点是真的唯一
            System.out.println(document.asXML());
            node.setText(poolName);
            node = document.selectSingleNode("//pool/capacity");
            node.setText(Long.toString(capacity));
            node = document.selectSingleNode("//pool/target/path");
            node.setText(poolPath);
            logger.info(document.asXML());
            logger.info(document.asXML());
            return document.asXML();
        } catch (IOException | DocumentException e) {
            e.printStackTrace();
            return "";
        }
    }

    public static String createDomainXML(String domainName, long memory, int vcpu, String volPath, String mac) {
        try {
            SAXReader saxReader = new SAXReader();
            String path = Objects.requireNonNull(XMLUtils.class.getClassLoader().getResource(domainXMLT)).getPath();
            Document document = saxReader.read(new File(path));
            Node node = document.selectSingleNode("//domain/name");//确保节点是真的唯一
            node.setText(domainName);

//            node = document.selectSingleNode("//domain/uuid");//确保节点是真的唯一
//            node.setText(uuid);

            node = document.selectSingleNode("//domain/memory");//确保节点是真的唯一
            node.setText(Long.toString(memory));

            node = document.selectSingleNode("//domain/currentMemory");//确保节点是真的唯一
            node.setText(Long.toString(memory));

            node = document.selectSingleNode("//domain/vcpu");//确保节点是真的唯一
            node.setText(Integer.toString(vcpu));

            node = document.selectSingleNode("//domain/devices/disk[@device='disk']/source");//确保节点是真的唯一
            Element element = (Element) (node);
            Attribute attribute = element.attribute("file");
            element.remove(attribute);
            element.addAttribute("file", volPath);

            node = document.selectSingleNode("//domain/devices/interface/mac");//确保节点是真的唯一
            element = (Element) (node);
            attribute = element.attribute("address");
            element.remove(attribute);
            element.addAttribute("address", mac);

            node = document.selectSingleNode("//domain/devices/interface/target");//确保节点是真的唯一
            element = (Element) (node);
            attribute = element.attribute("dev");
            element.remove(attribute);
            element.addAttribute("dev", "vnet" + System.currentTimeMillis());

//            node = document.selectSingleNode("//domain/devices/interface/ip");//确保节点是真的唯一
//            element = (Element) (node);
//            attribute = element.attribute("address");
//            element.remove(attribute);
//            element.addAttribute("address", ip);

            logger.info(document.asXML());
            return document.asXML();
        } catch (IOException | DocumentException e) {
            e.printStackTrace();
            return "";
        }
    }

    public static String createDomainXML(String domainName, String domainXML) {
        try {
            SAXReader saxReader = new SAXReader();
            InputStream inputStream = new ByteArrayInputStream(domainXML.getBytes());
            Document document = saxReader.read(new InputStreamReader(inputStream));
            Node node = document.selectSingleNode("//domain/name");//确保节点是真的唯一
            node.setText(domainName);
            return document.asXML();
        } catch (DocumentException e) {
            e.printStackTrace();
            return "";
        }
    }


    public static String getVolPath(String domainXML) {
        try {
            SAXReader saxReader = new SAXReader();
            //字符串转流
            InputStream inputStream = new ByteArrayInputStream(domainXML.getBytes());
            Document document = saxReader.read(new InputStreamReader(inputStream));
            Node node = document.selectSingleNode("//domain/devices/disk[@device='disk']/source");//确保节点是真的唯一
            Element element = (Element) (node);
            Attribute attribute = element.attribute("file");
            return attribute.getValue();
        } catch (DocumentException e) {
            e.printStackTrace();
            return null;
        }

    }
}

LinuxConnection类

package utils;

import ch.ethz.ssh2.Connection;
import ch.ethz.ssh2.Session;
import ch.ethz.ssh2.StreamGobbler;
import org.apache.commons.lang.StringUtils;

import java.io.*;

public class LinuxConnection {
    private final Connection connection;

    public LinuxConnection(String ip, String userName, String userPwd) throws IOException {
        System.out.println(ip);
        connection = new Connection(ip);
        connection.connect();
        connection.authenticateWithPassword(userName, userPwd);
    }

    public String execute(String cmd) throws Exception {
        System.out.println(cmd);
        String result;
        Session session = connection.openSession();
        session.execCommand(cmd);
        // 字符编码默认是utf-8
        String encoding = "UTF-8";
        result = processStdout(session.getStdout(), encoding);
        // 如果为输出为空,说明脚本执行出错了
        if (StringUtils.isBlank(result)) {
            result = processStdout(session.getStderr(), encoding);
        }
        return result;
    }


    private String processStdout(InputStream in, String charset) throws Exception {
        InputStream stdout = new StreamGobbler(in);
        StringBuilder stringBuilder = new StringBuilder();
        InputStreamReader inputStreamReader = null;
        BufferedReader bufferedReader = null;
        try {
            inputStreamReader = new InputStreamReader(stdout, charset);
            bufferedReader = new BufferedReader(inputStreamReader);
            String line;
            while ((line = bufferedReader.readLine()) != null) {
                stringBuilder.append(line).append("n");
            }
        } catch (UnsupportedEncodingException e) {
            throw new Exception("不支持的编码字符集异常", e);
        } catch (IOException e) {
            throw new Exception("读取指纹失败", e);
        } finally {
            if (bufferedReader != null)
                bufferedReader.close();
            if (bufferedReader != null)
                inputStreamReader.close();
            if (bufferedReader != null)
                stdout.close();
        }
        return stringBuilder.toString();
    }

    public void close() {
        connection.close();
    }
}

OK,初稿完结

转载请注明:文章转载自 www.051e.com
本文地址:http://www.051e.com/it/852391.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 ©2023-2025 051e.com

ICP备案号:京ICP备12030808号