Kubernetes(k8s)单机环境部署
1. Kubernetes (K8s) 简介
此文适合新手快速上手,涵盖安装、配置、基本使用 单机环境
2. 环境
系统要求
- 操作系统:Linux(Ubuntu/CentOS)或 macOS(开发环境)
- 内存:至少 2GB(推荐 4GB+)
- CPU:2 核+
- 存储:20GB+ 可用空间
安装工具
- Docker(K8s 依赖容器运行时)
- kubectl(K8s 命令行工具)
- Minikube(本地单节点 K8s,适合学习)
3. 前置配置
# 1.关闭 swap
sudo swapoff -a
sudo sed -i '/ swap / s/^\(.*\)$/#\1/g' /etc/fstab
# 2.加载内核模块
sudo modprobe overlay
sudo modprobe br_netfilter
# 3.设置内核参数
cat <<EOF | sudo tee /etc/sysctl.d/k8s.conf
net.bridge.bridge-nf-call-ip6tables = 1
net.bridge.bridge-nf-call-iptables = 1
net.ipv4.ip_forward = 1
EOF
sudo sysctl --system
4.安装container runtime(推荐使用 containerd)
Kubernetes v1.24 开始,完全移除了 dockershim
- 不再直接支持 Docker 作为容器运行时
- 推荐使用 containerd 或 CRI-O
# v1.6.x(兼容 Kubernetes v1.29)
sudo yum downgrade containerd.io-1.6.28* -y
sudo systemctl restart containerd
sudo systemctl enable containerd
ls /var/run/containerd/containerd.sock # 确认 socket 文件存在
containerd --version # 应显示 1.6.x
# 生成默认配置
sudo mkdir -p /etc/containerd
containerd config default | sudo tee /etc/containerd/config.toml
# 修改配置(使用 systemd cgroup 驱动)
sudo sed -i 's/SystemdCgroup = false/SystemdCgroup = true/g' /etc/containerd/config.toml
# 可选修改 pause 镜像地址(国内可用阿里云镜像)
sudo sed -i 's|registry.k8s.io/pause:3.9|registry.aliyuncs.com/google_containers/pause:3.9|g' /etc/containerd/config.toml
sudo systemctl restart containerd
3. 安装 kubeadm, kubelet 和 kubectl
方式 1:Minikube(推荐新手)
# 安装 Minikube(Linux/macOS)
curl -LO https://storage.googleapis.com/minikube/releases/latest/minikube-linux-amd64 # Linux
sudo install minikube-linux-amd64 /usr/local/bin/minikube
# 启动 Minikube(默认使用 Docker 驱动)
minikube start
# 验证
kubectl get nodes # 应返回一个节点(STATUS=Ready)
方式 2:kubeadm(多节点集群) 此处为单机演示
- 安装 kubeadm kubelet kubectl
# CentOS 添加 Kubernetes 的 yum 仓库,再
cat <<EOF | sudo tee /etc/yum.repos.d/kubernetes.repo
[kubernetes]
name=Kubernetes
baseurl=https://pkgs.k8s.io/core:/stable:/v1.29/rpm/
enabled=1
gpgcheck=1
gpgkey=https://pkgs.k8s.io/core:/stable:/v1.29/rpm/repodata/repomd.xml.key
EOF
# 安装 kubeadm kubelet kubectl
yum install -y kubeadm kubelet kubectl --disableexcludes=kubernetes
# 启动并设置开机自启 kubelet
sudo systemctl enable --now kubelet
# 启动并设置开机自启 kubeletcontainerd
systemctl enable --now containerd
准备镜像,镜像拉取问题见下文中的常见问题4和5
初始化主节点
非常关键的一步,失败会出现很多问题,可参考下文中的常见问题
# **初始化主节点 此步需要确保containerd,kubelet正常运行,以及镜像已经提前拉好** # 参数--apiserver-advertise-address=0.0.0.0:允许本地访问 API Server # 参数---pod-network-cidr=10.244.0.0/16 是用来配合 Flannel 网络插件的(或你改了 Calico 也行)。 # 参数--control-plane-endpoint=localhost:显式声明单节点控制平面 # 初始化成功会出现类似 Your Kubernetes control-plane has initialized successfully! kubeadm init \ --apiserver-advertise-address=192.168.0.2 \ --pod-network-cidr=10.244.0.0/16 \ --control-plane-endpoint=192.168.0.2 --ignore-preflight-errors=Swap # 如果有 swap 警告配置 kubectl
mkdir -p $HOME/.kube sudo cp -i /etc/kubernetes/admin.conf $HOME/.kube/config sudo chown $(id -u):$(id -g) $HOME/.kube/config安装网络插件(如 Calico)
# 此处单机选择安装Flannel kubectl apply -f https://github.com/flannel-io/flannel/releases/latest/download/kube-flannel.yml # 或者安装网络插件(如 Calico) kubectl apply -f https://docs.projectcalico.org/manifests/calico.yaml # 如果kubectl apply 无法应用 Calico 的 YAML 文件,可以下载文件再手动应用 # 使用 curl curl -O https://mirror.aliyuncs.com/kubernetes/network-plugin/calico.yaml # 如果 Calico 的默认配置(如 CIDR)与你的集群不匹配,可以编辑 calico.yaml # 检查 CALICO_IPV4POOL_CIDR 是否与 kubeadm init --pod-network-cidr 一致(默认 192.168.0.0/16 或 10.244.0.0/16) kubectl apply -f calico.yaml允许 Master 节点调度 Pod(单机必须)
kubectl taint nodes --all node-role.kubernetes.io/control-plane-
验证安装
# 查看集群状态
kubectl cluster-info
# 检查节点状态
kubectl get nodes # 应显示 Ready
# 检查容器运行时
kubectl get nodes -o wide | grep -i container # 应显示 containerd://1.6.x
常用命令速查
| 操作 | 命令 |
|---|---|
| 查看 Pod | kubectl get pods |
| 查看 Service | kubectl get svc |
| 查看日志 | kubectl logs |
| 进入容器 | kubectl exec -it |
| 删除 Pod | kubectl delete pod |
| 扩缩容 | kubectl scale –replicas=3 deployment/nginx |
卸载
# Minikube
minikube stop
minikube delete
# kubeadm
sudo kubeadm reset
sudo apt-get purge kubeadm kubectl kubelet # Ubuntu
sudo yum remove kubeadm kubectl kubelet # CentOS
常见问题
错误显示 container runtime is not running,说明 containerd(或 Docker)未正确配置或未运行。
解决方法:
- 如果使用 containerd:
# 确保 containerd 已安装并运行 sudo systemctl enable --now containerd sudo systemctl status containerd # 生成默认配置并启用 CRI 插件 sudo containerd config default | sudo tee /etc/containerd/config.toml sudo sed -i 's/SystemdCgroup = false/SystemdCgroup = true/' /etc/containerd/config.toml sudo systemctl restart containerd- 如果使用 Docker:
# 确保 Docker 已安装并运行 sudo systemctl enable --now docker sudo systemctl status docker # 配置 Docker 使用 systemd cgroup sudo mkdir -p /etc/docker cat <<EOF | sudo tee /etc/docker/daemon.json { "exec-opts": ["native.cgroupdriver=systemd"] } EOF sudo systemctl restart docker
- 如果使用 containerd:
错误 /proc/sys/net/bridge/bridge-nf-call-iptables does not exist 表示系统未加载 br_netfilter 内核模块。
解决方法:
# 加载内核模块 sudo modprobe br_netfilter # 确保重启后依然生效 echo "br_netfilter" | sudo tee /etc/modules-load.d/k8s.conf # 启用桥接流量转发 cat <<EOF | sudo tee /etc/sysctl.d/k8s.conf net.bridge.bridge-nf-call-ip6tables = 1 net.bridge.bridge-nf-call-iptables = 1 net.ipv4.ip_forward = 1 EOF sudo sysctl --systemkubelet 服务未能正常启动或健康检查失败
解决方法
- 检查 kubelet 状态和日志
# 查看 kubelet 运行状态 sudo systemctl status kubelet # 查看详细日志(若无状态异常) sudo journalctl -xeu kubelet --no-pager | tail -n 50 - 容器运行时(CRI)未就绪
# 检查 containerd 或 Docker 是否运行 sudo systemctl status containerd # 或 docker # 如果没有运行,启动并启用 sudo systemctl enable --now containerd sudo systemctl restart kubelet
- 检查 kubelet 状态和日志
kubeadm config images pull 失败
- 配置 containerd 镜像加速器
# 修改 containerd 配置 sudo mkdir -p /etc/containerd containerd config default | sudo tee /etc/containerd/config.toml # 添加国内镜像加速器(阿里云) sudo sed -i 's|registry.k8s.io|registry.aliyuncs.com/google_containers|g' /etc/containerd/config.toml sudo sed -i 's|docker.io|mirror.ccs.tencentyun.com|g' /etc/containerd/config.toml # 重启 containerd sudo systemctl restart containerd - 更换 Docker 仓库为国内源
# 1. 备份原有 Docker 仓库配置 sudo mv /etc/yum.repos.d/docker-ce.repo /etc/yum.repos.d/docker-ce.repo.bak # 2. 使用阿里云 Docker 镜像源 sudo tee /etc/yum.repos.d/docker-ce.repo <<'EOF' [docker-ce-stable] name=Docker CE Stable - AliYun baseurl=https://mirrors.aliyun.com/docker-ce/linux/centos/$releasever/$basearch/stable enabled=1 gpgcheck=1 gpgkey=https://mirrors.aliyun.com/docker-ce/linux/centos/gpg EOF # 3. 清理缓存并重新安装 sudo yum clean all sudo yum makecache sudo yum install -y containerd.io-1.6.28
- 配置 containerd 镜像加速器
当 kubeadm init 卡在 [preflight] Pulling images… 时,通常是由于 Docker/Containerd 镜像拉取失败 或 网络问题 导致
- 查看需要的镜像列表
kubeadm config images list --kubernetes-version=v1.29.15 # 输出示例 registry.k8s.io/kube-apiserver:v1.29.15 registry.k8s.io/kube-controller-manager:v1.29.15 registry.k8s.io/kube-scheduler:v1.29.15 registry.k8s.io/kube-proxy:v1.29.15 registry.k8s.io/coredns/coredns:v1.11.1 registry.k8s.io/pause:3.9 registry.k8s.io/etcd:3.5.16-0 - 手动拉取镜像
sudo kubeadm config images pull --kubernetes-version=v1.29.15- 如果拉取失败(如网络问题),尝试:
- 使用国内镜像源(如阿里云)
sudo kubeadm config images pull --image-repository=registry.aliyuncs.com/google_containers --kubernetes-version=v1.29.15 - 手动拉取并重命名:
docker pull registry.aliyuncs.com/google_containers/kube-apiserver:v1.29.15 docker tag registry.aliyuncs.com/google_containers/kube-apiserver:v1.29.15 registry.k8s.io/kube-apiserver:v1.29.15
- 使用国内镜像源(如阿里云)
- 如果拉取失败(如网络问题),尝试:
- 确认容器运行时如果想要清理 aliyun 那些 sha256 镜像
# 确认 kubelet 使用的容器运行时类型。 --container-runtime-endpoint=unix:///run/containerd/containerd.sock → 用的是 containerd ps -ef | grep kubelet | grep container-runtime # 如果是 containerd # 导出docker镜像 docker save registry.k8s.io/kube-apiserver:v1.29.15 -o kube-apiserver.tar # 导入到 containerd: ctr -n k8s.io images import kube-apiserver.tar # 验证 containerd 中镜像是否存在: ctr -n k8s.io images ls | grep kube-apiserver # 重启 kubele systemctl restart kubeletctr -n k8s.io images ls ctr -n k8s.io images ls | grep aliyuncs ctr -n k8s.io images rm <完整REF>
- 查看需要的镜像列表
API Server 还没起来或者挂了,错误信息如: error: error validating “calico.yaml”: error validating data: failed to download openapi: Get “https://192.168.0.2:6443/openapi/v2?timeout=32s”: dial tcp 192.168.0.2:6443: connect: connection refused
- 检查 kubelet 状态
systemctl status kubelet # 有没有绿色的 active (running)?如果不是,重启: systemctl restart kubelet - kube-apiserver 是否正常运行, 能不能看到 kube-apiserver 正在运行?如果没有,可能初始化没完成,或者配置挂了。
docker ps | grep kube-apiserver # 或 containerd 用户: crictl ps | grep kube-apiserver - 检查 kubectl 的配置是否 OK
~/.kube/config如果没配置好,去设置mkdir -p $HOME/.kube cp -i /etc/kubernetes/admin.conf $HOME/.kube/config chown $(id -u):$(id -g) $HOME/.kube/config
- 检查 kubelet 状态
crictl 输出报错如:ERRO[0000] validate service connection: validate CRI v1 runtime API for endpoint “unix:///var/run/dockershim.sock”: rpc error: code = Unavailable desc = connection error: desc = “transport: Error while dialing: dial unix /var/run/dockershim.sock: connect: no such file or directory”
- 说明当前 没有配置容器运行时的 socket 路径,也就是说:crictl 没法找到 containerd 或 docker 的接口来查看容器运行情况。
- 显式配置 crictl 使用 containerd,创建/编辑配置文件
cat <<EOF | sudo tee /etc/crictl.yaml runtime-endpoint: unix:///run/containerd/containerd.sock image-endpoint: unix:///run/containerd/containerd.sock timeout: 10 debug: false EOF# 测试是否成功识别 containerd, 如果一切正常,会输出 containerd 的详细信息(运行中的容器、版本等)。 crictl info - 检查 kubelet 是否和 containerd 联通: 编辑 /var/lib/kubelet/kubeadm-flags.env 看看是否有设置
KUBELET_KUBEADM_ARGS="--container-runtime=remote --container-runtime-endpoint=unix:///run/containerd/containerd.sock ..." - 然后重启 kubelet:
systemctl daemon-reexec systemctl restart kubelet- 验证测试
crictl ps | grep apiserver kubectl get nodes
Calico Pod 状态问题,如果 Pod 处于Pending、Error或者CrashLoopBackOff状态,就需要进一步排查。 要保证 Calico 相关的 Pod 都处于Running状态
#查看 Calico Pod 状态 kubectl get pods -n kube-system | grep calico #输出示例 calico-kube-controllers-565f855c6c-6v9z7 1/1 Running 0 3d calico-node-8h5g7 1/1 Running 0 3d calico-node-lt7f4 1/1 Running 0 3d # 查看特定 Pod 的详细信息 kubectl describe pod <pod-name> -n kube-system
* 镜像拉取失败无法拉取 Calico 镜像,可以尝试手动拉取
``` bash
# 可以手动代理下载,然后传输到目标主机导入镜像
docker pull docker.io/calico/cni:v3.25.0
docker save -o /path/to/calico-cni-v3.25.0.tar docker.io/calico/cni:v3.25.0
docker load -i /path/to/calico-cni-v3.25.0.tar
# 导入到 containerd:
ctr -n docker.io images import calico-cni-v3.25.0.tar
ctr -n docker.io images ls | grep cni
# 重启kubelet
sudo systemctl restart kubelet
- 其他必要步骤
注意版本兼容问题
彻底重置并重建集群:
# 删除文件 sudo kubeadm reset -f sudo rm -rf /etc/kubernetes/ /var/lib/etcd/ ~/.kube/ sudo systemctl restart kubelet # 重置 sudo kubeadm init \ --apiserver-advertise-address=192.168.0.2 \ --pod-network-cidr=10.244.0.0/16 \ --kubernetes-version=v1.29.15 \ --image-repository=registry.aliyuncs.com/google_containers \ # 使用阿里云镜像 --ignore-preflight-errors=Swap重置后再进行上面的如果成功初始化,记得保存 kubeadm join 命令并安装 CNI 插件
重启 kubelet
sudo netstat -tulnp | grep 6443确认 API Server 是否运行
# 检查 API Server 容器/Pod(根据容器运行时选择) sudo docker ps | grep kube-apiserver # Docker sudo crictl ps | grep kube-apiserver # Containerd检查 API Server 端口监听
sudo netstat -tulnp | grep 6443 # 正常输出示例 tcp 0 0 192.168.0.2:6443 0.0.0.0:* LISTEN <pid>/kube-apiserver验证修复
- 检查 kubelet 状态和日志
- 检查容器运行时状态:
sudo crictl ps # 或 sudo docker ps检查内核模块:
lsmod | grep br_netfilter cat /proc/sys/net/bridge/bridge-nf-call-iptables
完全卸载
以下命令适用于 kubeadm 方式部署的单节点(单机)集群:
# 1. 关闭所有 kubelet 服务(如果有 systemd 服务)
sudo systemctl stop kubelet
sudo systemctl disable kubelet
# 2. 重置 kubeadm 配置(会清理 etcd 数据、k8s 配置等)
sudo kubeadm reset -f
# 3. 删除网络相关配置(flannel/cni)
sudo rm -rf /etc/cni /opt/cni /var/lib/cni /var/lib/kubelet /etc/kubernetes
# 4. 清理 Docker/containerd 容器网络遗留
sudo ip link delete cni0 || true
sudo ip link delete flannel.1 || true
sudo ip link delete docker0 || true
# 5. 删除 Kubernetes 二进制文件(如果是手动解压安装的)
sudo rm -f /usr/local/bin/kubectl /usr/local/bin/kubeadm /usr/local/bin/kubelet
# yum安装方式
sudo yum remove -y kubeadm kubelet kubectl kubernetes-cni
sudo rm -rf /etc/kubernetes /var/lib/kubelet /etc/cni /opt/cni
rm -rf /etc/cni/net.d /var/lib/cni/
# 6. 删除日志和残留目录
sudo rm -rf ~/.kube
sudo rm -rf /var/log/pods
# 7. containerd和docker镜像清理
sudo crictl images
crictl images | grep -E 'k8s|flannel|dashboard|etcd' | awk '{print $1":"$2}' | xargs -r sudo crictl rmi
sudo crictl rmi IMAGE_ID
docker images
#删除所有未被使用的镜像 建议rmi 单个删除
docker images | grep -E 'k8s|flannel|dashboard|etcd' | awk '{print $3}' | xargs -r docker rmi -f
docker image prune -a -f
文档资源
- 官方文档:kubernetes.io
- 中文教程:Kubernetes 中文社区
清理并重新初始化脚本
#!/bin/bash
set -e
echo "🧼 [1/6] 停止 kubelet 服务..."
sudo systemctl stop kubelet || true
echo "🧹 [2/6] 重置 kubeadm 和清理网络配置..."
sudo kubeadm reset -f
sudo rm -rf /etc/cni/net.d
sudo rm -rf $HOME/.kube
sudo ip link delete cni0 || true
sudo ip link delete flannel.1 || true
echo "🔧 [3/6] 初始化 Kubernetes 控制平面..."
sudo kubeadm init \
--apiserver-advertise-address=192.168.0.2 \
--pod-network-cidr=10.244.0.0/16 \
--control-plane-endpoint=192.168.0.2
echo "👤 [4/6] 配置 kubectl 使用权限..."
mkdir -p $HOME/.kube
sudo cp /etc/kubernetes/admin.conf $HOME/.kube/config
sudo chown $(id -u):$(id -g) $HOME/.kube/config
echo "🌐 [5/6] 安装 Flannel 网络插件..."
kubectl apply -f https://raw.githubusercontent.com/flannel-io/flannel/master/Documentation/kube-flannel.yml
echo "🛑 [6/6] 移除控制节点的调度限制(适用于单机)..."
kubectl taint nodes --all node-role.kubernetes.io/control-plane- || true
sudo systemctl restart containerd
sudo systemctl restart kubelet
echo -e "\n✅ 集群初始化完成!执行以下命令查看状态:"
echo "kubectl get nodes"
echo "kubectl get pods -A"