Docker虚拟机管理(1)

可视化界面以及功能实现

import docker
import paramiko
import subprocess
import tkinter
import tkinter.messagebox
import tkinter.font as tkFont
from tkinter import ttk
import random
import os

host_share = '/share/ex'
docker_file = '/mpifile/ex'
volumes = {}
temp_volumes = {}
temp_volumes['bind'] = docker_file
temp_volumes['mode'] = 'rw'
volumes[host_share] = temp_volumes

ssh = paramiko.SSHClient()
ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy())
ssh.connect(hostname="192.168.43.99", port=22, username="bigdata", password="20000329")  # 20000329

ip1 = '192.168.43.243'  # ---no.0
ip2 = '192.168.43.99'  # ---no.1
docker_images = 'pythonmpiknn'
connect1 = ip1 + ':2375'
connect2 = ip2 + ':2375'
client1 = docker.DockerClient(base_url=connect1, use_ssh_client=True)
client2 = docker.DockerClient(base_url=connect2, use_ssh_client=True)
network = client1.networks.get('multihost')
CPU_liu = 3
CPU_miao = 3


def set_mpi_config():
    file_address = host_share + '/mpi_config'
    containers1 = client1.containers.list()
    containers2 = client2.containers.list()
    containers_ip = network.attrs['Containers']
    ips = []
    with open(file_address, mode='w', encoding='utf-8') as fp:
        for container in containers1:
            for container_ip in containers_ip:
                key = container_ip
                value = containers_ip[key]
                if value['Name'] == container.name:
                    ip = value['IPv4Address'][:-3]
                    if value['Name'] == 'master_liu':
                        fp.write(ip + ':' + str(1) + '\n')
                    else:
                        ips.append(ip)
        for container in containers2:
            for container_ip in containers_ip:
                key = container_ip
                value = containers_ip[key]
                if value['Name'] == container.name:
                    ip = value['IPv4Address'][:-3]
                    if value['Name'] == 'master_miao':
                        fp.write(ip + ':' + str(1) + '\n')
                    else:
                        ips.append(ip)
        for i in range(len(ips)):
            fp.write(ips[i] + ':' + str(1) + '\n')


def instruction():
    create_zero = tkinter.Toplevel()
    frame_main.pack(expand=tkinter.YES, fill=tkinter.BOTH)
    width = 600
    heigh = 500
    screenwidth = root.winfo_screenwidth()
    screenheight = root.winfo_screenheight()
    create_zero.geometry('%dx%d+%d+%d' % (width, heigh, (screenwidth - width) / 2, (screenheight - heigh) / 2))
    create_zero.title('使用说明')
    longtext = '''                                                   使用说明:

    1.  0号主机:bigdata-virtual-machine  1号主机:zhonghuan

    2.  两台主机的cpu核心数目最大都为3

    3.  两台主机最大内存都为16G

    4.  创建虚拟机时内存单位为GB
     '''
    show_data = tkinter.Label(create_zero, text=longtext, bg="white", justify='left', anchor='w',
                              font=tkFont.Font(family="微软雅黑", size=12, weight=tkFont.NORMAL)).pack(padx=10, pady=100)


def create():
    create_one = tkinter.Toplevel()
    frame_main = tkinter.Frame(create_one, bg="whitesmoke")
    frame_main.propagate(False)
    frame_main.pack(expand=tkinter.YES, fill=tkinter.BOTH)
    create_one.title('创建虚拟机')
    width = 600
    heigh = 450
    screenwidth = root.winfo_screenwidth()
    screenheight = root.winfo_screenheight()
    create_one.geometry('%dx%d+%d+%d' % (width, heigh, (screenwidth - width) / 2, (screenheight - heigh) / 2))
    global memory, CPU_number, docker_name, docker_place

    number3 = tkinter.StringVar()
    memory = ttk.Combobox(create_one, width=12, textvariable=number3, font=('Arial', 12))
    memory['values'] = ('1', '2', '3', '4', '5', '6', '7', '8', '9', '10', '11', '12', '13', '14', '15', '16')
    memory.place(width=150, x=300, y=20, height=40)
    memory.current(0)
    memory_label = tkinter.Label(create_one, text='内存大小', bg='whitesmoke', font=('Arial', 12))
    memory_label.place(x=70, y=20, width=200, height=40)

    number1 = tkinter.StringVar()
    CPU_number = ttk.Combobox(create_one, width=12, textvariable=number1, font=('Arial', 12))
    CPU_number['values'] = ('1', '2', '3', '4', '5', '6')
    CPU_number.place(width=150, x=300, y=100, height=40)
    CPU_number.current(0)
    CPU_number_label = tkinter.Label(create_one, text='CPU核数目', bg='whitesmoke', font=('Arial', 12))
    CPU_number_label.place(x=70, y=100, width=200, height=40)

    docker_name = tkinter.Entry(create_one)
    docker_name.place(width=150, x=300, y=180, height=40)
    docker_name_label = tkinter.Label(create_one, text='虚拟机名称', width=80, bg='whitesmoke', font=('Arial', 12))
    docker_name_label.place(x=70, y=180, width=200, height=40)

    number2 = tkinter.StringVar()
    docker_place = ttk.Combobox(create_one, width=12, textvariable=number2, font=('Arial', 12))
    docker_place['values'] = ('0', '1')
    docker_place.place(width=150, x=300, y=260, height=40)
    docker_place.current(0)
    docker_place_label = tkinter.Label(create_one, text='选择主机进行创建:', bg='whitesmoke', font=('Arial', 12))
    docker_place_label.place(x=70, y=260, width=200, height=40)

    button2 = tkinter.Button(create_one, text='创建虚拟机', command=create_container, font=('Arial', 12), width=50, height=2)
    button2.place(x=70, y=350)


