Blog

从 ECS、堡垒机到 K8s:理解云原生和分布式系统基础

把 ECS、堡垒机、容器、容器服务、K8s、微服务、分布式系统、回调地址、接口调用和服务调用串成一条清晰的学习线。

  • 云计算
  • Kubernetes
  • 微服务
  • 分布式系统

学习云计算、后端部署和分布式系统时,经常会同时遇到 ECS、堡垒机、容器、K8s、微服务、服务调用、回调地址这些词。它们不是同一个层级的概念,但确实会在同一套系统里一起出现。

可以先用一句话建立整体感觉:

ECS 是机器资源,堡垒机是安全入口,容器是应用运行的标准盒子,K8s 是管理容器的平台,微服务是业务拆分方式,分布式系统是多个服务通过网络协作形成的整体。

一张图看整体关系

一个典型的云上系统可能长这样:

图解一张图看整体关系
        开发者/运维人员
  |
  v
堡垒机
  |
  v
ECS 云服务器集群
  |
  v
K8s / 容器服务
  |
  v
多个业务服务实例
  |
  v
数据库、缓存、消息队列、第三方平台
      

这张图里,每一层解决的问题都不一样。

堡垒机解决“谁能登录机器、登录后做了什么”的安全审计问题。ECS 提供实际的计算资源。容器把应用和运行环境打包起来。K8s 或云厂商的容器服务负责把这些容器批量运行、扩容、重启和发布。微服务则是业务系统内部的拆分方式。分布式系统是这些服务共同协作后的系统形态。

ECS:云上的服务器

ECS 可以理解成云厂商提供的一台虚拟服务器。你可以在上面安装 Linux、Nginx、JDK、Node.js、Docker,也可以部署自己的后端服务。

如果不用容器,直接上线通常是这样:

图解ECS:云上的服务器
02

安装运行环境

03

上传代码或 jar 包

04

修改配置

05

启动进程

06

接入 Nginx 或负载均衡

这种方式简单直接,适合小项目、个人项目、服务数量很少的系统。但随着项目变大,它会越来越依赖“这台机器上到底装了什么”,环境差异和手工操作会变成风险。

堡垒机:进入服务器的安全入口

公司一般不会让所有人直接 SSH 到生产 ECS。更常见的做法是先登录堡垒机,再从堡垒机跳到目标服务器。

堡垒机主要解决三件事:

图解堡垒机:进入服务器的安全入口
02

操作审计

谁在什么时候执行了什么命令
03

安全收口

生产服务器不直接暴露给所有人

所以堡垒机不是运行应用的地方,而是管理登录和审计的入口。

容器:把应用和环境打包成标准盒子

容器通常和 Docker 一起出现。它的核心价值是把应用运行所需的东西打包到一个镜像里:

图解容器:把应用和环境打包成标准盒子
代码运行时依赖库系统工具启动命令

镜像

镜像运行起来之后,就是容器。

直接部署更像是“把程序装到服务器上跑”。容器部署更像是“把程序和环境装进标准盒子里,让服务器运行这个盒子”。

这能解决几个很现实的问题:

图解容器:把应用和环境打包成标准盒子
01

本地能跑,测试环境不能跑

02

测试环境能跑,生产环境不能跑

03

A 机器能跑,B 机器不能跑

因为容器把运行环境也一起固定住了,所以部署的一致性会更好。

容器服务:帮你管理一批容器的平台

当只有一个容器时,用 Docker 命令跑起来就够了。但真实业务里通常有很多服务、很多实例、很多机器。

这时就需要容器服务来做这些事:

图解容器服务:帮你管理一批容器的平台
        拉取镜像
启动容器
健康检查
失败重启
滚动发布
版本回滚
弹性扩缩容
服务发现
负载均衡
      

云厂商的容器服务,比如阿里云 ACK、腾讯云 TKE、华为云 CCE、AWS EKS,本质上大多是在托管 Kubernetes。

K8s:容器编排平台

K8s 是 Kubernetes 的简称。它不是一个业务框架,而是一个容器编排平台。

所谓编排,可以理解成:你告诉 K8s 你想要什么状态,K8s 负责尽量让系统达到这个状态。

比如你声明:

图解K8s:容器编排平台
02

使用 order-service:v1.2.0 镜像

03

每个实例需要健康检查

04

对外暴露一个稳定访问地址

K8s 会负责找机器、拉镜像、启动容器、检查状态。如果某个实例挂了,它会再拉起一个新的。如果压力变大,也可以把 3 个实例扩到 10 个。

K8s 解决的是“如何在一批机器上稳定运行大量容器”的问题。

为什么用容器部署,而不是直接上线

直接上线并不是错。小系统、一两台机器、发布不频繁时,直接部署可能更简单。

但当系统变复杂,容器部署的优势会明显起来。

第一,环境一致。镜像里带着运行环境,减少“机器差异”导致的问题。

第二,发布清晰。每次上线都是一个镜像版本,比如 order-service:v1.2.0,出问题可以回滚到 v1.1.0。

第三,扩容方便。直接部署要准备新机器、装环境、拷代码、改配置。容器平台里通常只需要调整副本数。

第四,资源利用率更高。机器不再固定只跑某一个服务,而是变成资源池,平台可以把容器调度到合适的机器上。

第五,依赖隔离更自然。一个服务需要 Java 8,另一个服务需要 Java 17,它们可以各自在自己的容器里运行。

所以容器化不是为了显得高级,而是为了让部署、发布、扩容和回滚更标准。

微服务架构:按业务能力拆系统

微服务架构是把一个大系统拆成多个小服务,每个服务负责一个相对独立的业务能力。

比如电商系统可以拆成:

图解微服务架构:按业务能力拆系统
02

商品服务

03

订单服务

04

支付服务

05

库存服务

06

物流服务

这些服务可以独立开发、独立部署、独立扩容。订单压力大,就扩订单服务。支付逻辑变更,就发布支付服务。

微服务不是按 Controller、Service、DAO 这种技术层拆,而是按业务能力拆。它的好处是边界清晰、团队协作方便、扩展能力强。代价是系统复杂度会上升,因为服务之间要通过网络通信。

分布式系统:多个节点通过网络协作

只要一个系统由多台机器、多个进程、多个服务共同组成,并通过网络协作,对外表现得像一个整体,就可以说它是分布式系统。

分布式系统会带来一些核心概念。

节点是系统里的某台机器、某个进程或某个服务实例。集群是一组节点共同提供能力。服务是对外提供某种业务能力的应用。实例是同一个服务启动出来的一份运行副本。

比如:

图解分布式系统:多个节点通过网络协作
02

订单服务实例 A/B/C

三个实例
03

运行这些实例的 ECS

节点
04

多个订单实例组成的整体

订单服务集群

分布式系统的难点在于网络是不稳定的,服务可能超时、失败、重复调用,数据也可能分布在多个地方。所以它常常需要处理:

图解分布式系统:多个节点通过网络协作
        服务发现
负载均衡
超时和重试
熔断和降级
限流
幂等性
分布式事务
最终一致性
链路追踪
日志收集
      

这也是为什么微服务和分布式系统不能只看“拆开之后更灵活”,还要看到“拆开之后协作更复杂”。

接口调用和服务调用

接口调用更强调某个 API 怎么被调用。

比如:

POST /api/order/create
GET /api/products/123
POST /pay/callback

它关注 URL、请求方法、参数、返回值和状态码。

服务调用更强调哪个服务在调用哪个服务。

比如:

图解接口调用和服务调用
02

订单服务

支付服务
03

支付服务

订单服务

服务调用底层也可能是 HTTP 接口,也可能是 RPC、gRPC 或消息队列。

所以这句话可以同时包含两个概念:

图解接口调用和服务调用
01

订单服务调用库存服务的 /stock/deduct 接口

其中“订单服务调用库存服务”是服务调用,“/stock/deduct”是接口调用。

回调地址:别人处理完之后反过来通知你

回调地址就是你提供给别人,让别人处理完事情后再来通知你的接口地址。

最典型的是支付:

图解回调地址:别人处理完之后反过来通知你
02

用户

完成付款
03

支付平台

调用你的回调地址:通知支付成功
04

你的系统

更新订单状态

回调地址通常长这样:

图解回调地址:别人处理完之后反过来通知你
01

https://api.example.com/pay/alipay/callback

02

https://api.example.com/payment/notify

它本质上也是接口,只是调用方向反过来了。你不是主动去问第三方“好了吗”,而是第三方完成后主动通知你。

回调常见于支付、转账、视频转码、文件处理、审核结果、物流状态变更等异步场景。

用下单支付串起来

把这些概念放进一个下单支付流程里,会更清楚:

图解用下单支付串起来
        用户
  |
  v
前端页面
  |
  v
API 网关 / 负载均衡
  |
  v
订单服务
  |-----------------> 库存服务:扣库存
  |-----------------> 优惠券服务:核销优惠券
  |-----------------> 支付服务:创建支付单
                         |
                         v
                      第三方支付平台
                         |
                         v
                      支付回调地址
                         |
                         v
                      支付服务更新支付状态
                         |
                         v
                      订单服务更新订单状态
      

这些服务可能都运行在容器里。容器由 K8s 管理。K8s 运行在一批 ECS 上。运维人员登录 ECS 时,可能要先经过堡垒机。订单服务、库存服务、支付服务之间的协作,就是分布式系统里的服务调用。支付平台通知支付结果,就是回调。

如果订单服务有 5 个实例,K8s 或负载均衡会把请求分发到其中某一个实例。如果某个实例挂了,平台会自动把它重启或替换掉。如果支付回调重复来了两次,支付服务就要做幂等处理,避免重复更新或重复发货。

术语速查表

图解术语速查表
02

堡垒机

登录服务器的安全入口,负责权限和审计
03

容器

应用和运行环境打包后的运行单元
04

镜像

容器启动前的标准包
05

容器服务

管理容器运行、发布、扩容的平台
06

K8s

容器编排平台,负责管理大量容器
07

微服务

按业务能力拆分出来的小服务
08

分布式系统

多个节点通过网络协作形成的系统
09

服务实例

某个服务运行起来的一份副本
10

服务发现

让调用方找到可用服务实例
11

负载均衡

把请求分发到多个实例
12

接口调用

调用某个 API
13

服务调用

一个服务调用另一个服务
14

回调地址

别人处理完成后反过来通知你的接口
15

幂等性

同一个操作执行多次,结果仍然正确
16

最终一致性

短时间可能不一致,最终达到一致

最后怎么理解这一组概念

可以按层次记:

图解最后怎么理解这一组概念
02

安全入口层

堡垒机
03

运行封装层

镜像、容器
04

运行管理层

K8s、容器服务
05

业务架构层

微服务
06

系统协作层

分布式系统、服务调用、回调、消息队列
07

稳定性保障

限流、熔断、降级、幂等、链路追踪

不要把这些词当成孤立术语背。真正理解它们的方式,是把它们放到一次业务请求里看:请求从哪里来,落到哪个服务,服务跑在哪里,如何扩容,失败了怎么办,异步结果怎么通知,数据最终如何保持正确。

这样看,云原生和分布式系统就不再是一堆难记的名词,而是一套围绕“稳定运行业务”的工程方法。