CNCF毕业项目的一些汇总

Fluentd

fluentd是一个搞笑的日志聚合器是用ruby编写的,并且可以很好的扩展。对于大部分企业来说,Fluentd足够高效并且消耗资源相对较少,另外一个Fluent-bit更加轻量级,占用资源更少,但是插件相对Fluentd来说不够丰富,所以整体来说Fluentd更加成熟,使用更加广泛。

工作原理

Fluentd通过一组给定的数据源抓取日志数据,处理后(转换成结构化的数据格式)将它们转发给其他服务,比如Elasticsearch、对象存储等等

  1. 首先Fluentd从多个日志源抓取数据
  2. 结构化并标记这些数据
  3. 然后根据匹配的标签将数据发送到多个目标服务器去

优势:

​ 和多数 Logstash 插件一样,Fluentd 插件是用 Ruby 语言开发的非常易于编写维护。所以它数量很多,几乎所有的源和目标存储都有插件(各个插件的成熟度也不太一样)。这也意味这我们可以用Fluentd 来串联所有的东西。

劣势:

​ 因为在多数应用场景下,我们会通过 Fluentd 得到结构化的数据,它的灵活性并不好。但是我们仍然可以通过正则表达式,来解析非结构化的数据。尽管,性能在大多数场景下都很好,但它并不是最好的,和 syslog-ng 一样,它的缓冲只存在与输出端,单线程核心以及 Ruby GIL 实现的插件意味着它大的节点下性能是受限的,不过,它的资源消耗在大多数场景下是可以接受的。对于小的或者嵌入式的设备,可能需要看看 Fluent Bit,它和 Fluentd 的关系与 Filebeat 和 Logstash 之间的关系类似。

典型应用场景:

​ Fluentd 在日志的数据源和目标存储各种各样时非常合适,因为它有很多插件。而且,如果大多数数据源都是自定义的应用,所以可以发现用 fluentd 的库要比将日志库与其他传输工具结合起来要容易很多。特别是在我们的应用是多种语言编写的时候,即我们使用了多种日志库,日志的行为也不太一样。

Helm

没有使用Helm之前,在Kubernetes部署应用,我们要依次部署deplyment、service等,步骤比较繁琐。况且随着很多微服务的项目化,负责的应用在容器中部署以及管理显得较为复杂。

helm通过打包的方式,支持发布的版本管理和控制,很大程度上简化了Kubernetes应用的部署和管理。

对于K8s来说,应用资源配置可以定义为K8s API对象,包括Deployment,Namespace,Service, PV(Persistent Volumes)和PVC(PersistentVolumeClaims)等等。通常一个应用的部署会涉及很多资源的共同协作,用户会定义这些API对象到一系列Yaml文件中,然后通过kubectl来逐一进行部署。

那么问题来了,假如我没接触过K8s, 只想部署个应用了解下,不会写Yaml一个个配这些资源对象怎么破?需要去结合K8s文档学习Yaml语法。过了几天我终于学会了,一个个配好了这些资源对象的Yaml文件,并逐一部署在这台机器上。后面想在这台机器上再重复部署几套,另外还有十台环境要配成和这台一样,怎么办?拷贝过去再一一部署出来?这配置管理也太麻烦了,不好用,直接劝退!

Helm中有一些自定义的概念和术语:

  • Charts: Helm使用的打包格式,一个Chart包含了一组K8s资源集合的描述文件。Chart有特定的文件目录结构,如果开发者想自定义一个新的 Chart,只需要使用Helm create命令生成一个目录结构即可进行开发。
  • Release: 通过Helm将Chart部署到 K8s集群时创建的特定实例,包含了部署在容器集群内的各种应用资源。
  • Tiller: Helm 2.x版本中,Helm采用Client/Server的设计,Tiller就是Helm的Server部分,需要具备集群管理员权限才能安装到K8s集群中运行。Tiller与Helm client进行交互,接收client的请求,再与K8s API Server通信,根据传递的Charts来生成Release。而在最新的Helm 3.x中,据说是为了安全性考虑移除了Tiller。
  • Chart Repository: Helm Chart包仓库,提供了很多应用的Chart包供用户下载使用,官方仓库的地址是https://hub.helm.sh,可以在上面发现很多有意思的项目。

Helm 为团队提供了在 Kubernetes 内部创建、安装和管理应用程序时需要协作的工具,有点类似于 Ubuntu 中的 APT 或 CentOS 中的 YUM