def create_container():
    position = docker_place.get()
    if position == "0":
        client = client1
        CPU_number_limit = CPU_liu
    elif position == '1':
        client = client2
        CPU_number_limit = CPU_miao
    if position != '0' and position != '1':
        tkinter.messagebox.showwarning("提示", '虚拟机参数输入错误')
        return
    name = docker_name.get()
    memory_number = int(eval(memory.get()))
    if memory_number > 16:
        tkinter.messagebox.showwarning("提示", '虚拟机超过主机最大内存容量')
        return
    mem_limit = memory.get() + 'g'
    number = int(eval(CPU_number.get()))
    if number > CPU_number_limit:
        tkinter.messagebox.showwarning("提示", '虚拟机超过最大CPU核数目')
        return
    CPU_list = []
    CPU_str = ''
    while len(CPU_list) < number:
        i = random.randint(0, 7)
        if i not in CPU_list:
            CPU_list.append(i)
            CPU_str += str(i)
            CPU_str += ','
    CPU_str = CPU_str[:-1]
    container1 = client.containers.run(image=docker_images, name=name, mem_limit=mem_limit, tty=True, privileged=True,
                                       detach=True, stdin_open=True, network='multihost', cpuset_cpus=CPU_str,
                                       volumes=volumes)
    tkinter.messagebox.showwarning("提示", '虚拟机创建成功')
    client1.close()
    client2.close()


def start():
    create_three = tkinter.Toplevel()
    frame_main = tkinter.Frame(create_three, bg="whitesmoke")
    frame_main.propagate(False)
    frame_main.pack(expand=tkinter.YES, fill=tkinter.BOTH)
    create_three.title('开启虚拟机')
    width = 600
    heigh = 400
    screenwidth = root.winfo_screenwidth()
    screenheight = root.winfo_screenheight()
    create_three.geometry('%dx%d+%d+%d' % (width, heigh, (screenwidth - width) / 2, (screenheight - heigh) / 2))
    global name2, docker_place2

    number2 = tkinter.StringVar()
    name2 = ttk.Combobox(create_three, width=12, textvariable=number2)
    containers1 = client1.containers.list(all=True)
    containers2 = client2.containers.list(all=True)
    containers1_run = client1.containers.list()
    containers2_run = client2.containers.list()
    list_temp = []
    for container in containers1:
        if container not in containers1_run:
            list_temp.append(container.name)
    for container in containers2:
        if container not in containers2_run:
            list_temp.append(container.name)
    if len(list_temp) == 0:
        list_temp.append('所有的docker容器都已经开启')
    name2['values'] = tuple(list_temp)
    name2.place(width=150, x=300, y=50, height=40)
    name2.current(0)
    # name2 = tkinter.Entry(create_three)
    # name2.place(width=250, x=500, y=70, height=20)
    name2_label = tkinter.Label(create_three, text='虚拟机名称', bg='whitesmoke', font=('Arial', 12))
    name2_label.place(x=70, y=50, width=200, height=40)

    number1 = tkinter.StringVar()
    docker_place2 = ttk.Combobox(create_three, width=12, textvariable=number1, font=('Arial', 12))
    docker_place2['values'] = ('0', '1')
    docker_place2.place(width=150, x=300, y=130, height=40)
    docker_place2.current(0)
    docker_place2_label1 = tkinter.Label(create_three, text='选择主机开启', bg='whitesmoke', font=('Arial', 12))
    docker_place2_label1.place(x=70, y=130, width=200, height=40)

    button1 = tkinter.Button(create_three, text='开启虚拟机', command=start_container, font=('Arial', 12), width=50,
                             height=2)
    button1.place(x=70, y=250)


