​Kubernetes的演变:从etcd到分布式SQL的过渡

news2024/7/2 3:43:06

DevRel领域专家Denis Magda表示,他偶然发现了一篇解释如何用PostgreSQL无缝替换etcd的文章。该文章指出,Kine项目作为外部etcd端点,可以将Kubernetes etcd请求转换为底层关系数据库的SQL查询。

受到这种方法的启发,Magda决定进一步探索Kine的潜力,从etcd切换到YugabyteDB。YugabyteDB是一个基于PostgreSQL构建的分布式SQL数据库。

etcd有什么问题?

etcd是Kubernetes用来存放所有集群数据的键值库。

在Kubernetes集群遇到可扩展性或高可用性(HA)问题之前,它通常不会引起人们的注意。以可扩展和高可用性(HA)的方式管理etcd对于大型Kubernetes部署来说尤其具有挑战性。

此外,Kubernetes社区对etcd项目的未来开发也有越来越多的担忧。它的社区规模正在缩小,只有少数维护人员有兴趣和能力支持和推进这个项目。

这些问题催生了Kine,这是一个etcd API到SQL的转换层。Kine正式支持SQLite、PostgreSQL和MySQL,这些系统的使用量正在不断增长,并且拥有强大的社区。

为什么选择分布式SQL数据库?

虽然PostgreSQL、SQLite和MySQL是Kubernetes的理想选择,但它们是为单一服务器部署而设计和优化的。这意味着它们可能会带来一些挑战,特别是对于具有更严格的可扩展性和可用性要求的大型Kubernetes部署。

如果开发人员的Kubernetes集群要求RPO(恢复点目标)为零,RTO(恢复时间目标)以秒为单位测量,那么MySQL或PostgreSQL部署的架构和维护将是一个挑战。如果人们有兴趣深入研究这个话题,可以探索PostgreSQL的高可用性选项。

分布式SQL数据库作为一个相互连接的节点集群,可以跨多个机架、可用区或区域部署。通过设计,它们具有高可用性和可扩展性,因此可以为Kubernetes改进相同的特性。

在YugabyteDB上启动Kine

而决定使用YugabyteDB作为Kubernetes的分布式SQL数据库是受到PostgreSQL的影响。YugabyteDB建立在PostgreSQL源代码的基础上,在提供自己的分布式存储实现的同时,重用了PostgreSQL的上半部分(查询引擎)。

YugabyteDB和PostgreSQL之间的紧密联系允许开发人员为YugabyteDB重新设计PostgreSQL的Kine实现。然而需要继续关注,这不会是一个简单的提升和转移的故事。

现在,将这些想法转化为行动,并在YugabyteDB上启动Kine。为此,使用了一个配备了8个CPU和32GB内存的Ubuntu22.04虚拟机。

首先,在虚拟机上启动一个三个节点的YugabyteDB集群。在进行分布式之前,可以在单个服务器上对分布式SQL数据库进行试验。有多种方法可以在本地启动YugabyteDB,但作者更喜欢的方法是通过Docker:

Shell 
 mkdir ~/yb_docker_data

 docker network create custom-network

 docker run -d --name yugabytedb_node1 --net custom-network \
 -p 15433:15433 -p 7001:7000 -p 9000:9000 -p 5433:5433 \
  -v ~/yb_docker_data/node1:/home/yugabyte/yb_data --restart unless-stopped \
  yugabytedb/yugabyte:latest \
  bin/yugabyted start --tserver_flags="ysql_sequence_cache_minval=1" \
  --base_dir=/home/yugabyte/yb_data --daemon=false
 
 docker run -d --name yugabytedb_node2 --net custom-network \
  -p 15434:15433 -p 7002:7000 -p 9002:9000 -p 5434:5433 \
  -v ~/yb_docker_data/node2:/home/yugabyte/yb_data --restart unless-stopped \
 yugabytedb/yugabyte:latest \
  bin/yugabyted start --join=yugabytedb_node1 --tserver_flags="ysql_sequence_cache_minval=1" \
  --base_dir=/home/yugabyte/yb_data --daemon=false
     
 docker run -d --name yugabytedb_node3 --net custom-network \
  -p 15435:15433 -p 7003:7000 -p 9003:9000 -p 5435:5433 \
  -v ~/yb_docker_data/node3:/home/yugabyte/yb_data --restart unless-stopped \
  yugabytedb/yugabyte:latest \
 bin/yugabyted start --join=yugabytedb_node1 --tserver_flags="ysql_sequence_cache_minval=1" \
 --base_dir=/home/yugabyte/yb_data --daemon=false

