docker容器虚拟化技术

by shota jolbordi

通过Shota Jolbordi

Docker has been a buzzword for tech people for the last several years, and the more times goes by, the more often you hear about it. We’re seeing it more in job requirements, and more companies are starting to incorporate it. Nowadays it feels like it’s something so basic and common in the development world that if you don’t know about it, you are behind everybody else.

在过去的几年中,Docker一直是技术人员的流行语,并且流逝的时间越多,您听到它的频率就越高。 我们在工作要求中看到了更多,并且越来越多的公司开始将其纳入。 如今,感觉就像是开发世界中如此基本和普遍的事物,如果您不了解它,那么您将落后于其他所有人。

No, but seriously, what is this “Docker” thing? Why is everybody so excited about it? What is it even? Can you define it? is this a desktop app? CLI tool? a website? service? is this thing for production or is it a dev tool? Both? I’ve heard it has these things like “images” and “containers” and it’s like a virtual machine but not really a virtual machine. Why do I even need it, and what does all of this have to do with this blue whale after all?

不,但是说真的,这个“ Docker”是什么? 为什么每个人都对此感到兴奋? 什至是什么? 你能定义吗? 这是桌面应用吗? CLI工具? 一个网站? 服务? 这是用于生产还是开发工具? 都? 我听说它具有“图像”和“容器”之类的东西,它就像一台虚拟机,但实际上不是虚拟机。 为什么我甚至需要它,而这一切与这条蓝鲸到底有什么关系呢?

In this article I’ll try to explain:

在本文中,我将尝试解释:

  • what exactly is “docker”到底是什么“码头工人”
  • why you might need it为什么你可能需要它
  • which problems is it trying to solve它试图解决哪些问题
  • how is it different from a virtual machine与虚拟机有何不同
  • when to use it over a virtual machine and vice versa何时在虚拟机上使用它,反之亦然
  • what are images and containers in general什么是图像和容器
  • and how they are implemented in docker.以及它们如何在docker中实现。

I’m going to go through all the concepts in a specific order so that every other topic I explain will require an understanding of the previous concepts. However, while reading this, if you don’t get something, or something feels vague, just keep reading, it will all make sense in the end. My advice about this article would be to read it 2 times to have your “aha moments”.

我将按特定顺序浏览所有概念,以便我解释的所有其他主题都需要对先前的概念有所了解。 但是,在阅读本文时,如果您听不懂任何东西,或者感到有些含糊,只需继续阅读,最终一切都会有意义。 我对本文的建议是,请阅读两次以获取您的“啊哈时刻”。

Okay enough with that, let’s get started!

好的,让我们开始吧!

什么是Docker? (What is Docker?)

There are many “docker” names you might hear throughout the internet, and for a newbie it might be overwhelming. Let’s take a moment and define some of those names to at least know which one is which.

您可能会在整个互联网上听到很多“码头工人”的名字,对于一个新手来说,它可能会让人不知所措。 让我们花点时间定义其中一些名称,至少知道哪个是哪个。

  • Docker, IncDocker公司
  • docker engine (community / enterprise )docker引擎(社区/企业)
  • docker for MacMac版docker
  • docker for windowsWindows的docker
  • docker client码头客户
  • docker host码头工人主机
  • docker server码头工人服务器
  • docker hub码头工人中心
  • docker registry码头工人注册表
  • docker compose码头工人撰写
  • docker swarm码头工人
  • docker machine码头工人机器
  • docker daemon码头工人守护进程

Quite a lot of dockers here, huh? I’m going to give you a short definition for each of the terms here so you know what they are.

这里有很多码头工人,对吗? 在这里,我将为您简要定义每个术语,以便您了解它们的含义。

Docker(公司) (Docker (company))

Docker, Inc was co-founded in 2010 by Solomon Hykes (CTO) in San Francisco, and at that time it was called dotCloud, Inc. They’ve been running a PaaS (platform as a service) type of business, similar to Heroku. To implement this they’ve been using Linux containers.

Docker,Inc由Solomon Hykes(CTO)于2010年在旧金山共同创立,当时称为dotCloud,Inc 。 他们一直在运行PaaS(平台即服务)类型的业务,类似于Heroku 。 为了实现这一点,他们一直在使用Linux容器。

In March of 2013 at PyCon, Solomon revealed a new product by dotCloud, Inc called “docker”. The motivation as he describes it in his talk (the first ever talk where docker was mentioned) was that people have been very interested in Linux containers and how they could build something with them, but the problem was that Linux containers were very complicated. At dotCloud, Inc they decided to simplify usage of Linux containers and make them accessible for everybody, so the software “docker” was born.

2013年3月,所罗门在PyCon上展示了dotCloud,Inc的新产品“ docker ”。 他在演讲中 (第一次提到docker的地方)描述的动机是,人们对Linux容器以及如何使用它们构建东西非常感兴趣,但是问题是Linux容器非常复杂。 在dotCloud,Inc,他们决定简化Linux容器的使用并使每个人都可以使用它们,因此诞生了“ docker”软件。

Later in 2013, dotCloud, Inc announced that they were changing their name to Docker, inc and their primary product from now on would be “docker” (software). They spun off their PaaS business to another company and the rest is history.

2013年下半年dotCloud,Inc宣布将其名称更改为Docker,inc ,从现在开始,他们的主要产品将是“ docker”(软件)。 他们将PaaS业务剥离给了另一家公司,剩下的就是历史了。

For us, we are primarily interested in docker software, not in the company itself, but I think it’s good to know a little bit of history behind it.

对于我们来说,我们主要是对docker软件感兴趣,而不是对公司本身感兴趣,但是我认为了解其背后的一些历史很好。

Docker(软件) (Docker (software))

Docker is available in 2 editions: Docker community edition (CE) and Docker enterprise edition (EE). For development environment and small teams, CE is the way to go, so in this article we won’t cover EE. CE is free and EE is how Docker, Inc actually makes money.

Docker有2个版本:Docker社区版(CE)和Docker企业版(EE)。 对于开发环境和小型团队,CE是必经之路,因此在本文中,我们将不介绍EE。 CE是免费的,而EE是Docker,Inc实际赚钱的方式。

Docker software consists of 2 separate programs, that is docker engine, also known as docker daemon (because it is, in fact, a daemon, running in the background ) and docker client.

Docker软件包含2个单独的程序,即docker engine,也称为docker daemon(因为实际上是后台运行的daemon)和docker client。

引擎/守护进程 (Engine / Daemon)