def start_container():
    position = docker_place2.get()
    name = name2.get()
    if position == "0":
        client = client1
    elif position == '1':
        client = client2
    if position != '0' and position != '1':
        tkinter.messagebox.showwarning("提示", '虚拟机参数输入错误')
        return
    name_list = []
    containers = client.containers.list(all=True)
    for container in containers:
        name_list.append(container.name)
    if name not in name_list:
        tkinter.messagebox.showwarning("提示", '要开启的虚拟机不存在')
        return
    container = client.containers.get(name)
    container.start()
    tkinter.messagebox.showwarning("提示", '成功开启虚拟机')


def stop():
    create_five = tkinter.Toplevel()
    frame_main = tkinter.Frame(create_five, bg="whitesmoke")
    frame_main.propagate(False)
    frame_main.pack(expand=tkinter.YES, fill=tkinter.BOTH)
    create_five.title('停止虚拟机')
    width = 600
    heigh = 400
    screenwidth = root.winfo_screenwidth()
    screenheight = root.winfo_screenheight()
    create_five.geometry('%dx%d+%d+%d' % (width, heigh, (screenwidth - width) / 2, (screenheight - heigh) / 2))
    global name3, docker_place3

    number1 = tkinter.StringVar()
    name3 = ttk.Combobox(create_five, width=12, textvariable=number1)
    containers1 = client1.containers.list()
    containers2 = client2.containers.list()
    list_temp = []
    for container in containers1:
        list_temp.append(container.name)
    for container in containers2:
        list_temp.append(container.name)
    name3['values'] = tuple(list_temp)
    name3.place(width=150, x=300, y=50, height=40)
    name3.current(0)
    name3_label = tkinter.Label(create_five, text='虚拟机名称', bg='whitesmoke', font=('Arial', 12))
    name3_label.place(x=70, y=50, width=200, height=40)

    number2 = tkinter.StringVar()
    docker_place3 = ttk.Combobox(create_five, width=12, textvariable=number2, font=('Arial', 12))
    docker_place3['values'] = ('0', '1')
    docker_place3.place(width=150, x=300, y=130, height=40)
    docker_place3.current(0)
    docker_place_label3 = tkinter.Label(create_five, text='选择主机停止', bg='whitesmoke', font=('Arial', 12))
    docker_place_label3.place(x=70, y=130, width=200, height=40)

    button3 = tkinter.Button(create_five, text='停止虚拟机', command=stop_container, font=('Arial', 12), width=50, height=2)
    button3.place(x=70, y=250)


def stop_container():
    position = docker_place3.get()
    name = name3.get()
    if position == "0":
        client = client1
    elif position == '1':
        client = client2
    if position != '0' and position != '1':
        tkinter.messagebox.showwarning("提示", '虚拟机参数输入错误')
        return
    name_list = []
    containers = client.containers.list()
    for container in containers:
        name_list.append(container.name)
    if name not in name_list:
        tkinter.messagebox.showwarning("提示", '要停止的虚拟机不存在')
        return
    container = client.containers.get(name)
    container.stop()
    tkinter.messagebox.showwarning("提示", '成功停止虚拟机')


def remove():
    create_four = tkinter.Toplevel()
    frame_main = tkinter.Frame(create_four, bg="whitesmoke")
    frame_main.propagate(False)
    frame_main.pack(expand=tkinter.YES, fill=tkinter.BOTH)
    create_four.title('删除虚拟机')
    width = 600
    heigh = 400
    screenwidth = root.winfo_screenwidth()
    screenheight = root.winfo_screenheight()
    create_four.geometry('%dx%d+%d+%d' % (width, heigh, (screenwidth - width) / 2, (screenheight - heigh) / 2))
    global name1, docker_place1

    number1 = tkinter.StringVar()
    name1 = ttk.Combobox(create_four, width=12, textvariable=number1)
    containers1 = client1.containers.list(all=True)
    containers2 = client2.containers.list(all=True)
    list_temp = []
    for container in containers1:
        list_temp.append(container.name)
    for container in containers2:
        list_temp.append(container.name)
    name1['values'] = tuple(list_temp)
    name1.place(width=150, x=300, y=50, height=40)
    name1.current(0)
    name1_label = tkinter.Label(create_four, text='虚拟机名称', bg='whitesmoke', font=('Arial', 12))
    name1_label.place(x=70, y=50, width=200, height=40)

    number2 = tkinter.StringVar()
    docker_place1 = ttk.Combobox(create_four, width=12, textvariable=number2, font=('Arial', 12))
    docker_place1['values'] = ('0', '1')
    docker_place1.place(width=150, x=300, y=130, height=40)
    docker_place1.current(0)
    docker_place_label1 = tkinter.Label(create_four, text='选择主机删除', bg='whitesmoke', font=('Arial', 12))
    docker_place_label1.place(x=70, y=130, width=200, height=40)

    button1 = tkinter.Button(create_four, text='删除虚拟机', command=remove_container, font=('Arial', 12), width=50,
                             height=2)
    button1.place(x=70, y=250)