注:在启动YugabyteDB节点时设置ysql_sequence_cache_minval=1,以确保数据库序列可以按顺序递增1。如果没有这个选项,一个Kine连接到YugabyteDB将缓存序列的下一个100个ID。这可能导致在Kubernetes集群引导期间出现“版本不匹配”错误,因为一个Kine连接可能插入ID范围从1到100的记录,而另一个Kine连接可能插入ID范围从101到200的记录。

接下来,使用PostgreSQL实现启动一个连接到YugabyteDB的Kine实例:

(1)克隆Kine库:

Shell 
1 git clone https://github.com/k3s-io/kine.git && cd kine

(2)启动一个连接到本地YugabyteDB集群的Kine实例:

Shell 
1 go run . --endpoint postgres://yugabyte:yugabyte@127.0.0.1:5433/yugabyte

(3)连接YugabyteDB,确认Kine架构已准备就绪:

SQL 
 psql -h 127.0.0.1 -p 5433 -U yugabyte

 yugabyte=# \d
       List of relations
 Schema |    Name     |   Type   |  Owner
 --------+-------------+----------+----------
  public | kine        | table    | yugabyte
  public | kine_id_seq | sequence | yugabyte
(2 rows)

很好,第一次测试成功了。Kine将YugabyteDB视为PostgreSQL,并且启动时没有任何问题。现在进入下一个阶段:使用YugabyteDB在Kine之上启动Kubernetes。

使用YugabyteDB在Kine上启动Kubernetes

Kine可以被各种Kubernetes引擎使用,包括标准的Kubernetes部署、Rancher Kubernetes引擎(RKE)或K3 (一种轻量级的Kubernetes引擎)。为简单起见,将使用后者。

K3s集群可以通过一个简单的命令启动:

(1)停止上一节中启动的Kine实例。

(2)启动连接到相同本地YugabyteDB集群的K3s(K3s可执行文件随Kine提供):

Shell 
curl -sfL https://get.k3s.io | sh -s - server --write-kubeconfig-mode=644 \
 --token=sample_secret_token \
--datastore-endpoint="postgres://yugabyte:yugabyte@127.0.0.1:5433/yugabyte"

(3)Kubernetes启动时应该没有问题,可以通过运行以下命令来确认:

Shell 
 k3s kubectl get nodes
 NAME STATUS ROLES AGE VERSION
 ubuntu-vm Ready control-plane,master 7m13s v1.27.3+k3s1

Kubernetes在YugabyteDB上无缝运行。这要归功于YugabyteDB很好的特性和与PostgreSQL的运行时兼容性。这意味着可以重用为PostgreSQL创建的大多数库、驱动程序和框架。

这可能标志着这一旅程的结束,可以回顾一下K3s日志。在Kubernetes引导期间,日志可能会报告缓慢的查询,如下所示:

SQL 
 INFO[0015] Slow SQL(total time: 3s) :
 SELECT
  *
 FROM (
  SELECT
  (
  SELECT
  MAX(rkv.id) AS id
  FROM
  kine AS rkv),
 (
  SELECT
  MAX(crkv.prev_revision) AS prev_revision
  FROM
  kine AS crkv
  WHERE
  crkv.name = 'compact_rev_key'), kv.id AS theid, kv.name, kv.created, kv.deleted, kv.create_revision, kv.prev_revision, kv.lease, kv.value, kv.old_value
  FROM
  kine AS kv
  JOIN (
  SELECT
  MAX(mkv.id) AS id
  FROM
  kine AS mkv
  WHERE
  mkv.name LIKE $1
  GROUP BY
  mkv.name) AS maxkv ON maxkv.id = kv.id
  WHERE
  kv.deleted = 0
  OR $2) AS lkv
 ORDER BY
  lkv.theid ASC
 LIMIT 10001