Docker engine is what actually enables Linux containers to work — it’s the “brain of docker” so to speak.

Docker引擎实际上是使Linux容器能够工作的要素-可以这么说,它是“ docker的大脑”。

Docker engine is responsible for running processes in isolated environments. For each process, it generates a new Linux container, allocates a new filesystem for it, allocates a network interface, sets an IP for it, sets NAT for it and then runs processes inside of it.

Docker引擎负责在隔离的环境中运行进程。 对于每个进程,它都会生成一个新的Linux容器,为其分配一个新的文件系统,分配一个网络接口,为其设置一个IP,为其设置NAT,然后在其中运行进程。

It also manages such things as creating, removing images, fetching images from the registry of choice, creating, restarting, removing containers and many other things. Docker engine exposes the rest API which can be used to control the daemon.

它还管理诸如创建,删除映像,从选择的注册表中获取映像,创建,重新启动,删除容器之类的事情。 Docker引擎公开了可用于控制守护程序的其余API。

客户 (Client)

Docker client provides the CLI to control docker daemon. It’s just an HTTP API wrapper. Basically, docker client sends API requests to docker engine which in itself actually does all the magic. Docker client and daemon don’t have to be on the same machine. You can access the CLI with the docker command from the terminal.

Docker客户端提供CLI来控制docker守护程序。 这只是一个HTTP API包装器。 基本上,泊坞窗客户端将API请求发送到泊坞窗引擎,而泊坞窗引擎实际上完成了所有操作。 Docker客户端和守护程序不必位于同一台机器上。 您可以从终端使用docker命令访问CLI。

主办 (Host)

Docker host is a computer that has docker daemon running on it. Sometimes it’s also called docker server.

Docker主机是一台运行docker守护程序的计算机。 有时也称为docker服务器。

枢纽 (Hub)

Docker hub is a docker image registry provided by Docker, Inc itself. It enables users to push images to their repository, make them public or private, and pull different images, all using the docker client CLI.

Docker Hub是Docker,Inc本身提供的Docker映像注册表。 它使用户可以使用Docker客户端CLI将映像推送到其存储库,将其设置为公共或私有,以及拉取不同的映像。

There are images for pretty much everything made by other people or companies, every language, every database, every version of it. It’s like GitHub for docker images. There are Docker image registries available by other companies, such as Quay, Google container registry, and Amazon Elastic Container Registry. Alternatively, you can host your own docker registry.

几乎有其他人或公司制作的所有图像,每种语言,每种数据库以及每种版本的图像。 就像GitHub上的docker镜像一样。 其他公司也提供Docker映像注册表,例如Quay , Google容器注册表和Amazon Elastic Container Registry 。 或者,您可以托管自己的Docker注册表。

登记处 (Registry)

Docker registry is a server-side application that allows you to host your own docker repository. It is provided in the form of an image hosted on docker hub. To make it work you need to pull an image called “registry” from docker hub and spin up the container from it. A Docker host running a “registry” container is now a registry server.

Docker注册表是一个服务器端应用程序,可让您托管自己的Docker存储库。 它以托管在docker hub上的映像的形式提供。 为了使其正常工作,您需要从docker hub提取一个名为“ registry”的映像,并从中旋转容器。 运行“注册表”容器的Docker主机现在是注册表服务器。

对于Mac (For Mac)

Docker for Mac is a separate software from docker, provided by Docker, Inc, that simplifies development with docker on Mac OS. The package includes docker client, the full-blown virtual machine running on Mac OS’s native HyperKit hypervisor, docker daemon installed inside this machine, docker-compose and docker-machine orchestration tools. The container’s exposed ports are forwarded from the VM to localhost automatically.

Docker for Mac是由Docker,Inc提供的与docker分离的独立软件,可简化在Mac OS上使用docker进行的开发。 该软件包包括docker客户端,在Mac OS的本地HyperKit虚拟机管理程序上运行的功能完善的虚拟机,安装在该计算机内部的docker守护程序,docker-compose和docker-machine Orchestration工具。 容器的公开端口会自动从VM转发到localhost。

对于Windows (For Windows)

Docker for Windows is same configured specifically for Windows. It uses Hyper-v (Windows 10’s native virtualization solution) for its virtualization software and also gives you the ability to run windows containers alongside Linux containers.

Windows的Docker与Windows专用的配置相同。 它为其虚拟化软件使用Hyper-v(Windows 10的本机虚拟化解决方案),还使您能够与Linux容器一起运行Windows容器。

机 (Machine)

Docker machine is an orchestration tool that allows you to manage multiple docker hosts. It lets you provision multiple virtual docker hosts locally, or on the cloud, and manage them with docker-machine commands. You can start, restart, and inspect managed hosts. You can point docker client to one of the hosts and then manage daemon on that host directly. There are many ways you can manage docker hosts with this tool, just have a look at the CLI reference.

Docker机器是一个编排工具,可让您管理多个Docker主机。 它使您可以在本地或在云上配置多个虚拟Docker主机,并使用docker-machine命令对其进行管理。 您可以启动,重新启动和检查托管主机。 您可以将Docker客户端指向主机之一,然后直接在该主机上管理守护程序。 您可以通过多种方法使用此工具管理Docker主机,只需查看CLI 参考即可 。

撰写 (Compose)

Docker compose is also an orchestration tool for docker. It allows you to easily manage multiple containers dependent on each other within one docker host via docker-compose CLI. You use a YAML file to configure all the containers. With one command you can start all containers in the correct order and set up networking between them. Here is the reference.

Docker compose还是docker的编排工具。 它使您可以通过docker-compose CLI在一个docker主机中轻松管理彼此依赖的多个容器。 您使用YAML文件来配置所有容器。 使用一个命令,您可以按正确的顺序启动所有容器并在它们之间建立网络。 这是参考 。

一群 (Swarm)

Docker swarm is another orchestration tool aimed to manage a cluster of docker hosts. While docker-compose managers multiple Docker containers within one docker host, docker swarm manages multiple docker hosts managing multiple Docker containers.

Docker swarm是另一个旨在管理docker主机集群的编排工具。 当docker-compose manager在一个docker主机中包含多个Docker容器时,docker swarm管理多个docker主机,从而管理多个Docker容器。

Unlike docker-compose and docker-machine, docker swarm is not a standalone orchestration software. Swarm mode is built in docker engine and is managed through Docker client.

与docker-compose和docker-machine不同,docker swarm不是独立的编排软件。 Swarm模式内置在Docker引擎中,并通过Docker客户端进行管理。

