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-node1、kubernetes-node2:工作节点(node)kubernetes-registry:私有镜像仓库
各主机命名设置可以参考:hostname命令 或者 linux常用命令
2. 安装 Docker
使用阿里云源安装 Docker CE:
阿里云 Docker 安装文档
验证安装:
docker version
systemctl enable docker --now
为了方便普通用户使用,可以将当前用户加入docker组中
sudo usermod -aG docker $USER
newgrp docker
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:节点代理,负责启动和管理 Podkubeadm:集群初始化工具kubectl:命令行客户端
使用命令如下:
curl -fsSL https://mirrors.aliyun.com/kubernetes-new/core/stable/v1.28/deb/Release.key |sudo gpg --dearmor -o /etc/apt/keyrings/kubernetes-apt-keyring.gpg
echo "deb [signed-by=/etc/apt/keyrings/kubernetes-apt-keyring.gpg] https://mirrors.aliyun.com/kubernetes-new/core/stable/v1.28/deb/ /" | sudo tee /etc/apt/sources.list.d/kubernetes.list
sudo apt-get update
sudo apt-get install -y kubelet kubeadm kubectl
其中的版本号“v1.28”, 可以根据阿里云镜像进行更改。
参考阿里云镜像源: 阿里云 Kubernetes 镜像
如果需要重装或更换不同版本,可以使用以下脚本卸载
#!/bin/bash
set -e
echo "===> [1/7] 停止 kubelet(如果存在)"
systemctl stop kubelet 2>/dev/null || true
echo "===> [2/7] 卸载 Kubernetes 组件(kubeadm / kubelet / kubectl)"
apt-get purge -y kubeadm kubelet kubectl || true
echo "===> [3/7] 清理 Kubernetes 核心目录"
rm -rf /etc/kubernetes
rm -rf /var/lib/kubelet
rm -rf /var/lib/etcd
echo "===> [4/7] 清理 CNI 网络残留(如果装过网络插件)"
rm -rf /etc/cni
rm -rf /opt/cni
rm -rf /var/lib/cni
echo "===> [5/7] 清理 kubeconfig(避免 kubectl 幻觉)"
rm -rf ~/.kube
echo "===> [6/7] 移除 Kubernetes apt 源(如果存在)"
rm -f /etc/apt/sources.list.d/kubernetes.list
echo "===> [7/7] 刷新 apt 状态"
apt-get update
echo
echo "✅ Kubernetes 已彻底卸载完成"
echo "👉 这台机器现在不再是 Kubernetes 节点"
echo "👉 可以放心重新安装任意版本"
5. 初始化 Master 节点
为避免镜像拉取是出现问题,使用kubeadm初始化之前先要准备好docker镜像,本次记录中通过
kubeadm config images list
获取镜像列表,然后从阿里云获取镜像存入本地harbor的方法,见如下的命令
#!/bin/bash
#
# 同步 Kubernetes 核心镜像到私有镜像仓库
# 说明:
# 1. 从阿里云 registry 拉取镜像(解决国外 registry 拉取慢的问题)
# 2. 重新打 tag 到私有镜像仓库 (比如阿里云镜像)
#-----------------------------
# 基本变量配置
#-----------------------------
K8S_VERSION="1.35.0" # 指定 Kubernetes 版本
SRC_REGISTRY="registry.aliyuncs.com/google_containers" # 源镜像仓库(阿里云公共镜像)
DST_REGISTRY="crpi-ckw9ia686aku4y4w.cn-shanghai.personal.cr.aliyuncs.com/tgtech" #目标私有仓库(阿里云私有镜像)
#-----------------------------
# Step 1: 获取该版本所需镜像列表
#-----------------------------
# kubeadm config images list会列出部署该版本 Kubernetes 所需的所有镜像,并提取最后一个字段
#-----------------------------
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} 已同步至私有镜像仓库。"
done
#-----------------------------
# Step 3: 完成提示
#-----------------------------
echo
echo "=========================================="
echo "[SUCCESS] 所有 Kubernetes ${K8S_VERSION} 核心镜像已同步完成。"
echo "可在 私有镜像仓库 上查看:${DST_REGISTRY}"
echo "=========================================="
上述镜像仓库在同步完成之后,就可以直接使用了,使用之前,要先进行登录,具体方法要参考:阿里云容器镜像服务
初始化之前的检查
可以使用如下脚本init_k8s_preflight.sh进行检查
#!/bin/bash
set -o pipefail
RED='\033[0;31m'
GREEN='\033[0;32m'
YELLOW='\033[1;33m'
NC='\033[0m'
fail_count=0
ok() { echo -e "${GREEN}[ OK ]${NC} $1"; }
warn() { echo -e "${YELLOW}[WARN]${NC} $1"; }
fail() { echo -e "${RED}[FAIL]${NC} $1"; fail_count=$((fail_count+1)); }
echo "===== Kubernetes init 前环境检查(Docker + cri-dockerd)====="
# --------------------------------------------------
# 1. 操作系统
# --------------------------------------------------
if [[ -f /etc/os-release ]]; then
source /etc/os-release
ok "操作系统: $PRETTY_NAME"
else
fail "无法识别操作系统"
fi
# --------------------------------------------------
# 2. 内核版本
# --------------------------------------------------
ok "内核版本: $(uname -r)"
# --------------------------------------------------
# 3. Swap
# --------------------------------------------------
if swapon --summary | grep -q .; then
warn "Swap 已开启(kubeadm 默认不推荐,需 --ignore-preflight-errors=Swap)"
else
ok "Swap 已关闭"
fi
# --------------------------------------------------
# 4. br_netfilter
# --------------------------------------------------
if [[ -e /sys/module/br_netfilter ]]; then
ok "br_netfilter 模块已加载"
else
fail "br_netfilter 模块未加载"
fi
# --------------------------------------------------
# 5. sysctl 参数
# --------------------------------------------------
check_sysctl() {
local key=$1
local expect=$2
local value
value=$(sysctl -n "$key" 2>/dev/null)
if [[ "$value" == "$expect" ]]; then
ok "$key = $value"
else
fail "$key = $value(期望 $expect)"
fi
}
check_sysctl net.bridge.bridge-nf-call-iptables 1
check_sysctl net.ipv4.ip_forward 1
# --------------------------------------------------
# 6. Docker
# --------------------------------------------------
if systemctl is-active --quiet docker; then
ok "Docker 正在运行"
else
fail "Docker 未运行"
fi
# --------------------------------------------------
# 7. CRI(强制 cri-dockerd)
# --------------------------------------------------
CRI_SOCKET="/var/run/cri-dockerd.sock"
if ! systemctl is-active --quiet cri-docker; then
fail "cri-dockerd 未运行"
elif ! command -v crictl &>/dev/null; then
fail "crictl 未安装,无法验证 CRI"
elif ! crictl --runtime-endpoint "unix://$CRI_SOCKET" info >/dev/null 2>&1; then
fail "cri-dockerd CRI API 不可用"
else
ok "CRI 可用:cri-dockerd"
fi
if [[ -S "$CRI_SOCKET" ]]; then
ok "CRI socket 存在: $CRI_SOCKET"
else
fail "CRI socket 不存在: $CRI_SOCKET"
fi
# --------------------------------------------------
# 8. Kubernetes 组件
# --------------------------------------------------
for bin in kubeadm kubelet kubectl; do
if command -v $bin &>/dev/null; then
ok "$bin 已安装"
else
fail "$bin 未安装"
fi
done
# --------------------------------------------------
# 9. 关键端口
# --------------------------------------------------
check_port() {
local port=$1
if ss -lnt | awk '{print $4}' | grep -q ":$port$"; then
fail "端口 $port 已被占用"
else
ok "端口 $port 可用"
fi
}
check_port 6443
check_port 10250
# --------------------------------------------------
# 10. Kubernetes 镜像拉取验证(致命)
# --------------------------------------------------
IMAGE_REPO="crpi-ckw9ia686aku4y4w.cn-shanghai.personal.cr.aliyuncs.com/tgtech"
K8S_VERSION="v1.35.0"
TEST_IMAGE="$IMAGE_REPO/kube-apiserver:$K8S_VERSION"
echo "[INFO] 测试 Docker 镜像拉取:$TEST_IMAGE"
if docker pull "$TEST_IMAGE" >/dev/null 2>&1; then
ok "Kubernetes 镜像可正常拉取"
else
fail "Docker 无法拉取 Kubernetes 镜像"
warn "请确认:"
warn "1) docker login 私有仓库已完成"
warn "2) 镜像 tag 与 Kubernetes 版本一致"
warn "3) 网络 / DNS / 防火墙"
fi
# --------------------------------------------------
# 11. pause 镜像版本检查(Docker + cri-dockerd)
# --------------------------------------------------
echo "[INFO]===== 检查 CRI pause 镜像版本 ====="
EXPECTED_PAUSE_IMAGE="crpi-ckw9ia686aku4y4w.cn-shanghai.personal.cr.aliyuncs.com/tgtech/pause:3.10.1"
CRI_SOCKET="/var/run/cri-dockerd.sock"
if ! command -v crictl &>/dev/null; then
fail "crictl 未安装,无法检查 pause 镜像"
else
ACTUAL_PAUSE_IMAGE=$(crictl --runtime-endpoint "unix://${CRI_SOCKET}" info 2>/dev/null \
| awk -F'"' '/sandboxImage/ {print $4}')
if [[ -z "$ACTUAL_PAUSE_IMAGE" ]]; then
fail "无法获取当前 pause 镜像"
elif [[ "$ACTUAL_PAUSE_IMAGE" == "$EXPECTED_PAUSE_IMAGE" ]]; then
ok "pause 镜像正确:$ACTUAL_PAUSE_IMAGE"
else
fail "pause 镜像不匹配"
warn "当前: $ACTUAL_PAUSE_IMAGE"
warn "期望: $EXPECTED_PAUSE_IMAGE"
warn "请先执行 sudo ./fix_cri_pause_version.sh"
fi
fi
# --------------------------------------------------
# 总结
# --------------------------------------------------
echo "-----------------------------------"
if [[ $fail_count -eq 0 ]]; then
echo -e "${GREEN}环境检查通过:可以执行 kubeadm init${NC}"
echo -e "${GREEN}CRI socket: unix://$CRI_SOCKET${NC}"
else
echo -e "${RED}环境检查失败:$fail_count 项未通过,请修复后再初始化${NC}"
fi
常见问题解决
下面容易检测不通过
[ OK ] Swap 已关闭
[ OK ] br_netfilter 模块已加载
[ OK ] net.bridge.bridge-nf-call-iptables = 1
[ OK ] net.ipv4.ip_forward = 1
主要是swap和网路模块问题,可以使用如下脚本进行修改:
- 关闭swap, fix_swap.sh
#!/bin/bash
set -e
echo "===== 关闭 Swap(Kubernetes 要求) ====="
#1. 关闭当前 swap
if swapon --summary | grep -q .; then
echo "[INFO] 检测到 Swap 已开启,正在关闭..."
sudo swapoff -a
else
echo "[OK] Swap 当前已关闭"
fi
#2. 注释 /etc/fstab 中的 swap
if grep -E '^\s*[^#].*\s+swap\s' /etc/fstab >/dev/null; then
echo "[INFO] 正在禁用 /etc/fstab 中的 Swap 配置..."
sudo sed -i.bak '/\sswap\s/s/^/#/' /etc/fstab
echo "[OK] Swap 已从 /etc/fstab 中禁用(已备份为 /etc/fstab.bak)"
else
echo "[OK] /etc/fstab 中未发现启用的 Swap"
fi
#3. 验证
if swapon --summary | grep -q .; then
echo "[FAIL] Swap 仍然开启"
exit 1
else
echo "[SUCCESS] Swap 已完全关闭"
fi
- 修改网络模块配置, fix_k8s_net.sh
#!/bin/bash
set -e
echo "===== 修复 Kubernetes 网络内核条件 ====="
# 1. 加载 br_netfilter 模块(立即生效)
if lsmod | grep -q br_netfilter; then
echo "[OK] br_netfilter 模块已加载"
else
echo "[INFO] 加载 br_netfilter 模块..."
sudo modprobe br_netfilter
echo "[OK] br_netfilter 模块已加载"
fi
# 2. 设置 sysctl 参数(立即生效)
echo "[INFO] 设置 sysctl 参数..."
sudo sysctl -w net.bridge.bridge-nf-call-iptables=1
sudo sysctl -w net.ipv4.ip_forward=1
# 3. 写入永久配置(开机自动生效)
echo "[INFO] 写入永久配置..."
sudo tee /etc/modules-load.d/k8s.conf >/dev/null <<EOF
br_netfilter
EOF
sudo tee /etc/sysctl.d/k8s.conf >/dev/null <<EOF
net.bridge.bridge-nf-call-iptables = 1
net.ipv4.ip_forward = 1
EOF
# 4. 重新加载 sysctl
sudo sysctl --system >/dev/null
# 5. 验证
echo "----- 验证结果 -----"
lsmod | grep br_netfilter
sysctl net.bridge.bridge-nf-call-iptables
sysctl net.ipv4.ip_forward
echo "[SUCCESS] Kubernetes 网络内核条件已修复"
- 修改pause镜像, fix_cri_pause_version.sh
#!/bin/bash
set -euo pipefail
echo "===== Fix cri-dockerd pause image ====="
#------------------------------
#可配置参数
#------------------------------
PAUSE_IMAGE="crpi-ckw9ia686aku4y4w.cn-shanghai.personal.cr.aliyuncs.com/tgtech/pause:3.10.1"
SERVICE_NAME="cri-docker.service"
DROPIN_DIR="/etc/systemd/system/${SERVICE_NAME}.d"
CONF_FILE="${DROPIN_DIR}/10-pause.conf"
#------------------------------
#检测 cri-dockerd binary
#------------------------------
CRI_BIN="$(command -v cri-dockerd || true)"
if [[ -z "$CRI_BIN" ]]; then
echo "[FAIL] 未找到 cri-dockerd 可执行文件"
exit 1
fi
echo "[INFO] cri-dockerd binary: $CRI_BIN"
#------------------------------
#检测 systemd service(正确方式)
#------------------------------
if ! systemctl cat "$SERVICE_NAME" >/dev/null 2>&1; then
echo "[FAIL] systemd 未识别 ${SERVICE_NAME}"
exit 1
fi
#------------------------------
#期望的 drop-in 内容(唯一真值)
#------------------------------
EXPECTED_CONF=$(cat <<EOF
[Service]
ExecStart=
ExecStart=$CRI_BIN \\
--container-runtime-endpoint fd:// \\
--pod-infra-container-image=${PAUSE_IMAGE}
EOF
)
#------------------------------
#幂等判断
#------------------------------
if [[ -f "$CONF_FILE" ]]; then
if diff -u <(sed '/^[[:space:]]*$/d' "$CONF_FILE") \
<(sed '/^[[:space:]]*$/d' <<<"$EXPECTED_CONF") \
>/dev/null; then
echo "[OK] pause image 已正确配置,无需修改"
exit 0
else
echo "[INFO] 发现旧配置,将更新 pause image"
fi
else
echo "[INFO] 未发现 pause 配置,将创建"
fi
#------------------------------
#写入 drop-in
#------------------------------
mkdir -p "$DROPIN_DIR"
cat > "$CONF_FILE" <<EOF
$EXPECTED_CONF
EOF
echo "[INFO] 写入 $CONF_FILE"
#------------------------------
#重载并重启
#------------------------------
systemctl daemon-reload
systemctl restart "$SERVICE_NAME"
echo "[OK] cri-dockerd pause image 修复完成"
初始化脚本
之后就可以初始化了,见如下脚本
- 命令式的方法 文件:
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 "初始化完成!"
注意要将其中的版本(上例子中的1.28.15)进行替换,执行初始化脚本:
bash init_k8s.sh
- 声明式方法
准备yaml文件kubeadm-init.yml,
apiVersion: kubeadm.k8s.io/v1beta4
kind: InitConfiguration
localAPIEndpoint:
advertiseAddress: 192.168.1.20
bindPort: 6443
nodeRegistration:
criSocket: unix:///var/run/cri-dockerd.sock
name: co50-ubuntu
---
apiVersion: kubeadm.k8s.io/v1beta4
kind: ClusterConfiguration
kubernetesVersion: v1.35.0
imageRepository: crpi-ckw9ia686aku4y4w.cn-shanghai.personal.cr.aliyuncs.com/tgtech
networking:
podSubnet: 10.244.0.0/16
serviceSubnet: 10.96.0.0/12
然后执行命令:
sudo kubeadm init --config kubeadm-init.yml
初始化成功后,根据 kubeadm init 的输出,复制 kubeadm join 命令到各个 node 节点运行。
6. 如果初始化失败,环境清理及检测,并重新初始化
说明(不要轻易执行此步骤):
初次安装是不需要进行环境清理的,因为本来就很干净,当安装过程出错,或者希望重新安装,才需要在初始化前进行环境清理,目的就是清理掉以往安装的文件残留, 这是在ubuntu24.04版本实验的结果,其他系统或版本未必可行。
而且,这是翻车后重建的步骤,不要轻易执行,除非初始化报错。
文件: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
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
初始化完成后,会有如下提示:
You should now deploy a pod network to the cluster.
Run "kubectl apply -f [podnetwork].yaml" with one of the options listed at:
https://kubernetes.io/docs/concepts/cluster-administration/addons/
以其中的flannel为例, 参考flannel github中的安装命令:
kubectl apply -f https://raw.githubusercontent.com/flannel-io/flannel/master/Documentation/kube-flannel.yml
但是,安装时使用的镜像不好下载,可以先下载后传到私有仓库并将yaml文件中对应的image进行修改,然后启动,命令依次为:
#download the yaml file
wget https://raw.githubusercontent.com/flannel-io/flannel/master/Documentation/kube-flannel.yml
#find the image
grep image: kube-flannel.yml
#download the image, and upload to private registry
docker pull xxxxx
docker tag xxxxx your.private.registry/namespae/xxxx:version
docker push your.private.registry/namespae/xxxx:version
#modify the image of kube-flannel.yml
vim kube-flannel.yml
#start the flannel
kubectl apply -f kube-flannel.yml
安装完成后查看node状态,应该为ready状态,如果不是,可以查看cni是否安装
#observe the node status, current-node-name
#show like network plugin is not ready: cni config uninitialized
#means that the cni is not installed
kubectl describe node co50-ubuntu
#observe the cni bin
#if only flannel, means that the cni is not installed
ls /opt/cni/bin
#install cni, and then it will show as below:
#ls /opt/cni/bin
#bandwidth dhcp firewall host-device ipvlan loopback portmap README.md static tuning vrf
#bridge dummy flannel host-local LICENSE macvlan ptp sbr tap vlan
sudo apt install -y kubernetes-cni
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. k8s命令补全
k8s本身自带这些功能,但需要开启 可以使用
kubectl completion -h
进行查看,将其命令写入.bashrc长期使用
echo 'source <(kubectl completion bash)' >> ~/.bashrc
echo 'source <(kubeadm completion bash)' >> ~/.bashrc
source ~/.bashrc
11. 常见问题排查
swap 未关闭
Kubernetes 要求禁用 swap:
sudo swapoff -a sed -i '/ swap / s/^/#/' /etc/fstab
镜像拉取失败
- 配置国内镜像仓库(如阿里云、七牛、腾讯云),或使用自建
kubernetes-registry。
- 配置国内镜像仓库(如阿里云、七牛、腾讯云),或使用自建
6443 端口被占用
检查并释放端口:
lsof -i :6443 kill -9 <PID>
flannel 网络不通
- 确认
--pod-network-cidr与 flannel 配置一致(默认10.244.0.0/16)。 - 检查 CNI 插件目录
/etc/cni/net.d/是否存在配置文件。
- 确认
12. 补充一些镜像相关的内容
- 不同概念之间的关系如下:
| 概念 | 是什么 | 解决什么问题 | 和谁有关 | hash 的用途 |
|---|---|---|---|---|
| layer | 文件系统变更包(tar) | 内容存储与复用 | 被 manifest 引用 | 内容去重、完整性校验 |
| config | 运行配置 JSON | 怎么运行容器 | 被 manifest 引用 | Image ID(运行身份) |
| manifest | 组装清单 JSON | 哪些 layer + 哪个 config 是一组 | 被 tag / manifest list 引用 | RepoDigest(镜像身份) |
镜像不是一个最终状态的文件系统,而是由多个不可变 layer 组成的构建历史。
每个 layer 只会增加内容或标记删除, 但已生成的 layer 内容永远不会被真正移除。
文档信息
- 本文作者:Chaojie Men
- 本文链接:https://menchaojie.github.io/2025/10/03/k8s/
- 版权声明:自由转载-非商用-非衍生-保持署名(创意共享3.0许可证)