docker管理平台(tkinter)

docker 管理平台

1.界面代码

import random
import tkinter as tk
from tkinter import ttk
import tkinter.messagebox
import docker
from run import run_mpi
import tkinter.font as tkFont
from time import sleep
import os
ip1='192.168.43.25'
ip2='192.168.43.15'
connect1 = ip1 + ':2376'
connect2 = ip2 + ':2376'
docker_image='eea3a56a5e4c'
client1 = docker.DockerClient(base_url=connect1, use_ssh_client=True)
try:
    client2 = docker.DockerClient(base_url=connect2, use_ssh_client=True)
except:
    print("lose connect")
    client2=client1
network = client1.networks.get('multihost')

def create_win():
    create_one = tk.Toplevel()
    frame_main = tk.Frame(create_one, bg="whitesmoke")

    frame_main.pack(expand=tk.YES, fill=tk.BOTH)
    create_one.title('创建虚拟机')
    create_one.geometry('800x600')  # 窗体大小
    global memory, CPU_number, docker_name, docker_place

    number3 = tk.StringVar()
    memory = ttk.Combobox(create_one, width=12, textvariable=number3)
    memory['values'] = ('1', '2', '3', '4')
    memory.place(width=250, x=500, y=20, height=20)
    memory.current(0)
    memory_label = tk.Label(create_one, text='请输入最大内存(单位GB)(范围1-4)', bg='whitesmoke')
    memory_label.place(x=20, y=20, width=400, height=20)


    docker_name = tk.Entry(create_one)
    docker_name.place(width=250, x=500, y=80, height=20)
    docker_name_label = tk.Label(create_one, text='请输入虚拟机名字', width=80, bg='whitesmoke')
    docker_name_label.place(x=20, y=80, width=400, height=20)

    number2 = tk.StringVar()
    docker_place = ttk.Combobox(create_one, width=12, textvariable=number2)
    docker_place['values'] = ('0', '1')
    docker_place.place(width=250, x=500, y=170, height=20)
    docker_place.current(0)
    docker_place_label = tk.Label(create_one, text='请选择在那一台物理机上创建docker:', bg='whitesmoke')
    docker_place_label.place(x=20, y=170, width=400, height=20)

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

def create_container():
    position = docker_place.get()
    if position == "0":
        client = client1

    elif position == '1':
        client = client2

    if position != '0' and position != '1':
        tk.messagebox.showwarning("提示", '虚拟机参数输入错误')
        return
    d_name = docker_name.get()
    memory_number = int(eval(memory.get()))
    if memory_number > 16:
        tk.messagebox.showwarning("提示", '虚拟机超过主机最大内存容量')
        return
    mem_limit = memory.get() + 'g'
    ports = {}
    name= '22/tcp'
    ports['name']='1002{}'.format(docker_name[-1])


    tk.messagebox.showwarning("提示", '虚拟机创建成功')

def status_win():
    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('查看虚拟机状态')
    create_two.geometry('1300x800')
    containers1 = client1.containers.list()
    result1 = {}
    try:
        client2 = docker.DockerClient(base_url=connect2, use_ssh_client=True)
    except:
        print("loss connect")
        client2 = client1
    for container in containers1:
        result1[container.name] = container_status(container)
    containers2 = client2.containers.list()
    result2 = {}
    for container in containers2:
        result2[container.name] = container_status(container)

    label1 = tkinter.Label(create_two, text='machine 0', font=('Arial', 14),bg="whitesmoke")
    label1.place(x=500, y=0, width=100, height=50)
    for i, k in enumerate(result1):
        data = result1[k]
        label = tkinter.Label(create_two, font=tkFont.Font(family="微软雅黑", size=12),bg="whitesmoke",text='name:{}     ip:{}    cup_num:{}    pid_num:{}    memory_use:{}    memory_total:{}   memory_percentage:{}'.format(data['name'],  data['ipv4'],data["cpus"],data['pids'],  data['memory_usage'], data['memory_total'], data['memory_per']))
        label.place(x=0, y=i*45+70, height=30)
    label2 = tkinter.Label(create_two, text='machine 1', font=('Arial', 14),bg="whitesmoke")
    label2.place(x=500, y=320, width=100, height=50)
    for i, k in enumerate(result2):
        data = result2[k]
        label = tkinter.Label(create_two, font=tkFont.Font(family="微软雅黑", size=12),bg="whitesmoke",text='name:{}     ip:{}    cup_num:{}    pid_num:{}    memory_use:{}    memory_total:{}   memory_percentage:{}'.format(data['name'],  data['ipv4'],data["cpus"],data['pids'],  data['memory_usage'], data['memory_total'], data['memory_per']))
        label.place(x=0, y=i*45+390, height=30)

