docker入门教程-概述
前言
docker其实很久以前就听说过了,也使用过。但是很多时候都仅仅知道它是一个开源的、GO语言开发的应用容器引擎,对docker的知识了解不够深入,大部分的时候都是需要用到的时候搜索一个博客搭一下这样,最近用到的一些东西总是与docker挂钩,于是乎打算系统地学习下docker。
Docker 是什么?
Docker是一个基于Go语言开发的一个开源应用容器引擎
;它基于Linux内核中的CGroup、Namespace、Union FS等技术,对应用进程进行封装隔离,并且独立于宿主机以及其他进程,这种运行时的状态被称为容器。
Docker早期的版本是基于LXC
(早期的Linux虚拟机技术)实现的,包括文件系统、网络互连、镜像管理等方面,极大简化了容器的管理。从0.7版本以后开始去除了LXC
,使用自行研发的Libcontainer,至1.11版本到现在,进一步演进为runC和containerd。
Docker的理念是将应用及依赖包打包到一个可移植的容器中,可以发布到任意Docker的引擎上,使用沙箱机制运行程序,程序之间互相隔离。
Dockerd 体系结构
运行原理
Docker 的核心就是镜像和容器,当client告知enginx启动一个容器的时候,如果该容器的image在本地不存在的话,就会去repository上拉取该镜像,拉取完成之后会启动一个shim进程去承载这个容器,而这个容器的运行由runC来负责。
- Containerd是一个守护进程,使用runC管理容器,向Docker Engine提供接口。
- Shim是一个真实运行的容器的真实垫片载体,每启动一个容器都会起一个新的shim的一个进程。
- runC是一个轻量级的工具,是Docker按照开放容器格式标准(OCF, Open Container Format)制定的一种具体实现,unC是从Docker的libcontainer中迁移而来的,实现了容器启停、资源隔离等功能,只用来运行容器。
体系结构
Docker使用客户端-服务器架构。Docker客户端与Docker 守护进程*进行对话,由该守护进程来完成了构建,运行和分发Docker容器的繁重工作。Docker客户端和守护程序可以在同一系统上运行,也可以将Docker客户端连接到远程Docker守护程序。Docker客户端和守护程序在UNIX sockets或network interface 上使用REST API进行通信。
-
Docker Client:客户端
The Docker client (
docker
) is the primary way that many Docker users interact with Docker. When you use commands such asdocker run
, the client sends these commands todockerd
, which carries them out. Thedocker
command uses the Docker API. The Docker client can communicate with more than one daemon. docker 客户端是用户使用docker的主要接口,当你使用例如
docker run
这样的命令的时候,客户端会发送这些命令到docker engine
来执行这些命令。 -
Ddocker Daemon:守护进程
The Docker daemon (
dockerd
) listens for Docker API requests and manages Docker objects such as images, containers, networks, and volumes. A daemon can also communicate with other daemons to manage Docker services. Docker守护程序(
dockerd
)侦听Docker API请求并管理Docker对象,例如image
,container
、network
和volumes
。守护程序还可以与其他守护程序通信以管理Docker服务。 -
Docker Images:镜像
An image is a read-only template with instructions for creating a Docker container. Often, an image is based on another image, with some additional customization. For example, you may build an image which is based on the
ubuntu
image, but installs the Apache web server and your application, as well as the configuration details needed to make your application run.You might create your own images or you might only use those created by others and published in a registry. To build your own image, you create a Dockerfile with a simple syntax for defining the steps needed to create the image and run it. Each instruction in a Dockerfile creates a layer in the image. When you change the Dockerfile and rebuild the image, only those layers which have changed are rebuilt. This is part of what makes images so lightweight, small, and fast, when compared to other virtualization technologies.
镜像是创建容器的只读模板,通常一个镜像会基于另一个镜像来构建,我们可以编写
DockerFile
来创建我们自己的镜像 -
Docker Container:容器
A container is a runnable instance of an image. You can create, start, stop, move, or delete a container using the Docker API or CLI. You can connect a container to one or more networks, attach storage to it, or even create a new image based on its current state.
By default, a container is relatively well isolated from other containers and its host machine. You can control how isolated a container’s network, storage, or other underlying subsystems are from other containers or from the host machine.
A container is defined by its image as well as any configuration options you provide to it when you create or start it. When a container is removed, any changes to its state that are not stored in persistent storage disappear.
-
Docker Registry:镜像仓库
A Docker registry stores Docker images. Docker Hub is a public registry that anyone can use, and Docker is configured to look for images on Docker Hub by default. You can even run your own private registry. If you use Docker Datacenter (DDC), it includes Docker Trusted Registry (DTR).
When you use the
docker pull
ordocker run
commands, the required images are pulled from your configured registry. When you use thedocker push
command, your image is pushed to your configured registry.容器是镜像的可运行实例
,可以使用Docker Api创建、启动、停止、移动和删除容器。可以将容器连接到一个或多个网络,也可以将储存连接到它。默认情况下,容器与其他容器及其主机之间的隔离程度相对较高。您可以控制容器的网络,存储或其他基础子系统与其他容器或与主机的隔离程度。容器由其映像以及在创建或启动时为其提供的任何配置选项定义。删除容器后,未存储在持久性存储中的状态更改将消失。
内部组件
-
Namespaces
命名空间,Linux内核提供的一种对进程资源隔离的机制,例如进程、网络、挂载点等资源。运行容器时,Docker会为该容器创建一组 命名空间。这些名称空间提供了一层隔离。容器的每个方面都在单独的名称空间中运行,并且对其的访问仅限于该名称空间。
-
CGroups
控制组,Linux内核提供的一种限制进程资源的机制,例如CPU、内存等资源。cgroup将应用程序限制为一组特定的资源。控制组允许Docker Engine将可用的硬件资源共享给容器,并有选择地实施限制和约束。例如,您可以限制特定容器可用的内存。
-
UnionFS
联合文件系统,支持将不同位置的目录挂载到同一虚拟文件系统,形成一种分层模型。联合文件系统或UnionFS是通过创建图层进行操作的文件系统,使其非常轻便且快速。Docker Engine使用UnionFS为容器提供构建模块。Docker Engine可以使用多个UnionFS变体,包括AUFS,btrfs,vfs和DeviceMapper。
容器和虚拟机的区别
容器和虚拟机具有相似的资源隔离和分配优势,但功能不同,因为容器虚拟化了操作系统,而不是硬件。容器更加便携和高效。
结构异同
虚拟机结构
虚拟机(VM)是将一台服务器转变为多台服务器的物理硬件的抽象。虚拟机管理程序允许多个VM在单台计算机上运行。每个VM包含操作系统,应用程序,必要的二进制文件和库的完整副本-占用数十GB。VM也可能启动缓慢。
容器结构
容器是应用程序层的抽象,将代码和依赖项打包在一起。多个容器可以在同一台计算机上运行,并与其他容器共享OS内核,每个容器在用户空间中作为隔离的进程运行。容器占用的空间少于VM(容器映像的大小通常为几十MB),可以处理更多的应用程序,并且需要的VM和操作系统更少。
各项对比
项目 | KVM(虚拟机) | Docker |
---|---|---|
启动时间 | 分钟级 | 秒级 |
量级 | 以G为单位 | 以M为单位 |
性能 | 需要Hypervisor层支持,虚拟化一些设备,具有完整的GuestOS,开销大,性能比容器底 | 共享宿主机内核,系统级虚拟化,占用的资源少,没有Hypervisor层的开销,性能接近物理机 |
安全性 | 与宿主机隔离,比较安全 | 由于共享宿主机内核,只是进程级的隔离饿,有一定隐患 |
使用要求 | 基于硬件完全虚拟化,需要硬件CPU虚拟化技术支持 | 可运行的Engine的主机即可 |
应用场景
-
项目部署
每次部署项目到测试、生产等环境,都要部署一大堆依赖的软件、工具,而且部署期间出现问题几率很大,不经意就花费了很长时间。Docker主要理念就是环境打包部署,可在任意Docker Engine运行。前期我们只需要将每个项目环境打包到镜像,push到镜像仓库,当有需要部署这个项目时,直接pull镜像启动容器,这个项目就可以访问了!一次构建多次部署,一劳永逸。
-
持续集成
一个项目版本快速迭代的测试场景,需要一个合理的CI(持续集成)/CD(持续部署)环境支撑。CI/CD是一个周期性自动化项目测试流程,包括构建、部署、测试、发布等工作,很少需要人工干预。Docker 可配合Jenkins持续集成。
-
微服务
微服务是近几年来IT圈内谈论比较多的一个名词,意义也很简单:尽可能细粒度拆分业务程序架构,由多个独立服务组成业务系统。Docker的容器设计原则:一个容器一个服务,容器之间相互隔离
-
弹性伸缩
说到弹性伸缩,通常是集群模式下存在。像AWS AutoScaling,可以自定义资源阈值,SLB自动添加EC2云主机,应对业务访问量突发情况。当适用Docker技术以后,这种弹性伸缩的单元就是云主机之上的容器了。容器集群化管理已经有成熟的解决方案,比如:官方的Swarm,谷歌的K8S
由于Docker容器快速启动特性,可以很快速的启动几十个、上百个容器来提供更多并发和资源利用率(如果宿主机资源不够,还需要加主机到集群中)。