基于Docker的开源云主机集群管理平台_第1页
基于Docker的开源云主机集群管理平台_第2页
基于Docker的开源云主机集群管理平台_第3页
基于Docker的开源云主机集群管理平台_第4页
基于Docker的开源云主机集群管理平台_第5页
已阅读5页,还剩48页未读 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

本科生毕业论文基于Docker的开源云主机集群管理平台 opensourcecloudclustermanagerplatformbasedonDocker

毕业设计(论文)原创承诺书1.本人承诺:所呈交的毕业设计(论文)《ActionScript3在Flash游戏制作中的应用》,是认真学习理解学校的《长春理工大学本科毕业设计(论文)工作条例》后,在教师的指导下,保质保量独立地完成了任务书中规定的内容,不弄虚作假,不抄袭别人的工作内容。2.本人在毕业设计(论文)中引用他人的观点和研究成果,均在文中加以注释或以参考文献形式列出,对本文的研究工作做出重要贡献的个人和集体均已在文中注明。3.在毕业设计(论文)中对侵犯任何方面知识产权的行为,由本人承担相应的法律责任。4.本人完全了解学校关于保存、使用毕业设计(论文)的规定,即:按照学校要求提交论文和相关材料的印刷本和电子版本;同意学校保留毕业设计(论文)的复印件和电子版本,允许被查阅和借阅;学校可以采用影印、缩印或其他复制手段保存毕业设计(论文),可以公布其中的全部或部分内容。以上承诺的法律结果将完全由本人承担!作者签名:年月日-51-摘要Docker日益火爆的今天,本次设计对其网络化和集群化能力做出了一个尝试。并开发了Kubernetes用来搭建了一个集群管控程序。本文就其的主要部件的设计的分析和具体实现的设计详细描述了容器的大规模化之后应该去完善的工作。在整个体系中,本设计将容器升级划分成了一个一个的Pod,并将其作为最小的调度单元。解除了集群管理程序和Docker程序的耦合。同时,通过ETCD集群做全局索引系统,利用其实现的Raft算法带来的集群写一致性,进而保证了整个系统的一致性。同时,为互联网与Pod之间增加了一层访问中间控制层,解决了传统软件服务发现和流量负载均衡的问题。但是,对于DNS的支持并未达到理想的程度。最后,利用自建的机制解决了服务的动态扩容难题,为快速部署服务提供了一个简单而可行的方案。关键字:容器集群云计算微服务

AbstractDockerincreasinglypopulartoday,wemadeanattemptonitsnetworkclusteringcapabilities.AndthedevelopmentofKubernetestobuildaclustercontrolprogram.Thisarticledescribesindetailthescaleofwhatweshoulddoafterworkontheanalysisofthecontainermainpartofthedesignandimplementationofthedesign.Inthewholesystem,wewillupgradethecontainerisdividedintoaoneofthePod,andasthesmallestdispatchunit.DecoupledclustermanagementproceduresandDockerprogram.Meanwhile,globalindexesdoETCDclustersystemthatusesRaftbringitsimplementationalgorithmclusterswriteconsistency,thusensuringconsistencythroughoutthesystem.Atthesametime,wewilladdanotherlayerofaccesscontrollayerintermediatebetweentheInternetandPod,tosolvethetraditionalsoftwareServicediscoveryandtrafficloadbalance.However,supportforDNSdidnotreachthedesiredlevel.Finally,weuseself-builtmechanismtosolvetheproblemofdynamicexpansionofServicesforrapiddeploymentServicesprovideasimpleandworkablesolution.Keywords:Container;Cluster;CloudComputing;Micro-Service

