微服务架构设计模式-第十二章

第12章 部署微服务应用

部署包含两个相互关联的概念:流程和架构。部署力促包括一些由开发人员和运维人员执行的步骤,以便将软件投入到生产环境。部署架构定义了该软件运行的环境结构。
70-部署
71-生产环境抽象视图
生产环境必须实现四个关键功能:

  • 服务管理接口:使开发人员能够创建、更新和配置服务。理想情况下,这个接口是一个可供命令行和图形部署工具调用的REST API
  • 运行时服务管理:确保始终运行着所需数量的服务实例。如果服务实例崩溃或由于某种原因无法处理请求,则生产环境必须重新启动它。如果运行服务的主机发生崩溃,则必须在其他主机上重新启动这些服务实例
  • 监控:让开发人员深入了解服务正在做什么,包括日志文件和各种应用指标。如果出现问题,必须提醒开发人员。
  • 请求路由:将用户的请求路由到服务。

12.1 部署模式:编程语言特定的发布包格式

12.1.1 使用编程语言特定的发布包格式进行部署的好处

  • 快速部署
    • 直接复制
    • 启动服务耗时很短
  • 高效的资源利用

12.1.2 使用编程语言特定的发布包格式进行部署的弊端

  • 缺乏对技术栈的封装
    • 运维团队必须了解部署每个服务的具体细节。每个服务都需要特定版本的运行时(版本号)。
  • 无法约束服务实例消耗的资源
  • 在同一台计算机上运行多个服务实例时缺少隔离
  • 很难自动判断防止服务实例的位置

12.2 部署模式:将服务部署为虚拟机

72-将服务打包为虚拟机镜像

12.2.1 将服务部署为虚拟机的好处

  • 虚拟机镜像封装了技术栈
  • 隔离的服务实例
  • 使用成熟的云计算基础设施

12.2.2 将服务部署为虚拟机的弊端

  • 资源利用效率较低
  • 部署速度相对较慢
  • 系统管理的额外开销(给操作系统和运行时打补丁)

12.3 部署模式:将服务部署为容器

73-将服务部署为容器

12.3.1 使用Docker部署服务

构建docker镜像

运行docker容器

docker compose,使用yaml文件以声明方式定义一组容器,然后以组的形式启动和停止这些容器

docker in action

12.3.2 将服务部署为容器的好处

  • 封装技术栈,可以用容器的API实现对服务的管理
  • 服务实例是隔离的
  • 服务实例的资源受到限制

12.3.3 将服务部署为容器的弊端

承担大量的容器镜像管理工作

12.4 使用Kubernetes部署FTGO应用程序

kubernetes in action

12.4.1 什么是Kubernetes

主要有三个功能:

  • 资源管理:将一组计算机视为由CPU、内存和存储卷构成的资源池,将计算机集群视为一台计算机
  • 调度:选择要运行容器的机器。默认情况下,调度考虑容器的资源需求和每个节点的可用资源。它还可以实现在同一节点上部署具有亲和性(affinity)的容器,或确保特定的几个容器分散部署在不同的节点之上
  • 服务管理:实现命名和版本化服务的概念,这个概念可以直接映射到微服务架构中的具体服务。编排框架确保始终运行所需数量的正常实例。它实现请求的负载均衡。编排框架也可以执行服务的滚动升级并允许你回滚到旧版本。

74-k8s集群
k8s架构

k8s集群中的计算机角色分为主节点和普通节点。主节点负责管理集群。k8s的普通节点称为 "工作节点",它会运行一个或多个pod,pod是k8s的部署单元,由一组容器组成。

主节点运行多个组件,包括以下内容:

  • API 服务器:用于部署和管理服务的REST API,例如,可被 kubectl 命令行使用
  • etcd:存储集群数据键值的 nosql 数据库
  • 调度器:选择要运行pod的节点
  • 控制器管理器:运行控制器,确保集群状态与预期状态匹配。例如,一种称为复制(replication)控制器的控制器提供启动和终止实例来确保运行所需数量的服务实例

