有状态应用容器化部署的成熟度?

有状态应用组件,如kafka、zk、redis等,目前容器化部署的成熟度如何?需要哪些特别关注的点以及带来的问题?显示全部

有状态应用组件,如kafka、zk、redis等,目前容器化部署的成熟度如何?需要哪些特别关注的点以及带来的问题?

收起
参与5

查看其它 1 个回答Garyy的回答

GaryyGaryy  系统工程师 , 某保险

应用程序的状态(state)就是应用程序组件完成工作(比如执行一个任务)所需的数据。所有的应用都有状态。架构模式、范例和语言从本质上描述了如何管理应用程序的行为(任务,操作等)和状态(数据)。
即使是微服务式应用程序也有状态!在微服务体系结构中,每个服务可以有多个实例,每个服务实例被设计为无状态。这意味着服务实例不会跨越两个或多个操作存储数据。因此,无状态就意味着任何服务实例都可以从某处获取执行一个行为所需的所有应用程序状态。这是微服务式应用程序的一个重要架构约束,因为它可以提升弹性、可扩展性,并允许任何可用的服务实例执行任何任务。
通常,应用程序状态存储在数据库、缓存、文件或其他形式的存储中。另外,任何需要在操作中记录的状态更改都必须写回存储。
所以,所有的程序都有状态,但是一个程序组件可以是无状态的——如果它可以干净地将行为从数据中分离出来并且可以获取行为所需的数据。但是,这似乎只是简单地将问题传递给了其他组件。另一个组件如何管理状态?这取决于我们下面要讨论的状态的类型。
一般应用程序有5种状态:

  1. 持久状态(Persistent state)
  2. 配置状态(Configuration state)
  3. 会话状态(Session state)
  4. 连接状态(Connection state)
  5. 集群状态(Cluster state)
    (1)持久状态
    持久的应用程序状态需要在应用程序重新启动和中断之后可继续。这种状态通常存储在冗余数据库层中,并对其执行定期备份。
    虽然可以将应用程序和数据库放在同一个容器中,但最好将它们分开,因为应用组件的更改频率会更高。分离数据库还允许在多个应用程序实例之间共享。
    如果你的应用已经使用外部数据库(不论是作为服务提供的数据库,还是安装在其他物理或虚拟服务器上的),你可以直接保留这个架构,并简单地通过容器化应用程序层来启动。大多数容器管理系统将允许将数据库访问信息作为配置状态传递给应用层容器
    (2)配置状态
    应用程序通常需要非域(non-domain)数据才能正确配置,比如其他外部服务的IP地址,或用于连接数据库的证书。
    由Heroku推广的大多数PaaS解决方案所采用的12要素应用宣言规定将配置数据存储在环境中。在容器化的世界里,大部分配置数据都可以作为可注入容器的环境变量进行管理。
    但是,机密信息(如凭证,密码,密钥和其他秘密数据)最好通过其他安全机制处理,这些机制可以更好地控制主机、网络或存储上的秘密数据可见和可访问。对于这种类型的配置状态,像KeyWhiz和Vault这样的凭证管理工具可以在具有一次性访问令牌的容器中使用。其他的选项还有将卷插件和密钥存储相结合以安全地向容器化应用提供秘密数据。
    (3)会话状态
    当用户登录时,应用程序可能生成会话数据。这可能是用户的身份验证密钥或其他临时状态。在大多数现代应用程序中,会话状态存储在分布式缓存或一个任何服务实例都能访问的数据库中。
    但是,在传统的多页面Web应用中,每个Web页面都需要访问由服务器管理的会话状态。因此,该会话的所有用户请求必须定向到相同的后端服务器,否则用户将被强制重新登录。这样的应用要求会话状态存储在特定服务器,即“粘性会话”(sticky session),并且所有对客户机会话的请求总是被路由到相同的服务。
    在容器化的世界里,你的容器的IP地址可能和你主机的IP地址不一样。如果您将第4-7层负载平衡解决方案用于具有有状态会话数据的前端应用程序容器,那么负载平衡器也将需要处理粘性会话。
    容器原生(container-native)解决方案Nirmata的服务网关提供对粘性会话的支持,并且可以在容器重新部署到主机之间时动态更新路由信息。
    (4)连接状态
    某些应用程序可能使用协议进行通信,如Websockets,因为通信实体可以通过连接交换消息序列,所以这些应用程序被认为是有状态的。相比之下,像HTTP这样的协议被认为是无状态的,因为服务器不记得任何请求状态,允许其他任何服务器回答下一个请求。
    (5)集群状态
    一些应用作为集群中的多个实例运行,以适应可用性和规模要求,需要共享集群成员和状态信息。此状态不是持久性的,但是如果集群成员更改,就需要更新状态。
    在集群应用中,每个集群成员都需要了解其他成员及其角色。大多数现代集群应用都需要使用初始成员集(通常是其IP地址和端口)进行引导,然后才能动态管理成员及其更改。但是,某些集群服务可能需要手动更新,并在需要传播成员信息的更改时重新启动。
    容器原生(container-native)编排系统有能力够处理这两种情况。例如,Kubernetes 最近引入了一个名为 PetSet 的功能来管理一个有状态的集群。Nirmata 支持对预先计算容器布局的集群系统进行预订编排,并为所有集群成员注入唯一标识和集群状态。
保险 · 2020-06-23
浏览1015

回答者

Garyy
Garyy0410
系统工程师某保险
擅长领域: 云计算存储容器

Garyy 最近回答过的问题

回答状态

  • 发布时间:2020-06-23
  • 关注会员:3 人
  • 回答浏览:1015
  • X社区推广