对于操作者而言,主要有如下功能:

  • 查找要安装和使用的预打包软件(Chart)
  • 轻松创建和托管自己的软件包
  • 将软件包安装到任何 K8s 集群中
  • 查询集群以查看已安装和正在运行的程序包
  • 更新、删除、回滚或查看已安装软件包的历史记录

jaeger

Jaeger 受 Dapper 和 OpenZipkin 的启发,是由 Uber Technologies 发布的开源分布式追踪系统。它用于监控和排查基于微服务的分布式系统问题,包括:

  • 分布式上下文传播
  • 分布式事务监控
  • 根因分析
  • 服务依赖关系分析
  • 性能 / 延迟优化

Jaeger 架构:

整体上讲,一个基础的 Jaeger 追踪系统包含下面几个部分:

  • jaeger-query: 用于客户端查询和检索组件,并包含了一个基础的 UI
  • jaeger-collector: 接收来自 jaeger-agent 的 trace 数据,并通过处理管道来执行。当前的处理管道包含验证 trace 数据,创建索引,执行数据转换以及将数据存储到对应的后端
  • jaeger-agent: 一个网络守护进程,侦听通过 UDP 发送的 spans ,它对其进行批处理并发送给收集器。它被设计为作为基础设施组件部署到所有主机。代理将收集器的路由和发现从客户机抽象出来
  • backend-storage: 用于指标数据存储的可插拔式后端存储,支持 Cassandra, Elasticsearch and Kafka
  • ingester: 可选组件,用于从 kafka 中消费数据并写入到可直接读取的 Cassandra 或 Elasticsearch 存储中

注意: trace 和 span 是链路追踪系统中的专业属于,span 就表示具体的一个工作单元,并且包含了该单元的元数据比如具体是什么操作,执行的时间等等,而 trace 是通过整个系统的数据路径,可以被认为是将 Spans 组成一个有向无环图 (DAG)

KEDA

以下内容由gpt生成

在Kubernetes(K8s)中,SRE代表Site Reliability Engineering(现场可靠性工程),它是一种将软件工程和运维运营原则结合起来的方法论,旨在确保应用程序和服务的高可靠性、可用性和可扩展性。

SRE是由Google提出的一种运维实践模式,强调将软件工程技术和自动化运维方法应用于管理和维护基础设施、应用程序和服务。SRE团队的主要目标是确保系统在高负载、故障和变化环境下仍然能够提供可靠的服务。

以下是SRE在Kubernetes中的一些关键方面和实践:

  1. 监控和警报:SRE强调对应用程序和基础设施进行全面的监控,并设置警报机制来及时发现和响应故障或异常情况。在Kubernetes中,可以使用各种监控工具和指标收集系统(如Prometheus、Grafana)来监控集群、节点和应用程序的状态。
  2. 自动化运维:SRE鼓励使用自动化工具和流程来减少人工操作、提高效率和准确性。在Kubernetes中,可以使用自动化工具和脚本来自动化部署、扩展、升级和回滚应用程序,以及自动化管理配置和存储等方面。
  3. 健康检查和故障恢复:SRE强调对应用程序和服务进行健康检查,并采取自动化的方法来恢复和修复故障。在Kubernetes中,可以使用健康检查和就绪探针来监测容器和应用程序的状态,并使用自动化的故障恢复机制(如重启、重新调度)来处理故障情况。
  4. 容量规划和扩展:SRE关注容量规划和扩展策略,以确保系统能够处理预期的负载和流量增长。在Kubernetes中,可以使用水平自动扩展(Horizontal Pod Autoscaling)和集群自动扩展等机制来根据需求动态调整应用程序的副本数量和集群规模。
  5. 故障注入和演练:SRE鼓励通过故障注入和演练来测试系统的可靠性和恢复能力。在Kubernetes中,可以使用工具和方法来模拟故障、测试备份和恢复策略,以评估系统在不同场景下的表现。

总的来说,SRE在Kubernetes中强调通过自动化、监控和故障恢复等实践来提高系统的可靠性和可用性。它与Kubernetes的特性和工具相结合,为构建和管理高可靠的容器化应用程序提供了方法和指导。

探索 KEDA(Kubernetes 事件驱动的自动缩放),这是一种适用于 Kubernetes 工作负载的有效自动缩放解决方案,并了解 KEDA 架构及其优势。