在一台机器上运行YugabyteDB时,这可能不是一个重要的问题,但是一旦切换到分布式设置,这样的查询就会成为热点并产生瓶颈。

因此克隆了Kine源代码,并开始探索PostgreSQL实现,寻找潜在的优化机会。

YugabyteDB的Kine优化

在这里,Magda与Franck Pachot合作,Pachot是一位精通SQL层优化的数据库专家,对应用程序逻辑没有或只有很少的更改。

在检查了Kine生成的数据库模式并将EXPLAIN ANALYZE用于某些查询之后,Franck提出了对任何分布式SQL数据库都有利的基本优化。

幸运的是,优化不需要对Kine应用程序逻辑进行任何更改。所要做的就是引入一些SQL级别的增强。因此,创建了一个直接支持YugabyteDB的Kine fork。

与此同时,与PostgreSQL相比,YugabyteDB的实现有三个优化:

(1)kine表的主索引已从primary index(id)更改为primary INCEX(id asc)。在默认情况下,YugabyteDB使用哈希分片在集群中均匀分布记录。然而,Kubernetes在id列上运行了许多范围查询,这使得切换到范围分片是合理的。

(2)通过在索引定义中包括id列,kine_name_prev_revision_uindex索引已被更新为覆盖索引:

CREATE UNIQUE INDEX IF NOT EXISTS kine_name_prev_revision_uindex ON kine (name asc, prev_revision asc) INCLUDE(id);

YugabyteDB的索引分布类似于表记录。因此,索引条目可能引用存储在不同YugabyteDB节点上的id。为了避免节点之间额外的网络往返,可以将id包含在二级索引中。

(3)Kine在完成Kubernetes请求的同时执行许多连接。如果查询规划器/优化器决定使用嵌套循环连接,那么在默认情况下,YugabyteDB查询层将每次读取和连接一条记录。为了加快这个过程,可以启用批处理嵌套循环连接。YugabyteDB的Kine实现通过在启动时执行以下语句来实现:

ALTER DATABASE " + dbName + " set yb_bnl_batch_size=1024;

尝试一下这个优化的YugabyteDB实现。

首先,停止之前的K3s服务,并从YugabyteDB集群中删除Kine模式:

(1)停止并删除K3s服务:

Shell 
 sudo /usr/local/bin/k3s-uninstall.sh
 sudo rm -r /etc/rancher

(2)删除模式:

SQL 
 psql -h 127.0.0.1 -p 5433 -U yugabyte

 drop table kine cascade;

接下来,启动一个为YugabyteDB提供优化版本的Kine实例:

(1)克隆fork:

Shell 
 git clone https://github.com/dmagda/kine-yugabytedb.git && cd kine-yugabytedb

(2)启动Kine:

Shell 
 go run . --endpoint "yugabytedb://yugabyte:yugabyte@127.0.0.1:5433/yugabyte"

Kine的启动没有任何问题。现在唯一的区别是,不是在连接字符串中指定“postgres”,而是指示“yugabytedb”以启用优化的YugabyteDB实现。关于Kine和YugabyteDB之间的实际通信,Kine继续使用Go的标准PostgreSQL驱动程序。

在Kine的优化版本上构建Kubernetes

最后,在这个优化版本的Kine上启动k3。

要做到这一点,首先需要从资源中构建k3:

(1)停止上一节中启动的Kine实例。

(2)克隆K3s存储库:

Shell 
 git clone --depth 1 https://github.com/k3s-io/k3s.git && cd k3s

(3)打开go.mod文件,并在replace(..)部分的末尾添加以下行:

Go 
 github.com/k3s-io/kine => github.com/dmagda/kine-yugabytedb v0.2.0

这条指令告诉Go使用带有YugabyteDB实现的最新版本的Kinefork。

(4)启用对私有仓库和模块的支持:

Shell 
 go env -w GOPRIVATE=github.com/dmagda/kine-yugabytedb

(5)确保更改生效:

Shell 
 go mod tidy

(6)准备构建K3s的完整版本:

Shell 
 mkdir -p build/data && make download && make generate

(7)构建完整版本:

Shell 
 SKIP_VALIDATE=true make

完成构建大约需要五分钟。