目录摘要 IAbstract II目录 III第1章绪论 11.1课题研究的背景及意义 11.1.1提高资源利用率 11.1.2服务的动态扩容和持续集成 11.2国内外研究现状 21.2.1.CasS平台 21.2.2.容器VS虚拟机——商用为主 21.2.3微服务化 31.3主要研究内容 41.4论文组织结构 4第2章总体设计 52.1功能设计 52.1.1 Minion节点组件 52.1.2Master节点组件 62.2基本概念 72.2.1Pod 72.2.2Service 92.2.3ReplicationController 92.2.4Label 9第3章详细设计 113.1Master节点 113.2Kubectl 113.3APIServer 113.3.1MinionRegistry 133.3.2PodRegistry 133.3.3ServiceRegistry 133.3.4ControllerRegistry 143.3.5EndpointsRegistry 143.3.6BindingRegistry 143.4Scheduler 15第4章设计实现 174.1Pod 174.1.1Volume 184.1.2容器通信 204.2ReplicationController 204.2.1RestartPolicy和ReplicationController 214.2.2ReplicationController的工作机制 224.2.3ReplicationController的应用场景 234.3Service 254.3.1工作机制 254.3.2数据结构定义 264.3.3服务发现 264.3.4HeadlessService 284.3.5入口地址和外部可路由性 284.3.6避免端口冲突 294.3.7Service入口 294.3.8存在的的不足 304.4APIServer 304.4.1设计目的 314.4.2资源对象的RESTful接口 314.4.3API操作的原子性 324.4.4APIServer流程 33第5章调度和网络 355.1网络 355.1.1网络模型 355.1.2具体实现 355.1.3其他工作 355.2Minion管理 375.2.1Minion发现 375.2.2Minion管控流程 375.3调度器 385.3.1调度策略 385.3.2例1:Predicates.PodFitsPorts 395.3.3例2:Priorities.LeastRequestedPriority 405.3.4缓存模型 41第6章实战部署 425.1环境准备 425.1.1下载软件包 425.1.2下载源码包进行编译 425.2upstart脚本 425.3安装kubernetes客户端程序 43第7章总结 44参考文献 45致谢 46附录 47第1章绪论1.1课题研究的背景及意义1.1.1提高资源利用率现行的网络服务器集群,有很大的一部分都是由巨量的服务器组成的,这些服务器根据资源的占用情况可以被分为IO密集型、计算密集型、存储型、图形工作站、特殊用型(例如堡垒机,基础交换机等)。事实上,对于IO密集型的机器,其计算能力会产生部分冗余,这个无法避免,甚至在LXC、KVM等轻量级虚拟化技术诞生之前都无法利用他们,造成了很大的资源浪费[1]。同样道理,计算密集型的IO、存储往往都是处于无法利用的状态。因此,对于,大规模应用来说一门轻量级的资源利用技术是极其迫切的需要[2]。在Docker之前,便有一些轻量级虚拟化技术[3]了,事实上,Docker本身也是基于LXC[4]做为基础建立的(0.8版本之后改用自己编译的libcontainer,本质还是LXC)。但是这些技术都有一个致命的缺陷,就是不支持冷备,所有的操作都是热操作。全热操作导致的一个巨大的问题就是无法进行快速的部署、启动和迁移。而Docker创新的采用了image和container分离的技术,并用版本控制系统来进行标记,让虚机迁移、部署、启动这个过程变得异常简单。当然,这样做带来的一点负面影响就是在编写虚机的时候较为麻烦,但是完全值得。1.1.2服务的动态扩容和持续集成服务,尤其是面向互联网的服务,始终面临着巨量用户的考验,随时可能到来,多大的量都可能。例如春节时候的12306、例如双十一的阿里巴巴,其各种资源都达到了瓶颈,无论是计算资源还是网络资源。而服务的高可用最简单的方法就是提升服务器的数量。但是如何快速接入服务,阿里巴巴会在每次购物节到来之前提前一个月安排专人对服务器进行扩容和补充,购物节结束之后又会进行服务器的删减。因为在平时维持这么巨量的服务器是完全没有意义的。这是阿里巴巴的做法,但是广大公司并没有阿里巴巴那样的财力物力。2015年初,一个叫足迹的App火了,但是她们连CEO加一起团队成员才8个人,面对的却是一天暴涨的400万用户量,服务器瞬间瘫痪,App彻底失效。她们除了给所有用户推送了一条道歉信之外什么都做不了,服务器有,但是就是提供不了服务。同样的例子也发生在了今年春节联欢晚会,但是却收到了不同的效果,其中容器技术贡献巨大。羊年春晚有两个热点,一个是巨量的网络春晚收视率,另一个就是微信红包。其中,为了推送巨量的网络视频流,春晚后勤便采用了Docker的动态扩容技术,在高峰到来之前迅速部署了巨量的容器,在不同的服务器之间进行轮询,并且自动发现并重启down掉的容器。正是这样可怕的动态扩容能力,保证了春晚网络直播的顺利进行。就我所实习的公司(七牛网络信息技术有限公司,以下简称七牛)来说,Docker已经成为七牛持续集成部署的一部分了。七牛将其用在了图片处理、ufop、MEMPG处理等业务上,每一个image服务都封装成一个container,大大提到了image服务的处理能力和持续集成能力和监控能力[5],每次部署机器,只需要拉取指定的二进制压缩包即可,简单方便。1.2国内外研究现状1.2.1.CasS平台Docker原本是DotCloud公司的一个主要项目,后来被开源出来,而DotCloud公司提供的正是CasS云。CasS即Container-as-Service的简写,对于这样的服务,编程人员可能并不了解,但是其实GoogleComputeEngine,SinaAppEngine,BaiduAppEngine2.0,阿里巴巴ECS云服务器,CloudFoundry(部分采用)等技术都是提供的CasS服务。但是对外表现来说,阿里巴巴的ECS更像一个PasS,但是其实底层还是用的容器技术(当然不可能是Docker)。国内,完全基于Docker的CasS公司DaoCloud也于前日正式对外提供服务。1.2.2.容器VS虚拟机——商用为主虚拟机技术,从最开始的分时系统,到后来的各种VM的乱战到Xen的统一服务器端江湖[6],直到现在KVM流行。“现在都是KVM[7],如果新一点的,就玩Container了。”计算机世界分为两条线,计算和存储,虚拟化属于计算这条线,而虚拟化又分为两条,硬件虚拟化和软件虚拟化,硬件虚拟化从IBM时代就开始了。1999年,一个叫VMwareWorkstation的公司流行了一段时间,这个公司就是现在的虚拟化巨头VMware。但是前几年被卖给EMC了,现在连EMC都自身难保。相较之,容器技术的概念也被提出很久了,根据国外的研究成果[8],之所以一致未曾实现,主要原因还是因为容器技术的不成熟。因为是进程级别虚拟化,其隔离系统总不会像硬件级别虚拟化一样密不透风,LinuxKernel上关于LXC的SecurityAnnounce有五十多个,但是没人敢去修,因为这个东西是牵一发而动全身的。从IBM360到VMware的流行,国外花了近二十年时间才让硬件虚拟化技术变得为商业所接受。同样的,容器技术要走进真正的商用还需要很长的一段路[9]。1.2.3微服务化云计算在当计算机科学高度发展的今天已经越来越多参与了我们正常的生产生活。同时,提供云计算服务的厂商也如雨后春笋般冒了出来。与传统的IT产业公司不同的是,云计算时代的互联网公司,作为云计算服务的提供者,越来越扮演着幕后的角色。典型的云计算时代,当你打开手机,点开某个门户网站,浏览一段视频,与人沟通交流,这一切的一切都是由巨量的服务支撑起来的。同样的,每一个服务都尽量做到轻量,简单。这也正是UNIX的设计哲学kISS:keepitsimple&stupid,这样的服务被称之为“微服务”。kISS:keepitsimple&stupid将服务拆散开,以链接、api、转发、负载均衡等方式对外提供,在提供商这里,拆小了业务逻辑,将原先生产一条飞机的难度降低到了生产一颗螺丝钉上去。对于开发者和消费者,微服务提供了更多的可能和更强大的兼容性。然而,抛开了完整的系统,而转向微服务的我们,该如何保证微服务的稳定和高可用呢?云计算就像一个池子,服务就像池子里的水,正常情况下,服务从提供商手里流出,保障其基础设施的运转良好。但是当你的池子不够大呢?扩容?是个好办法。但是这需要时间和成本的开销,而且运维反应速度慢和快也是衡量一个公司服务能力的重要标准。因此,在云计算时代,无论企业还是个人,都需要一个轻便,易于部署,快速迁移,快速启动的环境设置技术来支持服务启用、备份、容灾、迁移。这个技术,就是Docker。Docker是一个容器管理程序,由Golang编写,采用LXC做BackEnd,提供了容器的快速启动,快速部署,版本控制等方法。Docker就像一个集装箱,把服务需要的环境都封装在里面,想用的时候直接拿集装箱走并使用就可以。省去了很多无用而且缓慢的部署脚本,并且,其image的概念的提出,为冷备Docker提供了一个简单而且方便的途径。国内目前已经有学者开始对微服务化的可行性做了研究,并且,Docker也开始和传统的云计算平台结合[10]产生了奇妙的变化。1.3主要研究内容本文主要进行了如下的研究:对Kubernetes的设计和架构进行深度解析,分析各个组件的设计目的和具体实现提供一个简单、易用的自动化部署、持续集成、滚动升级、灰度、多版本追踪发布方案。让Docker能够更加简单的在生产环境中应用。提供一个可靠的横向扩展架构,搭建一个无状态易扩展的高可用服务器集群,自动实现负载均衡和动态扩容。研究虚网络和SDN网络的设计模型,并对其进行分析。以及在Kubernetes中的应用和实战。研究集群一致算法Raft[11],分析Kubernetes的集群的一致性。1.4论文组织结构本次论文共分三个大部分:总体设计、细节设计、实战部署。其中,第1章~第2章,主要讲述的是Kubernetes系统的架构和设计,以及一些特化的概念。第3章~第5章是Kubernetes系统的详细设计和技术细节。本部分从Master节点开始,逐步分析Kubernetes系统设计实践中出现的问题,并提出自己的解决方案。展示其各个组件的实现细节和技术上的缺陷。第6章是Kubernetes的实战部署,在一台Ubuntu14.04主机上搭建单节点的Kubernetes集群,并检测其安装结果。