In order to create a swarm you need to ssh into a machine you intend to make into a swarm and docker swarm init --advertise-addr <ip to publish>. This command will make a machine accessible on <ip to publish>. Other docker hosts can now join the swarm on this IP.

为了创建群集,您需要将ssh放入要放入群集的计算机,然后将docker swarm init --advertise-addr <ip to publi sh>放入群集。 此命令将使计算机可访问le on <ip to publish>。 现在,其他Docker主机可以加入该IP上的群。

摘要 (Summary)

Okay, so what did we learn so far?

好的,到目前为止我们学到了什么?

Docker is not a standalone software, it’s a platform for managing Linux containers. Whenever someone mentions docker in the context of software, they are talking about docker CE or docker EE.

Docker不是一个独立的软件,它是一个用于管理Linux容器的平台。 每当有人在软件上下文中提及docker时,他们都在谈论docker CE或docker EE。

Docker is developed by Docker, Inc to simplify the usage of Linux containers. The platform consists of multiple tools for running and managing Linux containers, which include:

Docker由Docker,Inc.开发以简化Linux容器的使用。 该平台包含用于运行和管理Linux容器的多种工具,其中包括:

  • Docker daemon/engine that is responsible for generation and running of Linux containers.Docker守护程序/引擎,负责生成和运行Linux容器。
  • Docker client that is a separate application which controls docker daemon through the REST API.Docker客户端是一个单独的应用程序,可通过REST API控制Docker守护程序。
  • Docker-compose, docker-machine, and docker swarm are orchestration tools, they are not necessary for running processes inside Linux containers, but they make container management very simple. To be frank, in real life scenarios they are pretty much a necessity, because managing all those containers, hosts and clusters of hosts manually is…well, let’s say it’s a bad business strategy.Docker-compose,docker-machine和docker swarm是编排工具,它们对于在Linux容器内运行进程不是必需的,但是它们使容器管理非常简单。 坦率地说,在现实生活中,它们是非常有必要的,因为手动管理所有这些容器,主机和主机集群是……嗯,我们说这是一个糟糕的业务策略。
  • Docker hub is a service that provides a registry of docker images. We can store our images on the docker hub and pull images made by others for us to use.Docker Hub是一项提供Docker映像注册表的服务。 我们可以将图像存储在docker hub上,并提取其他人制作的图像供我们使用。
  • Docker registry allows us to host our own private registry in case we don’t want to use an existing one.Docker注册表允许我们托管自己的私有注册表,以防我们不想使用现有的私有注册表。
  • Docker for Mac and Docker for Windows are separate tools that simplify developing with docker on Mac or Windows.Docker for Mac和Docker for Windows是单独的工具,可简化在Mac或Windows上使用Docker进行开发。

If you are a beginner, it’s ok if you don’t understand everything mentioned above 100%. Some things might be vague, you might have some questions, and that’s normal. I did mention images and containers multiple times but did not explain what they are.

如果您是初学者,也可以100%不理解上面提到的所有内容。 有些事情可能含糊不清,您可能有一些疑问,这很正常。 我确实多次提到图像和容器,但没有解释它们是什么。

This section is intended to help you navigate between all those names, remove uncertainty, and understand what is what so you don’t get overwhelmed when hearing all those different “docker <insert text>” type of titles.

本节旨在帮助您在所有这些名称之间导航,消除不确定性并了解什么,以便在听到所有这些不同的“ docker <插入文本>”类型的标题时不会感到不知所措。

With this sad, I think based on what we’ve learned so far, you should be able to more or less understand the following picture:

带着这种悲伤,我认为根据我们到目前为止所学的知识,您应该或多或少地了解以下情况:

As you can see, docker client and docker daemon are on different machines here, so this might answer some of your questions like…

如您所见,docker客户端和docker守护程序位于不同的计算机上,因此这可能会回答您的一些问题,例如…

Why did they split docker into client and engine? Why did not they make it so that CLI would control the engine directly instead of the rest API

他们为什么将docker分为客户端和引擎? 他们为什么不这样做,以便CLI可以直接控制引擎而不是其余的API

Well because it allows having the client and engine on different machines, so multiple different hosts can be managed from one computer.

好吧,因为它允许客户端和引擎位于不同的计算机上,所以可以从一台计算机管理多个不同的主机。

With all those things clarified, we can dive deeper.

在澄清了所有这些内容之后,我们可以进一步深入研究。

虚拟机 (Virtual Machines)

Hey, hey, wait a minute — are we talking about docker here or what?

嘿,等等,我们在这里谈论码头工人还是什么?

Yes, we are, however at some point in learning docker a natural question will emerge:

是的,我们是,但是在学习docker的某个时候,自然会出现一个问题:

What is the difference between VMs and Containers, and why would I use one over another?

VM和容器之间有什么区别,为什么我要一个又一个地使用?

Everybody who learns docker goes through this, and I think we might as well go through it now and get it out of the way.

每个学习docker的人都会经历这一过程,我认为我们不妨现在就通过它并摆脱它。

There is a lot out there about how virtual machines work under the hood. We can’t go over all the details in this article, but I will explain just enough so that you understand the difference between VM’s and Containers.

关于虚拟机如何在后台运行,有很多内容。 我们无法详细介绍本文中的所有详细信息,但我将仅作足够的解释,以便您了解VM与容器之间的区别。

Every computer, ever, be it the gigantic web server running Linux or your overpriced iPhone X, has 4 essential physical components:

每台计算机,无论是运行Linux的巨型网络服务器还是价格过高的iPhone X,都具有4个基本物理组件:

  • Processor (CPU),处理器(CPU),
  • Memory (RAM),内存(RAM),
  • Storage (HDD / SSD),存储(HDD / SSD)
  • The network card (NIC).网卡(NIC)。

The main task of any operating system is to basically manage those 4 resources. The part of the operating system that does this is called the Kernel, also referred to as the Core.

任何操作系统的主要任务是基本管理这4个资源。 操作系统中执行此操作的部分称为内核,也称为核心。

The kernel, simply put, is a part of the OS that controls the hardware. The kernel controls drivers for different IO devices such as a mouse, keyboard, headphones, microphone…etc. The kernel is the first program loaded when the computer is turned on, right after the bootloader, and then it handles the rest of the startup process. An absolute majority of the time that it takes to turn on the computer, is because of the Kernel.

简而言之,内核是控制硬件的操作系统的一部分。 内核控制用于不同IO设备的驱动程序,例如鼠标,键盘,耳机,麦克风等。 内核是启动计算机后紧接引导加载程序之后加载的第一个程序,然后它将处理其余的启动过程。 开机绝对是因为内核。

