溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊(cè)×
其他方式登錄
點(diǎn)擊 登錄注冊(cè) 即表示同意《億速云用戶服務(wù)條款》

python如何計(jì)算節(jié)點(diǎn)創(chuàng)建cgroups綁定虛擬核心

發(fā)布時(shí)間:2021-11-08 09:56:26 來源:億速云 閱讀:122 作者:小新 欄目:云計(jì)算

這篇文章給大家分享的是有關(guān)python如何計(jì)算節(jié)點(diǎn)創(chuàng)建cgroups綁定虛擬核心的內(nèi)容。小編覺得挺實(shí)用的,因此分享給大家做個(gè)參考,一起跟隨小編過來看看吧。

 
import MySQLdb

import os

import signal


import shlex

import subprocess

from eventlet.green import subprocess as green_subprocess

from eventlet import greenthread

import logging

import string

import time


mysql_host = "10.160.0.120"

mysql_db = "nova"

mysql_user = "nova"

mysql_passwd = "87da3417bb3a42ee"

mysql_port = 3306

mysql_charset = "utf8"

cgroups_hierarchy = "/home/cgroups/cpu"


LOG = logging.getLogger(__name__)

def create_process(cmd, root_helper=None, addl_env=None):
    if root_helper:
        cmd = shlex.split(root_helper) + cmd
    cmd = map(str, cmd)
    LOG.debug(("Running command: %s"), cmd)
    env = os.environ.copy()
    if addl_env:
        env.update(addl_env)
    
    obj = subprocess_popen(cmd, shell=False,
                            stdin=subprocess.PIPE,
                            stdout=subprocess.PIPE,
                            stderr=subprocess.PIPE,
                            env=env)
    
    return obj, cmd


def execute(cmd, root_helper=None, process_input=None, addl_env=None,
            check_exit_code=True, return_stderr=False):
    try:
        obj, cmd = create_process(cmd, root_helper=root_helper,
                                  addl_env=addl_env)
        _stdout, _stderr = (process_input and
                            obj.communicate(process_input) or
                            obj.communicate())
        obj.stdin.close()
        m = ("\nCommand: %(cmd)s\nExit code: %(code)s\nStdout: %(stdout)r\n"
              "Stderr: %(stderr)r") % {'cmd': cmd, 'code': obj.returncode,
                                       'stdout': _stdout, 'stderr': _stderr}
        LOG.debug(m)
        if obj.returncode and check_exit_code:
            raise RuntimeError(m)
    finally:
        greenthread.sleep(0)
    
    return return_stderr and (_stdout, _stderr) or _stdout


def _subprocess_setup():
    signal.signal(signal.SIGPIPE, signal.SIG_DFL)


def subprocess_popen(args, stdin=None, stdout=None, stderr=None, shell=False,
                     env=None):
    return green_subprocess.Popen(args, shell=shell, stdin=stdin, stdout=stdout,
                            stderr=stderr, preexec_fn=_subprocess_setup,
                            close_fds=True, env=env)


def query_db_of_local_vms():
    """ query controller node db for information about vms running on local host """
    conn = None
    try:
        conn = MySQLdb.connect(host=mysql_host,
                               user=mysql_user,
                               passwd=mysql_passwd,
                               db=mysql_db,
                               port=mysql_port,
                               charset=mysql_charset)
    except Exception as e:
        #LOG.error("Fail to connect mysql .")
        
        raise e
    else:

        LOG.info("Connect to mysql .")
    
    local_compute_name = get_host()
    
    sql = "SELECT vcpus,uuid FROM instances WHERE host='%s' AND deleted=0"%local_compute_name
    
    vms = {}
    
    try:
        cursor = conn.cursor()
        cursor.execute(sql)
        result = cursor.fetchall()
        cursor.close()
        conn.close()
        
        for item in result:
            vms.update({item[1]:item[0]})
    except Exception as ex:
        #LOG.error("Exception happens while querying mysql.")
        
        raise ex
    else:
        return vms

def get_host():
    return os.environ['HOSTNAME']


def get_ip():
    """ parse /etc/hosts to get local ip"""
    df = open("/etc/hosts")
    hosts = df.readlines()
    hostname = get_host()
    host_rec = [line for line in hosts if hostname in line and "#" not in line][0]
    return host_rec.split()[0].strip()


def check_cglib():
    """ check required cglibs"""
    check_pkgs = "rpm -qa"
    cglib_kw = "libcgroup"
    cmd = check_pkgs.split()
    pkgs = execute(cmd,root_helper=None)
    
    cglibs = [pkg for pkg in pkgs.split("\n") if cglib_kw in pkg]
    
    if len(cglibs)==0:
        print "libcgroup-x.xx-x.xx.x86_64 not installed.Exit."
        exit(1)