注意:一旦停止使用这个自定义K3s构建,可以按照说明卸载它。

在优化的Kubernetes版本上运行示例工作负载

在构建完成后,可以使用Kine的优化版本启动K3s。

(1)导航到包含构建构件的目录:

Shell 
 cd dist/artifacts/

(2)通过连接到本地YugabyteDB集群启动K3s:

Shell 
 sudo ./k3s server \
  --token=sample_secret_token \
 --datastore-endpoint="yugabytedb://yugabyte:yugabyte@127.0.0.1:5433/yugabyte"

(3)确认Kubernetes启动成功:

Shell 
 sudo ./k3s kubectl get nodes

 NAME STATUS ROLES AGE VERSION
 ubuntu-vm Ready control-plane,master 4m33s v1.27.4+k3s-36645e73
 

现在,部署一个示例应用程序,以确保Kubernetes集群不仅仅能够自我引导:

(1)采用Kubernetes克隆一个库的例子:

Shell 
 git clone https://github.com/digitalocean/kubernetes-sample-apps.git

(2)部署Emojivoto应用:

Shell 
 sudo ./k3s kubectl apply -k ./kubernetes-sample-apps/emojivoto-example/kustomize

(3)确保所有部署和服务成功启动:

Shell 
 sudo ./k3s kubectl get all -n emojivoto
 
 NAME READY STATUS RESTARTS AGE
 pod/vote-bot-565bd6bcd8-rnb6x    1/1 Running 0 25s
 pod/web-75b9df87d6-wrznp  1/1 Running 0 24s
 pod/voting-f5ddc8ff6-69z6v   1/1 Running 0 25s
 pod/emoji-66658f4b4c-wl4pt  1/1 Running 0 25s

 NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
 service/emoji-svc   ClusterIP 10.43.106.87 <none> 8080/TCP,8801/TCP 27s
 service/voting-svc   ClusterIP 10.43.14.118 <none> 8080/TCP,8801/TCP 27s
 service/web-svc   ClusterIP 10.43.110.237 <none> 80/TCP 27s

 NAME READY UP-TO-DATE AVAILABLE AGE
 deployment.apps/vote-bot  1/1 1 1 26s
 deployment.apps/web   1/1 1 1 25s
 deployment.apps/voting 1/1 1 1 26s
 deployment.apps/emoji 1/1 1 1 26s

 NAME DESIRED CURRENT READY AGE
 replicaset.apps/vote-bot-565bd6bcd8  1 1 1 26s
 replicaset.apps/web-75b9df87d6 1 1 1 25s
 replicaset.apps/voting-f5ddc8ff6  1 1 1 26s
 replicaset.apps/emoji-66658f4b4c  1  1   1   26s

(4)使用CLUSTER_IP:80调用服务/web svc以触发应用程序逻辑:

Shell 
 curl 10.43.110.237:80

应用程序将使用以下HTML进行响应:

HTML 
 <!DOCTYPE html>
 <html>
  <head>
  <meta charset="UTF-8">
  <title>Emoji Vote</title>
  <link rel="icon" href="/img/favicon.ico">
 
  <script async src="https://www.googletagmanager.com/gtag/js?id=UA-60040560-4"></script>
  <script>
  window.dataLayer = window.dataLayer || [];
  function gtag(){dataLayer.push(arguments);}
  gtag('js', new Date());
  gtag('config', 'UA-60040560-4');
  </script>
 </head>
 <body>
  <div id="main" class="main"></div>
  </body>
 
 <script type="text/javascript" src="/js" async></script>
 
 </html>

结语

完成工作!Kubernetes现在可以使用YugabyteDB作为其所有数据的分布式和高可用性SQL数据库。

现在可以进入下一阶段:在跨多个可用性区域和区域的真正云计算环境中部署Kubernetes和YugabyteDB,并测试解决方案如何处理各种中断。

软件开发构建工具

JNPF快速开发平台是一款基于SpringBoot+Vue3的全栈开发平台,采用微服务、前后端分离架构,基于可视化流程建模、表单建模、报表建模工具,快速构建业务应用,平台即可本地化部署,也支持K8S部署。

应用体验地址:https://www.jnpfsoft.com/?csdn,操作一下试试吧!

