K3s架构

在k3s集群中,一个节点运行控制平面的节点被称为 server ,而一个节点只运行 kubelet 则被称为 agent

serveragent 上都有容器运行时( container runtime ) 和对应 kubeproxy 来管理集群间的网络流量和tunneling。

../../_images/k3s.png

不过,和传统的 Kubernetes Atlas 架构不同,在K3s中没有清晰区别 masterworker 节点。Pods可以调度到任何能运行的角色的节点上进行管理。所以在K3s集群中,通常不命名 master 节点和 worker 节点,而是统称为 node

备注

也就是说,对于 K3s 这样面向有限硬件的 边缘云计算构建 集群,要构建高可用Kubernetes集群,理论上只需要3个节点的硬件。

后续我将尝试在3个节点上构建 树莓派堆叠 ,部署3节点 k3s 实现最小化高可用集群。

K3s为了实现轻量级的Kubernetes,对Kubernetes的大量可选组件做了裁剪,然后添加了一些基础组件,也就是 K3s简介 所述的基础依赖:

所有上述组件都被打包到一个单一二进制运行程序中,并且以一个相同进程运行。

除了上述经过精心选择和精简的组件, K3s 也可以通过 batteries included but replaceable 方式(一切皆备但可替换升级)扩展。例如,容器运行时可以由 containerd运行时(runtime) 替换成 Docker CE运行时, Flannel网络 可以替换成 Calico网络 ,本地存储可以替换成 Longhorn k8s分布式存储 等等,以适应更大更复杂的应用场景。

备注

k3s 支持不同的持久化方案,除了传统的 etcd - 分布式kv存储 还支持不同的数据库如 MySQL AtlasPostgreSQL Atlas 。在早期版本,还实验性支持过 分布式SQLite - Dqlite ,但在最近版本放弃支持。

我个人对嵌入式系统比较感兴趣,在轻量级的 Raspberry Pi Atlas 环境,我觉得基于 SQLite Atlas 的分布式 分布式SQLite - Dqlite 可能是更为精巧的解决方案。

备注

在树莓派上部署K3s 初期采用标准精简模式,然后再扩展采用 Longhorn k8s分布式存储

K3s发行版支持不同的架构:

  • AMD64

  • ARM64

  • ARMv7

备注

我最初没有注意到 k3s 发行版支持的ARM最低架构是 ARMv7 (虽然软件包打包为 armhf 看上去也是32位架构),所以规划采用 树莓派一代 来构建 最小和最低成本Kubernetes 。但是, 树莓派一代ARMv6 微架构,导致运行出现 ARM平台执行程序报错"Illegal instruction"解析

最终,我采用 源代码编译k3s 自己构建 ARMv6k3s 执行程序。

作为轻量级Kuberntes发行版, K3s 可以运行在:

伸缩性的部署

使用嵌入式DB的单节点部署

  • 可以在单节点部署最小化的K3s,使用相同的流程来部署验证,使用 helm 或 YAML文件来构建,可以使用CI/CD pipelines和容器镜像来实现

../../_images/k3s-architecture-single-server.png

使用外部DB实现高可用部署

../../_images/k3s-architecture-ha-server.png

对Agent节点的固定注册地址

在上述高可用服务器配置,每个node必须使用一个固定的注册地址注册到Kubernetes API,完成注册之后,agent node就会和server node直接通讯:

../../_images/k3s-production-setup.png

每个Agent节点通过 k3s agent 进程发起一个websocket连接进行注册,然后这个连接由 agent 进程在客户端的负载均衡维护:

  • agent注册时候使用的 fixed registration address 可以是DNS(其实就是DSN轮转)或者负载均衡(负载均衡到API服务器)

    • 通过DNS轮询(相当于负载均衡)agent可以注册到K3s API server上

    • 通过负载均衡(分发到后端的K3s API server)agent也可以注册到K3s API server上

    • 一旦agent完成注册,agent就会获得完整的K3s API server服务器列表(例如3台高可用)

      • 后续agent将在本地维护一个负载均衡(因为agent知道完整的K3s API server地址),并直接和API Server通讯

      • 后续agent将不会访问 fixed registration address (这个地址仅在注册时使用),这种方式可以避免 fixed registration address (负载均衡)的瓶颈

      • 如果某个API Server宕机,agent依然可以访问剩余的API Server(客户端维护负载均衡)

参考