def remove_container():
    position = docker_place1.get()
    name = name1.get()
    if position == "0":
        client = client1
    elif position == '1':
        client = client2
    if position != '0' and position != '1':
        tkinter.messagebox.showwarning("提示", '虚拟机参数输入错误')
        return
    name_list = []
    containers = client.containers.list(all=True)
    for container in containers:
        name_list.append(container.name)
    if name not in name_list:
        tkinter.messagebox.showwarning("提示", '要删除的虚拟机不存在')
        return
    container = client.containers.get(name)
    container.stop()
    container.remove()
    tkinter.messagebox.showwarning("提示", '成功删除虚拟机')


def check():
    create_two = tkinter.Toplevel()
    frame_main = tkinter.Frame(create_two, bg="whitesmoke")
    frame_main.propagate(False)
    frame_main.pack(expand=tkinter.YES, fill=tkinter.BOTH)
    create_two.title('查看虚拟机状态')
    width = 600
    heigh = 600
    screenwidth = root.winfo_screenwidth()
    screenheight = root.winfo_screenheight()
    create_two.geometry('%dx%d+%d+%d' % (width, heigh, (screenwidth - width) / 2, (screenheight - heigh) / 2))
    set_mpi_config()
    cmd = 'tar czf - /share/ex/mpi_config | ssh bigdata@' + '192.168.43.99' + ' tar xzf - -C /'
    os.system(cmd)
    containers1 = client1.containers.list(all=True)
    result1 = {}
    for container in containers1:
        result1[container.name] = docker_check_status(container, 0)
    containers2 = client2.containers.list(all=True)
    result2 = {}
    for container in containers2:
        result2[container.name] = docker_check_status(container, 1)

    label1 = tkinter.Label(create_two, text='HOST 0', font=('Arial', 12), bg="whitesmoke")
    label1.place(x=225, y=20, width=100, height=50)
    label = tkinter.Label(create_two, font=tkFont.Font(family="微软雅黑", size=10), bg="whitesmoke",
                          text='name     status      ip           pid_num    cpu_per    mem_use   mem_tot   mem_per').place(
        x=50, y=70, height=30)
    for i, k in enumerate(result1):
        data = result1[k]
        label = tkinter.Label(create_two, font=tkFont.Font(family="微软雅黑", size=10), bg="whitesmoke",
                              text='{}         {}       {}       {}       {}       {}       {}       {}'.format(
                                  data['name'], data['status'], data['ipv4'], data['pid_num'], data['cpu_percentage'],
                                  data['memory_use'], data['memory_total'], data['memory_percentage']))
        label.place(x=50, y=i * 20 + 100, height=30)

    label2 = tkinter.Label(create_two, text='HOST 1', font=('Arial', 12), bg="whitesmoke")
    label2.place(x=225, y=270, width=100, height=50)
    labelhost1 = tkinter.Label(create_two, font=tkFont.Font(family="微软雅黑", size=10), bg="whitesmoke",
                               text='name     status      ip           pid_num    cpu_per    mem_use   mem_tot   mem_per').place(
        x=50, y=320, height=30)
    for i, k in enumerate(result2):
        data = result2[k]
        label = tkinter.Label(create_two, font=tkFont.Font(family="微软雅黑", size=10), bg="whitesmoke",
                              text='{}         {}       {}       {}       {}       {}       {}       {}'.format(
                                  data['name'], data['status'], data['ipv4'], data['pid_num'], data['cpu_percentage'],
                                  data['memory_use'], data['memory_total'], data['memory_percentage']))
        label.place(x=50, y=i * 20 + 350, height=30)