Each operating systems has its own implementation of the kernel, but in fact they do all the same thing: they control the hardware.

每个操作系统都有自己的内核实现,但实际上它们都做同样的事情:它们控制硬件。

So how is it possible to run one OS inside another? Essentially what we need is a program that enables the Guest OS (the operating system that is running inside another operating system) to control the hardware of the Host OS (an operating system that has a guest OS running inside of it).

那么如何在一个OS中运行另一个OS? 本质上,我们需要一个程序,该程序使Guest OS(在另一个操作系统内运行的操作系统)能够控制Host OS(在其中运行来宾OS的操作系统)的硬件。

管理程序 (Hypervisor)

The hypervisor, also referred to as Virtual Machine Manager (VMM), is what enables virtualization (running several operating systems on one physical computer). It allows the host computer to share its resources between VMs.

虚拟机管理程序(也称为虚拟机管理器(VMM))可以实现虚拟化(在一台物理计算机上运行多个操作系统)。 它允许主机在VM之间共享其资源。

There are 2 types of Hypervisors:

虚拟机管理程序有两种类型:

Type 1, also called “Bare Metal Hypervisor”

类型1,也称为“裸机管理程序”

This software is installed right on top of the underlying machine’s hardware (so, in this case, there is no Host OS, there are only Guest OS’s). You would do this on a machine on which the whole purpose was to run many virtual machines.

该软件直接安装在基础计算机的硬件之上(因此,在这种情况下,没有主机OS,只有来宾OS)。 您将在一台旨在运行许多虚拟机的计算机上执行此操作。

Type 1 hypervisors have their own device drivers and interact with hardware directly unlike type 2 hypervisors. That’s what makes them faster, simpler and hence more stable.

与2型虚拟机管理程序不同,1型虚拟机管理程序具有自己的设备驱动程序并直接与硬件交互。 这就是使它们更快,更简单,因此更稳定的原因。

Type 2, also called “Hosted Hypervisor”

类型2,也称为“托管管理程序”

This is a program that is installed on top of the operating system. You are probably more familiar with it, like VirtualBox or VMware Workstation. This type of hypervisor is something like a “translator” that translates the guest operating system’s system calls into the host operating system’s system calls.

这是安装在操作系统顶部的程序。 您可能更熟悉它,例如VirtualBox或VMware Workstation。 这种类型的管理程序类似于“翻译器”,可将来宾操作系统的系统调用转换为主机操作系统的系统调用。

The system calls (syscalls) are a way in which a program requests a service from a Kernel, and the Kernel does — remember what? It manages underlying hardware.

系统调用(syscalls)是程序从内核请求服务的一种方式,而内核可以–记得吗? 它管理底层硬件。

For example, in your program, say you want to copy the content of one file into another. Pretty straightforward right? For this, you need to take some bytes from one part of your Hard Disk and put them into another part. So basically, you are doing stuff with a physical resource, the Hard Disk in this example, and you would need to initiate a system call to do this. Of course in all programming languages, this is abstracted away from you, but you get the point.

例如,在您的程序中,说您想将一个文件的内容复制到另一个文件中。 很简单吧? 为此,您需要从硬盘的一部分中取出一些字节,然后将它们放入另一部分中。 因此,基本上,您正在使用物理资源(在此示例中为硬盘)做事,并且您需要启动系统调用才能执行此操作。 当然,在所有编程语言中,这都是抽象的,但是您明白了。

Since all OS Kernels, despite being implemented in different ways, do the same job (control hardware), we just need a program that will “translate” a guest OS’s system calls to control the hardware.

由于所有OS内核尽管以不同的方式实现,但都执行相同的工作(控制硬件),所以我们只需要一个可以“转换”来宾OS的系统调用来控制硬件的程序。

An upside of a Type 2 hypervisor is that in this case we don’t have to worry about underlying hardware and it’s drivers. We really just need to delegate the job to the host OS, which will manage this stuff for us. The downside is that it creates a resource overhead, and multiple layers sitting on top of each other make things complicated and lowers the performance.

Type 2虚拟机管理程序的一个优点是,在这种情况下,我们不必担心底层硬件及其驱动程序。 我们真的只需要将作业委派给主机OS,主机OS将为我们管理这些工作。 缺点是,这会造成资源开销,并且彼此叠置的多层会使事情变得复杂,并降低性能。

货柜 (Containers)

Virtual machines are not the only virtualization technique. In the case of a virtual machine, we have a full-blown virtual computer, in its entirety, with its own dedicated Kernel. We allocate RAM for it, we allocate memory for it, and we interact with it as if it was a standalone computer.

虚拟机不是唯一的虚拟化技术。 对于虚拟机,我们拥有完整的功能完善的虚拟机,并拥有自己的专用内核。 我们为其分配RAM,为其分配内存,并与之交互,就好像它是一台独立的计算机一样。

There are several problems with this. First and most obvious is inefficient resource management. Once you allocate some resources for a VM, it’s going to hold onto them as long as it’s running.

这有几个问题。 首先也是最明显的是资源管理效率低下。 为VM分配了一些资源后,只要它正在运行,它就将保留这些资源。

For example: if you allocate 4 GB of RAM and 40GB of disk memory for a VM, once you run it, those resources will be unavailable as long as this VM is running. It might only need 1 GB of RAM at some moment, and you might be lacking RAM for some other process in another VM or host machine. But since it has this amount of RAM allocated, it’s just going to sit there unused.

例如:如果为VM分配4 GB的RAM和40GB的磁盘内存,则一旦运行它,只要此VM正在运行,这些资源将不可用。 有时可能只需要1 GB的RAM,并且另一台VM或主机中的其他进程可能缺少RAM。 但是,由于它已分配了此数量的RAM,因此它将被闲置。

Another problem is boot up time. Since the VM has its own Kernel, in case you need to restart your machine, it will need to boot up an entire Kernel. While the machine is rebooting, your service that was running in VM will be unavailable.

另一个问题是启动时间。 由于VM具有自己的内核,因此如果您需要重新启动计算机,则它将需要启动整个内核。 重新引导计算机时,在VM中运行的服务将不可用。

救援容器 (Containers to the rescue)

To put it simply, a container is a virtual machine without a Kernel. Instead, it is using the Kernel of a host operating system. To make this possible, we need a set of software and libraries that will allow containers to use the underlying OS Kernel, and sort of “link” them if you wish. Such libraries are, for example, “liblxc” and “libcontainer” (this last one is developed by Docker, Inc and is used inside docker engine).

