【云原生】docker+k8微服务容器化实战下篇

博主昵称:跳楼梯企鹅
博主主页面链接:博主主页传送门

博主专栏页面连接:专栏传送门--网路安全技术
创作初心:本博客的初心为与技术朋友们相互交流,每个人的技术都存在短板,博主也是一样,虚心求教,希望各位技术友给予指导。
博主座右铭:发现光,追随光,成为光,散发光;
博主研究方向:渗透测试、机器学习 ;
博主寄语:感谢各位技术友的支持,您的支持就是我前进的动力 ;



目录

一、Docker

1.服务docker化

2.私有仓库管理

3.Docker下的服务通讯

二、服务编排

1.Kubernetes

2.Mesos

3.Swarm

三、CICD

1.Gitlab触发构建

2.Jenkins pipeline流水线

3.Kubect操作k8s集群

四、微服务入门

1.微服务入门

2.优势劣势

3.如何通讯

4.如何发现、更新和部署

五、微服务周边

1.SpringBoot

2.SpringCloud

3.Dubbo

六、微服务开发

1.服务划分

2.rpc通讯

3.跨语言调用


前三部分前面写文章已经分享过了,今天接着继续讲解

前三部分点击链接请点击此处,跳转前三部分

四、微服务器入门

1.微服务器入门

微服务就是由一系列围绕自己也为开发的微小服务构成,他们独立部署运行在自己的进程里,基于分布式的管理。(通俗定义:微服务是一种架构,这种架构是将单个的整体应用程序分割成更小的项目关联的独立的服务。一个服务通常实现一组独立的特性或功能包含自己的业务逻辑和适配器。各个微服务之间的关联通过暴露api来实现。这些独立的微服务不需要部署在同一个虚拟机、同一个系统或同一个应用服务器中。)

2.优势劣势

(1)单体应用

(1)优点

 单一架构模式在项目初期很小的时候开发方便,测试方便,部署方便,运行良好。

(2)缺点

应用随着时间的推进,加入的功能越来越多,最终会变得巨大,一个项目中很有可能数百万行代码,互相之间繁琐的jar包;

久而久之,开发效率低,代码维护困难;

还有一个如果想整体应用采用新的技术,新的框架或者语言,那是不可能的;

任意模块的漏洞或者错误都会影响整个应用,降低系统的可靠性。

(2)微服务架构应用

(1)优点:

将服务拆分成多个单一职责的小的服务,进行单独部署,服务之间通过网络进行通信;

每个服务应该有自己单独的管理团队,高度自治;

服务各自有自己单独的职责,服务之间松耦合,避免因一个模块的问题导致服务崩溃

(2)缺点

 开发人员要处理分布式系统的复杂性;

多服务运维 难度随着服务的增加,运维的压力也在增大;

服务治理和服务监控关键;

3.如何通讯

无代理模式

 在这里,我们使微服务直接相互通信。你可以使用 HTTP 进行传统的请求响应,也可以使用 websocket(或 HTTP2)进行流式传输。
两个或多个微服务之间绝对没有中间节点(路由器和负载均衡器除外)。你可以直接连接到任何服务,只要你知道它们的服务地址和它们使用的 API。
听起来很基础,对吗?差不多是。有一些很棒的协议,例如 GRPC,可以使生活更加轻松。


优点:

  • 低延迟:此方法具有最低的延迟。这里没有代理,因此它很快。施加的限制主要是由于不良的 API 实现。但是同样,GRPC 之类的工具可确保您在 API 层获得最佳性能。
  • 易于实施:无代理的设计易于可视化和实施。这使生活变得更加轻松,世界变得更加幸福。
  • 易于调试:这种方法非常易于调试,尤其是在我要讨论的下一个方法中。在分布式系统中,调试或跟踪错误所在的位置非常重要。一天多次发布新版本时,这一点变得尤为重要。
  • 高吞吐量:在这种机制中,实际上是在工作而不是路由上花费了更多的CPU。现在可能还不那么明显,但是有代理的设计会使这一点更加清楚。大多数数据库 API 实际上使用无代理设计也就不足为奇了。