手动缩放正在慢慢成为过去。目前,自动缩放是常态,部署到 Kubernetes 集群中的组织可以获得内置的自动缩放功能,如 HPA(水平容器自动缩放)和 VPA(垂直容器自动缩放)。但这些解决方案有局限性。例如,HPA 很难根据内存或 CPU 使用率以外的指标将 Pod 的数量缩减为零或(取消)缩放 Pod。因此,引入了 KEDA(Kubernetes 事件驱动的自动缩放)来解决自动扩展 K8s 工作负载中的一些挑战。

KEDA 提供了一个可扩展的事件处理模型,使得应用程序能够根据外部事件(如消息队列、队列、日志、监控指标等)的到达情况自动调整其副本数量。它通过与Kubernetes的自动扩展机制(如HPA,Horizontal Pod Autoscaler)集成,实现根据事件负载动态调整应用程序的副本数量。

Open Policy Agent

Open Policy Agent(简称OPA)是一个开源策略引擎,通常用来做在微服务、API网关、Kubernetes、CI/CD等系统中做策略管理。

OPA将策略从代码中分离出来,按照官网的说法OPA实现了策略即代码,通过Rego声明式语言实现决策逻辑,当系统需要做出决策时,只需携带请求查询OPA即可,OPA会返回决策结果。

大型软件中各个组件都需要进行一些策略控制,比如用户权限校验、创建资源校验、某个时间段允许访问,如果每个组件都需要实现一套策略控制,那么彼此之间会不统一,维护困难。一个自然的想法是能否将这些策略逻辑抽离出来,形成一个单独的服务,同时这个服务可能需要提供各种不同sdk来屏蔽语言差异。

OPA正是解决这个问题,将散落在系统各处的策略进行统一,所有服务直接请求OPA即可。通过引入OPA可以降低系统耦合性,减少维护复杂度。

对比项OPACasbin
访问控制策略通过Rego可以实现多种策略原生支持ACL、ABAC、RBAC等多种策略
自定义策略支持通过自定义函数和Model实现,灵活性一般
调整策略复杂度更改/添加Rego逻辑即可如果已存在大量策略数据,需要考虑数据迁移
存储数据不支持支持存储策略存储到文件或数据库
运行方式内嵌、单独部署通常为内嵌
sdk支持语言Go、WASM(nodejs)、Python-rego,其他通过Restful API支持Java、Go、Python等多种常用语言
策略返回格式Json数据True/False
性能评估时间随着策略数据量会增加,支持多节点部署对于HTTP服务评估时间在1ms内

Prometheus

简介

prometheus是一款基于时序数据库的开源控制告警系统,非常适合Kubernetes集群的监控。

Prometheus的基本原理是通过HTTP协议周期性抓取被监控组件的状态,任意组件只要提供对应的HTTP接口就可以接入监控。不需要任何SDK或者其他的集成过程。这样做非常适合做虚拟化环境监控系统,比如VM,Docker,Kubernetes等。输出被监控组件信息的HTTP接口被叫做exporter。目前互联网公司常用的组件大部分都有exporter可以直接使用比如Varnish、Haproxy、Nginx、MySQL、Linux系统信息(包括磁盘、内存、CPU、网络等等)。Promethus有以下特点:

  • 支持多为数据模型:有度量名和键值对组成时间序列数据
  • 内置时间序列数据库TSDB
  • 支持promQL查询语言,可以完成非常复杂的查询和分析,对图标展示和告警有重要意义
  • 支持HTTP的Pull方式采集时间序列数据
  • 支持HTTPGetway采集顺势任务的数据
  • 支持服务发现和静态配置的俩种方式发现目标
  • 支持接入Grafana

架构

prometheus Server

主要负责数据采集和存储,提供PromQL查询语言的支持。包含了三个组件:

  • Retrieval:获取监控数据
  • TSDB:时间序列数据库(Time Serise Database),我们可以简单理解为一个优化后用来处理时间序列数据的软件,并且数据中的数据是按时间进行索引的。具备以下特点

    • 大部分时间都是顺序写入操作,很少设计修改数据
    • 删除操作都是删除一段时间的数据,很少设计修改数据
    • 删除操作都是删除一段时间的数据,而不涉及到删除无规律数据
    • 读操作一般都是升序或者降序
  • HttpServer 为告警和出图提供查询接口