普通节点运行多个组件,包括:

  • kubelet:创建和管理节点上运行的pod
  • kube-proxy:管理网络,包括跨pod的负载均衡
  • pods:应用程序服务

k8s额关键概念

  • pod:Pod是Kubernetes的基本部署单元。它由一个或多个共享IP地址和存储卷的容器组成。服务实例的pod通常由单个容器组成,例如运行JVM的容器。但在某些情况下,Pod包含一个或多个实现支持功能的边车(sidecar)容器。例如,Nginx服务器可以有一个边车容器,定期执行git pul l 以下载最新版本的网站。Pod的生命周期很短,因为Pod的容器或它运行的节点可能会崩溃。
  • Deployment:Pod的声明性规范。Deployment是一个控制器,可确保始终运行所需数量的Pod实例(服务实例)。它通过滚动升级和回滚来支持版本控制。
  • service:向应用程序服务的客户端提供的一个静态/稳定的网络地址。它是基础设施提供的服务发现的一种形式,如第3章所述。每个Service具有一个IP地址和一个可解析为该IP地址的DNS名称,并跨一个或多个Pod对TCP和UDP流量进行负载均衡处理。IP地址和DNS名称只能在Kubernetes内部访问。稍后,我将介绍如何配置可从集群外部访问的服务。
  • configMap:名称与值对的命名集合,用于定义一个或多个应用程序服务的外部化配置。Pod容器的定义可以引用ConfigMap来定义容器的环境变量。它还可以使用ConfigMap在容器内创建配置文件。可以使用Secret来存储敏感信息(如密码),它也是ConfigMap的一种形式。

12.4.2 在Kubernetes上部署Restaurant Service

略

12.4.3 部署API Gateway

k8s service 类型:

  • clusterIP
  • nodePort:可通过集群中所有节点上的集群范围的端口访问。任何集群节点上到该端口的任何流量都会负载均衡到后端 pod,必须选择 30000~32767 范围内的可用端口
  • LoadBalance:该 service 对象自动配置特定于云的负载均衡器

12.4.4 零停机部署

更新正在运行的服务三步骤:
1.使用前面描述的相同过程构建新的容器镜像并将其推送到镜像仓库。唯一的区别是镜像将使用不同的版本标签进行标记,例如,ftgo-restaurant-service:1.1.0.RELEASE。
2.编辑服务部署的 YAML 文件,以便它引用新镜像
3.使用 `kubectl apply -f` 命令更新部署

然后Kubernetes将对Pod进行滚动升级。它将逐步创建运行1.1.0。RELEASE版本的Pod,并终止运行Pod的1.0.0。RELEASE版本。Kubernetes做到这一点的好处在于,它不会终止旧的Pod,直到它们的替换品准备好处理请求。它使用readinessProbe机制(本节前面介绍的健康检查机制)来确定Pod是否已准备就绪。因此,总会有可用于处理请求的Pod。最终,假设新Pod成功启动,所有部署的Pod将运行新版本。

但是如果出现问题并且版本1.1.0。RELEASE的Pod无法启动怎么办? 也许存在一个错误,例如容器镜像名称拼写错误,或新配置属性的环境变量缺失。如果Pod无法启动,则部署将卡住。这时,你有两种选择。一种选择是修复YAML文件并重新运行kubectlapply-f以更新部署。另一种选择是回滚部署。

部署对象维护着称为rollout的部署历史记录。每次更新部署时,都会创建一个新的 rollout。因此,可以通过执行以下命令轻松地将部署回滚到以前的版本:kubectl rollout undo deployment ftgo-restaurant-service

然后,Kubernetes将使用运行旧版本1.0.0.RELEASE的Pod替换运行1.1.0.RELEASE版本的Pod。

Kubernetes部署是在不停机的情况下部署服务的好方法。但是如果在Pod准备好并接收生产流量后才出现错误呢? 在这种情况下,Kubernetes将继续推出新版本,因此越来越多的用户将受到影响。虽然你的监控系统有望检测到问题并快速回滚部署,但你至少会影响一部分用户。为了解决这个问题并使新版本的服务更可靠,我们需要一分为二地看问题:部署这个环节意味着服务在生产环境中运行;发布这个环节意味着使服务可用于处理生产流量。让我们看看如何使用服务网格来实现这一点。

