docker基本概念

docker基本概念

philo-尼可 586 2020-11-14

Docker


什么是虚拟化技术

谈到计算机的虚拟化技术,我们直接想到的便是虚拟机,虚拟机允许我们在一台物理计算机模拟出多台机器,简单地理解,虚拟化技术就是在一台物理计算机上,通过中间虚拟软件层Hypervisor隔离CPU、内存等硬件资源,虚拟出多台虚拟服务器,这样做的话,一台物理服务器便可以安装多个应用程序,达到资源利用的最大化,而且多个应用之间相互隔离,如下图所示:
15912534517346e8965356b2e4ca78475dbe1f8c322cf.png

虚拟机上部署应用示意图

虚拟机的优点

  • 可以把资源分配到不同的虚拟机,达到硬件资源的最大化利用
  • 与直接在物理机上部署应用,虚拟更容易扩展应用。
  • 云服务:通过虚拟机虚拟出不同的物理资源,可以快速搭建云服务。

虚拟机的不足之处

虚拟机的不足之外来自于对物理服务器资源的消耗,当我们在物理服务器创建一台虚拟机时,便需要虚拟出一套硬件并在上面运行完整的操作系统,每台虚拟机都占用许多的服务器资源。

Docker是什么?

相对于虚拟机的笨重,Docker则更显得轻量化,因此不会占用太多的系统资源。


Docker是使用时下很火的Golang语言进行开发的,其技术核心是Linux内核的Cgroup,Namespace和AUFS类的Union FS等技术,这些技术都是Linux内核中早已存在很多年的技术,所以严格来说并不是一个完全创新的技术,Docker通过这些底层的Linux技术,对Linux进程进行封装隔离,而被隔离的进程也被称为容器,完全独立于宿主机的进程。


所以Docker是容器技术的一种实现,也是操作系统层面的一种虚拟化,与虚拟机的通过一套硬件再安装操作系统完全不同。
159125345174836d1eb67f64a4265a878a466b9d0bf93.png
Docker容器与系统关系示意图

Docker 包括三个基本概念:

  • 镜像(Image):Docker 镜像(Image),就相当于是一个 root 文件系统。比如官方镜像 ubuntu:16.04 就包含了完整的一套 Ubuntu16.04 最小系统的 root 文件系统。
  • 容器(Container):镜像(Image)和容器(Container)的关系,就像是面向对象程序设计中的类和实例一样,镜像是静态的定义,容器是镜像运行时的实体。容器可以被创建、启动、停止、删除、暂停等。
  • 仓库(Repository):仓库可看成一个代码控制中心,用来保存镜像。

15918659247536f80e226c9f8471683820ad65fe234e9.png