指标采集

  • Exporters: Prometheus的一类数据采集组件的总称。它负责从目标处搜集数据,并将其转化为Prometheus支持的格式。与传统的数据采集组件不同的是,它并不向中央服务器发送数据,而是等待中央服务器主动前来抓取
  • Pushgateway: 支持临时性Job主动推送指标的中间网关

服务发现

  • Kubernetes_sd: 支持从Kubernetes中自动发现服务和采集信息。而Zabbix监控项原型就不适合Kubernets,因为随着Pod的重启或者升级,Pod的名称是会随机变化的。
  • file_sd: 通过配置文件来实现服务的自动发现

告警管理

通过相关的告警配置,对触发阈值的告警通过页面展示、短信和邮件通知的方式告知运维人员。

图形化展示

通过ProQL语句查询指标信息,并在页面展示。虽然Prometheus自带UI界面,但是大部分都是使用Grafana出图。另外第三方也可以通过 API 接口来获取监控指标。

对比Zabbix

主要使用场景区别是,Zabbix适合用于虚拟机、物理机的监控,因为每个监控指标是以 IP 地址作为标识进行区分的。而Prometheus的监控指标是由多个 label 组成,IP地址并不是唯一的区分指标,Prometheus 强大在可以支持自动发现规则,因此适合于容器环境。
从自定义监控项角度而言,Prometheus 开发难度较大,zabbix配合shell脚本更加方便。Prometheus在监控虚拟机上业务时,可能需要安装多个 exporter,而zabbix只需要安装一个 Agent。
Prometheus 采用拉数据方式,即使采用的是push-gateway,prometheus也是从push-gateway拉取数据。而Zabbix可以推可以拉。

ROOK

什么是Rook

Rook中文是扯的意思,它本身不是云存储,Rook是一个自我管理的分布式存储编排系统,Rook在存储和Kubernetes之间搭建了一个桥梁,是存储系统的搭建或者维护变得特别简单,Rook将分别是存储系统转变为自我管理、自我扩展、自我修复的存储服务。它让一些存储的操作,比如部署、配置、扩容、升级、迁移、灾难恢复、监视和资源管理变得自动化,无需人工处理。同时Rook支持CSI,可以利用CSI做一些PVC的快照、扩容、克隆操作。

Rook构建在Ceph技术之上,利用Ceph的分别是存储和对象存储能力。Ceph是一个开源的分别是存储系统,提供了可扩展性、高可用性和强一直存储的解决方案。Rook则通过将Ceph集成到Kubernetes中,提供了一种简单的方法来管理和部署Ceph存储集群。

Rook的目标是简化Kubernetes上的存储管理,通过存储服务作为Kubernetes的扩展来提供,为应用程序提供持久化存储的功能。Rook支持多种存储类型,包括块存储、文件系统和对象存储。快存储可以用于需要直接访问磁盘的应用程序,文件系统可以提供共享存储方访问,而对象存储适用于大规模、可扩展的数据存储需求。

Rook出现背景

在公司内部,除了生产环境并没有一个多余的Ceph集群,因为建立Ceph集群不仅需要大量服务器资源,本身的复杂度也需要人力成本。但是在企业内部使用Kubernetes时,无论在部署业务服务还是中间件服务,都能很明显地体会到Kubernetes的便利性和强大之处,所以我们在企业内部使用Kubernetes急群中。相对与生产环境,也需要保留它们的数据,但是非生产环境可能没有现成的存储平台供K8s使用,新搭建一个平台也需要耗费很多经历。

为了解决非生产环境数据持久化问题,很多公司都采用了NFS作为后端

NFS就是Network File System的缩写,它最大的功能就是可以通过网络,让不同的机器、不同的操作系统可以共享彼此的文件。NFS服务器可以让PC将网络中的NFS服务器共享的目录挂载到本地端的文件系统中,而在本地端的系统中来看,那个远程主机的目录就好像是自己的一个磁盘分区一样,在使用上相当便利

但一旦使用容器较多或者存储的数据量比较大,就容易造成性能问题,并且NFS服务器一旦出现问题,整个数据可能就会全部丢失。

特点