第2章总体设计2.1功能设计本系统名叫Kubernetes,是Google公司推出的一款类似于BorgBorg是Google公司内部使用的服务部署和动态迁移程序,Borg是Google公司内部使用的服务部署和动态迁移程序,未开源图2-SEQ图片1-\*ARABIC1Kubernetes网络图对于Kubernetes,其详细组件图如图2-2:Minion节点组件在每个对外提供服务的节点(对于整个集群来说,这些节点可以称之为minion)上,Kubernetes有如下组件:kubelet:管理Docker本身,与BackEnd通讯的程序,其本身就是一个守护进程,伴随着Docker一起启动。kube-Proxy:代理程序,对外提供Docker机器上的服务的网络转发,对内则进行端口映射和隧道压缩,将网络流转发致各个可用的服务容器上。图2-SEQ图片1-\*ARABIC2Kubernetes组件图2.1.2Master节点组件对于master节点,共有三个主要组件:kube-apiserver:本组件是Kubernetes系统的主要组件,对外,apiserver提供开放的端口,即,提供服务;对内,apiserver维持一个对于ETCD系统的RESTful持久化对象,以便于同步集群的信息。对整个集群,他是集群控制的入口,提供一个RESTful的api来对集群进行控制。kube-sScheduler:Kubernetes的调度程序,负责调度整个集群的资源,为部署容器提供自动化的执行方案这个这个地方原本是Borg系统最精华的部分,但是限于Google公司机密,因此做成了一个简单的服务。kube-controller-manager:Kubernetes的执行各种controller的程序,目前controller共有两类,分别是:endpoint-controller:负责关联Kubernetes的服务和容器当然,这里对于容器当然,这里对于容器并不是k8s的最基本调度单位,这里所说的实际上使指的Service和pod的正确映射关系,关于k8s的一些基本概念,将在下一节详细叙述replication-controller:负责定义容器的数量处在正确的值,即,关闭超过数量的容器,增加因为资源不足,意外宕机等原因而减少的容器的数量。etcd:etcd是一个由Coreos公司实现的简易k-v分布式数据存储系统,采用raft算法保证集群一致性。Kubernetes用它来实现了一个globalindex系统,从而达到全局的一致性保证。这里面主要存储的是Kubernetes系统的所有Label。2.2基本概念2.2.1PodPod,是Kubernetes的一个基本的调度单位,一个Pod对应的一组DockerContainer构成的容器组,在同一个Pod里,DockerVolume可以共同共享的挂载在同Pod中的所有DockerContainer中。如下图2-3。在逻辑上,Pod的提出结束了自己管理Docker容器的分立的状态,Pod建立了一个“逻辑虚拟机”的模型,在这个虚拟机里,每个Docker的Container相当于传统虚拟机的一个进程。而共享的Volume则构成了进程之间共同访问的文件资源。与正常的DockerContainer一样,Pod的生命周期,相对于整个集群来说是不持久的。同时,Pod给Kubernetes提供了一个程序上的解耦,因为Kubernetes底层是面向容器的,但不一定是只支持Docker的。因此,为了与Docker解除绑定,也为了能定义一个更准确的逻辑模型,Kubernetes启用了Pod的概念。在Pod被引入之前,我曾经尝试过在一个DockerContainer同时启用多个应用。但是后来发现这样做有其固有的缺陷:多个应用同时部署在一个DockerContainer之中,会增加不必要的软件的依赖,每当其中某个依赖的软件进行变更的时候,便不得不重建整个DockerContainer。而当DockerContainer的数量、大小达到一定规模的时候,这样做无疑会带来巨量的系统负担。用户不必运行自己的进程管理程序,多个进程之间也无需考虑进程信号量或退出码扩散等问题。将多个应用部署到同一个容器之中,将不可避免的加重容器,这里所说的加重是从启动时间、监控难度、调度难度等多个方面来考量的。图2-SEQ图片1-\*ARABIC3Pod结构图而引入Pod带来的了两点显著的改善:资源共享和容器通信Pod的引入将多个不同的为多个DockerContainer之间划分了一个界限,同一个Pod内部的容器共享同样的networknamespace、IP已经端口资源,能通过UDS进行通信。在这样一个扁平化的虚网络里,每一个Pod都有拥有其独立的IP地址,通过该IP地址,Pod之内的容器就能正常的与其他Minion、逻辑虚拟机、或者容器进行直接通信。同样的,共享存储卷(Volume)的存在,方便了同一个Pod之内的各个容器进行共享数据,以及避免了数据在容器的重建重启等过程中的丢失,保证了数据的一致性和安全性。易于管理和原生的DockerAPI不同,Kubernetes对底层的API进行封装和抽象,提供了一个方便而简易的接口,基本上所有的操作都可以通过一个JSON(YAML)文件来定义,简化了应用部署和管理的流程。Pod可以看成是管理和扩容的基本单位,这样,Docker容器的逻辑划分,Fate-Sharing参照Wikipade:/wiki/Fate-sharing,拷贝协同,主机管理,资源参照Wikipade:/wiki/Fate-sharing作为调度的基本单位,Kubernetes保证在整个系统里,Pod的数量都是恒定的,和Pod创建的时候给定的参数相同。当然,类似的,用户也可以动态的调整Pod的数量,这个过程完全是由Kubernetes自动调度完成的。当然,Pod的生命周期相对于集群来说是短暂的。他的行为被ReplicationController所驱动。那么,Pod是何时被创建,销毁,迁移是无法预测到的,每当给Pod绑定一个IP地址时候。用户是无法确定这个IP可以被持久的,持续的访问。即,对应的IP地址和端口是否还能存在。为了解决这个问题,Kubernetes引入了Services的概念。2.2.2Service与Pod相对,Service对应的是对外的概念。整个集群可以抽象成多个不同的服务,而每个服务则由一定数量的Pod组成。目前的Kubernetes采用的是iptables的nat网桥转发的功能实现的这个转发。生成kube-proxy的数据流,连接api-server和client上kube-proxy绑定的随机端口。对于集群的使用者来说,链接的就是Kubernetes的Service所提供的虚拟IP和端口,而其内部采用轮询或者随机访问的算法来平衡各个Pod之间的压力。2.2.3ReplicationControllerReplicationController是Kubernetes集群最有用的功能,它保证Kubernetes的集群里总能保持正确数量的Pod。在互联网环境下,为了保证服务的高可用性,服务提供者总是提供一通数量的的可执行的副本来提供服务。而当集群里副本数量低于规定值时,ReplicationController会从模板中创建或者直接复制现有Pod来创建出新的Pod。而且一旦创建Pod完毕之后,再修改模板并不会改变已经生成的Pod。同样的,对于过多的Pod出现的情况,ReplicationController会杀死过多的Pod,以维持整个集群的资源。在正常情况下,即使你的应用只用到一个Pod,Kubernetes也推荐你使用ReplicationController,这主要是因为ReplicationController会根据Pod的存活状态自动的进行容器的重启或者迁移。这样,便能最大程度的减少因为某个Pod异常退出而导致的服务不可用的情况,提高应用的容灾能力。Replication和Pod之间的关联,主要通过存储在Label的信息来维持。同样的,用户可以通过修改Label来动态的扩展Pod的数量。这在大规模部署上线的时候非常重要。省去了大量的部署脚本,同时也略过了复杂而缓慢的部署脚本。一切自动运行。2.2.4LabelLabel是用于区分和关联Pod、Service和ReplicationController的键值对,每一个Pod、Service、ReplicationController可以有多个不同的键值对,但是每个key只能对应一个value。Label的设计,使得Service能正常的将请求转发致多个Pod之中;同样的,多个Label共存的设计,可以让ReplicationController很容易的控制Pod的生成,启动和销毁。Kubernetes通过一个简单的LabelSelector机制,对Label进行字符串过滤和筛选,来解除各个组件之间的耦合,达到一个松散的状态。可以说Label(Selector)才是Kubernetes系统的核心。正因如此,纵观整个Kubernetes系统,可以发现只有Label要求了集群的强一致性,其他的组件并没有强制要求,或者有着一定的延时。而存储Label的etcd系统,正是一个强一致性的集群存储系统。