缺点:

  • 服务发现:在这种设计中,服务发现至关重要。服务发现机制需要具有足够的响应能力和可伸缩性,以反映集群的最新状态。
  • 连接噩梦:想象一下所有微服务需要相互连接,那将有很多联系。这些连接大多数都是相当空闲的。结果,浪费了很多资源。
  • 紧耦合:从本质上讲,无代理设计是紧耦合的。假设您有一个微服务来处理在线支付,现在您希望另一个微服务能够为您提供每分钟发生的付款数量的实时更新。这将需要您在多个微服务中进行修改,这是不希望的。

在许多情况下,无代理的设计是行不通的。您通常需要简单地发布一次消息,并让多个订阅者消费它。这就是代理模式。

4.如何发现、更新和部署

服务发现

所有的表现形式都是ip+端口的形式。

  • 传统服务

服务比较少的话,可以通过下面的方式。如果服务很多的话,基本运维人员都崩溃死了。

  • 微服务

服务太多的话,需要一种服务发现的机制。

  1. 客户端的发现
  2. 服务端的发现

 

部署更新和扩容

  • 传统服务

适合小项目,服务少,服务器少。

  1. 新服务的部署,代码写好,内网测试通过,上线,跟运维交涉那台服务器比较空闲,资源比较吃紧的情况,需要等待服务器到来在进行部署。服务器有了告诉运维将那个应用拷贝到我们的服务器上,可能通过ftp或者是自动化的方式,如果是web方法会需要拷贝一个tomcat分配一个端口号。查询服务器那些端口被用了,找一个没有被占用的,跟你的域名做域名解析,修改nginx,反向代理指向刚才的tomcat上。
  2. 更新直接ftp或者自动化更新下旧代码,直接用新代码更新就可以了。
  3. 任何应用都是2个实例,让服务高可用,所以更新代码的时候需要更新2次。下线一台,更新代码,上线。如果自动化做的不太好的话,基本人工成本很高
  4. 扩容跟部署一样都比较麻烦。
  • 微服务

服务数据居多,更新上线频繁。微服务如何解决这些问题呢 什么是服务排版,服务的发现,服务部署,服务更新,扩容,简化。

流行的服务编排工具

可以解决微服务遇到本节问题的解决

五、微服务器周边

1.SpringBoot

Spring Boot核心功能

  • 可以独立运行的Spring项目:可以以jar的形式独立运行,通过java -jar xx.jar即可运行
  • 内嵌servlet容器:可以选择内嵌tomcat,jetty等
  • 提供servlet简化maven配置:一个maven项目,使用了jar spring-boot-starter-web时,就会自动加载Spring-boot的依赖包
  • 自动配置spring:Spring boot会根据在类路径中的jar包、类,为jar包中的类自动封装配置bean
  • 准生产的应用健康:提供基于httpssh elnet运行时的项目进行监控
  • 无代码生成和xml配置:主要通过条件注解来实现

原理

Spring Boot常用的Starter (启动器)如下。

Spring-boot- strterlogging:使用Spring Boot默认的日志框架Logback。
Spring-boot-starter-log4j:添加Log4j的支持。
Spring-boot-starter-web:支持Web应用开发,包含Tomcat和Spring mvc。
Spring-boot-starter-tomcat:使用Spring Boot默认的Tomcat作为应用服务器。
Spring-boot- sarerjetty:使用Jetty而不是默认的Tomcat作为应用服务器。
Spring-boot- starter-test:包含常用的测试所需的依赖,如JUnit、Hamcrest、 Mockito 和Spring-test等。
Spring-boot-starter-AOP:包含Spring-AOP和AspectJ来支持面向切面编程(AOP)。
Spring-boot-starter-security:包含Spring-security。
Spring-boot-starter-jdbc:支持使用JDBC访问数据库。
Spring-boot-starter-redis:支持使用Redis.Spring-boot-starter-data-mongodb:包含Spring-data-mongodb 来支持MongoDB。
Spring-boot-starter-data-jpa:包含Spring-data-jpa、 Spring-orm 和Hibernate来支持JPA。Spring- boot starter amqp:通过Spring-rabbit支持AMQP。
Spring-boot-starter-actuator:添加适用于生产环境的功能,如性能指标和监测等功能。

