Kubernetes(K8s)从入门到精通系列之十:使用 kubeadm 创建一个高可用 etcd 集群

news2025/1/19 23:19:55

Kubernetes K8s从入门到精通系列之十:使用 kubeadm 创建一个高可用 etcd 集群

  • 一、etcd高可用拓扑选项
    • 1.堆叠(Stacked)etcd 拓扑
    • 2.外部 etcd 拓扑
  • 二、准备工作
  • 三、建立集群
    • 1.将 kubelet 配置为 etcd 的服务管理器。
    • 2.为 kubeadm 创建配置文件。
    • 3.生成证书颁发机构。
    • 4.为每个成员创建证书。
    • 5.复制证书和 kubeadm 配置。
    • 6.确保已经所有预期的文件都存在
    • 7.创建静态 Pod 清单。
    • 8.可选:检查集群运行状况。

一、etcd高可用拓扑选项

默认情况下,kubeadm 在每个控制平面节点上运行一个本地 etcd 实例。也可以使用外部的 etcd 集群,并在不同的主机上提供 etcd 实例。

可以设置HA集群:

  • 使用堆叠控制控制平面节点,其中 etcd 节点与控制平面节点共存
  • 使用外部 etcd 节点,其中 etcd 在与控制平面不同的节点上运行

1.堆叠(Stacked)etcd 拓扑

堆叠(Stacked)HA 集群是一种这样的拓扑, 其中 etcd 分布式数据存储集群堆叠在 kubeadm 管理的控制平面节点上,作为控制平面的一个组件运行。

每个控制平面节点运行 kube-apiserver、kube-scheduler 和 kube-controller-manager 实例。 kube-apiserver 使用负载均衡器暴露给工作节点。

每个控制平面节点创建一个本地 etcd 成员(member),这个 etcd 成员只与该节点的 kube-apiserver 通信。 这同样适用于本地 kube-controller-manager 和 kube-scheduler 实例。

这种拓扑将控制平面和 etcd 成员耦合在同一节点上。相对使用外部 etcd 集群, 设置起来更简单,而且更易于副本管理。

然而,堆叠集群存在耦合失败的风险。如果一个节点发生故障,则 etcd 成员和控制平面实例都将丢失, 并且冗余会受到影响。你可以通过添加更多控制平面节点来降低此风险。

因此,你应该为 HA 集群运行至少三个堆叠的控制平面节点。

这是 kubeadm 中的默认拓扑。当使用 kubeadm init 和 kubeadm join --control-plane 时, 在控制平面节点上会自动创建本地 etcd 成员。

在这里插入图片描述

2.外部 etcd 拓扑

具有外部 etcd 的 HA 集群是一种这样的拓扑, 其中 etcd 分布式数据存储集群在独立于控制平面节点的其他节点上运行。

就像堆叠的 etcd 拓扑一样,外部 etcd 拓扑中的每个控制平面节点都会运行 kube-apiserver、kube-scheduler 和 kube-controller-manager 实例。 同样,kube-apiserver 使用负载均衡器暴露给工作节点。但是 etcd 成员在不同的主机上运行, 每个 etcd 主机与每个控制平面节点的 kube-apiserver 通信。

这种拓扑结构解耦了控制平面和 etcd 成员。因此它提供了一种 HA 设置, 其中失去控制平面实例或者 etcd 成员的影响较小,并且不会像堆叠的 HA 拓扑那样影响集群冗余。

但此拓扑需要两倍于堆叠 HA 拓扑的主机数量。 具有此拓扑的 HA 集群至少需要三个用于控制平面节点的主机和三个用于 etcd 节点的主机。

在这里插入图片描述

二、准备工作

  • 三个可以通过 2379 和 2380 端口相互通信的主机。本文档使用这些作为默认端口。 不过,它们可以通过 kubeadm 的配置文件进行自定义。
  • 每个主机必须安装 systemd 和 bash 兼容的 shell。
  • 每台主机必须安装有容器运行时、kubelet 和 kubeadm。
  • 每个主机都应该能够访问 Kubernetes 容器镜像仓库 (registry.k8s.io), 或者使用 kubeadm config images list/pull 列出/拉取所需的 etcd 镜像。 本指南将把 etcd 实例设置为由 kubelet 管理的静态 Pod。
  • 一些可以用来在主机间复制文件的基础设施。例如 ssh 和 scp 就可以满足此需求。

