Docker 为什么出现 解决哪些问题 VS 虚拟机

news/2024/11/24 0:08:11/

传统分层架构 vs 微服务


对于微服务来说,有些服务可能依赖于数据,如果你需要依赖于数据存储,依赖于数据库,它推从的就是每个微服务维护自己的数据库,微服务和微服务之间只是通过网络调用去完成通信。

先从应用架构来看,容器解决了什么问题。

左边是单体架构,单体架构有什么特点呢?单体架构其实最早期的时候,开设一个网站,可能就一个war包,所有的业务逻辑都揉在一起。

这种紧耦合应用架构会导致,随着业务的复杂性提升,整个网站的维护成本会变的很高,比如修改一点功能,那么整个部分都得更新。(所有的功能逻辑都糅合在一起)

为了解决这个问题,后面出现了微服务,微服务可以点到点的通信,也可以开放一个统一的api网关,然后微服务和微服务之间去通信。这样也会带来一些问题,如右边这张图,一个大的平台可能会切分为几百上千个微服务,在一个业务里面,用户可能点击了页面上面的某个按钮,这可能是微服务调用微服务再去调用微服务,有可能一个业务流后面前端点击了一个按钮,后端是有几百个应用在互相调用。

这样在业务架构上面就需要考虑A服务调用B服务的时候,服务发现怎么做。一般想要调用,那么得知道服务的地址是什么,一般都是IP地址加上端口。所以在服务发布的时候,不管部署在虚拟机还是物理机,要有独立的IP和端口,有一个固定访问的URL。这样将服务发布出去就可以来调用了。

上面就是服务发布所需要了解的。

传统方式是有一个物理机,这个物理机可以将很多应用放上去,这个机器有一个IP但是可以有多个端口,所以可以将很多不同的服务根据端口不同发布到这个机器上面,带来的挑战就是因为IP只有一个,8080端口被占用,多个web服务就需要换端口。

随着时间发展就出现了虚拟化技术,一个物理机很大,我需要部署很多应用,就可以切成不同的虚拟机。每个虚拟机是独立的一个操作系统,这样的话其实就是每一个虚拟机都有自己独立的IP。所以可以在第一个虚拟机里面安装web应用,因为IP不一样可以在第二个虚拟机里面也安装web应用。这样就可以都占用8080端口。

通过这样就将资源做了一个切分,服务可以运行在默认的端口上面,因为都有独立的IP。

虚拟化引入的复杂性使我们运维成本和应用的性能都会有所下降。

有没有轻量级的方法实现这个目的?

传统的服务打包部署都非常简单,因为要将整个系统打包到一起了,一个配置文件和强悍的机器就可以将其启动起来了,但是还是有一些问题,比如一个系统用的功能是比较多的,有些功能用的比较少,对有些功能比较重要,可能要部署多份,那么所有的组件都需要被重复部署。

同时启动慢,调用关系混乱,修改一个bug引入10个bug。

微服务和微服务之间是基于网络调用去通信的,

微服务改造


分离微服务的方法建议∶

  • 审视并发现可以分离的业务逻辑业务逻辑(高内聚,低耦合,看看哪些业务是相对集中的,它们是一套业务逻辑,这些业务逻辑就天然的就应该是同一个组件)
  • 寻找天生隔离的代码模块,可以借助于静态代码分析工具

不同并发规模,不同内存需求的模块都可以分离出不同的微服务,此方法可提高资源利用率,节省成本一些常用的可微服务化的组件∶

  • 用户和账户管理
  • 授权和会话管理
  • 系统配置
  • 通知和通讯服务
  • 照片,多媒体,元数据等

有些业务模块没有很直接的方法去理解,有些工具可以去做代码扫描,去看哪些代码它们之间包调用的很少,如果两个包完全没有调用,往往意味着它们两个的逻辑是独立的,如果逻辑独立,那么其实它天然的就可以切分为不同的业务

分解原则∶基于 Size, Scope and capabilities

很多时候,我们会去探讨第一要将微服务切分到多维,这样就要探讨微服务的大小了,第二微服务的范围,第三微服务提供的能力。就是一个微服务平台,微服务子系统所支持的功能范围是什么,先确定好功能范围,再确定多维。

举个例子:listio是基于kubernetes上面一个服务网格治理平台,早期追求架构的纯粹性,一个控制面很多组件,好多组件从架构来说非常清晰,设计的非常好,后面就陷入了困境,一个控制面很多组件,当你做系统升级的时候,这个升级就陷入了困境,先升级哪个组件,后升级哪个组件,中间是否会有业务中断,这就会造成很多的困扰。

所以做个取舍,比如一些组件是一个团队维护的,那就合并好了,将一些组件变为一个组件了,这样升级的风险降低了,维护成本降低,这里面没有绝对的原则,完全看你的业务场景。

当去定义一个微服务的时候,功能的切分是一个方面,同时要考虑多种因素,比如团队的范围是什么,以及微服务未来升级的可维护性。

微服务之间通信