def container_status(container):
    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 = next(container.stats(decode=True))
    result['pids']=stats["pids_stats"]["current"]
    result["cpus"]=stats['cpu_stats']["online_cpus"]
    result["memory_total"]=stats["memory_stats"]["limit"]
    result["memory_usage"]=stats["memory_stats"]["usage"]
    result["memory_per"]="{}%".format(result["memory_usage"]/result["memory_total"]*100)
    return result

def start_win():
    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('开启虚拟机')
    create_three.geometry('800x600')  # 窗体大小
    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=250, x=500, y=70, height=20)
    name2.current(0)
    name2_label = tkinter.Label(create_three, text='请输入要开启名字',bg='whitesmoke')
    name2_label.place(x=20, y=70, width=400, height=20)

    number1 = tkinter.StringVar()
    docker_place2 = ttk.Combobox(create_three, width=12, textvariable=number1)
    docker_place2['values'] = ('0', '1')
    docker_place2.place(width=250, x=500, y=170, height=20)
    docker_place2.current(0)
    docker_place2_label1 = tkinter.Label(create_three, text='请选择在那一台物理机上开启docker:',bg='whitesmoke')
    docker_place2_label1.place(x=20, y=170, width=400, height=20)

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

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_win():
    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('停止虚拟机')
    create_five.geometry('800x600')  # 窗体大小
    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=250, x=500, y=70, height=20)
    name3.current(0)
    name3_label = tkinter.Label(create_five, text='请输入要停止名字', bg='whitesmoke')
    name3_label.place(x=20, y=70, width=400, height=20)

    number2 = tkinter.StringVar()
    docker_place3 = ttk.Combobox(create_five, width=12, textvariable=number2)
    docker_place3['values'] = ('0', '1')
    docker_place3.place(width=250, x=500, y=170, height=20)
    docker_place3.current(0)
    docker_place_label3 = tkinter.Label(create_five, text='请选择在那一台物理机上停止docker:', bg='whitesmoke')
    docker_place_label3.place(x=20, y=170, width=400, height=20)

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

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("提示", 'error')
        return

    container = client.containers.get(name)
    container.stop()
    tkinter.messagebox.showwarning("提示", '成功停止虚拟机')

def delete_win():
    create_four = tkinter.Toplevel()
    frame_main = tkinter.Frame(create_four, bg="whitesmoke")

    frame_main.pack(expand=tkinter.YES, fill=tkinter.BOTH)
    create_four.title('删除虚拟机')
    create_four.geometry('800x600')  # 窗体大小
    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=250, x=500, y=70, height=20)
    name1.current(0)
    name1_label = tkinter.Label(create_four, text='请输入要删除的虚拟机名字', bg='whitesmoke')
    name1_label.place(x=20, y=70, width=400, height=20)

    number2 = tkinter.StringVar()
    docker_place1 = ttk.Combobox(create_four, width=12, textvariable=number2)
    docker_place1['values'] = ('0', '1')
    docker_place1.place(width=250, x=500, y=170, height=20)
    docker_place1.current(0)
    docker_place_label1 = tkinter.Label(create_four, text='请选择在那一台物理机上删除docker:', bg='whitesmoke')
    docker_place_label1.place(x=20, y=170, width=400, height=20)

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

def delete_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 run_win():
    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('Run')
    create_four.geometry('800x600')  # 窗体大小
    global number2
    number2 = tkinter.StringVar()
    docker_place1 = ttk.Combobox(create_four, width=12, textvariable=number2)
    docker_place1.place(width=250, x=500, y=170, height=20)
    docker_place_label1 = tkinter.Label(create_four, text='process num', bg='whitesmoke',font=('Arial', 15))
    docker_place_label1.place(x=20, y=170, width=400, height=20)
    button1 = tkinter.Button(create_four, text='run', command=run_container, font=('Arial', 12), width=50,
                             height=2)
    button1.place(x=170, y=300)

def run_container():
    run_mpi()
    num=number2.get()
    cmd='docker exec -i host1 mpirun -n {} -f /root/hostfile /home/knn'.format(num)
    os.system(cmd)
    # while(1):
    #     stats=os.system(cmd)
    #     if(stats==0):
    #         break
    #     else:
    #         print("lose connect")
    #         sleep(1)




    tkinter.messagebox.showwarning("提示", 'end')