引擎式软件快速开发模式,除了上述功能,还配置了图表引擎、接口引擎、门户引擎、组织用户引擎等可视化功能引擎,基本实现页面UI的可视化搭建。内置有百种功能控件及使用模板,使得在拖拉拽的简单操作下,也能大限度满足用户个性化需求。由于JNPF平台的功能比较完善,本文选择这项工具进行展开,使你更加直观看到低代码的优势

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/894326.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

Linux Shell如果ping失败就重启网卡(详解)

直接上脚本 -------------------------------------------------------------------------- #vi /tmp/ping_check.sh #!/bin/bash IP="1.1.1.1" PacketLoss=`ping -c 4 -w 4 1.1.1.1 | grep packet loss | awk -F packet loss {print $1} | awk {print $NF}|se…

打开软件提示msvcr100.dll丢失的修复教程(解决方法)

电脑上出现了msvcr100.dll丢失的错误。这个错误导致无法正常运行一些使用C编写的程序。msvcr100.dll是Microsoft Visual C 2010 Redistributable安装程序提供的一个动态链接库文件。当一个程序需要使用msvcr100.dll中的函数或类时&#xff0c;它会在运行时动态链接到这个库文件…

前馈神经网络dropout实例

直接看代码。 &#xff08;一&#xff09;手动实现 import torch import torch.nn as nn import numpy as np import torchvision import torchvision.transforms as transforms import matplotlib.pyplot as plt#下载MNIST手写数据集 mnist_train torchvision.datasets.MN…

代码随想录-数组篇

2-二分查找 方法一&#xff1a; 左闭右闭&#xff0c;[left, right] class Solution { public:int search(vector<int>& nums, int target) {//[left, right]int left 0;int right nums.size() - 1 ;while(left < right){int middle left ((right - left)…

git 回滚相关问题

原本用as自带的git执行回滚任务&#xff0c; 但是提交之后发现并没有成功&#xff0c; 后面通过命令行的方式重新回滚并且提交上去&#xff0c;就可以了 说明as的git还是有点小瑕疵&#xff0c;还是命令行最稳妥 相关博文&#xff1a; git代码回滚操作_imkaifan的博客-CSDN博…

WebDAV之π-Disk派盘 + 那样记账

那样记账是一款个人记账应用,致力于提供简单和轻量的记账体验。以下是该应用的一些特点和功能: 1. 快速记账:那样记账提供多种直接记账方式,让您能够快速记录收入和支出。 2. 自定义:您可以自定义收支分类,以及记账的时间和金额。根据个人需求,随时修改和调整记账信息…

项目经理到底要不要懂技术?

大家好&#xff0c;我是老原。 “项目经理要不要懂技术&#xff1f;” 这个问题的争议性一直挺大&#xff0c;就好比先有的鸡还是先有的蛋&#xff0c;各方说各方有理。 我见过只负责流程不需要懂技术的pm&#xff0c;也见过pm连软硬件设计都有review的。 一般总结来说就是…

数据结构——链表详解

链表 文章目录 链表前言认识链表单链表结构图带头单循环链表结构图双向循环链表结构图带头双向循环链表结构图 链表特点 链表实现(带头双向循环链表实现)链表结构体(1) 新建头节点(2) 建立新节点(3)尾部插入节点(4)删除节点(5)头部插入节点(6) 头删节点(7) 寻找节点(8) pos位置…

GBU812-ASEMI新能源专用整流桥GBU812

编辑&#xff1a;ll GBU812-ASEMI新能源专用整流桥GBU812 型号&#xff1a;GBU812 品牌&#xff1a;ASEMI 封装&#xff1a;GBU-4 恢复时间&#xff1a;&#xff1e;50ns 正向电流&#xff1a;80A 反向耐压&#xff1a;1200V 芯片个数&#xff1a;4 引脚数量&#xff…

Windows基础安全知识

目录 常用DOS命令 ipconfig ping dir cd net user 常用DOS命令 内置账户访问控制 Windows访问控制 安全标识符 访问控制项 用户账户控制 UAC令牌 其他安全配置 本地安全策略 用户密码策略复杂性要求 强制密码历史&#xff1a; 禁止密码重复使用 密码最短使用期限…

