import docker import subprocess import tkinter import tkinter.messagebox import random import paramiko import tkinter.font as tkFont from PIL import Image, ImageTk from tkinter import ttk import webbrowser import os # 将mpi配置写入本地文件,再由本地通过sftp上传到宿主机挂在目录 unload_path = './mpi_config/servers' # 容器挂载的宿主机目录 host_share = '/mpi_config' # 容器中的mpi配置,与host_share共享文件 docker_file = '/mpich/mpi_config' 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.56", port=22, username="root", password="a000401.") # 文件传输stfp sftp_client = paramiko.Transport(("192.168.43.56", 22)) sftp_client.connect(username="root", password="a000401.") sftp = paramiko.SFTPClient.from_transport(sftp_client) ip1 = '192.168.43.56' ip2 = '192.168.43.66' ip3 = '192.168.43.60' # docker images配置好的mpi映像 docker_images = '802140ebb05d' connect1 = ip1 + ':2375' connect2 = ip2 + ':2375' connect3 = ip3 + ':2375' client1 = docker.DockerClient(base_url=connect1, use_ssh_client=True) client2 = docker.DockerClient(base_url=connect2, use_ssh_client=True) client3 = docker.DockerClient(base_url=connect3, use_ssh_client=True) # 设置网络模式为桥接 network1 = client1.networks.get('my_network') network2 = client2.networks.get('my_network') network3 = client3.networks.get('my_network') CPU_1 = 4 CPU_2 = 4 CPU_3 = 4 # mpi配置文件写到本地的目录中 def write_config(): # 有问题,系统自动运行windows的文件系统 file_address = '.' + host_share + '/servers' containers1 = client1.containers.list() containers2 = client2.containers.list() containers3 = client3.containers.list() containers_ip1 = network1.attrs['Containers'] containers_ip2 = network2.attrs['Containers'] containers_ip3 = network3.attrs['Containers'] ips = [] # 读容器ip添加到ips中 with open(file_address, mode='w', encoding='utf-8') as file_obj: for container in containers1: for container_ip in containers_ip1: key = container_ip value = containers_ip1[key] if value['Name'] == container.name: ip = value['IPv4Address'][:-3] if value['Name'] == 'master_1': file_obj.write(ip + ':' + str(1) + '\n') else: ips.append(ip) for container in containers2: for container_ip in containers_ip2: key = container_ip value = containers_ip2[key] if value['Name'] == container.name: ip = value['IPv4Address'][:-3] if value['Name'] == 'master_2': file_obj.write(ip + ':' + str(1) + '\n') else: ips.append(ip) for container in containers3: for container_ip in containers_ip3: key = container_ip value = containers_ip3[key] if value['Name'] == container.name: ip = value['IPv4Address'][:-3] if value['Name'] == 'master_3': file_obj.write(ip + ':' + str(1) + '\n') else: ips.append(ip) # 将ip写入servers文件 for i in range(len(ips)): file_obj.write(ips[i] + ':' + str(1) + '\n') # 创建虚拟机 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('创建虚拟机') create_one.geometry('800x600') # 窗体大小 global memory, CPU_number, docker_name, docker_place number3 = tkinter.StringVar() memory = ttk.Combobox(create_one, width=20, textvariable=number3) memory['values'] = ('1', '2', '3', '4', '5', '6', '7', '8') memory.place(x=500, y=100, width=250, height=20) memory.current(0) memory_label = tkinter.Label(create_one, text='请输入最大内存(单位GB)(范围1-8)', bg='white') memory_label.place(x=20, y=100, width=400, height=20) number1 = tkinter.StringVar() CPU_number = ttk.Combobox(create_one, width=12, textvariable=number1) CPU_number['values'] = ('0', '1', '2', '3', '4') CPU_number.place(x=500, y=150, width=250, height=20) CPU_number.current(0) CPU_number_label = tkinter.Label(create_one, text='请输入CPU核数目(范围0-4)', bg='white') CPU_number_label.place(x=20, y=150, width=400, height=20) docker_name = tkinter.Entry(create_one) docker_name.place(x=500, y=200, width=250, height=20) docker_name_label = tkinter.Label(create_one, text='请输入虚拟机名字', width=80, bg='white') docker_name_label.place(x=20, y=200, width=400, height=20) number2 = tkinter.StringVar() docker_place = ttk.Combobox(create_one, width=12, textvariable=number2) docker_place['values'] = ('1', '2', '3') docker_place.place(x=500, y=250, width=250, height=20) docker_place.current(0) docker_place_label = tkinter.Label(create_one, text='请选择在那一台物理机上创建docker:', bg='white') docker_place_label.place(x=20, y=250, width=400, height=20) # 选择一切容器参数后,调用docker_create()函数 button2 = tkinter.Button(create_one, text='创建虚拟机', command=docker_create, font=('Arial', 12), width=50, height=2) button2.place(x=170, y=400) # 查看虚拟机状态 def check(): write_config() # 上传至服务器 sftp.put(unload_path, host_share + '/servers') webbrowser.open("http://{:}:4040".format(ip1), new=0) 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('开启虚拟机') 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) containers3 = client3.containers.list(all=True) containers1_run = client1.containers.list() containers2_run = client2.containers.list() containers3_run = client3.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) for container in containers3: if container not in containers3_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='white') 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'] = ('1', '2', '3') 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='white') 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 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('删除虚拟机') 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) containers3 = client3.containers.list(all=True) list_temp = [] for container in containers1: list_temp.append(container.name) for container in containers2: list_temp.append(container.name) for container in containers3: 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='white') 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'] = ('1', '2' ,'3') 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='white') docker_place_label1.place(x=20, y=170, width=400, height=20) button1 = tkinter.Button(create_four, text='删除虚拟机', bg='white', command=remove_container, font=('Arial', 12), width=50, height=2) button1.place(x=170, y=300) 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('停止虚拟机') 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() containers3 = client3.containers.list() list_temp = [] for container in containers1: list_temp.append(container.name) for container in containers2: list_temp.append(container.name) for container in containers3: 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='white') 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'] = ('1', '2' ,'3') 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='white') 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 remove_container(): position = docker_place1.get() name = name1.get() if position == "1": client = client1 elif position == '2': client = client2 elif position == '3': client = client3 if position != '1' and position != '2' and position != '3': 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 start_container(): position = docker_place2.get() name = name2.get() if position == "1": client = client1 elif position == '2': client = client2 elif position == '3': client = client3 if position != '1' and position != '2' and position != '3': 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_container(): position = docker_place3.get() name = name3.get() if position == '1': client = client1 elif position == '2': client = client2 elif position == '3': client = client3 if position != '1' and position != '2' and position != '3': 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 docker_create(): position = docker_place.get() if position == '1': client = client1 CPU_number_limit = CPU_1 elif position == '2': client = client2 CPU_number_limit = CPU_2 elif position == '3': client = client3 CPU_number_limit = CPU_3 if position != '1' and position != '2' and position != '3': tkinter.messagebox.showwarning("提示", '虚拟机参数输入错误') return name = docker_name.get() memory_number = int(eval(memory.get())) if memory_number > 8: 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, 3) if i not in CPU_list: CPU_list.append(i) CPU_str += str(i) CPU_str += ',' CPU_str = CPU_str[:-1] print(CPU_str) print(CPU_list) # 参数:image-镜像id号 name-容器名 mem_limit-分配最大内存 tty # privileged-授予此容器扩展权限 detach-在后台运行容器并返回一个容器对象 # stdin_open-即使没有连接,也要保持STDIN打开。 # network-网络模式 client.containers.run(image=docker_images, name=name, mem_limit=mem_limit, tty=True, privileged=True, detach=True, stdin_open=True, network='my_network', cpuset_cpus=CPU_str, volumes=volumes) tkinter.messagebox.showwarning("提示", '虚拟机创建成功') client1.close() client2.close() client3.close() root = tkinter.Tk() root.title('docker虚拟机管理系统') # 标题 root.geometry('800x700') # 窗体大小 frame_top = tkinter.Frame(root, bg="SkyBlue") frame_top.pack(fill=tkinter.X) lbl_image = tkinter.Label(frame_top, width=150, height=80) lbl_image.pack(side=tkinter.LEFT) imgtop = Image.open(r'docker.jpg') img1 = imgtop.resize((150, 80), Image.ANTIALIAS) tk_img = ImageTk.PhotoImage(img1) lbl_image.image = tk_img lbl_image.config(image=tk_img) tkinter.Label(frame_top, text="云计算课程设计", bg='SkyBlue', font=tkFont.Font(family="微软雅黑", size=12, weight=tkFont.NORMAL)).pack(side=tkinter.LEFT, padx=20) tkinter.Label(frame_top, text="制作成员:刘涛 罗继睿 刘皓轩", bg="SkyBlue", height=2, font=tkFont.Font(family="微软雅黑", size=12, weight=tkFont.NORMAL)).pack(side=tkinter.RIGHT, padx=100) frame_main = tkinter.Frame(root, bg="LightBlue") frame_main.propagate(False) frame_main.pack(expand=tkinter.YES, fill=tkinter.BOTH) frame_maintop = tkinter.Frame(frame_main, bg="SkyBlue", width=800,height=10) frame_maintop.pack(fill=tkinter.X, padx=20, pady=10) imagetop = tkinter.Label(frame_maintop, width=800, height=40) tkinter.Label(frame_maintop, text="虚拟机管理器", bg="SkyBlue", fg='black', height=2, font=tkFont.Font(family="微软雅黑", size=18, weight=tkFont.BOLD)).pack(side=tkinter.LEFT, padx=300) frame_mainleft = tkinter.Frame(frame_main, width=800, height=40,bg="SkyBlue") frame_mainleft.pack(side=tkinter.RIGHT, fill=tkinter.Y, padx=30) tkinter.Label(frame_mainleft, text=" 主要功能", bg="SkyBlue", fg='black', height=2, font=tkFont.Font(family="微软雅黑", size=18, weight=tkFont.BOLD)).pack(anchor=tkinter.W, padx=300, pady=5) frame_mainleft.propagate(False) button1 = tkinter.Button(frame_mainleft, text='创建虚拟机', command=create, font=tkFont.Font(family="微软雅黑", size=11), width=50, height=2, bg='white').pack(padx=10, pady=5) button2 = tkinter.Button(frame_mainleft, text='查看虚拟机状态', command=check, font=tkFont.Font(family="微软雅黑", size=11), width=50, height=2, bg='white').pack(padx=10, pady=5) button3 = tkinter.Button(frame_mainleft, text='开启虚拟机', command=start, font=tkFont.Font(family="微软雅黑", size=11), width=50, height=2, bg='white').pack(padx=10, pady=5) button5 = tkinter.Button(frame_mainleft, text='停止虚拟机', command=stop, font=tkFont.Font(family="微软雅黑", size=11), width=50, height=2, bg='white').pack(padx=10, pady=5) button4 = tkinter.Button(frame_mainleft, text='删除虚拟机', command=remove, font=tkFont.Font(family="微软雅黑", size=11), width=50, height=2, bg='white').pack(padx=10, pady=5) root.mainloop() ssh.close()
Docker技术实践
该代码实现了一个Docker虚拟机管理系统,包括创建、查看、启动、停止和删除虚拟机的功能。系统通过SSH连接宿主机,使用SFTP传输文件,并通过Docker API管理分布在不同节点上的容器。同时,它能根据容器的网络信息动态生成MPI配置文件。
摘要由CSDN通过智能技术生成