if __name__ == '__main__':
    root = tk.Tk()
    root.title('docker虚拟管理')
    root.geometry('1200x800')
    root.title("docker虚拟管理")
    frame_top = tk.Frame(root, bg="#87CEEB")
    frame_top.pack(fill=tk.X)

    tk.Label(frame_top, text="MPI KNN", bg='#87CEEB',
                  font=tkFont.Font(family="微软雅黑", size=16, weight=tkFont.NORMAL)).pack(side=tk.LEFT, padx=20)
    tk.Label(frame_top, text="云计算课程设计", bg="#87CEEB", height=2,
                  font=tkFont.Font(family="微软雅黑", size=20, weight=tkFont.NORMAL)).pack(side=tk.RIGHT, padx=200)

    frame_main = tk.Frame(root, bg="whitesmoke")
    frame_main.propagate(False)
    frame_main.pack(expand=tk.YES, fill=tk.BOTH)

    frame_maintop = tk.Frame(frame_main, bg="white", height=80)
    frame_maintop.pack(fill=tk.X, padx=20, pady=10)
    imagetop = tk.Label(frame_maintop, width=180, height=60)
    tk.Label(frame_maintop, text="Docker Manager", bg="white", fg='black', height=4,
                  font=tkFont.Font(family="微软雅黑", size=20, weight=tkFont.BOLD)).pack(side=tk.LEFT, padx=450)

    frame_mainleft = tk.Frame(frame_main, width=800, bg="white")
    frame_mainleft.pack(fill=tk.Y, expand='yes',padx=30)
    frame_mainleft.propagate(False)
    button1 = tk.Button(frame_mainleft, text='创建虚拟机', command=create_win, font=tkFont.Font(family="微软雅黑", size=12),
                             width=50, height=2, bg='white').pack(padx=10, pady=10)
    button2 = tk.Button(frame_mainleft, text='查看虚拟机状态', command=status_win, font=tkFont.Font(family="微软雅黑", size=12),
                             width=50, height=2, bg='white').pack(padx=10, pady=10)
    button3 = tk.Button(frame_mainleft, text='开启虚拟机', command=start_win, font=tkFont.Font(family="微软雅黑", size=12),
                             width=50, height=2, bg='white').pack(padx=10, pady=10)
    button5 = tk.Button(frame_mainleft, text='停止虚拟机', command=stop_win, font=tkFont.Font(family="微软雅黑", size=12),
                             width=50, height=2, bg='white').pack(padx=10, pady=10)
    button4 = tk.Button(frame_mainleft, text='删除虚拟机', command=delete_win, font=tkFont.Font(family="微软雅黑", size=12),
                             width=50, height=2, bg='white').pack(padx=10, pady=10)
    button6 = tk.Button(frame_mainleft, text='运行mpi', command=run_win, font=tkFont.Font(family="微软雅黑", size=12),
                        width=50, height=2, bg='white').pack(padx=10, pady=10)
    root.mainloop()
    client1.close()

2.简单容错

通过ping docker容器来实现,主要利用了os库中的函数在本机执行命令来操作容器

import os
from heapq import merge
import subprocess
import docker
import subprocess
import os
def run_mpi():
    host_share = '/home/docker/mpi_config/'
    ip1 = '192.168.43.25'
    ip2 = '192.168.43.15'
    connect1 = ip1 + ':2376'
    connect2 = ip2 + ':2376'
    client1 = docker.DockerClient(base_url=connect1, use_ssh_client=True)
    flag=0
    try:
        client2 = docker.DockerClient(base_url=connect2, use_ssh_client=True)
        flag=1
    except:
        flag=0
        client2=client1
        print("lose connect")
    network = client1.networks.get('multihost')
    file_address = host_share + 'mpi_config'
    containers1 = client1.containers.list()
    containers_ip = network.attrs['Containers']
    ips = []
    with open(file_address, mode='w', encoding='utf-8') as file_obj:
        for container in containers1:
            container_name=container.name
            cmd='docker exec -i host1 ping  -c 1 {}'.format(container_name)
            res=1
            try:
                res = subprocess.call(cmd,shell=True,timeout=1)
            except subprocess.TimeoutExpired:
                print('{} loss connect'.format(container_name))
            if res!=0:
                continue
            for container_ip in containers_ip:
                key = container_ip
                value = containers_ip[key]
                if value['Name'] == container.name:
                    ip = value['IPv4Address'][:-3]
                    ips.append(ip)
                    break
        if flag==1:
            containers2 = client2.containers.list()
            for container in containers2:
                container_name = container.name
                cmd = 'docker exec -i host1 ping  -c 1 {}'.format(container_name)
                res = 1
                try:
                    res = subprocess.call(cmd, shell=True, timeout=1)
                except subprocess.TimeoutExpired:
                    print('{} loss connect'.format(container_name))
                if res != 0:
                    continue
                for container_ip in containers_ip:
                    key = container_ip
                    value = containers_ip[key]
                    if value['Name'] == container.name:
                        ip = value['IPv4Address'][:-3]
                        ips.append(ip)
                        break
        for i in range(len(ips)):
            file_obj.write(ips[i] + ':' + str(1) + '\n')
    cmd = 'docker cp /home/docker/mpi_config/mpi_config host1:/root/hostfile'
    os.system(cmd)
    client1.close()

上一篇:python界面编程-thinker


下一篇:python tkinter 入门教程