当前位置:首页 > 随笔 > 正文内容

Ubuntu 20.04 环境下 Kubernetes 1.26 集群的部署与配置实践

访客 随笔 2026年10月19日 1

环境准备与核心组件概述

本文旨在记录在 Ubuntu 20.04 操作系统上部署 Kubernetes 1.26.12 集群的完整流程。该版本选择主要考虑到与 Kubeflow Pipelines v2.0.5 的兼容性(最高支持至 v1.26)。

在开始部署前,需要理解以下核心组件的作用:

  • containerd:Kubernetes 默认使用的高性能容器运行时,负责管理容器的生命周期。
  • kubelet:运行在每个节点上的代理,负责维护 Pod 的生命周期并确保容器按照预期规格运行。
  • kubeadm:用于快速引导和初始化 Kubernetes 集群的命令行工具。
  • kubectl:用于与 Kubernetes 集群 API 进行交互的命令行客户端。
  • Pod:Kubernetes 调度的最小计算单元,可包含一个或多个紧密耦合的容器。

容器运行时 (containerd) 安装与配置

Kubernetes 通过 CRI (Container Runtime Interface) 与底层容器运行时进行通信。在所有计划加入集群的节点上,必须预先配置好 containerd 及其相关依赖。

配置内核模块与网络转发

为了确保容器网络能够正常工作,需要加载特定的内核模块并开启 IPv4 转发功能。以下脚本统一处理了这些系统级配置:

#!/bin/bash
# 配置内核模块
MODULES_CONF="/etc/modules-load.d/k8s.conf"
echo -e "overlay\nbr_netfilter" | sudo tee "$MODULES_CONF" > /dev/null
sudo modprobe overlay
sudo modprobe br_netfilter

# 配置 sysctl 网络参数
SYSCTL_CONF="/etc/sysctl.d/99-k8s.conf"
cat << 'SYSCTL_EOF' | sudo tee "$SYSCTL_CONF" > /dev/null
net.bridge.bridge-nf-call-iptables  = 1
net.bridge.bridge-nf-call-ip6tables = 1
net.ipv4.ip_forward                 = 1
SYSCTL_EOF

# 应用配置并验证
sudo sysctl --system > /dev/null
sysctl net.ipv4.ip_forward

安装 containerd、runc 与 CNI 插件

通过定义版本变量,可以更方便地管理和安装容器运行时的各个组件。执行以下脚本完成二进制文件的下载与部署:

#!/bin/bash
# 定义组件版本
CONTAINERD_VERSION="1.6.2"
RUNC_VERSION="1.1.4"
CNI_VERSION="1.1.1"
ARCH="amd64"

# 1. 安装 containerd
wget "https://github.com/containerd/containerd/releases/download/v${CONTAINERD_VERSION}/containerd-${CONTAINERD_VERSION}-linux-${ARCH}.tar.gz"
sudo tar -xzf "containerd-${CONTAINERD_VERSION}-linux-${ARCH}.tar.gz" -C /usr/local

# 2. 安装 runc
wget "https://github.com/opencontainers/runc/releases/download/v${RUNC_VERSION}/runc.${ARCH}"
sudo install -m 755 "runc.${ARCH}" /usr/local/sbin/runc

# 3. 安装 CNI 网络插件
sudo mkdir -p /opt/cni/bin
wget "https://github.com/containernetworking/plugins/releases/download/v${CNI_VERSION}/cni-plugins-linux-${ARCH}-v${CNI_VERSION}.tgz"
sudo tar -xzf "cni-plugins-linux-${ARCH}-v${CNI_VERSION}.tgz" -C /opt/cni/bin

配置 systemd cgroup 驱动与镜像加速

在 Linux 系统中,kubelet 和容器运行时必须使用相同的 cgroup 驱动。当系统使用 systemd 作为 init 系统时,应统一配置为 systemd cgroup 驱动。此外,针对国内网络环境,需要替换默认的 sandbox (pause) 镜像地址。

#!/bin/bash
# 生成默认配置文件
sudo mkdir -p /etc/containerd
containerd config default | sudo tee /etc/containerd/config.toml > /dev/null