简而言之,容器是没有内核的虚拟机。 而是使用主机操作系统的内核。 为了使之成为可能,我们需要一套软件和库,这些软件和库将允许容器使用底层的OS内核,并根据需要对它们进行“链接”。 此类库例如是“ liblxc”和“ libcontainer”(后一个库是由Docker,Inc开发的并在docker引擎内部使用)。

Containers have their own allocated filesystem and IP. Libraries, binaries, services are installed inside a container, however, all the system calls and Kernel functionality comes from the underlying host OS.

容器具有自己分配的文件系统和IP。 库,二进制文件,服务安装在容器内,但是,所有系统调用和内核功能都来自底层主机OS。

Containers are very lightweight. Boot up and restart happens very fast because they don’t need to start up the Kernel every time. They don’t waste physical resources since they don’t need them to be allocated for their Kernel, as they don’t have a separate Kernel.

容器非常轻巧。 引导和重新启动非常快速,因为它们不需要每次都启动内核。 他们不需要浪费物理资源,因为他们不需要为内核分配资源,因为他们没有单独的内核。

One drawback is that it’s only possible to run containers of the same type as the underlying OS. You can’t run Linux containers on Windows or Mac, because they need Linux Kennel to operate. The solution for Mac and Windows users would be to install a type 2 hypervisor such as VirtualBox or WMware Workstation, boot up the Linux machine, and then run Linux containers inside of it (in fact that’s what Docker for Mac and Docker for Windows do, but they use native hypervisors that come with the respective OS).