点对点:系统里面有很多微服务,这些微服务之间可以彼此通信,微服务都可以对外暴露接口,作为客户端可以直接访问任意一个服务,这些好处是更加自制了,对其他组件依赖少了,缺点如上。

点对点最佳实践是集群内部通过点对点。

通常来说微服务最佳实践就是点对点和api网官结合起来,外部有个客户端,要访问不同点内部服务,它的请求不会直接发到这个服务里面去,而是通过一个集中的api网关发起,这个客户端就直接将请求发到api网关,是一个集中的入口,在它的请求里面无论是通过header还是url来告诉api网关要访问哪个后端服务。那么这样的话api网关就可以将这个服务直接转到后端服务,这样api网关就可以做很多事情,比如说认证,比如说鉴权,比如说审计等,这些事情都可以在api网关当中集中去做掉。

请求给到后端的服务,那么微服务之间也有互相调用,那么它们之间可以互相调用,不要求每次调用都经过api网关。

Docker


  • 基于 Linux 内核的 Cgroup,Namespace,以及Union FS 等技术对进程进行封装隔离,属于操作系统层面的虚拟化技术,由于隔离的进程独立于宿主和其它的隔离的进程,因此也称其为容器。
  • 最初实现是基于 LXC,从 0.7 以后开始去除 LXC,转而使用自行开发的 Libcontainer,从1.11 开始,则进一步演进为使用 runC 和 Containerd。
  • Docker 在容器的基础上,进行了进一步的封装,从文件系统、网络互联到进程隔离等等,极 大的简化了容器的创建和维护,使得 Docker 技术比虚拟机技术更为轻便、快捷。

虚拟机和容器运行态的对比


来看一个完整的虚拟机技术栈:最下面是服务器,在这个服务器基础之上需要安装一个host os,host os上面是hypervisor(hypervisor是用来启动各个虚拟机的)。这个是在物理机上面需要安装的软件。

要在上面启动一个虚拟机,会去再去启动一个gust os,它会去模拟一个完整的操作系统,如果需要部署应用需要在上面安装中间件,依赖,最后部署应用。

可以看到这里面有两次操作系统,针对虚拟化技术来讲,最大的挑战是 任何问题的分析变的复杂。

  1. 比如一个网络问题,可能出现在上面这层,也可能出现在下面这层。调试就变得复杂。
  2. 然后性能也不会很好,就比如网络,任何的数据包进来要在主机的hostos走一遍,然后gustos再走一遍。
  3. 由于gustos是一个完整的操作系统,所以需要保留一些资源去支撑这个操作系统。这样资源利用率就降低了,因为会将一部分资源来支撑这个操作系统。

容器就变的简单多了,安装好操作系统之后,上面就是一个轻量级的docker引擎,再上面是就是你的应用了,所以只有一层操作系统。

整个操作系统资源基本上都是给应用的,因为docker engine是不吃资源的,所有资源都是给应用的。

