DockerQuickIN
Docker 快速入门
[TOC]
宝藏视频:https://www.bilibili.com/video/BV14s4y1i7Vf
如果你遇到过:
- 应用程序的部署和环境配置过于复杂
- 在开发环境好用,但是到了测试和生产环境都不好用的情况
- 作为新人加入项目组,需要花费大量的时间来配置开发环境
- 花费一整天甚至更长时间,一步一步按照配置部署文档来配置环境,但是最终却卡在中间某个步骤上,再也无法前进
那么,Docker
可以帮我们完美解决上面这些问题。
🐳 1. Docker
的基本概念
1.1 Docker
的简介
Docker
是一个用于构建(Build)、运行(Run)、传送(Share)应用程序的平台。
有了 Docker
,我们就可以将应用程序和运行他所需要的各种依赖包、第三方软件库、配置文件等打包在一起。以便在任何环境中都能正确的运行。Docker
可以让开发者打包他们的应用以及依赖包到一个轻量级、可移植的容器中,然后发布到任何流行的 Linux 机器上,也可以实现虚拟化。容器是完全使用沙箱机制,相互之间不会有任何接口,更重要的是容器性能开销极低。
Docker
从 17.03
版本之后分为 社区版 CE(Community Edition)
和 企业版 EE(Enterprise Edition)
。
1.2 为什么 要使用 Docker
为什么要使用 Docker
呢?
举个简单的例子:我们写了一个网站,用到了现在不叫流行的前后端分离架构,前端使用 Vue
框架来构建网站的界面,后端使用 Java
的 SpringBoot
框架来提供各种服务和接口,并且使用 MySQL
数据库来存储数据。
如果没有 Docker
,我们的步骤大概是这样的:
- Step-01:安装
NodeJS
环境。 - Step-02:安装各种
npm
依赖。 - Step-03:安装
Java
运行时环境。 - Step-04:安装各种第三方依赖包。
- Step-05:安装
MySQL
数据库。 - Step-06:配置各种环境变量、启动脚本。
- Step-07:配置
Redis
。 - Step-08:配置
Nginx
负载均衡。 - Step-09:其他配置项…
这仅仅是开发环境所需要进行的操作,当我们需要将我们的网站部署到测试环境或生产环境上,那么这些所有的步骤都需要重新再来一遍。
但是如果我们有了 Docker
,我们就可以将他们打包成一个个集装箱,只要我们在开发环境中运行成功了,那么在测试环境中一定也是可以运行成功的。
1.3 Docker
和 虚拟机的区别
我们可能了解或使用过一些虚拟机软件,如:VMware
、Virtalbox
、Parallels Desktop
,或者 Window
的 WSL
、Microsoft Hyper-V
等功能。
他们都是完整的操作系统,和实际上使用操作系统一样,可以在实际的操作系统中运行应用程序,这是通过一种叫做虚拟化(Hypervisor)的技术实现的。虚拟化技术是一种将物理资源虚拟为多个逻辑资源的技术,他可以将一台物理服务器虚拟成多个逻辑服务器,每个逻辑服务器都有自己的操作系统、CPU、内存、硬盘和网络接口等。不同的逻辑服务器之间是完全隔离的,可以独立运行。
虚拟机在一定程度上实现了资源的整合,可以将要一台服务器的计算能力、存储能力、网络资源分配给多个逻辑服务器。实现多台服务器的功能。但是其缺点也同样明显,每台虚拟机需要占用大量的资源,比如CPU、内存、硬盘、网络等,而且启动速度非常慢。但是其实我们的每台服务器上只需要运行一个主要对外提供服务的应用程序就可以了。并不需要一个完整的操作系统所提供的所有功能。
也许我们需要的只是一个Web服务器,但是使用虚拟机却需要启动一个完整的操作系统,包括操作系统的内核、各种系统服务、各种工具甚至图形界面等,这些我们并不需要的服务占用了大量的资源,导致了资源的浪费和启动速度慢的问题。
了解了虚拟机后,我们再来看一下 Docker
是如何解决的。需要注意,Docker
中***容器(Container)的概念。需要注意的是,Docker
和 容器是两个不同的概念,但是因为 Docker
的流行性,以至于很多人将 Docker
和 容器 混为一谈,实际上 Docker
只是容器的一种实现,是一个容器化的解决方案和平台。而容器是一种虚拟化技术,和虚拟机类似*,也是一个独立的环境,可以在这个环境中运行应用程序。和虚拟机不同的是,他并不需要在容器中运行一个完整的操作系统,而是使用宿主机的操作系统,所以启动速度非常快,通常只需要几秒钟。同时,因为需要的资源更少,所以可以在一台物理服务器上运行更多的容器,以便于更加充分的利用服务器的资源,减少资源的闲置和浪费。
正因如此,一台物理服务器上也许可以运行几个虚拟机,但是却可以运行上百个容器。
1.4 Docker
的基本原理和主要概念
镜像 Image:镜像是一个只读的模板,它可以用来创建容器。
容器 Container:容器是 Docker
的运行实例,他提供了一个独立的、可移植的环境,可以在这个环境中运行应用程序。
仓库 Registry:Docker
的仓库是一个用于存储 Docker
镜像的地方。最流行、最常用的仓库就是 Docker Hub
。
类似于 Java
和 C++
,镜像类似于类,而容器则就是类的实例,可以有一到多个容器。
Docker
使用的是 Client-Server
架构模式,Docker Client
和 Docker Daemon
之间通过 socket
或 RESTful API
进行通信。Docker Daemon
就是 Docker
服务端的守护进程,他负责管理 Docker
的各种资源。Docker Client
负责向 Docker Daemon
发送请求,Docker Daemon
接收到请求后进行处理,然后将要结果返回给 Docker Client
。Docker Daemon
是一个后台进程,用于接收并处理来自 Docker
客户端的请求,然后将结果返回给客户端。因此我们在终端中输入的各种 Docker
命令,其实都是通过 Docker Client
发送给 Docker Daemon
的,Docker Daemon
进行处理,最后将处理结果返回给 Docker Client
,然后就可以再终端中看到执行结果。
🐳 2. Docker
的安装配置
2.1 Windows
环境下下载安装 Docker
Docker
官网(目前国内无法正常访问):https://www.docker.com/
可以找一些镜像网站来进行下载安装。
下载完成后,需要运行 Docker
,才可以使用 Docker
的一系列命令。
Windows
系统下需要开启 Hyper-V
功能。开启方式如下:
- 在设置中搜索 启用或关闭 Windows 功能。
- 勾选
Hyper-V
选项,按照提示重启系统即可。
2.2 Linux(Ubuntu)
环境下下载安装 Docker
2.2.1 安装
① 使用官方安装脚本自动安装
1 | curl -fsSL https://get.docker.com | bash -s docker --mirror Aliyun |
② 或者使用国内daocloud一键安装命令:
1 | curl -sSL https://get.daocloud.io/docker | sh |
③ 手动安装
卸载旧版本
Docker
的旧版本被称为docker
、docker.io
或docker-engine
。如果已安装,请卸载它们。1
sudo apt-get remove docker docker-engine docker.io containerd runc
设置仓库
更新
apt
包索引1
sudo apt-get update
安装
apt
依赖包,用于通过HTTPS来获取仓库:1
2
3
4
5sudo apt-get install apt-transport-https \
ca-certificates \
curl \
gnupg-agent \
software-properties-common添加
Docker
的官方GPG
密钥:1
curl -fsSL https://mirrors.ustc.edu.cn/docker-ce/linux/ubuntu/gpg | sudo apt-key add -
设置稳定存储库:
1
2
3
4sudo add-apt-repository "deb [arch=amd64] \
https://mirrors.ustc.edu.cn/docker-ce/linux/ubuntu/ \
$(lsb_release -cs) \
stable"安装
Docker Engine-Community
更新
apt
包索引:1
sudo apt-get update
安装最新版本的
Docker Engine-Community
和containerd
,或者转到下一步安装特定版本:1
sudo apt-get install docker-ce docker-ce-cli containerd.io
安装特定版本的
Docker Engine-Community
1
2
3
4
5apt-cache madison docker-ce
docker-ce | 5:18.09.1~3-0~ubuntu-xenial | https://mirrors.ustc.edu.cn/docker-ce/linux/ubuntu xenial/stable amd64 Packages
docker-ce | 5:18.09.0~3-0~ubuntu-xenial | https://mirrors.ustc.edu.cn/docker-ce/linux/ubuntu xenial/stable amd64 Packages
...1
sudo apt-get install docker-ce=<VERSION_STRING> docker-ce-cli=<VERSION_STRING> containerd.io
测试安装成功
1
$ sudo docker run hello-world
2.2.2 卸载
1 | sudo yum remove docker \ |
2.3 Linux(CentOS7)
环境下下载安装 Docker
安装 Docker
的必要前提条件:要安装 Docker Engine
需要 CentOS 7
的维护版本。不支持或未测试存档版本。centos-extras
库必须启用。默认情况下,此存储库是启用的。建议使用 overlay2
存储驱动程序。
可以通过 uname –a
或 cat /etc/redhat-release
查询当前OS系统:
1 | [nilera@bigdata ~]$ uname -a |
1 | [nilera@bigdata ~]$ cat /etc/redhat-release |
2.3.1 安装
可以根据需要以不同的方式安装 Docker Engine
:
- 大多数用户会设置
Docker
的存储库并从中进行安装,以简化安装和升级任务。这是推荐的方法,这种方式需要访问互联网。 - 一些用户下载并手动安装
RPM
软件包,并完全手动管理升级。这在无法访问互联网的空白系统上安装Docker
的情况下非常有用。 - 在测试和开发环境中,一些用户选择使用自动便携式的脚本来安装
Docker
。
① 卸载旧版本
较旧的 Docker
版本称为 docker
或 docker-engine
。如果已安装这些程序,请卸载它们以及相关的依赖项。
② 使用存储库安装 Docker
设置存储库:
安装
yum-utils
软件包(提供yum-config-manager
实用程序)并且device mapper
存储驱动程序需要device-mapper-persistent-data
和lvm2
。1
2
3
4
5
6# 完整命令如下
# 安装 yum-utils、device-mapper-persistent-data、lvm2
sudo yum install -y yum-utils device-mapper-persistent-data lvm2
# 命令行执行效果
[nilera@bigdata ~]$ sudo yum install -y yum-utils device-mapper-persistent-data lvm2设置稳定的存储库(使用官方源地址,比较慢)。
1
[nilera@bigdata ~]$ sudo yum-config-manager --add-repo https://download.docker.com/linux/centos/docker-ce.repo
现在将
Docker Engine
软件包称为docker-ce
。分为2种方式:安装最新版本的
Docker Engine
和容器,或转到下一步以安装特定版本。如果提示接受
GPG
密钥,请验证指纹是否匹配060A 61C5 1B55 8A7F 742B 77AA C52F EB6B 621E 9F35
,如果是,则接受它。1
[nilera@bigdata ~]$ sudo yum install docker-ce docker-ce-cli containerd.io
要安装特定版本的
Docker Engine-Community
,需要在存储库中列出可用版本,然后选择并安装。列出并排序存储库中可用的版本。本示例按版本号(从高到低)对结果进行排序,并被截断:
1
[nilera@bigdata ~]$ sudo yum list docker-ce --showduplicates | sort -r
通过其完整的软件包名称安装特定版本,该软件包名称是软件包名称
docker-ce
加上版本字符串。例如:docker-ce-18.09.1
。1
[nilera@bigdata ~]$ sudo yum install docker-ce-<VERSION_STRING> docker-ce-cli-<VERSION_STRING> containerd.io
使用存储库安装
Docker CE
完成Docker
已安装但尚未启动。docker
组已被创建,但没有用户添加到该组。1
2
3
4
5
6
7[nilera@bigdata ~]$ cat /etc/group
root:x:0:
bin:x:1:
...
ntp:x:38:
cgred:x:996:
docker:x:995:启动
Docker
服务1
[nilera@bigdata ~]$ sudo systemctl start docker
通过运行
hello-world
映像来验证是否正确安装了Docker Engine
:1
2[nilera@bigdata ~]$ sudo docker version
[nilera@bigdata ~]$ sudo docker run hello-world
③ 使用便捷脚本安装 Docker CE
Docker
在 get.docker.com
和 test.docker.com
上提供了便捷脚本,用于将 Docker Engine-Community
的边缘版本和测试版本快速且非交互地安装到开发环境中。脚本的源代码在 docker-install
存储库中。
⚠ 不建议在生产环境中使用这些脚本 ⚠
具有一定风险:
- 脚本需要运行
root
或具有sudo
特权。在运行脚本之前,应仔细检查和审核脚本。 - 这些脚本尝试检测 Linux 发行版和版本,并配置软件包管理系统。此外,脚本不允许自定义任何安装参数。从Docker的角度或自己组织的准则和标准角度来看,这可能导致不支持的配置。
- 这些脚本将安装软件包管理器的所有依赖项和建议,而无需进行确认。根据主机的当前配置,可能会安装大量软件包。
- 该脚本未提供用于指定要安装哪个版本的 Docker 的选项,而是安装了在”edge”通道中发布的最新版本。如果已使用其他机制将Docker安装在主机上,请不要使用便捷脚本。
2.3.2 卸载
1 | $ sudo yum remove docker \ |
2.4 Docker
测试
启动之后,即可在终端使用 Docker
的各种命令了。我们可以使用一条简单的命令来进行测试:
1 | C:\Users\NilEra>docker version |
我们可以看到 Client
和 Server
的信息,如果只能看到 Client
,则表示 Docker
没有启动,需要启动 Docker
之后才可以看到 Server
。
🐳 3. Docker
的常用命令
3.1 Docker Desktop
的使用
3.1.1 Docker Containers
& Images
容器和镜像
Docker Desktop
是 Docker
的图形化界面,Docker Desktop
封装了容器日常使用和管理的各种常用功能,打开控制台面板后,可以看到 Containers
容器和**Images
镜像**,这两个菜单项分别用于查看本机的容器列表和镜像列表。
对于菜单项中的内容,我们可以进行一系列操作。
比如,我们可以点击 RUN
按钮运行一个镜像,等同于执行了 docker run
命令。点击三个小圆点,有几个选项 Inspect
、Pull
、Push to Hub
、Remove
,分别用于查看镜像的详细信息、拉取镜像、推送镜像、移除镜像。
3.1.2 Docker Volumes
逻辑卷
此外,还有 Volumes
逻辑卷 菜单项,在这个菜单项列表中可以看到容器的逻辑卷,逻辑卷是 Docker
中用来存储的。
Docker
容器有一个特点,就是容器中的数据是不会持久化的,当我们创建一个容器的时候,它通常以一个干净的文件系统开始,容器启动之后,我们可以在文件中创建文件、修改文件,但是当容器停止之后,容器中的所有数据都会丢失掉。
如果我们想要对于 Docker
中的数据进行容器的持久化应该怎么做?
逻辑卷就是用来解决这个问题的,它可以将容器中的目录或者指定路径映射到宿主机的某一目录或者位置上,这样就可以将数据保存到宿主机的磁盘上,实现了数据的持久化。
3.1.3 Docker Dev Environments
开发环境
用于管理开发环境,简单来说就是可以创建一个开发环境,然后通过一些代码配置这个开发环境,这样就可以将这个开发环境共享给项目中的其他开发人员,让每个人都在一个相同的环境下进行开发,避免因为环境的不一致导致的各种问题。
🐳 4. 如何从零开始构建一个 Docker
镜像
4.1 容器化和 Dockerfile
**容器化(Containerization)**:就是将应用程序打包成容器,然后在容器中运行应用程序的过程。
容器化的过程可以分为以下几个步骤:
- 创建一个
Dockerfile
:来告诉Docker
构建应用程序镜像所需要的步骤和配置。 - 使用
Dockerfile
构建镜像。 - 使用镜像创建和运行容器。
Dockerfile
是一个文本文件,里面包含了一条条指令,用于告诉 Docker
如何构建镜像,这个镜像中包括了我们应用程序执行的所有命令,如各种依赖、配置环境和运行应用程序所需要的所有内容,一般来说包括:精简版的操作系统(如Alpine
)、应用程序的运行时环境(如NodeJS
、Python
、Java
)、应用程序(如打包好的 jar
包)、应用程序的第三方依赖库或包、应用程序的配置文件、环境变量等。
一般来说,我们会在项目的根目录下创建一个叫 Dockerfile
的文件,在这个文件中写入构建镜像所需要的各种指令之后,Docker
就会根据这个 Dockerfile
文件来构建一个镜像,有了这个镜像后,我们就可以根据这个镜像来创建容器,然后在容器中运行应用程序。
4.2 编写 Dockerfile
- 新建一个名为
HelloDocker
的文件夹,使用VSCode
打开该文件夹 - 在文件夹中创建一个
index.js
文件,简单的输入一些代码内容,比如输出一段内容到控制台
1 | console.log("Hello Docker!"); |
- 我们可以使用
NodeJS
来测试这个JavaScript
文件,NodeJS
是一个运行时环境,它可以让我们在浏览器之外的环境运行JavaScript
代码。JavaScript
和NodeJS
的关系就像Java
和JRE
的关系一样,如果想在浏览器之外的环境中运行JavaScript
代码就需要NodeJS
。可以使用下面的命令运行index.js
。
1 | PS D:\HelloDocker> node index.js |
所以,当我们想要在另一个环境中运行这个应用程序时,都需要执行那些步骤呢?
- 安装操作系统
- 安装
JavaScript
的运行环境 - 复制应用程序、依赖包、配置文件
- 执行启动命令运行程序
而有了
Docker
后,我们可以将上述的步骤写入到Dockerfile
中,剩下的工作交给Docker
自动完成。创建
Dockerfile
文件在
Dockerfile
中,我们需要先指定一个基础镜像,镜像是按层次结构来构建的,每一层都是基于上一层的,所以我们需要先指定一个基础镜像,然后在此基础上添加我们的应用程序。注意
Dockerfile
中不需要注释,这里只是为了便于理解所以添加了注释
1 | # 指定基础镜像 |
4.3 创建镜像
构建
Docker
镜像执行
docker build
命令,hello-docker
是镜像名称;.
表示当前目录,即Dockerfile
所在目录。
1 | PS D:\HelloDocker> docker build -t hello-docker . |
- 执行完成后,我们可以使用命令
docker images
或docker image ls
查看所有镜像。
1 | PS D:\HelloDocker> docker images |
4.4 启动容器
- 使用
docker run
命令运行容器。
1 | PS D:\HelloDocker> docker run hello-docker |
4.5 在其他设备上测试容器
为了测试我们的容器,我们可以将我们的镜像上传到
Docker Hub
或者Harbor
镜像仓库中,上传完成之后,可以使用 Play with Docker 进行测试。上传镜像可以使用
docker push
命令。需要注意的是,推送镜像可能会出现问题:docker:denied: requested access to the resource is denied
,遇到这个问题时,可以参考解决docker:denied: requested access to the resource is denied_docker login - CSDN。① 确保自己登录了
Docker
② 将镜像打
TAG
,使用docker tag hello-docker:latest nilerak/hello-docker:1.0.0
③ 推送镜像,使用
docker push nilerak/hello-docker:1.0.0
使用
docker pull
命令下载镜像文件。
1 | docker pull nilerak/hello-docker:1.0.0 |
🐳 5. 如何运行一个 Docker
容器
🐳 6. Docker Compose
和 Kubernetes
6.1 Docker Compose
Docker Compose 是 Docker 官方的开源项目,是一个用于定义和运行多容器 Docker
应用程序的工具,使用 Yaml
文件配置应用程序的服务,只需运行一条命令即可创建并启动所有的服务。
例如我们的项目可能需要前端(Vue)、后端(SpringBoot)、数据库(MySQL)、缓存(Redis)、负载均衡(Nginx)等多个服务器,这些服务相互独立,但是又存在一定的关联,需要相互配合来工作,前端需要连接后端、后端需要连接数据库。这些服务之间的关联关系,就是 Docker Compose
要解决的问题。它通过一个单独的 docker-compose.yaml
文件来将这一组互相关联的容器组合在一起,形成一个项目,然后使用一条命令 docker compose up
即可启动、停止、重建这些服务,这样就可以非常方便的管理这些服务了。
参考文献
DockerQuickIN