在本文中,将探讨使用 k3s 的 kine 项目来替换掉 etcd,并通过实验使用 kubeadm 去 run 一个 k8s 集群,并用 k3s 的 kine 项目来替换掉 etcd。
为什么使用 kine
etcd 在 Kubernetes 之外基本上没有应用的场景,并且 etcd 迭代也比较慢,由于没有人愿意维护因此一直在衰退 [1],并且,Kubernetes 集群中,etcd 也是一个影响集群规模的重大因素。并且 K3S 存在一个项目 Kine 可以使用关系型数据库运行,这样对集群维护者来说可以不需要维护复杂的 etcd 集群,由于关系型数据库有很多高可用方案,这将使得 k8s 集群规模变成了无限可能。
Kine 介绍
前文提到,kubernetes (kube-apiserver) 与 etcd 是耦合的,如果我们要使用 RDBMS 去替换 etcd 就需要实现 etcd 的接口,那么这个项目就是 Kine [2]。
Kine 是一个 etcdshim,处于 kube-apiserver 和 RDBMS 的中间层,它实现了 etcdAPI的子集(不是etcd的全部功能),Kine 在 RDBMS 数据库之上实现了简单的多版本并发控制;将所有信息存储在一个表中;每行存储此 key 的修订, key, 当前值, 先前值, 先前修订,以及表示该 Key 是已创建还是已删除的标记,通过这种机制可以作为 shim 层来替换 etcd。
简单提一句,shim 是计算机程序设计中的术语,表现为一个小型函数库,服务等,通过截取 API 调用,修改传入参数,来处理自行处理对应操作或者将操作交由其它地方执行。
总的来说 shim 是一种可以在新环境中支持老 API,也可以在老环境里支持新 API 辅助运行库或服务,在云原生场景中,我们经常看到 docker-shim,cri-shim 等。
前提条件
本文实验环境使用的软件版本如下
软件/硬件 | 版本 |
---|---|
操作系统 | Debian 11(bullseye) 2C/4G |
Kubernetes版本 | v1.28.11(截至文章编写时间的最新版) |
Kubernetes集群部署工具 | kubeadm |
Kine | v0.11.10 (截至文章编写时间的最新版) |
MySQL | Docker运行,镜像 mysql:5.7 |
使用 kubeadm 构建控制平面
为了展现 kine 的作用,首先我们需要准备一个 k8s 集群,这里简单使用 kubeadm + containerd 来构建一个 kuebrnetes 集群。
安装 containerd
载入内核依赖项
containerd 或 docker 的安装都需要内核支持 overlay
和 br_netfilter
模块,overlay 为 containerd 运行的文件系统,netfiler 用于维护容器内 (inter-container) 的网络。所以我们需要加载对应的内核模块。
|
|
手动执行下面命令
|
|
通过仓库 containerd
contanerd 是作为 docker-ce 的下层,所以很多 Linux 发行版都有对应的包管理工具的仓库,这里面维护了基本上比较新的版本,可以直接在对应操作系统下载
CentOS
|
|
Debian
Debian仓库中通常都有比较新版本的 containerd,可以直接安装
|
|
安装
|
|
离线安装
如果需要离线环境安装的话,可以在手动下载 containerd 和 runc 后传入内网
下载 Containerd 的二进制包,这里下载containerd-<VERSION>-<OS>-<ARCH>.tar.gz
格式名称的发行版,后边在单独下载安装 runc
|
|
将其解压缩到 /usr/local 下:
|
|
接下来从 runc 的 github 上下载安装 runc,该二进制文件是静态构建的,并且应该适用于任何Linux发行版。
|
|
为了通过 systemd 管理 containerd,请还需要从仓库中下载 containerd.service 单元文件
|
|
配置配置文件
|
|
配置驱动为 systemd
将配置文件修改为实例所述
|
|
一键修改命令
|
|
启动服务
|
|
使用kubeadm构建集群
加载内核依赖项
|
|
执行以下命令使配置立即生效:
|
|
安装kubeadm kubelet kubectl
安装 kubeadm 可以参考官网的步骤来 [3]
使用基于debian 包管理仓库
使用 Kubernetes apt 仓库
|
|
下载公共签名key
|
|
添加适合的 k8s 版本仓库,这里是 1.28
|
|
更新包索引
|
|
不使用包管理工具
下载 kubeadm
, kubelet
, kubectl
二进制文件
|
|
下载 kubelet 的 system单元文件 或手动添加所需的 systemd 单元文件
|
|
或者手动创建 kubelet.serivce 的 systemd 的单元文件
这个文件是将 rpm 或 dpkg 包的 kubelet.service 和上述 10-kubeadm.conf 融合为一起的,效果是相同的
|
|
离线环境镜像下载
列出所使用的镜像
|
|
下载对应镜像,并上传到私有仓库
|
|
生成配置文件
|
|
使用配置文件安装
|
|
使用命令初始化
|
|
这个时候控制平面已经可以正常工作了
|
|
使用 kine 来替换 etcd
查看官方示例
首先根据 kine 官方 example 来查看最小示例的来学习如何使用 kine [4],通过文章得知,kine 运行有两种方式,kine 与数据库之间的使用 ssl 链接。
mysql
|
|
postgres
|
|
这时我们需要查看一下 kine 的参数
|
|
通过参数得知,上面的除了官方给出的,kine 与数据库之间的连接也可以不使用 ssl,并通过 --server-cert-file
与 --server-key-file
来作为 kube-apiserver 连接 etcd 所使用的证书指定给 kine 就可以启动了。
编写静态文件
这里我们只需要删除 /etc/kubernetes/manifests/etcd.yaml
并将 etcd 使用的证书挂载到 kine pod 中,那么我们编写 /etc/kubernetes/manifests/kine.yaml
文件。
|
|
kubuadm 生成的 kubelet 的 KubeletConfiguration 文件,中静态文件得路径参数 “staticPodPath”
|
|
这个时候可以启动 kubelet 服务,然后查看静态 Pod,此时可以看到, kube-system 名称空间 已经没有 etcd pod了
|
|
此时就可以继续部署 k8s 的 worker 节点和 CNI 了
探索 kine
我们可以查看数据库表结构,来探索 kine 是如何实现的 etcdAPI 转换的,我们可以看到,kine 会在启动参数中配置的库名 创建对应的数据库,并且仅有一个表 kine
|
|
观察表结构
|
|
查看数据是如何存储的
|
|
如上所示,有一个名为的表 “kine”包含所有数据。Kine 使用数据库作为日志结构存储,因此来自 API 服务器的每次写入都会创建一个新行来存储已创建或更新的 Kubernetes 对象,“name” 列使用与 etcd 相同的存储结构 “/registry/RESOURCE_TYPE/NAMESPACE/NAME” 表示集群中对象。
k3s 资源分析
k3s 官方提供了 Resource Profiling [5] 来对比了 RDBMS 与 etcd 的性能对比。
总结
因为 RDBMS 大家都很熟悉,并且更高性能的分布式解决方案也有很多,例如 YugabyteDB (PostgreSQL兼容的分布式数据库),也可以预创建 kine 表,通过分区形式将不同数据存储到不同的分区内。而且 k8s 对象的历史数据也是可以根据一定的规则进行删除,因为 kubernetes 中的对象都是实时协调的,所以也不怕误删除,这样就会使得 kubernetes 规模有更大扩展的可能。