单体应用拆分成微服务后,能够实现快速开发迭代,但因为小服务太多,导致测试和部署的成本提高。
单体应用中,将Spring Boot工程打包成一个war包,然后部署在Linux服务器的Tomcat中就可以了。
拆分成微服务后,修改一个需求,可能会涉及多个微服务,这个时候,被修改过的代码都需要重新测试、打包、部署、上线发布。无形之中,给现场运维人员增加了成倍的工作压力。
微服务通常会在共有云上创建ECS进行扩容,ECS通常只包含了基本的操作系统环境,没有包含运行java的环境jdk,就需要在ECS上安装jdk,而且每个服务依赖的jdk版本可能也不会相同,一般情况下,都会采用jdk8,但有些喜爱前言技术的项目经理,可能要试一下jdk21,毕竟也是一个长期稳定的大版本。
而容器技术可以解决上面的两个问题(代码部署难、缺环境)。
时下容器技术最火的当属Docker,很多小伙伴也用了多年,只知道它是容器技术,可以将程序和依赖打到Docker里,然后发布在Linux服务器中,就完成了程序的部署,一次构建、到处运行,很牛逼,至于其它的,就不知道了,也不想知道~
一、神之容器 Docker
Docker是一个开源的应用容器引擎,让开发者可以打包他们的应用以及依赖包到一个可移植的镜像中,然后发布到任何流行的Linux或Windows操作系统的机器上,也可以实现虚拟化。容器是完全使用沙箱机制,相互之间不会有任何接口。
Docker属于Linux容器的一种封装,提供简单易用的容器使用接口。它是目前最流行的Linux容器解决方案。
一个完整的Docker由以下七个部分组成:
- Docker Client 客户端。
- Docker Daemon 守护进程,提供Docker Server,用于接收Docker Client的请求,Docker Server 通过路由Router与分发调度,找到相应的 Handler 来执行请求。
- Docker Image 镜像,包含Distribution(分发)、Layer(层)、Image(镜像)、Registry(注册中心)、Reference(引用)。
- Docker Driver 驱动,Docker架构中的驱动模块,它主要通过与Docker守护进程进行交互,实现对Docker容器执行环境的定制和管理。
- Docker Graph 内部数据库,Docker Graph是Docker中的一种数据结构,用于记录和跟踪Docker镜像和容器之间的关系;
- Libcontainer 函数库,Libcontainer是Docker的底层容器管理库,它提供了一组接口和函数,用于创建和管理容器。Libcontainer直接与内核交互,负责容器的命名空间、cgroup、网络设备等底层操作。
- Docker Container 容器,Docker Container是Docker中的容器实例,它是通过Driver和Libcontainer共同协作创建出来的。Driver提供了容器的运行环境定制,而Libcontainer则负责容器的具体创建和管理操作。
二、Docker架构图
- 用户使用 Docker Client(客户端) 与 Docker Daemon 建立通信,并发送请求给后者,客户端和守护程序之间通过REST API进行通信,可以使用UNIX套接字或网络接口;
- Docker Daemon(后台守护进程)提供Docker Server,用于接收Docker Client的请求,Docker Server 通过路由Router与分发调度,找到相应的 Handler 来执行请求,Docker Daemon提供Docker Engine,Engine是Docker 架构中的运行引擎,在Docker Engine中,一个Job可以被认为是内部最基本的工作执行单元。Docker可以做的每一项工作,都可以抽象为一个Job。例如,在容器内部运行一个进程,这是一个Job;创建一个新的容器,这也是一个Job。
- Docker Image 镜像,包含Distribution(分发)、Layer(层)、Image(镜像)、Registry(注册中心)、Reference(引用)。
- Docker Driver 驱动,Docker架构中的驱动模块,它主要通过与Docker守护进程进行交互,实现对Docker容器执行环境的定制和管理;
- 当需要容器镜像时,则从 Registry(注册中心) 中下载镜像,并通过镜像管理驱动 Graphdriver 将下载镜像以 Graph 的形式存储;
- Docker Graph 内部数据库,Docker Graph是Docker中的一种数据结构,用于记录和跟踪Docker镜像和容器之间的关系;
- 一个 Repository 表示某类镜像的仓库,同一个 Repository 内的镜像用 Tag 来区分,一个 Registry 包含多个Repository,一个 Repository 包含同类型的多个 Image,并存储着每一个容器镜像的具体信息;GraphDB是一个基于SQLite的小型图数据库,记录容器镜像之间的关系;
- rootfs是Docker容器的根文件系统,它位于bootfs之上,表现为Docker容器的根目录,包含基本的文件和目录。在Docker中,rootfs由内核挂载为“只读”模式,而后通过“联合挂载”技术额外挂载一个“可写”层;
- 通过 Networkdriver 完成Docker容器网络环境的配置,其中包括Docker启动时为Docker环境创建网桥等功能;
- Docker Execdriver是Docker容器的执行驱动,负责创建容器运行命名空间,负责容器资源使用的统计与限制,负责容器内部进程的真正运行等;
- Libcontainer是Docker的底层容器管理库,它提供了一组接口和函数,用于创建和管理容器。Libcontainer直接与内核交互,负责容器的命名空间、cgroup、网络设备等底层操作;
- Docker Container是Docker中的容器实例,它是通过Driver和Libcontainer共同协作创建出来的。Driver提供了容器的运行环境定制,而Libcontainer则负责容器的具体创建和管理操作。Docker Container是Docker架构中服务交付的最终体现形式。实现“一次构建,到处运行”的目标,大大提高了应用程序的部署效率和可移植性。
1、Docker Client 客户端
Docker Client是Docker的客户端工具,也被称为Docker命令行界面(CLI)。它是用户与Docker平台进行交互的主要方式。
Docker Client 的主要作用如下:
- 用户交互界面:Docker Client提供了用户友好的命令行交互界面,用户可以通过输入命令来执行各种Docker操作,例如创建容器、启动容器、停止容器、构建镜像等。
- 容器管理:通过Docker Client,用户可以方便地管理Docker容器。可以创建新的容器、启动、停止、重启容器,并且还可以查看容器的日志、状态等信息。
- 镜像管理:Docker Client也允许用户管理Docker镜像。用户可以搜索、下载、构建、删除镜像等操作,以满足应用程序部署的需求。
- 资源配置:用户可以通过Docker Client配置容器的运行资源,例如CPU、内存等。这样可以确保容器在运行时具有合适的资源配置。
- 网络通信:Docker Client可以与Docker Daemon进行通信,发送请求并接收响应。它使用REST API或其他通信协议与Docker Daemon进行交互,从而实现对Docker容器的远程管理。
Docker Client是用户与Docker平台进行交互的重要工具。它提供了命令行界面,让用户能够方便地管理Docker容器和镜像,并进行资源配置和网络通信等操作。
2、Docker Daemon 守护进程
Docker Daemon是Docker的守护进程,它是Docker平台的后台服务组件,充当服务器角色。
Docker Daemon 的主要作用如下:
- 容器管理:Docker Daemon负责创建、启动、停止、删除和管理Docker容器。它接收来自Docker客户端的请求,并根据请求执行相应的容器管理操作。
- 镜像管理:Docker Daemon也管理Docker镜像。它可以下载、上传、构建和删除镜像,并管理镜像的版本控制和安全性。
- 网络资源管理:Docker Daemon负责创建和管理Docker容器的网络环境。它配置和管理容器的网络设置,确保容器之间的通信和互相访问。
- 数据卷管理:Docker Daemon还管理容器的数据卷,用于持久化存储容器中的数据,保证数据的可靠性和持久性。
Docker Daemon是Docker平台的核心组件,提供容器、镜像、网络和数据卷的管理功能。它扮演着守护进程的角色,确保Docker平台的正常运行和管理。
3、镜像(Image)
在Docker镜像中,Distribution、Layer、Image、Registry和Reference各自扮演了重要角色。
- Distribution(分发):通常涉及到Docker镜像的分发和运输。Docker镜像可以通过不同的方式进行分发,例如直接从Registry下载,或者通过特定的工具导入和导出;
- Layer(层):Docker镜像由多个layer层组成,每层都是一个只读的文件系统。这种分层设计可以实现共享和复用,提高效率。当镜像中的文件发生变化时,Docker只会下载发生变化的层,而不是整体镜像,节省了时间和宽带;
- Image(镜像):镜像是Docker的核心,它是运行容器的基础。镜像包含了运行应用程序的所有文件和依赖,是一个只读模板,可以通过镜像创建新的容器实例;
- Registry(注册中心):Registry是存储和管理Docker镜像的服务器。它是用户上传、下载、管理Docker镜像的地方。例如Dokcer Hub就是一个公共的Registry;
- Reference(引用):引用指的是Docker镜像的一种标识,通过引用,用户可以指定需要操作的特定镜像;
4、Docker Driver 驱动模块
Docker Driver是Docker的驱动模块,主要负责驱动Docker容器的运行。它通过与操作系统的交互,实现对Docker容器的创建、启动、运行和管理等操作。
Docker Driver 的主要作用如下:
- 容器创建与启动:Driver负责根据用户的指令创建新的容器实例,并启动它们。它会与底层操作系统交互,设置好容器运行所需的各种环境和资源。
- 容器运行环境定制:Driver可以根据用户的需求定制容器的运行环境。这包括网络配置、存储挂载、进程管理等,确保容器在特定的环境中按照预期运行。
- 容器状态管理:Driver维护着容器的状态信息,包括容器的运行状态、资源使用情况等。它可以提供容器状态的查询和监控功能,让用户了解容器的实时状态。
- 容器资源管理:Driver还负责管理容器的资源,如CPU、内存、磁盘空间等。它可以对容器使用的资源进行限制和控制,确保容器不会超出预设的资源限制。
Docker Driver是Docker中非常重要的组件,它通过与操作系统的交互,实现了Docker容器的创建、运行和管理等功能,为Docker平台的正常运行提供了底层支持。
5、Docker Graph内部数据库
Docker Graph是Docker中的一种数据结构,用于记录和跟踪Docker镜像和容器之间的关系。
Docker Graph 的主要作用如下:
- 关系追踪:Docker Graph能够记录容器和镜像之间的关系,包括哪个镜像被用来创建哪个容器,容器之间是否存在依赖关系等。这种关系追踪使得用户能够更好地理解和管理容器与镜像之间的关联。
- 资源管理:通过Docker Graph,用户可以更方便地进行资源管理,例如查找和删除不再需要的镜像和容器。它提供了一种全局视图,帮助用户了解整个Docker环境中的资源利用情况。
- 性能优化:Docker Graph可以提供一些性能方面的优化。通过分析和理解Graph中的关系,Docker可以智能地选择最合适的镜像层和缓存策略,从而提高镜像构建和容器启动的速度。
Docker Graph在Docker的较新版本中可能已经被替代或集成到其他组件中,因此具体实现和用法可能会因版本而异。
6、Docker Libcontainer函数库
Docker Libcontainer函数库中包含:
- namespaces:namespaces技术用于实现Docker容器之间的隔离。通过namespaces,可以实现网络、通信、文件、权限等对象的隔离,确保容器在独立的环境中运行,并且相互之间不会产生干扰。这种隔离机制有助于提高容器的安全性和稳定性。
- Cgroups:Cgroups(Control Groups)用于对Docker容器所占用的系统资源进行限制和管理。它可以控制容器的CPU、内存、磁盘I/O等资源的使用量,确保容器不会消耗过多的资源,从而防止系统过载或资源耗尽。
- netlink:netlink是Linux内核提供的一种用于内核与用户空间进程之间通信的机制。在Docker Libcontainer中,netlink主要用于完成Docker容器的网络环境配置和创建。它使得容器能够与网络进行交互,实现网络通信和功能。
- capabilities:capabilities机制用于在Docker容器内部对进程的权限进行更精细的控制。它将超级用户root的权限分割成各种不同的capabilities权限,允许根据需求将特定的权限授予容器内的进程。这种权限管理方式增强了容器的安全性,防止潜在的安全漏洞和攻击。
这些组件和技术在Libcontainer中协作,共同实现了Docker容器的隔离、资源管理、网络通信和权限控制等功能,为Docker平台的稳定性和安全性提供了重要支持。
7、Docker Container 容器实例
Docker Container是Docker中的容器实例,它是通过Driver和Libcontainer共同协作创建出来的。Driver提供了容器的运行环境定制,而Libcontainer则负责容器的具体创建和管理操作。Docker Container是Docker架构中服务交付的最终体现形式。实现“一次构建,到处运行”的目标,大大提高了应用程序的部署效率和可移植性。
Docker Container 的主要作用如下:
- 应用程序的隔离运行:Docker Container提供了轻量级、独立的运行环境,使得应用程序可以在隔离的容器中运行,避免不同应用之间的干扰和冲突;
- 环境一致性:因为Docker Container包含了应用程序及其依赖项,所以可以确保在任何环境中都能以相同的方式运行,提高了应用的可移植性和稳定性;
- 资源控制和隔离:Docker Container允许对每个容器进行资源限制,例如CPU、内存等。这样可以防止某个容器消耗过多资源,确保系统的稳定运行;
- 快速部署和扩展:Docker Container的轻量级特性使得它可以快速启动和停止,非常适合于云计算和微服务架构中的快速部署和横向扩展;
- 版本控制和回滚:通过标记和版本控制,可以轻松管理和回滚容器的版本,提高了应用程序的版本管理和部署的灵活性;
- 安全性增强:Docker Container提供了隔离的运行环境,可以减少系统漏洞和攻击面,提高应用程序的安全性。
Docker Container是Docker技术的核心组件之一,它提供了轻量级、隔离的运行环境,用于部署、运行和管理应用程序。它的出现改变了传统应用部署和运维的方式,提高了开发、测试、运维的效率和质量。
三、Docker安装
1、卸载Docker
sudo yum remove docker \
docker-client \
docker-client-latest \
docker-common \
docker-latest \
docker-latest-logrotate \
docker-logrotate \
docker-engine
2、需要的安装包
yum install -y yum-utils
3、设置镜像仓库
yum-config-manager \
--add-repo \
https://download.docker.com/linux/centos/docker-ce.repo
用国内的。
yum-config-manager --add-repo http://mirrors.aliyun.com/docker-ce/linux/centos/docker-ce.repo
更新软件包索引。
yum mackecache fast
4、安装Docker相关
ce社区版,ee企业版,推荐安装企业版。
yum install docker-ce docker-ce-cli containerd.io。
5、启动Docker
systemctl start docker
6、使用docker version查看版本
7、启动hello world镜像
docker run hello-world
8、卸载
yum remove docker-ce docker-ce-cli containerd.io
rm -rf /var/lib/docker
rm -rf /var/lib/containerd
四、run的流程和docker原理
1、run的流程
2、与传统虚拟化方式对比
这就是Docker为何比虚拟化更快的原因,Docker有着比虚拟机更少的抽象层,docker利用的是宿主机的内核,VM需要的是Guest OS。
五、Docker镜像常用命令
1、基本命令
docker version
docker info
docker 命令 --help #万能命令
docker images。
解释:
- REPOSITORY:镜像的仓库源。
- TAG:镜像的标签。
- IMAGE ID:镜像的ID。
- CREATE:镜像的创建时间。
- SIZE:镜像的大小。
可选项
- -a:列出全部的镜像。
- -q:只显示镜像的ID。
2、搜索镜像
docker search。
可选项
--filter-STATUS-3000 #搜索大于3000的。
3、下载镜像
指定版本下载。
docker pull 镜像名[:tag]。
4、删除镜像
docker rmi -f 镜像id。
六、docker容器常用命令
1、下载容器
docker pull centos。
2、docker run [可选参数] image
参数说明:
- --name:容器名称。
- -d:后台方式运行。
- -it:使用交互方式运行,进入容器查看内容(例如:docker run -it centos /bin/bash)。
- -p :指定容器的端口号 -p 8080:8080(主机端口:容器端口)。
3、列出所有的运行的容器
docker ps [参数]。
- -a:列出当前正在运行的容器。
- -n :显示最近创建的容器。
- -q :只显示容器的编号。
例如:docker ps -aq,显示当前正在运行的容器的编号。
4、删除容器
- docker rm 容器id :不能删除正在运行的容器。
- docker rm -f $(docker ps -a) :删除所有的容器。
- docker ps -a -q|xargs docker rm :删除所有的容器。
5、启动和停止容器
- docker start 容器id。
- docker restart 容器id。
- docker stop 容器id。
- docker kill 容器id,强制停止。
6、进入当前正在运行的容器
- 方式一:docker exec -it 容器id /bin/bash,进入容器后开启一个新的终端(常用)。
- 方式二:docker attach 容器id,进入容器当前正在执行的终端。
7、从容器内拷贝文件到主机
docker cp 容器id:容器内路径 主机路径。
例如:docker cp 容器id:/home/test.java /home。
8、其它常用命令
后台启动容器 -d。
查看日志命令。
docker logs --help。
显示指定行数的日志:
docker logs -tf --tail 10 容器id。
-f:内容,,,-t:时间。
例如:循环执行。
docker run -d centos /bin/sh -c "while;do echo hello world;sleep 1;done"。
显示容器中的进行信息。
查看docker内部的进程信息:docker top 容器id。
查看容器的元数据。
docker inspect --help。
显示容器的所有信息:
docker inspect 容器id。
七、docker常用命令小结
常用命令 | 命令含义 |
attach | 当前shell下attach连接指定运行镜像 |
build | 通过Dockerfile定制镜像 |
commit | 提交当前容器为新的镜像 |
cp | 从容器中拷贝指定文件或者目录到宿主机中 |
create | 创建一个新的容器,同run 但不启动容器 |
diff | 查看docker容器变化 |
events | 从docker服务获取容器实时事件 |
exec | 在已存在的容器上运行命令 |
export | 导出容器的内容流作为一个tar归档文件(对应import) |
history | 展示一个镜像形成历史 |
images | 列出系统当前镜像 |
import | 从tar包中的内容创建一个新的文件系统映像(对应export) |
info | 显示系统相关信息 |
inspect | 查看容器详细信息 |
kill | 强制停止指定docker容器 |
load | 从一个tar包中加载一个镜像(对应save) |
login | 注册或者登陆一个docker源服务器 |
logout | 从当前Docker registry退出 |
logs | 输出当前容器日志信息 |
pause | 暂停容器 |
port | 查看映射端口对应的容器内部源端口 |
ps | 列出容器列表 |
pull | 从docker镜像源服务器拉取指定镜像或者库镜像 |
push | 推送指定镜像或者库镜像至docker源服务器 |
rename | 重命名容器 |
restart | 重启运行的容器 |
rm | 移除一个或者多个容器 |
rmi | 移除一个或多个镜像(无容器使用该镜像才可以删除,否则需要删除相关容器才可以继续或者-f强制删除) |
run | 创建一个新的容器并运行一个命令 |
save | 保存一个镜像为一个tar包(对应load) |
search | 在docker hub中搜索镜像 |
start | 启动容器 |
stats | 统计容器使用资源 |
stop | 停止容器 |
tag | 给镜像打标签 |
top | 查看容器中运行的进程信息 |
unpause | 取消暂停容器 |
version | 查看容器版本号 |
wait | 截取容器停止时的退出状态值 |