本文基于 Kubernetes 1.2.9版本
集群类型
K8S 高可用集群拓扑类型分为两种:堆叠拓扑、集群拓扑。
- 这两种拓扑结构有各自的优缺点,综合成本和实际业务量来选型(均可应用与生产环境)。
- 开发测试环境部署这两种集群拓扑的单控制面板节点(有单点故障风险,勿在生产环境中使用)即可。
堆叠拓扑
堆叠拓扑的 K8S 高可用集群如下图所示, 其中etcd分布式数据存储集群堆叠在kubeadm管理的控制面板节点上,作为控制面板节点的一个组件运行。
- 每个控制面板节点运行
apiserver、scheduler和controller-manager实例;apiserver使用load balancer暴露给工作节点。 - 每个控制平面节点创建一个本地
etcd成员,该etcd成员只与该节点的apiserver通信;这同样适用于本地controller-manager和scheduler实例。 - 这种拓扑将控制面板和
etcd成员耦合在同一节点上;相对使用外部拓扑的etcd集群,设置起来更简单,而且更易于副本管理。 - 堆叠集群存在耦合失败的风险;如果一个节点发生故障,则
etcd成员和控制面板实例都将丢失,并且冗余会受到影响;可以通过添加更多控制平面节点来降低此风险(若采用这种 HA 方式搭建 K8S 集群,官方推荐运行至少三个堆叠的控制面板节点)。
该集群拓扑结构是
kubeadm安装 K8S 集群默认采用的集群拓扑,当使用kubeadm init和kubeadm join --control-plane时, 在控制面板节点上会自动创建本地etcd成员。
外部拓扑
外部拓扑的 K8S 高可用集群etcd的 HA 集群如下图所示,其中etcd分布式数据存储集群在独立于控制面板节点的其他节点上运行。
- 与堆叠拓扑一样,外部拓扑中的每个控制面板节点都会运行
apiserver、scheduler和controller-manager实例; 同样,apiserver使用load balancer暴露给工作节点;但是etcd成员在不同的主机上运行,每个etcd主机与每个控制面板节点的apiserver通信。 - 该拓扑结构解耦了控制面板和
etcd成员;因此它提供了一种高可用设置,其中失去控制面板实例或者etcd成员的影响较小,并且不会像堆叠拓扑那样影响集群冗余。 - 但此拓扑需要两倍于堆叠拓扑的主机数量。具有此拓扑的高可用集群至少需要三个用于控制平面节点的主机和三个用于
etcd节点的主机。
部署工具
K8S 有多种部署方式:
- kind:是一个使用 Docker 容器节点运行本地 K8S 集群的工具;主要用于测试 K8S 本身,但也可用于本地开发或 CI。
minikube:可快速搭建的单节点本地版 K8S,主要用于本地开发和学习 K8S。kubeadm:创建和管理 K8S 集群,可应用于生产环境。
此外,无论哪种安装部署方式都会使用到kubectl命令行工具,该工具可以对 K8S 集群运行命令;使用它可以在 K8S 中部署应用、监测和管理集群资源以及查看日志。
主机配置
本文采用 K8S 单控制面板节点的外部拓扑集群架构来部署 K8S;所需主机配置如下
| 职责角色 | IP地址 | 操作系统 | 配置规格 | 主机名称 |
|---|---|---|---|---|
| 控制面板(control plane node) | 10.0.0.110 |
AlmaLinux OS 9.3 | 4 vCPU 4GiB | kube-alma-m-01 |
| 工作节点(worker node) | 10.0.0.120 |
AlmaLinux OS 9.3 | 4 vCPU 4GiB | kube-alma-n-01 |
| 工作节点(worker node) | 10.0.0.121 |
AlmaLinux OS 9.3 | 4 vCPU 4GiB | kube-alma-n-02 |
上述主机配置遵循官方文档中要求的最低配置,此外还需满足以下条件:
使用兼容 K8S 的 Linux 操作系统(K8S 项目为基于 Debian 和 Red Hat 的 Linux 发行版以及一些不提供包管理器的发行版提供通用的指令)。
每台机器至少
2GiB RAM,2vCPU。集群中的所有机器的网络彼此均能相互连接。
每台机器的主机名、MAC、product_uuid 必须唯一。
开启 K8S 运行必须的端口(关闭防火墙即可,目前各大云平台的云主机默认也未开启防火墙,都是通过安全组来控制端口);需要放行的端口如下:
- 控制面板:
协议 方向 端口范围 目的 使用者 TCP 入站 6443 Kubernetes API server 所有 TCP 入站 2379-2380 etcd server client API kube-apiserver, etcd TCP 入站 10250 Kubelet API 自身, 控制面 TCP 入站 10259 kube-scheduler 自身 TCP 入站 10257 kube-controller-manager 自身 - 工作节点:
协议 方向 端口范围 目的 使用者 TCP 入站 10250 Kubelet API 自身, 控制面 TCP 入站 30000-32767 NodePort Services† 所有
- 控制面板:
配置交换区:建议关闭交换区,避免不必要的折腾。
kubelet的默认行为是在节点上检测到交换内存时无法启动。kubelet自v1.22起已开始支持交换分区,自v1.28起,仅针对cgroup v2支持交换分区。kubelet的 NodeSwap 特性门控处于 Beta 阶段,但默认被禁用。kubelet若未被正确配置使用交换分区,则你必须禁用交换分区。- 临时禁用交换区:
sudo swapoff -a - 永久禁用交换区:可能需要在如
/etc/fstab、systemd.swap等配置文件中禁用交换分区,具体的配置因操作系统的发行版本不同而有差异。
- 临时禁用交换区:
sudo dnf config-manager –add-repo https://download.docker.com/linux/centos/docker-ce.repo
sudo dnf -y install containerd.io
sudo systemctl enable containerd.service
systemctl start containerd
systemctl status containerd
cat <<EOF | sudo tee /etc/modules-load.d/k8s.conf
overlay
br_netfilter
EOF
sudo modprobe overlay
sudo modprobe br_netfilter
1 | cat <<EOF | sudo tee /etc/modules-load.d/k8s.conf |
通过运行以下指令确认 br_netfilter 和 overlay 模块被加载:
1 | lsmod | grep br_netfilter |
通过运行以下指令确认 net.bridge.bridge-nf-call-iptables、net.bridge.bridge-nf-call-ip6tables 和 net.ipv4.ip_forward 系统变量在你的 sysctl 配置中被设置为 1:
1 | sysctl net.bridge.bridge-nf-call-iptables net.bridge.bridge-nf-call-ip6tables net.ipv4.ip_forward |
1 | cat <<EOF | sudo tee -a /etc/containerd/config.toml |
你需要启用 CRI 支持才能在 Kubernetes 集群中使用 containerd。 要确保 cri 没有出现在 /etc/containerd/config.toml 文件中 disabled_plugins 列表内。如果你更改了这个文件,也请记得要重启 containerd
需要重启。
1 |
|
Add the Kubernetes repo
exclude 参数确保了与 Kubernetes 相关的软件包在运行 yum update 时不会升级,因为升级 Kubernetes 需要遵循特定的过程。
1 | cat <<EOF | tee /etc/yum.repos.d/kubernetes.repo |
Add the CRI-O repo
1 | cat <<EOF | tee /etc/yum.repos.d/cri-o.repo |
Install official package dependencies
1 | sudo dnf install -y \ |
Install the packages from the added repos
1 | sudo dnf install -y --repo cri-o --repo kubernetes \ |
设置 kubelet 为开机自启动即可,由于没有生成配置文件,集群初始化后自动启动:
1 | systemctl enable --now kubelet |
设置 cri-o 开机自启动:
1 | sudo systemctl daemon-reload && sudo systemctl enable crio && sudo systemctl start crio |
确认 cri-o 服务是否在运行中:
1 | sudo crictl --runtime-endpoint unix:///var/run/crio/crio.sock version |
输出如下:
1 | Version: 0.1.0 |
前置准备
设置主机名:
1 | sudo hostnamectl set-hostname kube-alma-m-01 |
1 | sudo hostnamectl set-hostname kube-alma-n-01 |
1 | sudo hostnamectl set-hostname kube-alma-n-02 |
配置内网DNS:这里使用ikuai网关实现,配置如下图
关闭防火墙:学习阶段可以关闭防火墙,并且公有云上也没有防火墙,只有安全组。
1 | sudo systemctl stop firewalld && sudo systemctl disable firewalld && sudo reboot |
时间同步(公有云跳过):Kubernetes 要求集群中的节点时间必须精确一致,所以在每个节点上添加时间同步:
1 | sudo dnf -y install chrony && systemctl enable chronyd --now |
查看同步状态
1 | chronyc sources |
关闭 SELinux:
1 | sudo sed -i 's/enforcing/disabled/' /etc/selinux/config && sudo reboot |
关闭 swap 分区:容器虚拟化需要关闭 swap 分区
1 | sudo sed -ri 's/.*swap.*/#&/' /etc/fstab && sudo reboot |
下载 Kubernetes 安装所需镜像
1 | sudo kubeadm config images pull --image-repository registry.aliyuncs.com/google_containers |
输出如下:
1 | [config/images] Pulled registry.aliyuncs.com/google_containers/kube-apiserver:v1.29.3 |
查看下载的镜像:
1 | crictl images |
输出如下:
1 | IMAGE TAG IMAGE ID SIZE |
注意:
- containerd 的客户端工具有 ctr、crictl 和 nerdctl。
- ctr 是由 containerd 提供的一个客户端工具。
- crictl 是 CRI 兼容的容器运行时命令行接口,和 containerd 无关,由 Kubernetes 提供,可以使用它来检查和调试 Kubernetes 节点上的容器运行时和应用程序。
- nerdctl 是和 Docker 兼容的 CLI 客户端,支持 Compose,默认没有安装,需要手动安装。