第3章详细设计3.1Master节点Master节点主要包含了KubernetesMaster/APIServer的主要注册机和声明生命,包括Pod,Controller,Service,EndPoint,Minion,Binding的Registry,以及一个RESTful的分布式存储系统。整个程序是Kubernetes控制程序、管理Kubernetes的主要构件Pod、Service、ReplicationController是容器的最开始入口。3.2Kubectlkubectl是Kubernetes自带的控制程序,通过kubectl可以和集群进行动态的交互和管理。kubectl被设计来动态的管理集群,可以动态的创建、启动、连接Pod和Service;并且查询集群的状态,包括各个Pod的状态,各个Minion的状态;启动和停止某个服务,并且动态的Bind某个服务到某个Pod模板上,这样就相当于新启动了一个服务。需要清楚的是,在旧Kubernetes0.7版本的Kubernetes之中前,一直是由一个叫kubecfg的入口来控制的,而现在是kubectl。同样的,其运作方式也发生了巨大的变化,如图3-1。从图中可以看到,kubecfg通过发送请求到一个叫kube-client的程序,并由kube-client转发致APIServer,其优点是可以将kube-client从Master上拆分出来,让master的逻辑更为纯粹。但随着集群功能的增加,APIServer/Client的设计实际上冗余了两套API,为了消除这个不必要的冗余。Kubernetes将kubecfg取消,并编写了一套kubectl来与APIServer直接连接。3.3APIServerKubernetes的Master上维持着一个RESTful的Storage,被称为APIServerStorage,整个Storage通过etcd实现,主要存储的各种不同类型的lable,还有少量的集群总体信息,如图3-1所示。图3-1kubectl和kubecfg工作模式图图3-2APIServer组件图3.3.1MinionRegistryMinionRegistry负责跟集群中交互确认有多少个Minion,Kubernetes通过封装Minion的Label来实现APIServer的中/minion部分的RESTfulAPI。通过这些API,用户可以对MinionRegistry进行Create,Get,List,Delete等操作(对应增删改查中的CRD操作)。同样的,因为是Minion,主机实体不支持Update操作,只能进行创建或者删除。最后,MinionRegistry将Minion的信息存储到etcd集群。另外,kubelet会收集Minion的各种资源容量信息,并分析。而Master上的调度算法则会根据MinionRegistry维持的这些资源信息来考虑是否在这个节点上新建Pod。需要注意的是,当集群资源不足的时候,调度算法会自动忽略容量信息,而采取一种平衡的算法将Pod公平的平均分发至不同的Minion上,所以,保证集群机器性能类似或者相差不大是一个很好的做法。3.3.2PodRegistryPodRegistry负责统计跟踪集群中有多少Pod的运行信息,以及这些Pod和Minion的映射关系。同时,PodRegistry将自己和CloudProvider的信息及其他运行时信息封装成以上类似的RESTful接口,

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

最新文档

评论

0/150

提交评论