负载和 Pod 的关联逻辑
在 Kubernetes 中,负载指的是 Deployment、StatefulSet 和 DaemonSet 这三种资源:
- Deployment 用于管理无状态的 Pod,通过 ReplicaSet 进行管理;
- StatefulSet 用于管理有状态的 Pod;
- DaemonSet 管理的 Pod 会部署在所有集群节点中。
如何确定哪些 Pod 是由哪个负载进行管理的?这些 Pod 是怎么与负载进行关联的?
在 Kubernetes 中,负载指的是 Deployment、StatefulSet 和 DaemonSet 这三种资源:
如何确定哪些 Pod 是由哪个负载进行管理的?这些 Pod 是怎么与负载进行关联的?
KubeVela 的多集群管理依赖于 Cluster Gateway 组件,在 KubeVela 的 Helm Chart 中会自动安装。KubeVela 并不会直连集群,而是必须通过 Cluster Gateway 连接集群进行管理。
包括集群管理在内的功能都是依赖于 Cluster Gateway 实现的,所以 Cluster Gateway 是 KubeVela 多集群管理必不可少的一个组件。
Kubernetes 是容器编排引擎,用来对容器进行自动化部署、扩缩和管理。Kubernetes 更像是一个对资源进行管理和分配的系统,只负责把工作负载进行合理调度,最大化利用集群资源。
在实践中 Kubernetes 集群往往是部署很多套的,不同的业务线、不同部门或子公司都是使用的独立的集群,甚至常见的同一个服务会部署在不同区域的集群中以实现用户就近服务。要想实现将服务同时部署到多个集群单纯靠 Kubernetes 是不行的。严格来讲,在 Kubernetes 中是没有这里所说的应用这个维度的。
在应用的整个生命周期中,应用是可以存在多个集群,多个环境的。如在开发中可以把应用部署在开发测试集群,在上线后可以同时部署到生产和容灾集群,这很显然是一种超越 Kubernetes 集群的概念。
由于 Kubernetes 无法完成对应用的管理,所以业界诞生了多种方案来解决应用管理的需求,常见的有 OCM、Karmada 和 KubeVela,本文将对这几种方案进行总体介绍并基于使用需求进行选型。
在 Kubernetes 中,kube-apiserver 是整个集群的大脑和心脏,是控制集群的入口,所有模块都是通过其提供的 HTTP REST API 接口来操作集群的。
由于是所有模块的数据交互和通信的枢纽,大量组件直接通过 HTTP 请求 apiserver 带来的访问压力是非常大的。一但 apiserver 出现异常,整个集群就会受到影响,甚至崩溃。
所以尽可能降低 apiserver 的访问压力是很有必要的,Informer 机制就是 Kubernetes 解决这个问题的方案。Informer 本质就是 client-go
提供的一种本地缓存机制:
通过 Informer 机制,大大降低了 Kubernetes 各个组件跟与 API Server 的通信压力,同时 ETCD 的查询压力也同样得到缓解。
Kubernetes 内部很多核心组件是有状态的,都以一主多从多实例的方式运行。这些组件的一主多从中,只有主实例负责处理数据,从实例处在热备状态。当主实例异常时从实例将竞选成为主实例并接替进行任务处理,所以这个选举机制是 Kubernetes 对于这有状态组件高可用的保障。
核心组件如 kube-scheduler 或 kube-controller-manager 等组件,在同一时刻只有一个实例在处理业务逻辑,因此需要在启动的实例中进行选主,决定哪个实例负责处理任务。这些核心组件都是使用的 client-go 中提供的工具类 leaderelection
,也就是本文的主角。
leaderelection
依赖于 Kubernetes 中提供的 Endpoints
、ConfigMap
和 Lease
三种资源锁,leaderelection
选主的实现方式就是基于这三种资源锁:
除了能在核心组件中使用,这个组件也能使用在我们开发的应用中,前提是我们的应用运行在 Kubernetes 环境且有操作资源锁的权限。
最近公司在组织各个系统的开发人员在搞信创改造,其中有部分改造内容就是要让系统能兼容 ARM 架构的 CPU。我们的系统都是运行在 Kubernetes 的容器中的,所以需要将应用打包到不同架构的镜像中。
Docker 提供了多平台的支持,可以将不同架构的镜像打包成一个镜像,部署时再根据运行的架构不同拉取不同架构的镜像运行,构建多平台镜像可以使用 BuildX 组件实现。
爱快软路由有非常完善的监控功能,但因为是爱快自己的体系,很不灵活,只能满足基本的使用,没法在 Prometheus 里使用,想要做些告警的功能就更不行了。
再加上最近跑网心云的虚机挂了几天才发现,搞一套内网的监控告警体系迫在眉睫了。对于家庭内网的监控告警,有几个需求需要满足:
基于 JWT 来实现 Token 认证很简单,相对复杂的签名认证算法都已经封装到工具包里,使用起来很容易。
而真正造成 JWT 的应用困难其实是在适应业务上,并不是所有业务都适合原生的 JWT 特性。我们很多时候选型使用 JWT 看重的是其无状态和校验方便的优点,但在实际的业务场景中经常是要 Revoke 功能的。
如果要实现 Token 的 Revoke 那 Token 会变成有状态,这让人使用起来非常纠结。 我都有状态了为啥还要用 JWT?直接生成一个 ID 存 Redis 不更简单?直接用 Redis 缓存有效性来控制 Token 的有效性,失效删除就好了。
最终选择使用 JWT 作为 Token 主要是基于以下考虑:
和漏桶算法算法类似,令牌桶算法的核心是固定“进口”速率,可以应对突发流量,是非常非常常用的算法。
通常在实现中,令牌的增加都是基于时间的延迟计算和预消费的思想。