2.SpringCloud

Spring Cloud为开发人员构建微服务架构提供了完整的解决方案,SpringCloud是若干个框架的集合,它包括spring-cloud-config、spring-cloud-bus等近20个子项目,它提供了服务治理、服务网关、智能路由、负载均衡、断路器、监控跟踪、分布式消息队列、配置管理等领域的解决方案

Spring Cloud技术栈

Spring Cloud 提供一站式的微服务架构解决方案,如下图:

 

为什么使用Spring Cloud

  微服务架构的优点表明它可以提高我们的生产力,但是分布式系统本身的技术成本问题给互联网那些创业型公司不少的挑战,阿里、百度等巨头所提供的微服务技术只是解决其中某个问题,而整合封装这些优秀的技术恐怕是Spring最擅长的领域了,Spring Cloud也正因为此而诞生。
  使用Spring Cloud来构建微服务架构可以省去你整合各家技术的成本,Spring Cloud为我们构建微服务架构提供了一站式的解决方案,就好比当初Spring诞生是为解决EJB企业应用开发的众多问题而提供的一站式轻量级企业应用开发解决方案一样,随着使用Spring Cloud公司数量的增加,相信微服务将被Spring Cloud一统江湖。

服务治理

什么是服务治理
  微服务架构的缺点中最主要的就是由于微服务数量众多导致维护成本巨大,服务治理为解决此问题而产生的。服务治理的作用是让维护人员从人工维护中解放出来,由服务自维护,微服务作为服务提供方主动向服务治理中心注册,服务的消费方通过服务治理中心查询需要的服务并进行调用。
如下图:

 

 

Spring Cloud Eureka
  Spring Cloud Eureka 是对Netflix公司的Eureka的二次封装,它实现了服务治理的功能,Spring Cloud Eureka提供服务端与客户端,服务端即是服务注册中心,客户端完成服务的注册与发现。服务端和客户端均采用Java语言编写(Eureka支持多语言)。
  如下图显示了Eureka Server与Eureka Client的关系:

 

 

 

负载均衡

什么是负载均衡
  负载均衡是微服务架构中必须使用的技术,通过负载均衡来实现系统的高可用、集群扩容等功能。负载均衡可通过硬件设备及软件来实现,硬件比如:F5、Array等 ,软件比如:LVS、Nginx等 。
如下图是负载均衡的架构图:

 

 

  用户请求先到达负载均衡器(也相当于一个服务),负载均衡器根据负载均衡算法将请求转发到微服务。负载均衡算法有:轮训、随机、加权轮训、加权随机、地址哈希等方法,负载均衡器维护一份服务列表,根据负载均衡算法将请求转发到相应的微服务上,所以负载均衡可以为微服务集群分担请求,降低系统的压力。

Spring Cloud Ribbon
  Spring Cloud Ribbon是基于客户端的负载均衡工具,负载均衡分为服务端负载均衡和客户端负载均衡,3.1小节的图形指的是服务端负载均衡,客户端负载均衡与服务端负载均衡的区别在于客户端要维护一份服务列表,Ribbon从Eureka Server获取服务列表,Ribbon根据负载均衡算法直接请求到具体的微服务,中间省去了负载均衡服务。
  如下图是Ribbon负载均衡的流程图:

 

 

 

3.Dubbo

dubbo+zookeeper+spring/springboot

