Kubernetes

2025/10/03 k8s 共 4627 字,约 14 分钟

Kubernetes 集群搭建笔记(Ubuntu 24.04 + kubeadm + Docker + cri-dockerd + Flannel)

本文记录了在 windows 虚拟机VMware中安装 Ubuntu 24.04 ,从零开始搭建一个 Kubernetes 集群的过程,版本为 v1.28.15,使用 Docker 作为容器运行时,通过 cri-dockerd 适配,网络插件选用 Flannel


1. 主机规划

  • kubernetes-master:控制平面节点(master)
  • kubernetes-node1kubernetes-node2:工作节点(node)
  • kubernetes-registry:私有镜像仓库

2. 安装 Docker

使用阿里云源安装 Docker CE:
阿里云 Docker 安装文档

验证安装:

docker version
systemctl enable docker --now

3. 安装 cri-dockerd

Kubernetes 从 1.24 起不再直接支持 Docker,需要 cri-dockerd 作为适配层。

参考文档:cri-dockerd 安装

安装完成后,确认 socket 文件路径:

  • Docker:/var/run/cri-dockerd.sock
  • containerd:/var/run/containerd/containerd.sock

4. 安装 Kubernetes 组件

需要安装以下三个组件:

  • kubelet:节点代理,负责启动和管理 Pod
  • kubeadm:集群初始化工具
  • kubectl:命令行客户端

参考阿里云镜像源: 阿里云 Kubernetes 镜像


5. 初始化前环境清理脚本

文件:prepare_env.sh

#!/bin/bash
set -e

echo "[1/5] 停止 kubelet..."
sudo systemctl stop kubelet

# 检测 CRI
if [ -S /var/run/cri-dockerd.sock ]; then
    CRI_SOCKET="unix:///var/run/cri-dockerd.sock"
    echo "[+] Docker CRI detected, using $CRI_SOCKET"
elif [ -S /var/run/containerd/containerd.sock ]; then
    CRI_SOCKET="unix:///var/run/containerd/containerd.sock"
    echo "[+] containerd detected, using $CRI_SOCKET"
else
    echo "[-] No CRI detected! Exiting."
    exit 1
fi

echo "[2/5] 重置 kubeadm..."
sudo kubeadm reset -f --cri-socket=$CRI_SOCKET --ignore-preflight-errors=Swap