# 替换 Sandbox 镜像为阿里云镜像源
sudo sed -i 's|registry.k8s.io/pause:.*|registry.aliyuncs.com/google_containers/pause:3.9"|g' /etc/containerd/config.toml

# 启用 systemd cgroup 驱动
sudo sed -i 's/SystemdCgroup = false/SystemdCgroup = true/g' /etc/containerd/config.toml

# 配置 systemd 服务并启动
sudo wget https://raw.githubusercontent.com/containerd/containerd/main/containerd.service -O /usr/local/lib/systemd/system/containerd.service
sudo systemctl daemon-reload
sudo systemctl enable --now containerd

Kubernetes 核心组件安装

kubeadm、kubelet 和 kubectl 需要安装在集群的所有节点上。我们通过配置 APT 仓库来安装指定版本的组件。

配置 APT 仓库并安装组件

#!/bin/bash
K8S_VERSION="1.26"
KEYRING_PATH="/etc/apt/keyrings/k8s-apt-keyring.gpg"
SOURCES_LIST="/etc/apt/sources.list.d/k8s.list"

# 安装基础依赖
sudo apt-get update
sudo apt-get install -y apt-transport-https ca-certificates curl gpg

# 导入 GPG 密钥
sudo mkdir -p /etc/apt/keyrings
curl -fsSL "https://pkgs.k8s.io/core:/stable:/v${K8S_VERSION}/deb/Release.key" | sudo gpg --dearmor -o "$KEYRING_PATH"

# 添加 Kubernetes APT 源
echo "deb [signed-by=${KEYRING_PATH}] https://pkgs.k8s.io/core:/stable:/v${K8S_VERSION}/deb/ /" | sudo tee "$SOURCES_LIST" > /dev/null

# 安装并锁定版本
sudo apt-get update
sudo apt-get install -y kubelet kubeadm kubectl
sudo apt-mark hold kubelet kubeadm kubectl

配置 kubelet cgroup 驱动

为了确保 kubelet 与 containerd 的 cgroup 驱动保持一致,可以通过配置 drop-in 文件来显式指定参数,而无需修改 kubeadm 的全局配置文件:

#!/bin/bash
# 配置 kubelet 额外参数
cat << 'EOF' | sudo tee /etc/default/kubelet
KUBELET_EXTRA_ARGS="--cgroup-driver=systemd"
EOF

# 重载配置并重启 kubelet
sudo systemctl daemon-reload
sudo systemctl restart kubelet

常见故障排查与解决方案

1. containerd 服务启动失败 (TOML 解析错误)

现象:执行 systemctl start containerd 时,服务进入 failed 状态。查看 /var/log/syslog 发现报错信息为 failed to load TOML... duplicated tables。

原因:在 /etc/containerd/config.toml 文件中存在重复的插件配置块(例如出现了两次 [plugins."io.containerd.grpc.v1.cri".registry])。

解决:检查并清理配置文件中重复的段落,确保每个 plugin key 唯一,然后重启服务。

2. 找不到 containerd.sock 文件

现象:执行 kubectl 或容器命令时报错 dial unix /var/run/containerd/containerd.sock: connect: no such file or directory。

原因:containerd 服务未正常运行或未生成 socket 文件。

解决:检查服务状态并重新启动。

sudo systemctl status containerd
sudo systemctl enable containerd
sudo systemctl restart containerd

3. PV/PVC 资源卡在 Terminating 状态

现象:使用 kubectl delete 删除 PersistentVolume 或 PersistentVolumeClaim 后,资源状态一直停留在 Terminating,无法彻底清除,且无法重新创建同名资源。

原因:Kubernetes 存在数据保护机制,当资源仍被其他组件引用或存在 finalizers 时,会阻止物理删除。

解决:通过 patch 命令强制移除 finalizers,解除保护机制后再执行删除操作。

# 移除 PV 的 finalizers
kubectl patch pv my-data-volume --type merge -p '{"metadata":{"finalizers": null}}'
kubectl delete pv my-data-volume

# 移除 PVC 的 finalizers
kubectl patch pvc my-data-claim --type merge -p '{"metadata":{"finalizers": null}}'
kubectl delete pvc my-data-claim

4. Pod 删除后自动重新创建