【菜鸡读论文】MS-TCT: Multi-Scale Temporal ConvTransformer for Action Detection

【菜鸡读论文】MS-TCT: Multi-Scale Temporal ConvTransformer for Action Detection 大家好哇&#xff01;是谁美滋滋地准备开始放暑假了&#xff01;没错&#xff01;你没有听错&#xff01;放暑假&#xff01; 谁能想到都已经立秋了&#xff0c;竟然有人还在实验室&#xf…

java-IONIO

一、JAVA IO 1.1. 阻塞 IO 模型 最传统的一种 IO 模型&#xff0c;即在读写数据过程中会发生阻塞现象。当用户线程发出 IO 请求之后&#xff0c;内 核会去查看数据是否就绪&#xff0c;如果没有就绪就会等待数据就绪&#xff0c;而用户线程就会处于阻塞状态&#xff0c;用户线…

Codeforces Round 893 (Div. 2)B题题解

文章目录 [The Walkway](https://codeforces.com/contest/1858/problem/B)问题建模问题分析1.分析所求2.如何快速计算每个商贩被去除后的饼干数量代码 The Walkway 问题建模 给定n个椅子&#xff0c;其中有m个位置存在商贩&#xff0c;在商贩处必须购买饼干吃&#xff0c;每隔…

u8g2 自制字体

显示器 SSD1306 单片机ARDUINO NANO 使用U8G2 将表情生成字库文件 使用DRAWGLYPH 显示表情字库 GIF转成40X80 GIF转PNG PNG 转1位 PNG生成BDP BDP生成 C U8G2源代码的TOOL\FONT中包含了PNG转BDP BDP转.C 文件 下载原代码 &#xff1a; GitHub - olikraus/u8g2: U8gl…

python3 0基础学习----数据结构(基础+练习)

python 0基础学习笔记之数据结构 &#x1f4da; 几种常见数据结构列表 &#xff08;List&#xff09;1. 定义2. 实例&#xff1a;3. 列表中常用方法.append(要添加内容) 向列表末尾添加数据.extend(列表) 将可迭代对象逐个添加到列表中.insert(索引&#xff0c;插入内容) 向指定…

redis查看执行的命令+配置文件命令

1.SLOWLOG LEN 获取 Slowlog 的长度&#xff0c;以确定 Slowlog 中有多少条记录 2.SLOWLOG GET 获取 Slowlog 中的具体记录。你可以使用 SLOWLOG GET 命令来获取第 n 条记录的详细信息&#xff0c;其中 n 是记录的索引&#xff08;从 0 开始&#xff09; 3.如果你想获取多条最…

RFID赋能新能源电池生产的智慧演进

随着全球对可再生能源的需求不断增长&#xff0c;新能源电池作为储能和供电的重要组成部分&#xff0c;正逐渐成为关注的焦点。然而&#xff0c;新能源电池的生产过程中存在着一系列挑战&#xff0c;如追踪和管理电池的生命周期、确保质量和安全等。在这方面&#xff0c;RFID正…

【WPF】 本地化的最佳做法

【WPF】 本地化的最佳做法 资源文件英文资源文件 en-US.xaml中文资源文件 zh-CN.xaml 资源使用App.xaml主界面布局cs代码 App.config辅助类语言切换操作类资源 binding 解析类 实现效果 应用程序本地化有很多种方式&#xff0c;选择合适的才是最好的。这里只讨论一种方式&#…

微信公众平台发布小程序流程

最近因为部署小程序&#xff0c;学习了下如何部署小程序 1. 取消不检验合法域名并上传小程序 建议在小程序上传之前&#xff0c;先取消不校验合法域名并真机调试下。 2. 登录微信公众平台 登录微信公众平台 3. 设置服务器域名 在开放->开发管理->开发设置找到服务器…

Minio知识点+linux下安装+面试总结

一 Minio简介 MinIO 是一个基于Apache License v2.0开源协议的对象存储服务。它兼容亚马逊S3云存储服务接口&#xff0c;非常适合于存储大容量非结构化的数据&#xff0c;例如图片、视频、日志文件、备份数据和容器/虚拟机镜像等&#xff0c;而一个对象文件可以是任意大小&…