一个缺点是只能运行与基础操作系统相同类型的容器。 您不能在Windows或Mac上运行Linux容器,因为它们需要Linux Kennel才能运行。 针对Mac和Windows用户的解决方案是安装第2类管理程序,例如VirtualBox或WMware Workstation,启动Linux计算机,然后在其中运行Linux容器(实际上,这是Mac的Docker和Windows的Docker所做的,但它们使用的是各自操作系统随附的本机虚拟机管理程序。

Setting up and running Linux containers is not that straightforward. It’s troublesome and requires a decent knowledge of Linux. Managing them is even more tedious.

设置和运行Linux容器并不是那么简单。 这很麻烦,需要对Linux有一定的了解。 管理它们更加繁琐。

As I’ve mentioned above, what Docker, Inc does is it makes Linux containers easy to use and available to everybody, and you do not have to be a Linux geek to use Linux containers nowadays thanks to docker.

正如我上面提到的, Docker,Inc.所做的是使Linux容器易于使用并且所有人都可以使用,而且由于Docker,您现在不必成为Linux怪胎才能使用Linux容器。

容器VS虚拟机 (Containers VS Virtual Machines)

From the previous section about containers, you might think that containers are just better virtualization solutions than VM’s, but that’s not how it is.

在上一节有关容器的部分中,您可能会认为容器是比VM更好的虚拟化解决方案,但事实并非如此。

A container’s purpose is running processes in an isolated environment, for docker each container for every single process. VM’s are for emulating an entire machine. Nowadays only Linux and windows containers exist, but there are all kinds of hypervisors to emulate any kind of operating system. You can run windows 10 inside an iPad if you wish. Those 2 are different technologies and they don’t compete with each other.

容器的目的是在隔离的环境中运行进程,对于Docker每个容器来说,每个进程都是如此。 VM用于模拟整个计算机。 如今,仅存在Linux和Windows容器,但是有各种各样的虚拟机管理程序可以模拟任何类型的操作系统。 您可以根据需要在iPad上运行Windows 10。 那两种是不同的技术,彼此之间没有竞争。

VM’s are more secure, since containers make system calls directly to the Kernel. This opens up a whole verity of vulnerabilities.

由于容器直接向内核调用系统,因此VM更加安全。 这就打开了漏洞的全部真实性。

Some low-level software that messes with a Kernel directly should be sandboxed inside a virtual machine.

一些直接与内核混乱的低级软件应在虚拟机内部进行沙箱处理。

Often you can see docker containers running inside virtual machines in the production environment, so VM’s and containers actually stick together very well.

通常,您会看到docker容器在生产环境中的虚拟机中运行,因此VM与容器实际上很好地结合在一起。

Docker映像和容器 (Docker images and containers)

Docker introduces several concepts that simplify…or I would rather say revolutionize the usage of Linux Containers

Docker引入了一些简化的概念…或者我想说是彻底改变了Linux容器的使用

Linux containers in docker are made from templates called “images”. An image is a basically a binary file that holds the state of a Linux machine (without the Kernel of course). You can draw a parallel to VM’s disk images such as .vdi, .vmdk or .vhd files.

Docker中的Linux容器由称为“映像”的模板制成。 映像基本上是一个二进制文件,其中包含Linux机器的状态(当然没有内核)。 您可以绘制与VM的磁盘映像(例如.vdi.vmdk.vhd文件)平行的图形。

Docker’s approach to images is different from a VM’s. In a VM you would just mount a disk image, run the VM, and you would have a running instance of a machine. Whenever you modify filesystem in VM, install or remove anything, all of this is reflected on an image you’ve mounted. The image is basically the Hard Disk of the machine.

Docker的映像方法与VM的方法不同。 在虚拟机中,您只需挂载磁盘映像,运行虚拟机,然后您将拥有一台正在运行的计算机实例。 每当您在VM中修改文件系统,安装或删除任何内容时,所有这些都会反映在您已挂载的映像上。 该映像基本上是计算机的硬盘。

In docker, images are read-only — you don’t run images directly, instead, you make a copy of an image and run it. This running instance of an image is called a container. By doing this you can have several instances of the same Linux container running at the same time, made from the same template, that are images. Whatever happens with a container does not affect the image it was made from. You can make as many instances of a container from an image as your hardware allows you to run.

在docker中,图像是只读的-您不直接运行图像,而是创建图像的副本并运行它。 图像的此运行实例称为容器。 通过这样做,您可以使同一Linux容器的多个实例同时运行,它们是由同一模板制成的,它们是映像。 容器发生的任何情况均不会影响其制成的图像。 您可以从映像中创建尽可能多的容器实例,而您的硬件可以运行该实例。

通过Union Mount合并图像 (Merge images via Union Mount)

For creating and storing images, docker uses Union Filesystem. It’s a service in Linux, FreeBSD, and NetBSD. Union Filesystems allow us to create one filesystem out of multiple different ones by merging them all together. The content’s of directories that have the same path will be seen together in a single merged directory. The process of merging is called “union mounting”.

为了创建和存储图像,docker使用联合文件系统。 它是Linux,FreeBSD和NetBSD中的一项服务。 联合文件系统使我们可以通过将多个不同文件系统合并在一起来创建一个文件系统。 具有相同路径的目录的内容将在单个合并目录中一起显示。 合并的过程称为“联合安装”。

This is roughly how it works:

大致是这样的:

There are 3 layers that come into play: base layer, overlay, and diff layer.When merging 2 filesystems, the process looks something like this (keep in mind I’m oversimplifying here):

共有3个层:基础层,覆盖层和diff层。合并两个文件系统时,该过程看起来像这样(请注意,我在这里简化了):

So we have a base filesystem, and we want to introduce some changes, add files/folders, remove files/folders.

因此,我们有一个基本的文件系统,我们想进行一些更改,添加文件/文件夹,删除文件/文件夹。

First we will create an overlay filesystem (empty at this point ) and diff filesystem (also empty at this point ). Then we will union mount those filesystems using the union filesystem service built into Linux. When looking into the overlay filesystem it will give us the view of the base filesystem. We can add stuff to it, remove stuff from it, as the actual base filesystem will be unaffected. Instead all changes made to the overlay filesystem will be stored in the diff filesystem. The diff filesystem shows the difference between the base and overlay filesystems.

首先,我们将创建一个覆盖文件系统(此时为空)和diff文件系统(此时也为空)。 然后,我们将使用内置在Linux中的联合文件系统服务来联合挂载那些文件系统。 当查看覆盖文件系统时,它将为我们提供基本文件系统的视图。 我们可以向其中添加内容,也可以从中删除内容,因为实际的基本文件系统不会受到影响。 相反,对覆盖文件系统所做的所有更改都将存储在diff文件系统中。 diff文件系统显示了基本文件系统和覆盖文件系统之间的差异。

After we’re done editing the overlay filesystem, we will unmount it. In the end, we have the merged filesystem of overlay and base layers, and the actual base filesystem is unaffected.

编辑完覆盖文件系统后,我们将其卸载。 最后,我们有了覆盖层和基础层的合并文件系统,而实际的基础文件系统不受影响。

This is exactly how docker images are “stacked” on top of each other. Docker uses this exact technology to merge image filesystems.

这正是docker映像彼此“堆叠”的方式。 Docker使用这项精确的技术来合并映像文件系统。

In order to create your image on top of the already existing image, you need to touch Dockerfile. This is a text file with a set of instructions on how to build an image. Take a look at this simple example.

为了在现有映像之上创建映像,您需要touch Dockerfile 。 这是一个文本文件,其中包含有关如何构建图像的一组说明。 看一下这个简单的例子。

Inside the terminal run:

在终端内部运行:

docker build <path of the folder with Dockerfile in it>.

docker build <path of the folder with Dockerfile in >。

This command will build an image based on the instructions given in Dockerfile.

该命令将基于Dockerfile中给出的指令构建映像。

First line: FROM nodesource/trusty5.1

第一行: FROM nodesource/trusty5.1

This line indicates that the base layer of this image is another image called nodesource/trusty5.1. By default docker will first try to look for this image locally. If it’s not there it will pull this image from docker hub, or from another docker image registry on this matter. So you just need to configure docker client to look for images in another image registry.

此行指示此映像的基础层是另一个称为nodesource/trusty5.1 。 默认情况下,docker将首先尝试在本地查找该映像。 如果不存在,它将就此从docker hub或另一个docker image注册表中拉取该映像。 因此,您只需要配置Docker客户端即可在另一个映像注册表中查找映像。

Second line: WORKDIR /app

第二行: WORKDIR /app

This line tells docker that all the subsequent commands executed via RUN in Dockerfile will be executed from /app.

该行告诉docker在Dockerfile中通过RUN执行的所有后续命令将从/app执行。

Third line: ADD . /app

第三行: ADD . /app ADD . /app

This line tells docker which filesystems to merge on build. In this example, we see that the overlay layer is the current directory, relative to Dockerfile, and the base layer is /app inside nodesource/trusty5.1 (an image).The base filesystem’s sub filesystem /app will be merged with an overlay filesystem. If /app filesystem does not exist in the base layer, it will be created as an empty folder.

该行告诉docker在构建时要合并的文件系统。 在这个例子中,我们看到,所述覆盖层为当前目录,相对于Dockerfile,和基底层是/appnodesource/trusty5.1 (图像)。该碱的文件系统的文件系统的子/app将与覆盖合并文件系统。 如果/app文件系统在基础层中不存在,它将被创建为一个空文件夹。

RUN command will execute a command inside an image while building it via default shell /bin/shRUN <command>; === /bin/sh <;command>

RUN命令将在图像内部执行命令,同时通过默认shell /bin/sh构建它RUN <comma nd> ; === /bin/sh < ; === /bin/sh < ;命令>

EXPOSE command will serve as documentation for a user to see which port the application is using. It’s not necessary.

EXPOSE命令将作为文档供用户查看应用程序正在使用哪个端口。 这不是必需的。

CMD will run a command in a container that will be built from this image on startup.

CMD将在启动时从该映像构建的容器中运行命令。

In this example, nodesource/thrusty5.1 is an Ubuntu image with nodeJs 5.1 installed inside of it. Inside ./app directory relative to Dockerfile we have a nodeJs application. When merging them we’ll get an image of Ubuntu with nodeJs 5.1 installed in it and my application inside of it in the /app directory.

在此示例中, nodesource/thrusty5.1是Ubuntu映像,其中安装了nodeJs 5.1。 在相对于Dockerfile的./app目录中,我们有一个nodeJs应用程序。 合并它们时,我们将获得安装了nodeJs 5.1的Ubuntu映像,并在/app目录中包含我的应用/app

We can then spin up as many containers as we want from this template. Every container will execute npm start inside /app directory of a container on startup.

然后,我们可以根据需要从模板中旋转任意数量的容器。 每个容器在npm start都会在容器的/app目录内执行npm start

码头集装箱 (docker containers)

Docker containers, as you already know, are running copies of an image. One additional thing that docker does when creating a container from an image is that it adds a read-write filesystem over the image’s filesystem because the image’s filesystem is read-only.

如您所知,Docker容器正在运行映像的副本。 泊坞窗从映像创建容器时要做的另一件事是,由于映像的文件系统是只读的,因此它在映像的文件系统上添加了一个读写文件系统。

Docker containers are a bit different than usual Linux containers. Docker containers are made specifically to run a single process in an isolated environment of a Linux container. That’s why we have CMD in Dockerfile, which indicates which process is this going to be. The Docker container will be automatically terminated once there is no process running inside of it.

Docker容器与通常的Linux容器有些不同。 Docker容器专门用于在Linux容器的隔离环境中运行单个进程。 这就是为什么我们在Dockerfile中有CMD的原因,它指示了将要进行的过程。 一旦Docker容器内部没有进程运行,它将自动终止。

Docker containers are not supposed to maintain any state, so you can’t ssh into your docker container (well technically you can, but don’t). You should not have it running several processes at once, like, for example, the database and the app that use it. In this case, you would use 2 separate containers and make them communicate with each other. Docker containers are a specific use case of Linux containers to build loosely coupled stateless applications as services.

Docker容器不应保持任何状态,因此您不能将ssh放入Docker容器(从技术上讲可以,但不能)。 您不应该让它同时运行多个进程,例如,使用它的数据库和应用程序。 在这种情况下,您将使用2个单独的容器并使它们彼此通信。 Docker容器是Linux容器的一种特定用例,用于构建松耦合的无状态应用程序作为服务。

容器间通讯 (Inter-Container communication)

As I’ve mentioned above, every container should only be running one process. So perhaps now a natural question will emerge: if for example, my app is running in one container and the database is running in another, how do I connect from my app to a database that is running in another container? You can’t connect to localhost in this case.

如上所述,每个容器只能运行一个进程。 因此,现在也许会出现一个自然的问题: 例如,如果我的应用程序在一个容器中运行,而数据库在另一个容器中运行,如何将我的应用程序连接到在另一个容器中运行的数据库? 在这种情况下,您将无法连接到本地主机。

Docker introduced networking for standalone containers. A very high-level overview of network usage looks like this: you create a new network, which creates a subnet for this network alone. You start a container and attach it to this network, and all containers attached to the same network will be able to ping each other, as if they were on a LAN. Then you can connect from one service running in one container to a service running in another one, as long as they are on the same network.

Docker引入了用于独立容器的网络。 网络使用情况的高级概述如下所示:创建一个新网络,该网络将单独为此网络创建一个子网。 您启动一个容器并将其连接到该网络,所有连接到同一网络的容器将能够相互ping通,就像它们在LAN上一样。 然后,您可以从在一个容器中运行的一项服务连接到在另一个容器中运行的服务,只要它们在同一网络上即可。

Okay now, how does it look like?

好吧,现在看起来怎么样?

Run docker network create <some name>:

运行docker network create <some na me>:

You can list all available networks by running docker network list:

您可以通过运行docker network list列出所有可用的网络:

Run docker network inspect <network id or name> to see the network subnet and which containers are currently attached to it:

运行docker network inspect <network id or na me>以查看网络子网以及当前连接到哪个容器:

As you can see, it shows the network’s subnet, default getaway, and we also see there are no containers attached to it.

如您所见,它显示了网络的子网,默认逃脱,并且我们还看到没有附加容器。

Now I’m going to create 2 containers, from 2 different images, nodejsapi, mongo and run them. --net options indicate which network to use:

现在,我将根据2个不同的图像( nodejsapimongo创建2个容器并运行它们。 --net选项指示要使用的网络:

docker run <image name> creates a container from an image and starts it. Now I’ll inspect the network again:

docker run <image na me>从图像创建一个容器并启动它。 现在,我将再次检查网络:

As you now can see 2 containers are running attached to this network. We can also see the IP’s they are using and that they are running on the same subnet. I should be able to ping one container from another now.

如您现在所见,有2个容器正在运行并连接到该网络。 我们还可以看到它们正在使用的IP,它们正在同一子网中运行。 我现在应该可以从另一个容器ping一个容器。

Let’s get an IP of one of the running containers:

让我们获取一个正在运行的容器的IP:

Here I’ve executed the ifconfig command inside a container with id 8d3aaca5750f and redirected output to my terminal.

在这里,我在ID为8d3aaca5750f的容器内执行了ifconfig命令,并将输出重定向到我的终端。

The IP happens to be 172.19.0.2.

IP碰巧是172.19.0.2

Fo from this container, I should be able to ping another one with an IP of 172.19.0.3:

从这个容器中,我应该能够ping通另一个IP为172.19.0.3

This was just a simple example of docker networks. There is much more to it, so check out the official documentation.

这只是docker网络的一个简单示例。 还有更多内容,因此请查阅官方文档 。

卷数 (Volumes)

As I’ve said before, Docker containers are not supposed to maintain any state. But what if we need state? In fact, some processes are inherently stateful, like a database. For example, a database needs to maintain all the files with data, as that’s a purpose of the database. If we store this data inside a container, when it’s is gone, so is the data. Additionally, we can’t share this data between multiple instances of the container.

正如我之前所说,Docker容器不应保持任何状态。 但是,如果我们需要状态怎么办? 实际上,某些过程本身就是有状态的,例如数据库。 例如,数据库需要使用数据维护所有文件,因为这是数据库的目的。 如果我们将这些数据存储在容器中,那么当数据消失时,数据也将消失。 此外,我们无法在容器的多个实例之间共享此数据。

To solve this problem, docker introduced volumes. Volumes allow us to store data on the host machine, or on any other machine for that matter, even on the cloud and link the container (or several containers) to this storage.

为了解决此问题,docker引入了卷。 卷使我们能够将数据存储在主机或与此相关的任何其他计算机上,甚至存储在云上,并将容器(或几个容器)链接到该存储。

For example, previously you could see how I created a container from a MongoDB image and ran it using this command:

例如,以前您可以看到我如何从MongoDB映像创建容器并使用以下命令运行它:

docker run -d — net=myTestNetwork mongo

docker run -d — net=myTestNetwork mongo

When running a container like this, Mongo DB will run inside this Linux container, and save database files under the /data/db directory inside the container.

当运行这样的容器时,Mongo DB将在该Linux容器内运行,并将数据库文件保存在该容器内的/data/db目录下。

Now consider this:

现在考虑一下:

docker run -d -v /folder-on-host-machine/data/db:/data/db — net=myTestNetwork mongo.

docker run -d -v /folder-on-host-machine/data/db:/data/db — net=myTestNetwork mongo

The -v flag mounts a volume to a container, so now data between host folder’s /folder-on-host-machine/data/db and the container’s /data/db will be synchronized. Now we can potentially run several instances of a MongoDB container and link them all to this volume on a host machine. If one of the instances shuts down, another one is still available and data is not lost because data is stored on a host machine, not inside a container. The container itself is stateless, as it should be.

-v标志将卷安装到容器,因此主机文件夹的/folder-on-host-machine/data/db与容器的/data/db/data/db将同步。 现在,我们可以潜在地运行MongoDB容器的多个实例,并将它们全部链接到主机上的该卷。 如果其中一个实例关闭,则另一个实例仍然可用,并且数据不会丢失,因为数据存储在主机上而不是容器内。 容器本身应该是无状态的。

There is much more to learn about volumes, like details and use cases, but we won’t cover them in this article. Here I just explained what are they and why we need them.

关于卷,还有更多的东西要学习,例如细节和用例,但是我们将不在本文中介绍。 在这里,我只是解释了它们是什么以及我们为什么需要它们。

最后的话 (Final words)

So this is Docker, in a nutshell! It’s an amazing technology that revolutionizes how we develop, deploy and scale our applications. Here we have just scratched the surface, more is on you to discover.

简而言之,这就是Docker! 这项惊人的技术彻底改变了我们开发,部署和扩展应用程序的方式。 在这里,我们只是从头开始,还有更多内容要发现。

Any constructive feedback is appreciated.

任何建设性的反馈意见表示赞赏。

If you made it this far, please give me some “claps” :)

如果到目前为止,请给我一些“鼓掌” :)