概念说明
Docker 镜像(Images)Docker 镜像是用于创建 Docker 容器的模板,比如 Ubuntu 系统。
Docker 容器(Container)容器是独立运行的一个或一组应用,是镜像运行时的实体。
Docker 客户端(Client)Docker 客户端通过命令行或者其他工具使用 Docker SDK (https://docs.docker.com/develop/sdk/) 与 Docker 的守护进程通信。
Docker 主机(Host)一个物理或者虚拟的机器用于执行 Docker 守护进程和容器。
Docker RegistryDocker 仓库用来保存镜像,可以理解为代码控制中的代码仓库。
Docker Hub(https://hub.docker.com) 提供了庞大的镜像集合供使用。
一个 Docker Registry 中可以包含多个仓库(Repository);每个仓库可以包含多个标签(Tag);每个标签对应一个镜像。
通常,一个仓库会包含同一个软件不同版本的镜像,而标签就常用于对应该软件的各个版本。我们可以通过 <仓库名>:<标签> 的格式来指定具体是这个软件哪个版本的镜像。如果不给出标签,将以 latest 作为默认标签。
Docker MachineDocker Machine是一个简化Docker安装的命令行工具,通过一个简单的命令行即可在相应的平台上安装Docker,比如VirtualBox、 Digital Ocean、Microsoft Azure。

Docker与虚拟机之间的比较

Docker是在操作系统进程层面的隔离,而虚拟机是在物理资源层面的隔离,两者完全不同,另外,我们也可以通过下面的一个比较,了解两者的根本性差异。

从上面的容器与虚拟机的对比中,我们明白了容器技术的优势。

容器解决了开发与生产环境的问题

开发环境与生产环境折射的是开发人员与运维人员之间的矛盾,也许我们常常会听到开发人员对运维人员说的这样一句话:“在我的电脑运行没问题,怎么到了你那里就出问题了,肯定是你的问题”,而运维人员是认为是开发人员的问题。


开发人员需要在本机安装各种各样的测试环境,因此开发的项目需要软件越多,依赖越多,安装的环境也就越复杂。


同样的,运维人员需要为开发人员开发的项目提供生产环境,而运维人员除了应对软件之间的依赖,还需要考虑安装软件与硬件之间的兼容性问题。


就是这样,所以我们经常看到开发与运维相互甩锅,怎么解决这个问题呢?


容器就是一个不错的解决方案,容器能成为开发与运维之间沟通的语言,因为容器就像一个集装箱一样,提供了软件运行的最小化环境,将应用与其需要的环境一起打包成为镜像,便可以在开发与运维之间沟通与传输。

Docker的版本

Docker分为社区版(CE)和企业版(EE)两个版本,社区版本可以免费使用,而企业版则需要付费使用,对于我们个人开发者或小企业来说,一般是使用社区版的。


打印Docker版本

# 打印docker版本
$ docker version


拉取镜像并运行容器

# 拉取hello-world镜像
docker pull hello-world


# 使用hello-world运行一个容器
docker run hello-world


运行上面的命令之后,如果有如下图所示的输出结果,则说明安装已经成功了。

1591253747713d5693f0356ba42ad91f9e8634320405c.png

Docker的基本概念

镜像(Image)、容器(Container)与仓库(Repository),这三个是Docker中最基本也是最核心的概念,对这三个概念的掌握与理解,是学习Docker的关键。

镜像(Image)

什么是Docker的镜像?


Docker本质上是一个运行在Linux操作系统上的应用,而Linux操作系统分为内核和用户空间,无论是CentOS还是Ubuntu,都是在启动内核之后,通过挂载Root文件系统来提供用户空间的,而Docker镜像就是一个Root文件系统。


Docker镜像是一个特殊的文件系统,提供容器运行时所需的程序、库、资源、配置等文件,另外还包含了一些为运行时准备的一些配置参数(如匿名卷、环境变量、用户等)。


镜像是一个静态的概念,不包含任何动态数据,其内容在构建之后也不会被改变。


下面的命令是一些对镜像的基本操作,如下:


查看镜像列表

# 列出所有镜像
docker image ls


由于我们前面已经拉取了hello-world镜像,所以会输出下面的内容:

REPOSITORY            TAG            IMAGE ID        CREATED         SIZE
hello-world           latest         fce289e99eb9    7 months ago    1.84kB


下面的命令也一样可以查看本地的镜像列表,而且写法更简洁。

# 列表所有镜像
docker images


从仓库拉取镜像


前面我们已经演示过使用docker pull命令拉取了hello-world镜像了,当然使用docker image pull命令也是一样的。


一般默认是从Docker Hub上拉取镜像的,Docker Hub是Docker官方提供的镜像仓库服务(Docker Registry),有大量官方或第三方镜像供我们使用,比如我们可以在命令行中输入下面的命令直接拉取一个CentOS镜像:

docker pull centos


docker pull命令的完整写法如下:

docker pull [选项] [Docker Registry 地址[:端口号]/]仓库名[:标签]


拉取一个镜像,需要指定Docker Registry的地址和端口号,默认是Docker Hub,还需要指定仓库名和标签,仓库名和标签唯一确定一个镜像,而标签是可能省略,如果省略,则默认使用latest作为标签名,另外,仓库名则由作者名和软件名组成。


那么,我们上面使用CentOS,那是因为省略作者名,则作者名library,表示Docker官方的镜像,所以上面的命令等同于:

docker pull library/centos:latest

因此,如果拉取非官方的第三方镜像,则需要指定完整仓库名,如下:

docker pull mysql/mysql-server:latest


运行镜像


使用docker run命令,可以通过镜像创建一个容器,如下:

docker run -it centos /bin/bash

**
删除镜像


当本地有些镜像我们不需要时,那我们也可以删除该镜像,以节省存储空间,不过要注意,如果有使用该镜像创建的容器未删除,则不允许删除镜像。

# image_name表示镜像名,image_id表示镜像id
dockere image rm image_name/image_id

删除镜像的快捷命令:

docker rmi image_name/image_id

#### 容器(Container) Docker的镜像是用于生成容器的模板,镜像分层的,镜像与容器的关系,就是面向对象编程中类与对象的关系,我们定好每一个类,然后使用类创建对象,对应到Docker的使用上,则是构建好每一个镜像,然后使用镜像创建我们需要的容器。

**启动和停止容器**

启动容器有两种方式,一种是我们前面已经介绍过的,使用docker run命令通过镜像创建一个全新的容器,如下: ```shell docker run hello-world ``` 另外一种启动容器的方式就是启动一个已经停止运行的容器: ```shell # container_id表示容器的id docker start container_id ``` 要停止正在运行的容器可以使用docker container stop或docker stop命令,如下: ```shell # container_id表示容器的id docker stop container_id ```


查看所有容器


如果要查看本地所有的容器,可以使用docker container ls命令:

# 查看所有容器
docker container ls

查看所有容器也有简洁的写法,如下:

# 查看所有容器
docker ps

**
删除容器


我们也可以使用docker container rm命令,或简洁的写法docker rm命令来删除容器,不过不允许删除正在运行的容器,因此如果要删除的话,就必须先停止容器。

# container_id表示容器id,通过docker ps可以看到容器id
$ docker rm container_id

当我们需要批量删除所有容器,可以用下面的命令:

# 删除所有容器
docker rm $(docker ps -q)
# 删除所有退出的容器
docker container prune


进入容器

在使用 -d 参数时,容器启动后会进入后台。此时想要进入容器,可以通过以下指令进入:

  • docker attach
  • docker exec:推荐大家使用 docker exec 命令,因为此退出容器终端,不会导致容器的停止。
# 进入容器,container_id表示容器的id,command表示Linux命令,如/bin/bash
docker exec -it container_id command
# 进入容器,container_id表示容器的id,command表示Linux命令,如/bin/bash
docker attach container_id

仓库(Repository)

在前面的例子中,我们使用两种方式构建镜像,构建完成之后,可以在本地运行镜像,生成容器,但如果在更多的服务器运行镜像呢?很明显,这时候我们需要一个可以让我们集中存储和分发镜像的服务,就像Github可以让我们自己存储和分发代码一样。


Docker Hub就是Docker提供用于存储和分布镜像的官方Docker Registry,也是默认的Registry,其网址为https://hub.docker.com,前面我们使用docker pull命令便从Docker Hub上拉取镜像。


Docker Hub有很多官方或其他开发提供的高质量镜像供我们使用,当然,如果要将我们自己构建的镜像上传到Docker Hub上,我们需要在Docker Hub上注册一个账号,然后把自己在本地构建的镜像发送到Docker Hub的仓库当中,Docker Registry包含很多个仓库,每个仓库对应多个标签,不同标签对应一个软件的不同版本。

Docker的组成与架构

在安装好并启动了Docker之后,我们可以使用在命令行中使用Docker命令操作Docker,比如我们使用如下命令打印Docker的版本信息。

docker verion


其结果如下:

1591253746690a3c13a94a3ef42c6add853af0058b05a.png



从上面的图中,我们看到打出了两个部分的信息:Client和Server。

这是因为Docker跟大部分服务端软件一样(如MySQL),都是使用C/S的架构模型,也就是通过客户端调用服务器,只是我们现在刚好服务端和客户端都在同一台机器上而已。

因此,我们可以使用下面的图来表示Docker的架构,DOCKER_HOST是Docker Server,而Clinet便是我们在命令中使用Docker命令。
![1591253748560975b4227190b42c9b810bb2a86a64621.png](http://blog.20190616.xyz/upload/2020/10/1591253748560-975b4227-190b-42c9-b810-bb2a86a64621-809b8bbd8ff54f32a467ec054446215f.png)

Docker Engine

Docker Server为客户端提供了容器、镜像、数据卷、网络管理等功能,其实,这些功能都是由Docker Engine来实现的。

  1. dockerd:服务器守护进程。
  2. Client docker Cli:命令行接口
  3. REST API:除了cli命令行接口,也可以通过REST API调用Docker


下面是Docker Engine的示例图:

1591253747703e965ab7bb3224799bb0e49f7350e27bb.png

---------------未完,待续---------------


# docker # 概念 # 基础