Rook具有以下特点

  • 可扩展性:Rook利用Ceph的分布式架构,可以方便地扩展存储容量和性能,以满足不断增长的存储需求。
  • 高可用性:Rook通过复制和故障转移提供高可用性,确保数据的安全性和持久性
  • 灵活性:Rook支持集多种存储类型和存储策略,可以根据应用程序的需求选择适当的存储方式
  • 集成性:Rook与Kubernetes紧密集成,利用Kubernetes强大的编排和调度功能来管理存储资源
  • 易用性:Rook提供了简化的资源定义和管理接口,使用户能够轻松地创建、扩展管理存储集群
  • 活跃的社区:Rook 是一个活跃的开源项目,拥有庞大的社区支持和贡献者,不断改进和完善
  • 数据保护:Rook 提供了数据保护功能,包括快照和备份,可以帮助用户实现数据的可靠性和恢复性
  • 动态调整:Rook 允许用户在运行时动态调整存储资源,包括容量、性能和存储策略的调整,而无需停止或重启应用程序
  • 多租户支持:Rook 支持多租户环境,可以在同一个 Kubernetes 集群中为不同的用户或团队提供独立的存储空间和访问控制
  • 生态系统整合:Rook 与 Kubernetes 生态系统中的其他工具和项目无缝集成,例如 Prometheus、Grafana 等,可以实现存储集群的监控和可视化
  • 持续发展:Rook 是一个活跃的开源项目,持续发展和改进。它拥有广泛的社区支持和开发者社区,不断推出新的功能和增强

Rook架构

Rook 通过在 Kubernetes 集群中运行 Ceph,Kubernetes 应用程序可以挂载由 Rook 管理的块设备和文件系统,或者可以使用 S3/Swift API 进行对象存储。Rook 操作员可自动配置存储组件并监控集群,以确保存储保持可用且正常运行。

Rook Operator是一个简单的容器,拥有引导和监控存储集群所需的一切。操作员将启动和监控Ceph监控pod、CephOSD守护进程已提供RADOS存储,以及启动和管理其他的Ceph守护进程。Operator通过初始化Pod和服务所需的其他资源来管理池、对象存储(S3、Swift)和文件系统的CRD。

操作员将监控存储守护进程以确保集群健康。Ceph mon 将在必要时启动或进行故障转移,并随着集群的增长或收缩而进行其他调整。操作员还将监视 Ceph 自定义资源 (CR) 中指定的所需状态更改并应用更改。

Rook 会自动配置 Ceph-CSI 驱动程序以将存储安装到您的 Pod。该rook/ceph映像包含管理集群所需的所有工具。Rook 不在 Ceph 数据路径中。许多 Ceph 概念(例如放置组和挤压图)都是隐藏的,因此您不必担心它们。相反,Rook 在物理资源、池、卷、文件系统和存储桶方面为管理员创建了简化的用户体验。需要时可以使用 Ceph 工具应用高级配置。

针对上图中的组件进行说明:

  • Rook Operator(蓝色层):Operator自动化Ceph的配置
  • CSI 插件和配置程序(橙色层):Ceph-CSI 驱动程序提供卷的配置和安装
  • Ceph 守护进程(红色层):Ceph 守护进程运行核心存储架构

上面显示了三种支持的存储类型的示例应用程序:

  • 块存储用蓝色应用程序表示,该应用程序已ReadWriteOnce (RWO)安装卷。应用程序可以读取和写入 RWO 卷,而 Ceph 管理 IO
  • 共享文件系统由两个共享 ReadWriteMany (RWX) 卷的紫色应用程序表示。两个应用程序都可以同时主动读取或写入该卷。Ceph 将通过 MDS 守护进程确保多个写入者的数据得到安全保护
  • 对象存储由橙色应用程序表示,可以使用标准 S3 客户端读取和写入存储桶

说明:生产集群必须具有三个或更多节点才能实现弹性存储平台

上图中块存储类型(蓝色)创建具有 RWO 卷的应用程序的流程:

  • 应用程序创建 PVC 来请求存储
  • PVC 定义了用于配置存储的 Ceph RBD 存储类 (sc)
  • K8s 调用 Ceph-CSI RBD 配置程序来创建 Ceph RBD 映像
  • kubelet 调用 CSI RBD 卷插件来挂载应用程序中的卷
  • 该卷现在可供读取和写入

说明:ReadWriteOnce 卷一次可以安装在一个节点上

上图中共享文件系统类型(紫色)创建具有 RWX卷的应用程序的流程:

  • 应用程序创建 PVC 来请求存储
  • PVC 定义了用于配置存储的 CephFS 存储类 (sc)
  • K8s调用Ceph-CSI CephFS配置器创建CephFS子卷
  • kubelet 调用 CSI CephFS 卷插件来挂载应用程序中的卷
  • 该卷现在可供读取和写入