翻译自: https://www.freecodecamp.org/news/comprehensive-introductory-guide-to-docker-vms-and-containers-4e42a13ee103/

docker容器虚拟化技术

docker容器虚拟化技术_Docker,虚拟机和容器的全面介绍相关推荐

  1. Docker容器虚拟化技术---Docker运维管理(Swarm集群管理)3

    Docker容器虚拟化技术-Docker运维管理(Swarm集群管理)3 Swarm集群管理 docker swarm是docker官方提供的一套容器编排系统,是Docker公司推出的官方容器集群平台 ...

  2. Docker容器虚拟化技术---Docker高级实战(DockerFile)2

    Docker容器虚拟化技术-Docker高级实战(DockerFile) DockerFile是一个文本格式的配置文件,用户可以使用DockerFile来快速创建自定义的镜像. 1. DockerFi ...

  3. Docker技术( 容器虚拟化技术 )

    Docker--容器虚拟化技术 第一章 Docker介绍 诞生背景 Docker 介绍 虚拟机技术与容器虚拟化技术 虚拟机技术 容器虚拟化技术 官方网址 第二章 Docker安装 前提条件 安装Doc ...

  4. 容器虚拟化技术Docker(一)简介、安装、常见命令、数据卷、安装常规软件

    容器虚拟化技术Docker(一)简介.安装.常见命令.数据卷.安装常规软件 1.Docker简介 1.简介 Docker的主要目标是"Build,Ship and Run Any App,A ...

  5. [由零开始] 容器虚拟化技术和自动化部署-Docker

    伴随着信息技术的飞速发展,虚拟化技术早已经广泛应用到各种关键场景中. 部署.交付.运行 传统来看,虚拟化(vm)既可以通过硬件模拟来实现,也可以通过操作系统软件来实现.而容器技术则 更为优雅,它充分利 ...

  6. Docker——容器虚拟化技术

    目录 一.Docker介绍 诞生背景 Docker介绍 虚拟机技术与容器虚拟化技术 虚拟机技术 容器虚拟化技术 官方网站 二.Docker安装 安装Docker Docker管理命令 Docker底层 ...

  7. 实战:Docker容器虚拟化技术(使用DockerFile构建镜像并搭建 swarm+compose集群)5

    实战:Docker容器虚拟化技术 (使用DockerFile构建镜像并搭建 swarm+compose集群)5 要求: 使用DockerFile构建镜像并搭建 swarm+compose集群 在Swa ...

  8. Docker容器虚拟化技术---Docker运维管理(Docker Compose)4

    Docker容器虚拟化技术-Docker运维管理(Docker Compose)4 Docker Compose 通过前面的讲解我们知道使用一个Dockerfile模板文件,可以很方便地定义一个单独的 ...

  9. kvm虚拟化技术下虚拟机磁盘的数据保护

    摘要:kvm虚拟化技术下虚拟机的磁盘空间中数据的保护与恢复,考虑kvm的服务器级别的可用性. 1.kvm技术简单介绍    kvm虚拟化技术由几部分构成,kvm内核模块(cpu和内存的虚拟化及管理), ...