所以相比虚拟机来说性能和资源利用率都提高了。(虚拟机技术需要虚拟一个操作系统的,这就需要完整的操作系统的加载,这个是需要占用内存,要维护系统需要有自己kernel,这块需要占用CPU,所以会有一部分资源来支撑这个操作系统,这些资源是不能给业务使用的,所以从整体来看,资源利用率会比较低

docker本身就是在主机上面启动进程这样一个过程,所以它就是一个简单的fork,在排查问题的时候也是相对简单的,因为整个技术栈很短。

性能对比


容器秒级启动,甚至更短的毫秒级启动,反正也就是一个fork操作。但马是虚拟机需要分钟级别才启动起来。

对于硬盘使用容器有个非常聪明的办法,容器镜像那块细说,一般来说基础镜像并且还是共享的。

但是虚拟机动不动镜像几百兆,几个G,这样硬盘的使用容器更加占用优势。

容器本来就是在主机上跑的原生的这种进程,你可以将其理解为裸金属的机器上系统性能,如果慢要具体排查一下具体什么问题,比如给的资源少了,网络传输慢了。

虚拟机是弱于物理机的,因为有一个虚拟层,虚拟层意味着针对虚拟化的特殊处理,比如网络包,协议栈可能需要多次处理,这样的性能就不会很好,虚拟机一台机器可能最多支持几十个了,

为什么要用 Docker


  • 更高效的利用系统资源(所有系统资源都是给应用的)
  • 更快速的启动时间(任何容器里面运行的应用,它只是在主机上面普通的进程,所以应用启动的时间就是主机启动应用的时间,而不需要启动额外的os)
  • 一致的运行环境
  • 持续交付和部署
  • 更轻松的迁移
  • 更轻松的维护和扩展

容器操作


启动:

docker run-it 交互的方式去运行
-d  后台运行,以daemon的方式去运行这个服务
-p  端口映射
-v  磁盘挂载[root@docker ~]# docker run -itd -p 88:80 nginx
e70a5541fa9992b1b7b663c359fed63722eff2ce1e29665a6f6bba9993716c0d
[root@docker ~]# docker ps
CONTAINER ID   IMAGE     COMMAND                  CREATED         STATUS         PORTS                               NAMES
e70a5541fa99   nginx     "/docker-entrypoint.??   3 seconds ago   Up 2 seconds   0.0.0.0:88->80/tcp, :::88->80/tcp   hardcore_ride

启动已终止容器

docker start

停止容器

docker stop

查看容器进程

docker ps

你只需要通过一条简单的命令就可以按照你的要求,,启动一个新的容器进程。

docker有镜像的概念,就像就像虚拟机的镜像类似。

查看容器细节:
docker inspect <containerid>

进入容器:

docker attach
docker exec[root@docker ~]# docker exec -it e70a5541fa99 bash
root@e70a5541fa99:/# cat /etc/resolv.conf 
# Generated by NetworkManager
search sh1.qingcloud.com
nameserver 100.64.7.3

通过 nsenter:

PID=$(docker inspect --format "{{ .State.Pid }}" <container>)
$ nsenter --target $PID --mount --uts --ipc --net --pid

拷贝文件至容器内:

docker cp file1 <containerid>:/file-to-path[root@docker ~]# docker cp file e70a5541fa99:/
root@e70a5541fa99:/# exit
exit

先将基础镜像从dockerhub上面拉取下来,可以通过env来指定一些环境变量,可以通过add的操作将之前编译好的文件添加到这个容器镜像里面去,那么它实际上做了一个copy,最后通过entrypoint命令来指定容器镜像在运行的时候启动哪个程序。

之后通过构建镜像和推送镜像到镜像仓库,那么就可以使用docker run的命令来拉取这个镜像并且运行了。

容器启动的时候会有一个entrypoint的进程,入口进程,那个进程就是在你的pid namspace里面看到1的进程号,其他进程都是那个进程fork出来的。


http://www.ppmy.cn/news/533003.html

相关文章

秋招·记录

10月23日 多益网络 笔试 G 10月24日 理想汽车 笔试 10月26日 公诚管理咨询 一面 调岗>招标/投标代理 拒 10月26日 广联达 笔试 G 10月27日 创必承 笔试 10月27日 广州乐牛游戏 笔试 10月28日 惠州西文思 一面 10月28日 惠州佰维 一面 10月30日 华勤 笔试 10月30…

TCP 连接建立 故障排查

TCP连接的状态详解以及故障排查 我们通过了解TCP各个状态&#xff0c;可以排除和定位网络或系统故障时大有帮助。 1、TCP状态 了解TCP之前&#xff0c;先了解几个命令&#xff1a; linux查看tcp的状态命令&#xff1a; 1) netstat -nat 查看TCP各个状态的数量 2)lsof -i:…

Pormetheus k8s服务发现配置详解

创建sa账号&#xff0c;在k8s集群的master节点操作 #创建一个sa账号 对sa账号授权&#xff0c;这样普罗米修斯才能对k8s集群有一定的权限&#xff0c;采集其他节点的信息。、 [rootmaster ~]# kubectl create serviceaccount monitor -n monitor serviceaccount/monitor crea…

Ubuntu 22.04 一次及其繁琐的 允许 Traceroute 探测漏洞修复之旅

前言&#xff1a;允许 Traceroute 探测是绿盟漏洞扫描器报出来的一个漏洞&#xff0c;如下图&#xff1a; 我的系统是ubuntu 22.04&#xff0c;但由于是用户提供的虚拟机&#xff0c;会有些定制的部分&#xff0c;具体定制了哪部分就不知道了&#xff0c;直接描述问题。 解决问…

RK3399教程:wifi驱动调试技巧

公众号 欢迎扫码关注本人微信公众号&#xff1a;公众号上分享更多嵌入式知识和资料&#xff0c;分享个人学习嵌入式的心得体会。欢迎大家一起来玩呀。 疑问点&#xff1f; Android hal层需要配置那些东西&#xff1f; rk3399的wifi模组自适应支持多款wifi是什么技术原理&am…

机器学习平台建设

本文从机器学习平台的架构开始&#xff0c;再到具体的功能&#xff0c;然后从需求的角度带给读者思考&#xff0c;找到合适的机器学习平台建设之路。最后&#xff0c;推荐了微软开源开放的机器学习平台OpenPAI&#xff0c;是可私有部署的机器学习训练平台。 本文不少要点都可以…

java计算机毕业设计花田音乐网站源码+mysql数据库+系统+lw文档+部署

java计算机毕业设计花田音乐网站源码mysql数据库系统lw文档部署 java计算机毕业设计花田音乐网站源码mysql数据库系统lw文档部署 本源码技术栈&#xff1a; 项目架构&#xff1a;B/S架构 开发语言&#xff1a;Java语言 开发软件&#xff1a;idea eclipse 前端技术&#xff…

java计算机毕业设计高校实习管理平台系统源码+mysql数据库+系统+lw文档+部署

java计算机毕业设计高校实习管理平台系统源码mysql数据库系统lw文档部署 java计算机毕业设计高校实习管理平台系统源码mysql数据库系统lw文档部署 本源码技术栈&#xff1a; 项目架构&#xff1a;B/S架构 开发语言&#xff1a;Java语言 开发软件&#xff1a;idea eclipse 前…