三、建立集群

一般来说,是在一个节点上生成所有证书并且只分发这些必要的文件到其它节点上。

1.将 kubelet 配置为 etcd 的服务管理器。

说明:必须在要运行 etcd 的所有主机上执行此操作。

由于 etcd 是首先创建的,因此你必须通过创建具有更高优先级的新文件来覆盖 kubeadm 提供的 kubelet 单元文件。

cat << EOF > /etc/systemd/system/kubelet.service.d/kubelet.conf
# 将下面的 "systemd" 替换为你的容器运行时所使用的 cgroup 驱动。
# kubelet 的默认值为 "cgroupfs"。
# 如果需要的话,将 "containerRuntimeEndpoint" 的值替换为一个不同的容器运行时。
#
apiVersion: kubelet.config.k8s.io/v1beta1
kind: KubeletConfiguration
authentication:
anonymous:
 enabled: false
webhook:
 enabled: false
authorization:
mode: AlwaysAllow
cgroupDriver: systemd
address: 127.0.0.1
containerRuntimeEndpoint: unix:///var/run/containerd/containerd.sock
staticPodPath: /etc/kubernetes/manifests
EOF

cat << EOF > /etc/systemd/system/kubelet.service.d/20-etcd-service-manager.conf
[Service]
ExecStart=
ExecStart=/usr/bin/kubelet --config=/etc/systemd/system/kubelet.service.d/kubelet.conf
Restart=always
EOF

systemctl daemon-reload
systemctl restart kubelet

检查 kubelet 的状态以确保其处于运行状态:

systemctl status kubelet

2.为 kubeadm 创建配置文件。

使用以下脚本为每个将要运行 etcd 成员的主机生成一个 kubeadm 配置文件。

# 使用你的主机 IP 更新 HOST0、HOST1 和 HOST2 的 IP 地址
export HOST0=10.0.0.6
export HOST1=10.0.0.7
export HOST2=10.0.0.8

# 使用你的主机名更新 NAME0、NAME1 和 NAME2
export NAME0="infra0"
export NAME1="infra1"
export NAME2="infra2"

# 创建临时目录来存储将被分发到其它主机上的文件
mkdir -p /tmp/${HOST0}/ /tmp/${HOST1}/ /tmp/${HOST2}/

HOSTS=(${HOST0} ${HOST1} ${HOST2})
NAMES=(${NAME0} ${NAME1} ${NAME2})

for i in "${!HOSTS[@]}"; do
HOST=${HOSTS[$i]}
NAME=${NAMES[$i]}
cat << EOF > /tmp/${HOST}/kubeadmcfg.yaml
---
apiVersion: "kubeadm.k8s.io/v1beta3"
kind: InitConfiguration
nodeRegistration:
 name: ${NAME}
localAPIEndpoint:
 advertiseAddress: ${HOST}
---
apiVersion: "kubeadm.k8s.io/v1beta3"
kind: ClusterConfiguration
etcd:
 local:
     serverCertSANs:
     - "${HOST}"
     peerCertSANs:
     - "${HOST}"
     extraArgs:
         initial-cluster: ${NAMES[0]}=https://${HOSTS[0]}:2380,${NAMES[1]}=https://${HOSTS[1]}:2380,${NAMES[2]}=https://${HOSTS[2]}:2380
         initial-cluster-state: new
         name: ${NAME}
         listen-peer-urls: https://${HOST}:2380
         listen-client-urls: https://${HOST}:2379
         advertise-client-urls: https://${HOST}:2379
         initial-advertise-peer-urls: https://${HOST}:2380
EOF
done

3.生成证书颁发机构。

如果你已经拥有 CA,那么唯一的操作是复制 CA 的 crt 和 key 文件到 etc/kubernetes/pki/etcd/ca.crt 和 /etc/kubernetes/pki/etcd/ca.key。 复制完这些文件后继续下一步,“为每个成员创建证书”。

如果你还没有 CA,则在 $HOST0(你为 kubeadm 生成配置文件的位置)上运行此命令。

kubeadm init phase certs etcd-ca

这一操作创建如下两个文件:

  • /etc/kubernetes/pki/etcd/ca.crt
  • /etc/kubernetes/pki/etcd/ca.key

4.为每个成员创建证书。