说明:ReadWriteMany 卷可以安装在多个节点上供应用程序使用

上图中共享文件系统类型(橙色)创建可访问 S3 存储桶的应用程序的流程:

  • 应用程序创建一个 ObjectBucketClaim (OBC) 来请求存储桶
  • Rook 操作员创建一个 Ceph RGW 存储桶(通过 lib-bucket-provisioner)
  • Rook 操作员使用访问存储桶的凭据创建一个密钥,并创建一个包含存储桶信息的配置映射
  • 应用程序从机密中检索凭据
  • 该应用程序现在可以使用 S3 客户端读取和写入存储桶

SPIFFE

OPA主要关注策略引擎和决策评估,用于访问控制和策略管理,而SPIFFE则专注于身份认证和信任管理,用于安全地管理和传递身份认证信息。两者在应用领域和功能目标上有所不同,但它们可以共同用于构建安全、可信和可管理的分布式系统和云原生应用。

SPIFFE,即每个人的安全生产身份框架(Secure Production Identity Framework for Everyone),是一套开源标准,用于在动态和异构环境中安全地进行身份识别。采用 SPIFFE 的系统无论在哪里运行,都可以轻松可靠地相互认证。

SPIFFE 开源规范的核心是——通过简单 API 定义了一个短期的加密身份文件 SVID。然后,工作负载进行认证时可以使用该身份文件,例如建立 TLS 连接或签署和验证 JWT 令牌等。

SPIFFE 已经在云原生应用中得到了大量的应用,尤其是在 IstioEnvoy 中。下面将向你介绍 SPIFFE 的一些基本概念。

工作负载

工作负载是个单一的软件,以特定的配置部署,用于单一目的;它可能包括软件的多个运行实例,所有这些实例执行相同的任务。工作负载这个术语可以包含一系列不同的软件系统定义,包括:

  • 一个运行 Python 网络应用程序的网络服务器,在一个虚拟机集群上运行,前面有一个负载均衡器。
  • 一个 MySQL 数据库的实例。
  • 一个处理队列中项目的 worker 程序。
  • 独立部署的系统的集合,它们一起工作,例如一个使用数据库服务的网络应用程序。网络应用程序和数据库也可以单独被视为工作负载。

SPIFFE 而言,工作负载往往比物理或虚拟节点更加细化——通常细化到节点上的单个进程。这对工作负载来说至关重要,例如,在容器编排器中托管的工作负载,几个工作负载可能在同一个节点上(但彼此隔离)。

SPIFFE 而言,一个工作负载也可能跨越许多节点。例如,一个可弹性扩展的网络服务器可能同时运行在许多机器上。

虽然工作负载的粒度会因环境而异,但就 SPIFFE 而言,我们假设工作负载之间有足够好的隔离,这样恶意的工作负载就不能窃取他人的凭证。这种隔离的稳健性和实现的机制超出了 SPIFFE 的范围。

SPIFFE ID

SPIFFE ID 是一个字符串,可以唯一地、具体地标识一个工作负载。SPIFFE ID 也可以分配给工作负载所运行的中间系统(如一组虚拟机)。例如,spiffe://acme.com/billing/payments 是一个有效的SPIFFE ID。

SPIFFE ID 是一个统一资源标识符(URI),其格式如下:spiffe://信任域/工作负载标识符

工作负载标识符是一个信任域内的特定工作负载的唯一标识。

SPIFFE 规范详细描述了 SPIFFE ID 的格式和使用。

信任域

信任域对应于系统的信任根。信任域可以代表个人、组织、环境或部门,运行他们自己独立的 SPIFFE 基础设施。在同一信任域中确定的所有工作负载都会被颁发身份文件,它们可以根据信任域的根密钥进行验证。

通常建议将处于不同物理位置(如不同的数据中心或云区域)或应用不同安全实践的环境(如与生产环境相比的暂存或实验环境)的工作负载放在不同的信任域中。

SPIFFE 可验证的身份文件(SVID)

SVIDSPIFFE Verifiable Identity Document) 是工作负载向资源或调用者证明其身份的文件。如果 SVID 是由 SPIFFE ID 的信任域内的机构签发的,则被认为是有效的。

SVID 包含一个 SPIFFE ID,代表了服务的身份。它将 SPIFFE ID 编码在一个可加密验证的文件中,目前支持两种格式:X.509 证书或 JWT 令牌。