现象:手动删除某个 Pod 后,系统立刻又创建了一个相同名称或相似的新 Pod。

原因:该 Pod 是由高级控制器(如 Deployment、StatefulSet)管理的。控制器会持续监控并确保期望的副本数与实际运行的副本数一致。

解决:需要删除管理该 Pod 的上级控制器,而不是直接删除 Pod。可以通过脚本动态获取并删除其 Owner 资源:

#!/bin/bash
POD_NAME="ml-pipeline-visualizationserver-7d8f9b-x2k4l"
NAMESPACE="kubeflow-user-example-com"

# 获取 Pod 的 Owner 名称
OWNER_NAME=$(kubectl get pod "$POD_NAME" -n "$NAMESPACE" -o jsonpath='{.metadata.ownerReferences[0].name}')
OWNER_KIND=$(kubectl get pod "$POD_NAME" -n "$NAMESPACE" -o jsonpath='{.metadata.ownerReferences[0].kind}')

echo "发现上级控制器: $OWNER_KIND/$OWNER_NAME"

# 删除上级控制器
kubectl delete "$OWNER_KIND" "$OWNER_NAME" -n "$NAMESPACE"
标签: Kubernetes

相关文章

可以按小时收费的VPS

很多 VPS 提供商都支持 按小时计费(hourly billing),想短期试用 / 临时搭建节点、测试网络、短期项目等场景非常合适。下面是当前最主流且靠谱的按小时 VPS 选项,分别按不同需求场景整理: 1. Vultr(全球节点,包括日本) 按小时计费 可选机房:东京 / 大阪 / 洛杉矶 / 法兰克福 / 伦敦 … 支持 PayPal(部分情况),但更常用信用卡/PayPal+卡价格参考$...

Node.js 中的异步编程:回调与 Promise

Node.js 是一个基于 JavaScript 构建的单线程、非阻塞运行环境,它通过异步编程机制来高效处理多个操作。在执行如文件读取、API 请求或数据库查询等任务时,Node.js 不会等待这些操作完成,而是使用回调函数和 Promise 来避免阻塞主线程。 回调方式实现异步 那么当异步操作完成后,Node.js 如何知道接下来要做什么呢?这就要用到 回调函数(callback)。 回调本质上...

Selenium自动化测试入门指南

Selenium自动化测试入门指南

什么是自动化测试? 自动化测试是指利用软件工具自动执行测试用例,模拟用户操作,如打开网页、点击链接、输入文本等,并验证结果是否符合预期。 其主要优点包括: 大幅减少人工成本 测试速度快 可以在非工作时间运行 支持持续集成和交付 然而,它也存在一些局限性,例如开发成本较高、不适合快速变化的项目、依赖稳定的UI界面等。 自动化测试的应用条件 适合引入自动化测试的情况包括: 手动测试耗时且需要大量...

MariaDB Galera集群故障快速恢复指南

OpenStack控制节点采用三节点MariaDB Galera集群架构。当数据库集群因故障重启时,有时会出现Galera集群无法正常启动的问题。虽然有多种方法可以恢复数据库服务,但如何实现快速启动同时确保数据完整性呢? 通过分析日志发现,MariaDB Galera集群节点宕机时会在日志中输出以下信息: [Note] WSREP: 新集群视图:全局状态: 874d8e7e-5980-11e8-8...

Android 中 EventBus 的通信机制与实现原理深度解析

EventBus 核心设计思想 EventBus 是一个基于观察者模式的事件总线框架,广泛应用于 Android 平台以实现组件解耦。它通过中心化的消息分发机制,使不同层级、不同线程的对象能够以"发布-订阅"方式通信,避免了传统接口回调或广播带来的强依赖问题。 核心角色说明 事件(Event):任意 Java 对象,作为数据载体,如网络状态变更通知、用户登录信息等。 发布者(Publi...

二叉树基础操作实现(C语言)

二叉树基础操作实现(C语言)

二叉树遍历方法 以下为二叉树结构示例 前序访问实现: void traversePreOrder(TreeNode* node) { if (node == NULL) { printf("N "); return; } printf("%d ", node->value); trave...

发表评论

访客

◎欢迎参与讨论,请在这里发表您的看法和观点。