kubeadm init phase certs etcd-server --config=/tmp/${HOST2}/kubeadmcfg.yaml
kubeadm init phase certs etcd-peer --config=/tmp/${HOST2}/kubeadmcfg.yaml
kubeadm init phase certs etcd-healthcheck-client --config=/tmp/${HOST2}/kubeadmcfg.yaml
kubeadm init phase certs apiserver-etcd-client --config=/tmp/${HOST2}/kubeadmcfg.yaml
cp -R /etc/kubernetes/pki /tmp/${HOST2}/
# 清理不可重复使用的证书
find /etc/kubernetes/pki -not -name ca.crt -not -name ca.key -type f -delete

kubeadm init phase certs etcd-server --config=/tmp/${HOST1}/kubeadmcfg.yaml
kubeadm init phase certs etcd-peer --config=/tmp/${HOST1}/kubeadmcfg.yaml
kubeadm init phase certs etcd-healthcheck-client --config=/tmp/${HOST1}/kubeadmcfg.yaml
kubeadm init phase certs apiserver-etcd-client --config=/tmp/${HOST1}/kubeadmcfg.yaml
cp -R /etc/kubernetes/pki /tmp/${HOST1}/
find /etc/kubernetes/pki -not -name ca.crt -not -name ca.key -type f -delete

kubeadm init phase certs etcd-server --config=/tmp/${HOST0}/kubeadmcfg.yaml
kubeadm init phase certs etcd-peer --config=/tmp/${HOST0}/kubeadmcfg.yaml
kubeadm init phase certs etcd-healthcheck-client --config=/tmp/${HOST0}/kubeadmcfg.yaml
kubeadm init phase certs apiserver-etcd-client --config=/tmp/${HOST0}/kubeadmcfg.yaml
# 不需要移动 certs 因为它们是给 HOST0 使用的

# 清理不应从此主机复制的证书
find /tmp/${HOST2} -name ca.key -type f -delete
find /tmp/${HOST1} -name ca.key -type f -delete

5.复制证书和 kubeadm 配置。

证书已生成,现在必须将它们移动到对应的主机。