echo "[3/5] 清理旧证书和配置..."
sudo rm -rf /etc/kubernetes/pki
sudo rm -rf /etc/kubernetes/*.conf
sudo rm -rf ~/.kube

echo "[4/5] 删除旧的 etcd 数据和 kubelet 状态..."
sudo rm -rf /var/lib/etcd
sudo rm -rf /var/lib/kubelet/*

echo "[5/5] 检查端口 6443 占用..."
if lsof -i :6443 >/dev/null; then
    echo "[-] Port 6443 is still in use! Please kill the process occupying it before proceeding."
    lsof -i :6443
    exit 1
fi

echo "环境清理完成,CRI socket: $CRI_SOCKET"

执行脚本:

bash prepare_env.sh

6. 初始化 Master 节点

为避免镜像拉取是出现问题,使用kubeadm初始化之前先要准备好docker镜像,本次记录中通过

kubeadm config images list

获取镜像列表,然后从阿里云获取镜像存入本地harbor的方法,见如下的命令

#!/bin/bash
#
# 同步 Kubernetes 核心镜像到私有 Harbor 仓库
# 版本:1.28.15
# 说明:
#   1. 从阿里云 registry 拉取镜像(解决国外 registry 拉取慢的问题)
#   2. 重新打 tag 到内部 Harbor
#   3. 推送到内网 Harbor
#   4. 删除中转镜像,避免混乱
#

#-----------------------------
# 基本变量配置
#-----------------------------
K8S_VERSION="1.28.15"                                     # 指定 Kubernetes 版本
SRC_REGISTRY="registry.aliyuncs.com/google_containers"    # 源镜像仓库(阿里云镜像)
DST_REGISTRY="kubernetes-registry.moon.com/google_containers"  # 目标私有仓库(Harbor)

#-----------------------------
# Step 1: 获取该版本所需镜像列表
#-----------------------------
# kubeadm 会列出部署该版本 Kubernetes 所需的所有镜像
# 例如:registry.k8s.io/kube-apiserver:v1.28.15
# awk 提取最后一段,只保留 "kube-apiserver:v1.28.15"
#-----------------------------
echo "[INFO] 获取 Kubernetes $K8S_VERSION 镜像列表..."
images=$(kubeadm config images list --kubernetes-version="${K8S_VERSION}" | awk -F'/' '{print $NF}')

#-----------------------------
# Step 2: 循环同步每个镜像
#-----------------------------
for image in ${images}; do
    echo
    echo "==============================="
    echo "[INFO] 正在处理镜像: ${image}"
    echo "==============================="

    # 拉取镜像(从阿里云源)
    echo "[STEP] 拉取 ${SRC_REGISTRY}/${image}"
    docker pull ${SRC_REGISTRY}/${image}

    # 打上私有仓库标签
    echo "[STEP] 重新打标签为 ${DST_REGISTRY}/${image}"
    docker tag ${SRC_REGISTRY}/${image} ${DST_REGISTRY}/${image}

    # 推送到私有 Harbor 仓库
    echo "[STEP] 推送到 Harbor:${DST_REGISTRY}/${image}"
    docker push ${DST_REGISTRY}/${image}

    # 删除中转镜像,只保留目标镜像
    echo "[STEP] 删除本地中转镜像 ${SRC_REGISTRY}/${image}"
    docker rmi ${SRC_REGISTRY}/${image}

    echo "[DONE] 镜像 ${image} 已同步至 Harbor。"
done

#-----------------------------
# Step 3: 完成提示
#-----------------------------
echo
echo "=========================================="
echo "[SUCCESS] 所有 Kubernetes ${K8S_VERSION} 镜像已同步完成。"
echo "可在 Harbor 上查看:${DST_REGISTRY}"
echo "=========================================="

之后就可以初始化了,见如下bash文件

文件:init_k8s.sh

#!/bin/bash
set -e

# 请根据 prepare_env.sh 输出填入 CRI socket
CRI_SOCKET="unix:///var/run/cri-dockerd.sock"

echo "[1/1] 初始化 Kubernetes master..."
sudo kubeadm init \
  --kubernetes-version=1.28.15 \
  --apiserver-advertise-address=10.0.0.5 \
  --image-repository=kubernetes-registry.moon.com/google_containers \
  --pod-network-cidr="10.244.0.0/16" \
  --service-cidr="10.96.0.0/12" \
  --ignore-preflight-errors=Swap \
  --cri-socket=$CRI_SOCKET

echo "------------------------------------------------"
echo "初始化完成!"

执行初始化脚本:

bash init_k8s.sh

初始化成功后,根据 kubeadm init 的输出,复制 kubeadm join 命令到各个 node 节点运行。


7. 配置 kubectl

在 master 节点执行:

mkdir -p $HOME/.kube
sudo cp -i /etc/kubernetes/admin.conf $HOME/.kube/config
sudo chown $(id -u):$(id -g) $HOME/.kube/config

验证:

kubectl get nodes

8. 安装网络插件 Flannel

安装 Flannel 网络插件,保证 Pod 之间可以互通:

kubectl apply -f https://raw.githubusercontent.com/flannel-io/flannel/master/Documentation/kube-flannel.yml

9. 验证集群状态

kubectl get nodes

示例输出:

NAME                STATUS   ROLES           AGE   VERSION
kubernetes-master   Ready    control-plane   47h   v1.28.15
kubernetes-node1    Ready    <none>          26h   v1.28.15
kubernetes-node2    Ready    <none>          26h   v1.28.15

至此,Kubernetes 集群安装完成 🎉


10. 常见问题排查

  1. swap 未关闭

    • Kubernetes 要求禁用 swap:

      sudo swapoff -a
      sed -i '/ swap / s/^/#/' /etc/fstab
      
  2. 镜像拉取失败

    • 配置国内镜像仓库(如阿里云、七牛、腾讯云),或使用自建 kubernetes-registry
  3. 6443 端口被占用

    • 检查并释放端口:

      lsof -i :6443
      kill -9 <PID>
      
  4. flannel 网络不通

    • 确认 --pod-network-cidr 与 flannel 配置一致(默认 10.244.0.0/16)。
    • 检查 CNI 插件目录 /etc/cni/net.d/ 是否存在配置文件。

文档信息

Search

    Table of Contents