最新文章

  1. 超好用的Swift 4.0 字符截取快速便捷方法
  2. SQL*PLUS常用命令
  3. 不用任何软件,让电脑不中***
  4. VC/MFC中常用宏的含义
  5. JBoss Fuse 6.2发布–指导如何快速尝试
  6. 记一次生产频繁出现 Full GC 的 GC日志定位
  7. 第一公会强势分析《TmoLand》快速回本玩法
  8. Reactjs 15.4.X IE11 Objects are not valid as a React child
  9. 在不推动提交的情况下触发Travis-CI重建?
  10. MyBatis源码阅读(十二) --- Spring加载MyBatis过程
  11. 迈克尔杰克逊全部专辑下载
  12. MEGA2560 arduino烧录USB 芯片flash以及bootloader记录
  13. 合批/批量渲染 (Batch)、实例化Instancing
  14. 史上最全软件测试Web测试要点,吐血整理。
  15. 新安装的Eclipse,出现英文乱码,标题窗口英文乱码,打开的Java类窗口显示名称出现乱码
  16. 反向题在测试问卷信效度_问卷信度效度检验
  17. Android service 不被杀死“永不退出的服务”(双进程,服务,多进程,微信)
  18. php sphinx配置,sphinx的配置和管理
  19. TestCenter测试管理工具安装和卸载(B)
  20. 找到office16\excel.exe

热门文章

  1. 【HTML】兴唐二十八节课之常用标签(不定期更新)
  2. 【Elastic Stack(一)】Elastic Stack简介
  3. String类常用方法(看一眼就懂)
  4. 1小时学会:最简单的iOS直播推流(十一)spspps和AudioSpecificConfig介绍(完结)
  5. swift判断iPhone 各种型号
  6. xCode 开发快捷键
  7. Quartz2D在项目中的实际使用
  8. 怎么剪切一段音乐其中的片段
  9. JS数字转换成货币格式
  10. Xbox One 游戏欣赏: Xbox Fitness 太极拳游戏