由于令牌容易受到重放攻击(replay attack),即在传输过程中获得令牌的攻击者可以使用它来冒充工作负载,因此建议尽可能使用 X.509-SVID。然而,在某些情况下,JWT令牌格式是唯一的选择,例如,当你的架构在两个工作负载之间有一个L7代理或负载均衡器。

关于 SVID 的详细信息,请参阅 SVID 规范

SPIFFE 工作负载 API

工作负载 API 提供以下内容。

对于X.509格式的身份文件(X.509-SVID):

  • 其身份,描述为 SPIFFE ID。
  • 一个与该 ID 绑定的私钥,可用于代表工作负载签署数据。一个相应的短期 X.509 证书也将被创建,即 X509-SVID。这可以用来建立 TLS 或以其他方式对其他工作负载进行认证。
  • 一组证书——被称为信任包。一个工作负载用来验证另一个工作负载提出的X.509-SVID

对于 JWT 格式的身份文件(JWT-SVID):

  • 其身份,描述为 SPIFFE ID
  • JWT 令牌
  • 一组证书——被称为信任包,一个工作负载用来验证其他工作负载的身份。

AWS EC2 实例元数据 APIGoogle GCE 实例元数据 API 类似,工作负载 API 不要求调用的工作负载对自己的身份有任何了解,也不要求调用 API 时拥有任何认证令牌。这意味着你的应用程序不需要与工作负载共同部署任何认证密钥。

然而,与这些其他 API 不同的是,Workload API 与平台无关,可以在进程级和内核级识别正在运行的服务,这使得它适合与 Kubernetes 等容器调度器一起使用。

为了最大限度地减少密钥泄露的风险,所有私钥(和相应的证书)都是短期的,经常自动轮换。工作负载可以在相应的密钥过期前从工作负载API请求新的密钥和信任包。

信任包

当使用 X.509-SVID 时,目标工作负载使用信任包(Trust Bundle)来验证源工作负载的身份。信任包是一个或多个证书机构(CA)根证书的集合,工作负载认为这些证书是可信的。信任包包含 X.509 和 JWT SVID 的公钥材料。

用来验证 X.509 SVID 的公钥材料是一组证书。用于验证 JWT 的公钥材料是一个原始公钥。信任包的内容是经常轮换的。工作负载在调用工作负载 API 时检索信任包。

SPIRE

SPIRE是SPIFFE标准的参考实现。SPIR由俩个组件组成:SPIREServer(负责创建SVID和trust bundle)以及SPIRE Agent实例(负责向工作负载提供身份)

当 Spire Server 启动时,Server 会使用自己的私钥生成一个自签名证书 ( 也可通过上游 CA 机构的插件去请求证书 ),此证书会被用来为信任域中的所有工作负载签发 SVID 。与此同时,如果 Spire Server 是第一次启动,它会生成 Trust Bundle ( 每次签名密钥对轮换时,server 都会更新 trust bundle ),将其存储在数据库中,并通过公开的 API 将其暴露出去,以供 Agent 去访问。然后 Spire Server 会开放注册接口,允许管理员向其发起工作负载注册请求。

注册工作负载的过程

在注册工作负载之前,需要先向 Spire Server 中添加注册条目, Server 中维护着一张注册表,每个注册条目都包含三个字段:

  1. SPIFFE ID
  2. Parent ID
  3. Selector :一组选择器,可以理解为一组标签。

在工作负载证明期间,agent 将会用工作负载的标签与注册条目中的标签做匹配,以确定注册条目,并签发相应的 SVID。

在开始介绍节点证明过程与工作负载证明过程之前,简单回顾一下节点与工作负载的定义:

  • 节点:在计算机系统上下文中运行计算工作负载的逻辑或物理实体,节点是运行工作负载的基础计算系统。
  • 工作负载:是正在运行的应用程序,一般使用特定配置部署同一任务,该配置可以由多个正在运行的实例组成。在云计算里是用来承载计算的工作节点,包括公有云私有云主机系统、Docker 容器节点以及微服务等。

节点证明过程

SPIRE agent 必须伴随着工作负载一起运行。通常来讲,每个裸机服务器、 VM 实例都会运行一个 Spire Agent 实例。

当 SPIRE agent 启动时,它会首先检索 SPIRE server 之前发布的 trust bundle 。基于 trust bundle ,SPIRE agent 连接到 SPIRE server 并验证 server 的身份。