基于java的分布式服务治理框架Dubbo,它致力于提供高性能和透明化的RPC远程服务调用方案,以及SOA服务治理方案,使得应用可以通过高性能RPC实现服务的输出、输入功能和spring框架无缝集成。Dubbo包含远程通讯、集群容错和自动发现三个核心部分。

当前由于RPC协议、注册中心元数据不匹配问题,在面临微服务基础框架选型时Dubbo与Spring Cloud是只能二选一,Dubbo之后会积极寻求适配到Spring Cloud生态,比如作为Spring Cloud的二进制通信方案来发挥Dubbo的性能优势,或者Dubbo通过模块化以及对http的支持适配到Spring Cloud。

六、微服务器开发

1.服务器划分

微服务架构被广泛用于互联网公司,其优势在于每个服务足够小,相互之间具备隔离性。配合一些基础设施,能够使得需求快速迭代上线。但是每个服务的粒度应该多大呢,服务之间的关系应该是怎样的呢?首先我们来探讨一下微服务划分的目标。微服务划分涉及到两个对象,一个是微服务,一个是开发人员。所以目标是高效有序将微服务及开发人员组织起来。
 

 

 

按接口(业务)划分

    不同的服务解决不同业务问题。问题就是公共模块(鉴权、底层方法)我要写多套。适用于中型团队,因为公共模块也不是天天改。最大程度将业务耦合性降低,A模块挂了不影响B模块,而且模块可以分配给不同的人,单独治理。线下麻烦点,但是线上稳定点。

举例:账号模块,此时可能是每个单体里面都有一套账号数据生成代码,然后用同一个git维护,一旦更新了就所有单体都要更新。尽管也是模块化逻辑,但是最终它还是会打包并部署为单体式应用。

问题:

    代码冗余严重。
    单机扛不住只能上负载均衡,查日志可能要查多台机器。更新也是,要批量上代码。
    数据库难以隔离,尤其是用户这种量最多的数据,可能一个bug导致全盘慢。
    故障无法转移,A机器挂了, B机器的代码是一样的,基本也会挂。
    影响的是一个整体业务,无法降级,无法熔断。挂就是一个业务挂。

按模块(数据)划分

    不同的服务提供不同的数据。

适用于大型公司,业务量很大,每个模块都是一个小团队负责。最大程度减少沟通成本。因为当人员数量上来后,最大的消耗并不是编码时间,而是沟通时间。

举例:我将账号集中到一个服务,所有人需要账号信息都找我来拿,然后我这边用负载均衡、集群保证我的高可用,如果有人要更新用户数据,要我走我的接口,要么走我的消息队列,我来维护账号数据的一致性。

围绕业务或者数据构建,服务关注单一业务。服务间采用轻量级的通信机制,可以全自动独立部署,可以使用不同的编程语言和数据存储技术。微服务架构通过业务拆分实现服务组件化,通过组件组合快速开发系统,业务单一的服务组件又可以独立部署,使得整个系统变得清晰灵活。
分多细

细的好处:

    (1)服务都能够独立部署
    (2)扩容和缩容方便,有利于提高资源利用率
    (3)拆得越细,耦合相对会减小
    (4)拆得越细,容错相对会更好,一个服务出问题不影响其他服务
    (5)扩展性更好

细的坏处:

    (1)拆得越细,系统越复杂
    (2)系统之间的依赖关系也更复杂
    (3)运维复杂度提升
    (4)监控更加复杂
    (5)出问题时定位问题更难

2.rpc通讯

在单体式应用中,各个模块之间的调用是通过编程语言级别的方法或者函数来实现的。但是一个基于微服务的分布式应用是运行在多台机器上的。一般来说,每个服务实例都是一个进程。因此,如下图所示,服务之间的交互必须通过进程间通信(RPC)来实现。

 

RPC实现技术

服务之间的通信采用同步的请求/响应模式,可以选择基于HTTP的REST或者Thrift。服务之间的通信采用异步的、基于消息的通信模式,可以选择AMQP或者STOMP。大量开源消息中间件可供选择,比如RabbitMQ、Apache Kafka、Apache ActiveMQ和NSQ。消息格式可以选择基于文本的,比如 JSON和XML;二进制格式(效率更高)的,比如Avro和Protocol Buffer。

 采用异步的,基于消息的通信模式
