原创做者,公众号【程序员读书】,欢迎关注公众号,转载文章请注明出处哦。mysql
Docker
是时下热门的容器技术,相信做为一名开发人员,你必定据说过或者使用过,不少人会把Docker
理解为一个轻量级虚拟机,但其实Docker
与虚拟机(VM
)是两种不一样的计算机虚拟化技术,也有不少人会以为,有了虚拟机,那为何还要使用Docker
呢?linux
带着内心的一点点疑问,让咱们一块儿来学习Docker
吧。程序员
咱们仔细想一想,在没有计算虚拟化技术的“远古”年代,若是咱们要部署一个应用程序(Application
),通常的步骤是怎么样的?sql
第一步确定是先要准备一台物理服务器,而后在物理服务器上安装一个操做系统(Operating System
),有了操做系统以后,便在操做系统上安装运行咱们的应用程序,这个过程能够用下面的图来表示:docker
那么,这种方式有什么问题呢?其实,在物理机上部署应用有如下几个缺点:编程
部署很是慢:由于咱们得先准备硬件服务器,接着还要安装操做系统,而后再部署应用程序,并且应用程序还有不少的依赖软件,因此这个过程是比较慢的。centos
成本很是高:主要是物理器成本过高,即便是部署一个简单的应用,也须要一台服务器。bash
资源浪费:若是应用太简单,也容易浪费硬件资源,好比CPU
和内存服务器
迁移和扩展太慢:若是须要迁移应用,或者扩展应用,都要再准备其余的物理服务器,过程很麻烦,也很慢。网络
那么有什么办法能够解决这些问题呢?答案即是虚拟化技术。
谈到计算机的虚拟化技术,咱们直接想到的即是虚拟机,虚拟机容许咱们在一台物理计算机模拟出多台机器,简单地理解,虚拟化技术就是在一台物理计算机上,经过中间虚拟软件层Hypervisor
隔离CPU
、内存等硬件资源,虚拟出多台虚拟服务器,这样作的话,一台物理服务器即可以安装多个应用程序,达到资源利用的最大化,并且多个应用之间相互隔离,以下图所示:
能够把资源分配到不一样的虚拟机,达到硬件资源的最大化利用
与直接在物理机上部署应用,虚拟机更容易扩展应用。
云服务:经过虚拟机虚拟出不一样的物理资源,能够快速搭建云服务。
虚拟机的不足之处在于对物理服务器资源的消耗,当咱们在物理服务器建立一台虚拟机时,便须要虚拟出一套硬件并在上面运行完整的操做系统,每台虚拟机都占用许多的服务器资源。
相对于虚拟机的笨重,Docker
则更显得轻量化,所以不会占用太多的系统资源。
Docker
是使用时下很火的Golang
语言进行开发的,其技术核心是Linux
内核的Cgroup
,Namespace
和AUFS
类的Union FS
等技术,这些技术都是Linux
内核中早已存在不少年的技术,因此严格来讲Docker
并非一个彻底创新的技术,Docker
经过这些底层的Linux
技术,对Linux
进程进行封装隔离,而被隔离的进程也被称为容器,彻底独立于宿主机的进程。
因此Docker
是容器技术的一种实现,也是操做系统层面的一种虚拟化,与虚拟机经过一套硬件再安装操做系统彻底不一样。
Docker
是在操做系统进程层面的隔离,而虚拟机是在物理资源层面的隔离,二者彻底不一样,另外,咱们也能够经过下面的一个比较,了解二者的根本性差别。
从上面的容器与虚拟机的对比中,咱们明白了容器技术的优点。
开发环境与生产环境折射的是开发人员与运维人员之间的矛盾,也许咱们经常会听到开发人员对运维人员说的这样一句话:“在个人电脑运行没问题,怎么到了你那里就出问题了,确定是你的问题”,而运维人员则认为是开发人员的问题。
开发人员须要在本机安装各类各样的测试环境,所以开发的项目须要软件越多,依赖越多,安装的环境也就越复杂。
一样的,运维人员须要为开发人员开发的项目提供生产环境,而运维人员除了应对软件之间的依赖,还须要考虑安装软件与硬件之间的兼容性问题。
就是这样,因此咱们常常看到开发与运维相互甩锅,怎么解决这个问题呢?
容器就是一个不错的解决方案,容器能成为开发与运维之间沟通的语言,由于容器就像一个集装箱同样,提供了软件运行的最小化环境,将应用与其须要的环境一块儿打包成为镜像,即可以在开发与运维之间沟通与传输。
Docker
分为社区版(CE
)和企业版(EE
)两个版本,社区版本能够无偿使用,而企业版则须要付费使用,对于咱们我的开发者或小企业来讲,通常是使用社区版的。
Docker CE
有三个更新频道,分别为stable
、test
、nightly
,stable
是稳定版本,test
是测试后的预发布版本,而nightly
则是开发中准备在下一个版本正式发布的版本,咱们能够根据本身的需求下载安装。
好了,经过前面的介绍,咱们应该对Docker
有了初步的了解,下面开始进入Docker
的学习之旅了。
而学习Docker
的第一步,从安装Docker
运行环境开始,咱们以Docker
的社区版本(CE
)安装为例。
Docker
社区版本提供了Mac OS
,Microsoft Windows
和Linux
(Centos
,Ubuntu
,Fedora
,Debian
)等操做系统的安装包,同时也支持在云服务器上的安装,好比AWS Cloud
。
Docker
为Windows
提供了一个桌面应用程序管理的安装包(Docker Desktop for Windows
),不过对系统有如下几点要求:
64
位Windows10
专业版,企业版,教育版,构建在15063
或更高版本,BIOS
中启用虚拟化。一般,默认状况下启用虚拟化。4GB
内存。CPU
支持SLAT
。若是操做系统知足上面的要求,则能够直接下载安装包直接安装,在安装成功后,Docker
并不会自动启动,须要咱们本身启动,咱们能够在开始菜单中找到Docker
,以下图,单击启动即可启动。
若是系统达不到上面的要求,好比说你用的是Windows 7
操做系统,这时候要想使用Docker
,便须要借助Docker Toolbox
,Docker Toolbox
是Docker
提供的在比较旧的Mac OS
,Windows
操做系统上安装Docker
环境的工具集。
Docker Toolbox
包括docker-cli(就是咱们在终端使用的docker命令行工具)
,docker-compose(多容器管理工具)
,docker-mecahine
,VirtualBox(虚拟机)
,Kitematic(docker的GUI管理工具)
。
本质上使用Docker Toolbox
安装Docker
环境,其实是在VirtualBox
中建立一个Linux
虚拟机,并在虚拟机上安装Docker
。
另外,在安装过程当中会开启Windows
的Hyper-V
模块(Windows
操做系统实现虚拟化的一种技术),这里面有个要注意的点是若是开启了Hyper-V
,则VirtualBox
再也不生效了。
如同Windows
操做系统同样,Docker
为Mac OS
也同样提供一个桌面应用程序(Docker Desktop for Mac
),比较简单,从docker
官网上下载Dokcer.dmg
安装,打开Docker.dmg
,以下图所示:
直接拖动Docker
图标便完成了安装。
对于比较老的Mac OS
操做系统,也能够像Windows
同样,使用Docker Toolbox
,这点能够参考上面的介绍。
在Mac OS
上安装完成以后,在Application
中找到Docker
图标,双击打开即可以启动Docker
了,以下:
在Linux
操做系统上的安装,主要以Centos7
为例,其余Linux
系统的发行版本,如Ubuntu
,Debian
,Fedora
等,能够自行查询Docker
的官方文档。
可能有些Linux
预先安装Docker
,但通常版本比较旧,因此能够先执行如下代码来删除旧版本的Docker
。
$ sudo dnf remove docker \
docker-client \
docker-client-latest \
docker-common \
docker-latest \
docker-latest-logrotate \
docker-logrotate \
docker-selinux \
docker-engine-selinux \
docker-engine
复制代码
$ sudo yum-config-manager \
--add-repo \
https://download.docker.com/linux/centos/docker-ce.repo
复制代码
$ sudo yum install docker-ce docker-ce-cli containerd.io
复制代码
# 启动docker守护进程
$ sudo systemctl start docker
复制代码
经过上面几种方式安装了Docker
以后,咱们能够经过下面的方法来检测安装是否成功。
# 打印docker版本
$ docker version
复制代码
# 拉取hello-world镜像
docker pull hello-world
# 使用hello-world运行一个容器
docker run hello-world
复制代码
运行上面的命令以后,若是有以下图所示的输出结果,则说明安装已经成功了。
镜像(Image
)、容器(Container
)与仓库(Repository
),这三个是docker
中最基本也是最核心的概念,对这三个概念的掌握与理解,是学习docker
的关键。
什么是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
复制代码
好了,关于Docker
镜像的相关知识,咱们就简单地介绍到这里,有机会的话,咱们单独写一篇文章来谈谈,特别构建Docker
镜像部分的相关知识,有必要深刻再学习一下。
Docker
的镜像是用于生成容器的模板,镜像分层的,镜像与容器的关系,就是面向对象编程中类与对象的关系,咱们定好每个类,而后使用类建立对象,对应到Docker
的使用上,则是构建好每个镜像,而后使用镜像建立咱们须要的容器。
启动容器有两种方式,一种是咱们前面已经介绍过的,使用docker run
命令经过镜像建立一个全新的容器,以下:
docker run hello-world
复制代码
另一种启动容器的方式就是启动一个已经中止运行的容器:
# container_id表示容器的id
docker start container_id
复制代码
要中止正在运行的容器可使用docker container stop
或docker stop
命令,以下:
# 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
复制代码
# 进入容器,container_id表示容器的id,command表示linux命令,如/bin/bash
docker exec -it container_id command
复制代码
在前面的例子中,咱们使用两种方式构建镜像,构建完成以后,能够在本地运行镜像,生成容器,但若是在更多的服务器运行镜像呢?很明显,这时候咱们须要一个可让咱们集中存储和分发镜像的服务,就像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 verion
复制代码
其结果以下:
从上面的图中,咱们看到打出了两个部分的信息:Client
和Server
。
这是由于Docker
跟大部分服务端软件同样(如MySQL
),都是使用C/S
的架构模型,也就是经过客户端调用服务器,只是咱们如今恰好服务端和客户端都在同一台机器上而已。
所以,咱们可使用下面的图来表示Docker
的架构,DOCKER_HOST
是Docker server
,而Clinet即是咱们在命令中使用docker
命令。
docker server
为客户端提供了容器、镜像、数据卷、网络管理等功能,其实,这些功能都是由Docker Engine
来实现的。
dockerd
:服务器守护进程。Client docker Cli
:命令行接口REST API
:除了cli命令行接口,也能够经过REST API
调用docker
下面是Docker Engine
的示例图:
做为一名开发人员,在学习或开发过程当中,总须要安装各类各样的开发环境,另外,一个技术团队在开发项目的过程,也经常须要统一开发环境,这样可能避免环境不一致引起的一些问题。
虽然使用虚拟机能够解决上面的问题,但虚拟机过重,对宿主机资源消耗太大,而做为轻量级容器技术,Docker
能够简单轻松地解决上述问题,让开发环境的安装以及应用的部署变得很是简单,并且使用Docker
,比在虚拟机安装操做系统,要简单得多。
欢迎扫码关注,共同窗习进步