USER=ubuntu
HOST=${HOST1}
scp -r /tmp/${HOST}/* ${USER}@${HOST}:
ssh ${USER}@${HOST}
USER@HOST $ sudo -Es
root@HOST $ chown -R root:root pki
root@HOST $ mv pki /etc/kubernetes/

6.确保已经所有预期的文件都存在

$HOST0 所需文件的完整列表如下:

/tmp/${HOST0}
└── kubeadmcfg.yaml
---
/etc/kubernetes/pki
├── apiserver-etcd-client.crt
├── apiserver-etcd-client.key
└── etcd
    ├── ca.crt
    ├── ca.key
    ├── healthcheck-client.crt
    ├── healthcheck-client.key
    ├── peer.crt
    ├── peer.key
    ├── server.crt
    └── server.key

在 $HOST1 上:

$HOME
└── kubeadmcfg.yaml
---
/etc/kubernetes/pki
├── apiserver-etcd-client.crt
├── apiserver-etcd-client.key
└── etcd
    ├── ca.crt
    ├── healthcheck-client.crt
    ├── healthcheck-client.key
    ├── peer.crt
    ├── peer.key
    ├── server.crt
    └── server.key

在 $HOST2 上:

$HOME
└── kubeadmcfg.yaml
---
/etc/kubernetes/pki
├── apiserver-etcd-client.crt
├── apiserver-etcd-client.key
└── etcd
    ├── ca.crt
    ├── healthcheck-client.crt
    ├── healthcheck-client.key
    ├── peer.crt
    ├── peer.key
    ├── server.crt
    └── server.key

7.创建静态 Pod 清单。

既然证书和配置已经就绪,是时候去创建清单了。 在每台主机上运行 kubeadm 命令来生成 etcd 使用的静态清单。

root@HOST0 $ kubeadm init phase etcd local --config=/tmp/${HOST0}/kubeadmcfg.yaml
root@HOST1 $ kubeadm init phase etcd local --config=$HOME/kubeadmcfg.yaml
root@HOST2 $ kubeadm init phase etcd local --config=$HOME/kubeadmcfg.yaml

8.可选:检查集群运行状况。

如果 etcdctl 不可用,你可以在容器镜像内运行此工具。 你可以使用 crictl run 这类工具直接在容器运行时执行此操作,而不是通过 Kubernetes。

ETCDCTL_API=3 etcdctl \
--cert /etc/kubernetes/pki/etcd/peer.crt \
--key /etc/kubernetes/pki/etcd/peer.key \
--cacert /etc/kubernetes/pki/etcd/ca.crt \
--endpoints https://${HOST0}:2379 endpoint health
...
https://[HOST0 IP]:2379 is healthy: successfully committed proposal: took = 16.283339ms
https://[HOST1 IP]:2379 is healthy: successfully committed proposal: took = 19.44402ms
https://[HOST2 IP]:2379 is healthy: successfully committed proposal: took = 35.926451ms
  • 将 ${HOST0} 设置为要测试的主机的 IP 地址。

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

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

相关文章

【MATLAB第64期】【保姆级教程】基于MATLAB的SOBOL全局敏感性分析模型运用(含无目标函数,考虑代理模型)

【MATLAB第64期】【保姆级教程】基于MATLAB的SOBOL全局敏感性分析模型运用&#xff08;含无目标函数&#xff0c;考虑代理模型&#xff09; 版本更新&#xff1a; 2023/8/5&#xff1a; 1.因BP作为代理模型不稳定&#xff0c;经过测试&#xff0c;libsvm比rf /bp 效果稳定且精…

MSF恶意程序利用——CS上线

Msfvenom是一个Metasploit独立的有效负载生成器&#xff0c;也是msfpayload和msfencode的替代品。是用来生成后门的软件。 申明&#xff1a;本篇文章的用意仅做学习使用&#xff01; 网络搭建环境&#xff1a; 软件&#xff1a;Vmware Workstation 17 攻击机&#xff1a;Ka…

【手撕C语言】多线程

(꒪ꇴ꒪ )&#xff0c;Hello我是祐言QAQ我的博客主页&#xff1a;C/C语言,Linux基础,ARM开发板&#xff0c;软件配置等领域博主&#x1f30d;快上&#x1f698;&#xff0c;一起学习&#xff0c;让我们成为一个强大的攻城狮&#xff01;送给自己和读者的一句鸡汤&#x1f914;&…

Qt-QSlider样式

文章目录 QSliderQSS 代码QSlider 分析QSlider The slider is the classic widget for controlling a bounded value.It lets the user move a slider handle along a horizontal or vertical groove and translates the handles position into an integer value within the l…

Java课题笔记~ AspectJ 的开发环境(掌握)

AspectJ 的开发环境(掌握) &#xff08;1&#xff09; maven 依赖 <dependencies><dependency><groupId>junit</groupId><artifactId>junit</artifactId><version>4.12</version><scope>test</scope></depe…

简单动态字符串 sds

Redis 设计了简单动态字符串&#xff08;Simple Dynamic String&#xff0c;SDS&#xff09;的结构&#xff0c;用来表示 字符串。相比于 C 语言中的字符串实现&#xff0c;SDS 这种字符串的实现方式&#xff0c;会提升字符串的操 作效率&#xff0c;并且可以用来保存二进制数据…

Element-Plus DatePicker获取时间戳

文章目录 0、先上答案1、渔&#xff1f;1-1 Element-Plus 官网1-2 溯源 Day.js 0、先上答案 <!-- 秒 --><el-date-pickerv-model"timeStamp"type"datetime"value-format"X"/><!-- 毫秒 --><el-date-pickerv-model"tim…

Spring Boot 最佳实践

本文翻译自国外论坛 medium&#xff0c;原文地址&#xff1a;https://medium.com/raviyasas/spring-boot-best-practices-for-developers-3f3bdffa0090 Spring Boot 是一种广泛使用且非常流行的企业级高性能框架。以下是一些最佳实践和一些技巧&#xff0c;我们可以使用它们来…

【Git分布式版本控制系统一】你还不会用Git进行项目管理?

&#x1f942;(❁◡❁)您的点赞&#x1f44d;➕评论&#x1f4dd;➕收藏⭐是作者创作的最大动力&#x1f91e; 前言 众所周知&#xff0c;分布式版本控制系统git是工作以后进行项目管理必不可少的工具&#xff0c;我将繁杂的命令进行了归类整理和总结&#xff0c;供大家参考学习…

springboot+vue真实项目部署详细步骤

sprinbootvue项目详细部署步骤 文章目录 sprinbootvue项目详细部署步骤1、准备部署文件2、安装mysql2.1、配置mysql2.2、用navicat远程连接mysql导入数据2.3、导入mysql数据 3、安装jdk4、安装nginx5、安装redis6、创建对应的目录层级和启动6.1 构建启动脚本6.2 、修改两个后台…

数据库索引的使用

1、MySQL的基本架构 架构图 左边的client可以看成是客户端&#xff0c;客户端有很多&#xff0c;像我们经常你使用的CMD黑窗口&#xff0c;像我们经常用于学习的WorkBench&#xff0c;像企业经常使用的Navicat工具&#xff0c;它们都是一个客户端。右边的这一大堆都可以看成是…

Python系统学习1-5-容器

1、字符串 字符串是不可变的数据 原因&#xff1a;如果在原有内存中修改&#xff0c;很可能破坏其他数据的空间 现象&#xff1a;每次需要修改字符串时&#xff0c;都会创建新数据&#xff0c;替换变量中存储的地址 字符串字面值 (1)建议使用双引号 name01 "悟空&q…

中介者模式(C++)

定义 用一个中介对象来封装(封装变化)一系列的对象交互。中介者使各对象不需要显式的相互引用(编译时依赖->运行时依赖)&#xff0c;从而使其耦合松散(管理变化)&#xff0c;而且可以独立地改变它们之间的交互。 应用场景 在软件构建过程中&#xff0c;经常会出现多个对象…

VUE框架:vue2转vue3全面细节总结(5)过渡动效

大家好&#xff0c;我是csdn的博主&#xff1a;lqj_本人 这是我的个人博客主页&#xff1a; lqj_本人_python人工智能视觉&#xff08;opencv&#xff09;从入门到实战,前端,微信小程序-CSDN博客 最新的uniapp毕业设计专栏也放在下方了&#xff1a; https://blog.csdn.net/lbcy…

公文写作素材:“干”字型排比句40例

1.怀着真诚“想干”&#xff0c;扛着担当“敢干”&#xff0c;瞄着路径“能干”&#xff0c;盯着责任“真干”&#xff0c;想着办法“会干”&#xff0c;带着智慧“巧干”&#xff0c;揣着情怀“认干”&#xff0c;铆着劲头“实干”。 2.脱下“皮鞋”、换上“运动鞋”&#xff…

3 vue的if语法

vue的if语法是相当于一个标签的属性来写进去的&#xff0c;比如说<h1 v-if“”>。要注意的是if语句里可以自动从数据层取值的&#xff0c;比如<h1 v-if"message">&#xff0c;这里就会自动把key为message的值取过来&#xff0c;而如果要传一个字符串&…

Vue [Day5]

自定义指令 全局注册 和 局部注册 inserted在指令所在的元素 被插入到页面中时&#xff0c;触发 main.js import Vue from vue import App from ./App.vueVue.config.productionTip false// 1.全局注册指令 Vue.directive(focus, {// inserted在指令所在的元素 被插入到页…

Java个人博客系统--基于Springboot的设计与实现

目录 一、项目概述 应用技术 接口实现&#xff1a; 数据库定义&#xff1a; 数据库建表&#xff1a; 博客表数据库相关操作&#xff1a; 添加项⽬公共模块 加密MD5 页面展示&#xff1a;http://121.41.168.121:8080/blog_login.html 项目源码&#xff1a;https://gitee…

初学 Python 需要安装哪些软件?超级实用,小白必看!

前言 大家早好、午好、晚好吖 ❤ ~欢迎光临本文章 编程这个东西是真的奇妙。 对于懂得的人来说&#xff0c;会觉得这个工具是多么的好用、有趣&#xff0c;而对于小白来说&#xff0c;就如同大山一样。 其实这个都可以理解&#xff0c;大家都是这样过来的。 那么接下来就说…

Spring简述

Sping是什么Spring主要模块IOCDI依赖注入的三种方式 AOP术语 Sping是什么 Spring是一个轻量级的开源框架&#xff0c;主要作用是为了简化开发&#xff0c;它以IOC&#xff08;控制反转&#xff09;和AOP&#xff08;面向切面编程&#xff09;为内核 Spring主要模块 我们一般…