def docker_check_status(container, flag):
    result = {}
    result['name'] = container.name
    containers_ip = network.attrs['Containers']
    ip = '----'
    result['ipv4'] = ip
    for container_ip in containers_ip:
        key = container_ip
        value = containers_ip[key]
        if value['Name'] == container.name:
            ip = value['IPv4Address'][:-3]
            result['ipv4'] = ip
            break

    stats = container.stats(decode=True)
    stats_value = next(stats)
    short_id = container.short_id
    status = container.status
    result['status'] = status
    result['id'] = short_id
    # view_time = stats_value['read'][:-11]
    # view_time = view_time[0:11] + str((int(view_time[11:13]) + 8) % 24) + view_time[13:]
    # result['view_time'] = view_time
    try:
        pids_num = stats_value['pids_stats']['current']
    except:
        pids_num = 0
    result['pid_num'] = pids_num
    if flag == 0:
        out = subprocess.Popen('docker stats {}'.format(container.name), shell=True, stdout=subprocess.PIPE)
        for n, v in enumerate(out.stdout):
            if n == 1:
                value = bytes.decode(v.strip()).split(' ')
                valuelist = [j for j in value if j != '' and j != '/']
                result['cpu_percentage'] = valuelist[2]
                result['memory_use'] = valuelist[3]
                result['memory_total'] = valuelist[4]
                result['memory_percentage'] = valuelist[5]
                out.terminate()
                break
    if flag == 1:
        command = "docker stats --no-stream " + container.name
        stdin, stdout, stderr = ssh.exec_command(command)
        a = (stdout.read().decode()).split('\n')[1]
        b = a.split(' ')
        list1 = []
        for i in range(len(b)):
            if len(b[i]) > 1:
                list1.append(b[i])
        result['cpu_percentage'] = list1[2]
        result['memory_use'] = list1[3]
        result['memory_total'] = list1[4]
        result['memory_percentage'] = list1[5]

    return result


root = tkinter.Tk()
root.title('docker虚拟管理')  # 标题
width = 600
heigh = 600
screenwidth = root.winfo_screenwidth()
screenheight = root.winfo_screenheight()
root.geometry('%dx%d+%d+%d' % (width, heigh, (screenwidth - width) / 2, (screenheight - heigh) / 2))


frame_top = tkinter.Frame(root, bg="yellow")
frame_top.pack(fill=tkinter.X)
tkinter.Label(frame_top, text="虚拟机管理器", bg='yellow',
              font=tkFont.Font(family="微软雅黑", size=20, weight=tkFont.NORMAL)).pack(side=tkinter.LEFT, padx=20)
tkinter.Label(frame_top, text="制作成员:钟欢 李凯琦", bg="yellow", height=2,
              font=tkFont.Font(family="微软雅黑", size=10, weight=tkFont.NORMAL)).pack(side=tkinter.RIGHT, padx=20)


frame_main = tkinter.Frame(root, bg="whitesmoke")
frame_main.propagate(False)
frame_main.pack(expand=tkinter.YES, fill=tkinter.BOTH)
tkinter.Label(frame_main, text="                                  功能                                  ", bg="white",
              fg='black', height=1, font=tkFont.Font(family="微软雅黑", size=20, weight=tkFont.BOLD)).pack(anchor=tkinter.N,padx=5, pady=5)
frame_main.propagate(False)


button0 = tkinter.Button(frame_main, text='使用说明(使用前必看)', command=instruction,font=tkFont.Font(family="微软雅黑", size=12),
                         width=50, height=2, bg='white').pack(padx=10, pady=5)
button1 = tkinter.Button(frame_main, text='创建虚拟机', command=create,font=tkFont.Font(family="微软雅黑", size=12),
                         width=50, height=2, bg='white').pack(padx=10, pady=5)
button3 = tkinter.Button(frame_main, text='开启虚拟机', command=start, font=tkFont.Font(family="微软雅黑", size=12), width=50,
                         height=2, bg='white').pack(padx=10, pady=5)
button5 = tkinter.Button(frame_main, text='停止虚拟机', command=stop, font=tkFont.Font(family="微软雅黑", size=12), width=50,
                         height=2, bg='white').pack(padx=10, pady=5)
button4 = tkinter.Button(frame_main, text='删除虚拟机', command=remove, font=tkFont.Font(family="微软雅黑", size=12), width=50,
                         height=2, bg='white').pack(padx=10, pady=5)
button2 = tkinter.Button(frame_main, text='查看虚拟机状态', command=check,font=tkFont.Font(family="微软雅黑", size=12), width=50,
                         height=2, bg='white').pack(padx=10, pady=5)

root.mainloop()
ssh.close()
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值