推出新版本的一种更可靠的方法是将部署流程与发布流程分开:

  • 部署流程:让服务开始在生产环境中运行
  • 发布流程:试最终用户可以使用(访问)服务

我们使用以下步骤将服务部署到生产环境中:

  1. 将新版本部署到生产环境中,而不向其路由任何最终用户请求
  2. 在生产中进行测试
  3. 将其发布给少数最终用户
  4. 逐步将其发布给越来越多的用户,直到它处理所有生产流量为止
  5. 任何时候出现问题,请恢复旧版本,否则,一旦你确信新版本正常工作,请删除旧版本

istio 服务网格概述

它是一个网络层,所有服务的网络流量都通过 istio 进行处理。

  • 流量管理:包括服务发现、负载均衡、路由规则和断路器
  • 通信安全:使用传输层安全性(TLS)保护服务间通信
  • 遥测(telemetry):捕获有关网络流量的指标并实施分布式追踪
  • 策略执行:强制实施配额和费率限制
    75-istio架构
    本小节重点介绍 istio 的流量管理功能

istio 由控制平面和数据平面组成。控制平面实现管理功能,包括配置数据平面处理流量路由。数据平面由 envoy 代理组成,每个服务实例一个。

控制平面的两个主要组成部分是 pilot 和 mixer。pilot 从底层基础设施中提取有关已部署服务的信息。例如,当在 k8s 上运行时,pilot 会检索服务和健康 pod。它根据定义的路由规则配置 envoy 代理以路由流量。mixer 从 envoy 代理收集遥测信息并执行策略。

Istio Envoy 代理是Envoy (www.envoyproxy.io)的修改版本。它是一种高性能代理,支持各种协议,包括 TCP HTTP HTTPS 等低级协议以及更高级别的协议。还支持 mongodb、redis 和 dynamoDB 协议。还支持强大的服务间通信,具有断路器、速率限制和自动重试等功能。它可以通过 TLS 进行 envoy 通信来保证应用程序内的安全通信。

istio 使用 envoy 作为边车(sidecar),边车是一个与服务实例并行运行的进程或容器,负责实现服务运行时需要的一些公共功能。在 k8s 上运行时,envoy 代理是服务的 pod 中的一个容器。

使用 k8s 样式的 yaml 配置文件配置 istio。它有一个名为 istioctl 的命令行工具,类似于 kubectl。可以使用 istioctl 来创建、更新和删除规则与策略。

使用 istio 部署服务

  • Kubernetes服务端口必须使用【-】的Istio命名约定,其中 protocal是http、http 2、grpc、mongo 或 redis。如果端口未命名,则 istio 会将端口视为 tcp 端口,并且不会应用基于规则的路由
  • 一个 pod 应该有一个 app 标签,例如 app:ftgo-consumer-service,用于标识服务,以支持Istio分布式跟踪。
  • 为了同时运行多个版本的服务,k8s 部署的名称必须包含版本,例如ftgo-consumer-service-v1、ftgo-consumer-service-v2 等。部署的 pod 应该有一个 version 标签,例如 version:v1,用来指定版本,以便 istio 可以路由到特定版本

12.4.5 使用服务网格分隔部署与发布流程

略

12.5 部署模式:Serverless部署

略

12.5.1 使用AWS Lambda进行Serverless部署

12.5.2 开发Lambda函数

12.5.3 调用Lambda函数

12.5.4 使用Lambda函数的好处

12.5.5 使用Lambda函数的弊端

12.6 使用AWS Lambda和 AwS Gateway部署RESTful服务

略

12.6.1 AwS Lambda版本的Restaurant Service

12.6.2 把服务打包为ZIP文件

12.6.3 使用Serverless框架部署Lambda函数

posted @ 2026-10-02 19:07  LHX2018  阅读(3)  评论(0)    收藏  举报