def init_cgroups():
    
    """ensure cgrouplib installed"""
    check_cglib()
    
    """ create cgroups base architecture """
    """clear old cgroups settings mounted on cgroups_hierarchy """
    cg_clear()
    
    """create base cgroups hierarchy"""
    create_hierarchy = ("mkdir -p %s"%cgroups_hierarchy).split()
    execute(create_hierarchy,root_helper=None)
    
    """mount target subsystem,that's cpuset,to established hierarchy."""
    mount_cg = ("mount -t cgroup -o cpuset cpuset2015  %s"%cgroups_hierarchy).split()
    execute(mount_cg,root_helper=None)


def cpuinfo():
    """ get cpu counts and memory nodes """
    cpuinfo = "lscpu"
    cmd = cpuinfo.split()
    retv = execute(cmd,root_helper=None)
    memNodes = retv.count("NUMA node")-1
    cpus = string.atoi([line for line in retv.split("\n") if "CPU(s)" in line][0].split(":")[1].strip())
    return {"cpu_count":cpus,"memNodes":memNodes}


def assign_cores():
    """ cal out schemes of core binding for instances running on local host"""
    vmDetails = query_db_of_local_vms()
    cpuinfos = cpuinfo()
    def assign(require,all):
        tmp = {}
        i=0
        for k,v in require.iteritems():
                    cores = [p%all for p in xrange(i,i+v)]
                    i=i+v
                    tmp.update({k:{"cores":cores,"memNodes":"0-%d"%(cpuinfos["memNodes"]-1)}})
        return tmp
    vmDetails = assign(vmDetails,cpuinfos["cpu_count"])
    return vmDetails


def get_pids(vmDetails):
    query_pids = "ps aux"
    cmd = query_pids.split()
    retv = execute(cmd,root_helper=None)
    qemu_kvm_processes =[p for p in retv.split("\n") if "qemu-kvm" in p and len(p)>100]
    tmp = {} 
    for vmDetail in vmDetails:
        tmp.update({vmDetail:vmDetails[vmDetail]})
        for qkp in qemu_kvm_processes:
            if vmDetail not in qkp:
                continue                
            else:
                pid = string.atoi(qkp.split()[1]) 
                tmp[vmDetail]["pid"] = pid
    return tmp
 

def create_cgs_for_instances(vmDetails):
    for item in vmDetails:
        detail = vmDetails[item]
        if "pid" not in detail or "cores" not in detail or "memNodes" not in detail:
            print "Instance %s invalid"%item
            continue
        else:
            """ create private group for each instance"""
            instance_cg = "%s/%s"%(cgroups_hierarchy,item)
            create_cg_for_instance = ("mkdir -p %s"%instance_cg).split()
            execute(create_cg_for_instance,root_helper=None)
            setcpu_txt = "%s"%detail["cores"][0]
            if len(detail["cores"]) > 1:
                for core_num in detail["cores"][1:]:
                    setcpu_txt = "%s,%s"%(setcpu_txt,core_num)
     
            setmem_txt = detail["memNodes"]
            
            fd_setcpu = open("%s/cpuset.cpus"%instance_cg,"w")
            fd_setcpu.write(setcpu_txt)
            fd_setcpu.close()
            fd_setmem = open("%s/cpuset.mems"%instance_cg,"w")
            fd_setmem.write(setmem_txt)
            fd_setmem.close()
            
            print detail["pid"]
            fd_task = open("%s/tasks"%instance_cg,"w")
            fd_task.write("%s"%detail["pid"])
            fd_task.close()
           

def cg_clear():
    """ destroy existing cgroups """
    cgclear = "umount -t cgroup %s"%cgroups_hierarchy
    cmd = cgclear.split()
    try:
        execute(cmd,root_helper=None)
    except Exception as e:
        pass


def periodic_task():
    init_cgroups()
    hosted_vms = assign_cores()
    hosted_vms = get_pids(hosted_vms)
    create_cgs_for_instances(hosted_vms)
 
if __name__ == "__main__":
    periodic_task() 
    while True:
        time.sleep(3*60)
        print "Loop Job."
        periodic_task()

該腳本作用是:連接數(shù)據(jù)庫查詢出運(yùn)行在當(dāng)前宿主下的客戶機(jī)的cpu配額,然后再根據(jù)當(dāng)前宿主的CPU信息,做出虛擬核心的分配;創(chuàng)建cgroups 綁定虛擬核心,實(shí)現(xiàn)資源隔離.

該腳本后臺(tái)運(yùn)行:

nohup python /path/to/this/scripy  &

感謝各位的閱讀!關(guān)于“python如何計(jì)算節(jié)點(diǎn)創(chuàng)建cgroups綁定虛擬核心”這篇文章就分享到這里了,希望以上內(nèi)容可以對(duì)大家有一定的幫助,讓大家可以學(xué)到更多知識(shí),如果覺得文章不錯(cuò),可以把它分享出去讓更多的人看到吧!

向AI問一下細(xì)節(jié)

免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如果涉及侵權(quán)請(qǐng)聯(lián)系站長郵箱:is@yisu.com進(jìn)行舉報(bào),并提供相關(guān)證據(jù),一經(jīng)查實(shí),將立刻刪除涉嫌侵權(quán)內(nèi)容。

AI