例如打车软件如何使用消息发布/订阅:

行程管理服务在发布-订阅channel内创建一个行程消息,并通知调度服务有一个新的行程请求,调度服务发现一个可用的司机然后向发布-订阅channel写入司机建议消息(Driver Proposed message)来通知其他服务。

 采用同步的,基于请求/响应的通信模式
打车软件如何使用REST:

乘客通过移动端向行程管理服务的/trips资源提交了一个POST请求。行程管理服务收到请求之后,会发送一个GET请求到乘客管理服务以获取乘客信息。当确认乘客信息之后,紧接着会创建一个行程,并向移动端返回201状态码响应。

使用基于HTTP的协议的好处:

  • HTTP非常简单并且大家都很熟悉。
  • 可以使用浏览器扩展(比如Postman)或者curl之类的命令行来测试API。
  • 内置支持请求/响应模式的通信。
  • HTTP对防火墙友好。
  • 不需要中间代理,简化了系统架构。

使用基于HTTP的协议的不足之处:

  • 只支持请求/响应模式交互。可以使用HTTP通知,但是服务端必须一直发送HTTP响应才行。
  • 因为客户端和服务端直接通信(没有代理或者buffer机制),在交互期间必须都在线。
  • 客户端必须知道每个服务实例的URL。客户端必须使用服务实例发现机制。

3.跨语言调用

Sidecar

Spring Cloud Netflix Sidecar 包含一个简单的http api来获取给定服务的所有实例(即主机和端口)。然后可以通过从Eureka获取其路由条目的嵌入式Zuul代理来代理服务调用。可以通过主机查找或通过Zuul代理访问Spring Cloud Config服务器。但是第三方程序必须执行健康检查(服务心跳检测),以便Sidecar可以根据应用程序启动或关闭时,向eureka报告。

Sidecar使用步骤

1.需要一个第三方的程序,可以是python,nodejs,php等一系列非java语言编写的程序,本文我们使用了一个java编写的第三方接口程序。

2.第三方程序提供health接口,接口返回json格式的字符串

3.创建sidecar项目

<1>引入坐标依赖  

<parent>
   <groupId>org.springframework.boot</groupId>
   <artifactId>spring-boot-starter-parent</artifactId>
   <version>2.3.3.RELEASE</version>
   <relativePath/> <!-- lookup parent from repository -->
</parent>

<dependencies>
   <dependency>
      <groupId>com.ctrip.framework.apollo</groupId>
      <artifactId>apollo-client</artifactId>
      <version>1.4.0</version>
   </dependency>
   <dependency>
      <groupId>org.springframework.cloud</groupId>
      <artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
   </dependency>
   <dependency>
      <groupId>org.springframework.cloud</groupId>
      <artifactId>spring-cloud-netflix-sidecar</artifactId>
   </dependency>
</dependencies>

<2>配置文件   

spring:
  application:
    name: microservice-sidecar  #服务名
server:
  port: 8070
eureka: #加入到eureka
  client:
    service-url:
      defaultZone: http://localhost:8761/eureka
  instance:
    prefer-ip-address: true
sidecar:
  port: 8060     #异构微服务的端口
  healthUri: http://localhost:8060/health  #对应第三方程序的health接口

相关文章

最近一直在开发Apworks框架的案例代码,同时也在一起修复Apw...
最近每天都在空闲时间努力编写Apworks框架的案例代码WeText。...
在《Kubernetes中分布式存储Rook-Ceph部署快速演练》文章中,...
最近在项目中有涉及到Kubernetes的分布式存储部分的内容,也...
CentOS下Docker与.netcore(一) 之 安装 CentOS下Docker与.ne...
CentOS下Docker与.netcore(一) 之 安装 CentOS下Docker与.ne...