SPIRE agent 向 SPIRE server 证明其身份的过程称就是“节点证明”。在云实例或 K8s 上,SPIRE agent 可以使用特定于每个云提供商的机制向 server 证明实例的身份。对于裸机实例或 VM,agent 支持其他方法来证明其身份,包括引导 ( Bootstrap ) 证书、字符串连接令牌等。

工作负载证明过程

当工作负载启动时,并不知道自己的 SPIFFE ID 是什么,或者说不知道自己的身份是什么,它需要询问运行在同一个节点上的 Spire Agent “我是谁?”。而 Spire Agent 为了确认工作负载的身份,需要先获取工作负载的 Selector。

这取决于工作负载的运行环境,agent 获取工作负载 Selector 信息的方式略有不同。例如

  1. 在 K8s 中,agent 可通过 kubelet 获取到工作负载的 image name、pod name、pod label 等信息
  2. 对于直接运行在 unix 域中的进程,agent 可通过插件获取到工作负载的
  • ounix :user 工作负载启动时使用的用户 ( eg : unix : user : nginx )
  • ounix : path 工作负载启动时使用的二进制文件路径 ( eg: /usr/bin/nginx )
  • ounix : sha256 工作负载二进制启动文件的 SHA256 摘要
  • 对于运行在 docker 中的容器,agent 可获取容器的 docker : label 、 docker : env 、 docker : iamge_id 等信息

采用SPIFFE和SPIRE的优势

  1. 因为任何工作负载之间的访问都必须经过身份认证,所以当工作负载受到攻击时,可以通过快速锁定身份的攻击源,减小被进一步攻击的可能性。
  2. 降级运维工作的复杂程度,通过一致的、自动化的身份管理,有效降低运维成本。
  3. 完善了安全方面的可观测性,相互通信的工作负载双方都明确知道对方的身份,所以日志和审计工作将会变得更加轻松。

Vitess

Vitess是一个用于部署、扩展和管理大型MySQL实例集群的数据库解决方案。Vitess集MySQL数据库的很多重要特性和NoSQL数据库的可扩展性于一体。它的架构设计使得您可以像在物理机上一样在公共云或私有云架构中有效运行。它结合并扩展了许多重要的MySQL功能,同时兼具NoSQL数据库的可扩展性。 Vitess可以帮助您解决以下问题:

  1. 支持您对MySQL数据库进行分片来扩展MySQL数据库,应用程序无需做太多更改。
  2. 从物理机迁移到私有云或公共云。
  3. 部署和管理大量的MySQL实例。

Vitess包括使用与本机查询协议兼容的JDBC和Go数据库驱动。此外,它还实现了MySQL服务器协议,该协议几乎与任何其他语言都兼容。

自2011年以来,Vitess一直为YouTube所有的数据库提供服务,现在已被许多企业采用并应用于实际生产。

特性

  • 性能提升

    • 连接池 - 将前端应用程序以多路复用的方式映射到MySQL连接池以优化性能。
    • 查询结果重用 – 对于相同结果集的查询,多个查询并发查询时,vttablet会识别和管理相同查询,等待第一个查询结果完成,并发送给所有的调用者。
    • 事务管理 – 限制并发事务数、管理事务超时时间以优化总体吞吐量。
  • 保护机制

    • 查询重写和清理 – 避免漫无目的的更新,对大查询添加limits。
    • 查询黑名单 – 可通过自定义规则以防止可能存在问题的查询命中数据库。
    • 查询超时 – 可自定义查询超时时间值,Vitess将干掉超时的查询。
    • 表别访问权限控制定义 – 可以针对不同的接入用户指定表的访问控制权限 (ACLs)。
  • 监控

    • 性能分析: Vitess提供工具可让您监控,诊断和分析数据库性能。
    • 流式查询 – 使用传入查询列表来提供OLAP工作。
    • 更新流 – 服务器流式传输数据库中更改的行列表,可用作将更改传播到其他数据存储的机制。
  • 拓扑管理工具

    • Master管理工具(用于reparent处理)
    • 基于Web GUI的管理端
    • 可工作于多个数据中心/区域的设计
  • 拆分

    • 几乎无缝的动态分片拆分
    • 支持垂直和水平分片拆分
    • 多种分片方案,支持自定义分片方案
Last modification:December 21, 2023
如果觉得我的文章对你有用,请随意赞赏