CentOS7.6 单机部署 K8S 集群

📚 系统准备(所有节点)

以下步骤需要在您的虚拟机上执行,为K8s安装做好准备。

  1. 关闭防火墙 K8s 需要特定的端口进行通信,为避免冲突,建议关闭防火墙。

    sh 复制代码
    systemctl stop firewalld
    systemctl disable firewalld
  2. 关闭 SELinux 将 SELinux 设置为 permissive 模式,这是容器访问主机文件系统所必需的。

    sh 复制代码
    setenforce 0
    sed -i 's/^SELINUX=enforcing$/SELINUX=permissive/' /etc/selinux/config
  3. 关闭 Swap Kubelet 在 Kubernetes 1.8+ 版本中不支持 Swap,必须关闭。

    sh 复制代码
    swapoff -a
    sed -i '/ swap / s/^(.*)$/#\1/g' /etc/fstab
  4. 配置网络参数 使桥接的 IPv4 流量传递到 iptables 的链,这是网络插件正常工作所必需的。

    sh 复制代码
    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
  5. 设置主机名与 hosts(可选但建议) 设置一个易于识别的主机名,并确保在/etc/hosts中正确解析。

    sh 复制代码
    hostnamectl set-hostname k8s-master
    echo "$(hostname -I | awk '{print $1}') k8s-master" >> /etc/hosts

📦 安装Kubernetes组件

  1. 配置 Docker(如已安装请检查) K8s 对 Docker 版本有要求,建议使用Docker 18.09.x或19.03.x等已验证的版本。同时,需要将 Docker 的 Cgroup 驱动改为 systemd 以与 Kubelet 保持一致。

    sh 复制代码
    sudo cat > /etc/docker/daemon.json <<-'EOF'
    {
      "exec-opts": ["native.cgroupdriver=systemd"],
      "registry-mirrors": ["https://8aklptao.mirror.aliyuncs.com"]
    }
    EOF
    sudo systemctl daemon-reload
    sudo systemctl restart docker
  2. 添加 Kubernetes 的阿里云 YUM 源

    sh 复制代码
    cat <<EOF > /etc/yum.repos.d/kubernetes.repo
    [kubernetes]
    name=Kubernetes
    baseurl=https://mirrors.aliyun.com/kubernetes/yum/repos/kubernetes-el7-x86_64/
    enabled=1
    gpgcheck=1
    gpgkey=https://mirrors.aliyun.com/kubernetes/yum/doc/yum-key.gpg https://mirrors.aliyun.com/kubernetes/yum/doc/rpm-package-key.gpg
    EOF
  3. 安装 kubeadm, kubelet 和 kubectl 建议指定版本安装,以避免版本不兼容问题。这里以 1.19.0 为例(请选择稳定版本)。

    sh 复制代码
    sudo yum install -y kubelet-1.19.0 kubeadm-1.19.0 kubectl-1.19.0 --disableexcludes=kubernetes
    sudo systemctl enable --now kubelet

🚀 初始化Master节点(控制平面)

  1. 如果初始化时遇到镜像拉取问题,可以手动拉取:

    sh 复制代码
    images=(
        kube-apiserver:v1.19.0
        kube-controller-manager:v1.19.0
        kube-scheduler:v1.19.0
        kube-proxy:v1.19.0
        pause:3.2
        etcd:3.4.13-0
        coredns:1.7.0
    )
    
    for image in ${images[@]}; do
        docker pull registry.aliyuncs.com/google_containers/$image
        docker tag registry.aliyuncs.com/google_containers/$image k8s.gcr.io/$image
    done
  2. 使用 kubeadm init 初始化集群 使用 --image-repository 参数指定阿里云镜像仓库,这是解决国外镜像无法下载的关键。

    sh 复制代码
    sudo kubeadm init \
      --apiserver-advertise-address=$(hostname -I | awk '{print $1}') \
      --image-repository=registry.aliyuncs.com/google_containers \
      --kubernetes-version=v1.19.0 \
      --service-cidr=10.96.0.0/12 \
      --pod-network-cidr=10.244.0.0/16 \
      --ignore-preflight-errors=Swap

    参数说明:

    • --apiserver-advertise-address: 指定 API Server 公布的 IP 地址,通常是本机 IP。
    • --image-repository: 指定从阿里云拉取控制平面镜像。
    • --pod-network-cidr: 指定 Pod 网络 IP 范围,必须与后续安装的网络插件匹配(此处为 Flannel 网络设置)。
  3. 配置 kubectl 认证文件 初始化成功后,按照屏幕提示执行以下命令,使当前用户能够使用 kubectl。

    sh 复制代码
    mkdir -p $HOME/.kube
    sudo cp -i /etc/kubernetes/admin.conf $HOME/.kube/config
    sudo chown $(id -u):$(id -g) $HOME/.kube/config
  4. 安装 Pod 网络插件(CNI) 网络插件是集群内 Pod 之间通信的基础。这里使用 Flannel。由于其原始 YAML 文件地址可能被墙,可以先下载到本地或直接应用。

    sh 复制代码
    # 直接应用(如果网络通畅)
    kubectl apply -f https://raw.githubusercontent.com/coreos/flannel/master/Documentation/kube-flannel.yml
    
    # 如果无法下载,可尝试先获取文件内容(例如通过其他途径下载),然后使用本地的yml文件
    # kubectl apply -f kube-flannel.yml

✅ 验证集群状态

等待几分钟,让所有Pod启动完成。

  1. 查看节点状态

    sh 复制代码
    kubectl get nodes

    如果一切正常,你应该看到k8s-master节点的状态为 Ready

  2. 查看所有 Pod 状态

    sh 复制代码
    kubectl get pods -n kube-system -o wide

    检查所有核心组件(如 coredns, flannel 等)是否都处于 Running 状态。

🔍 检查节点当前污点

首先,我们需要确认你的节点上当前设置的污点到底是什么。不同版本的 Kubernetes 或不同的安装方式可能会使用不同的污点键名。

请执行以下命令来查看节点的详细污点信息:

sh 复制代码
kubectl describe node k8s-master | grep Taints

或者使用这个更清晰的查看方式:

sh 复制代码
kubectl get nodes -o=custom-columns=NAME:.metadata.name,TAINTS:.spec.taints

🛠️ 可能的原因与解决方案

根据上述命令的输出,你可以参考下表判断具体情况并采取相应操作:

情况说明 可能的原因 解决方案
输出 Taints: <none> 节点上确实已无污点,Pod 应可正常调度。 无需任何操作,你的集群已经允许在 Master 节点上调度 Pod。
输出包含 node-role.kubernetes.io/master:NoSchedule 在稍早版本的 Kubernetes(约 1.24 之前)中,控制平面节点的污点键名是 master 而非 control-plane 使用对应的污点键名进行移除: kubectl taint nodes --all node-role.kubernetes.io/master:NoSchedule-
输出包含其他键名的污点 可能存在其他自定义或特定环境设置的污点。 根据 kubectl describe node 输出中显示的完整污点信息,使用 kubectl taint nodes <node-name> <taint-key>- 命令移除。

💎 验证结果

无论采用哪种方案,执行成功后,再次运行 kubectl describe node k8s-master | grep Taints,应该会看到 Taints: <none>。之后,你再部署 Pod 就不会被节点污点所阻挡了 。

💡 理解污点与容忍度

简单来说,污点(Taint) 是打在节点上的一个"标记",用于拒绝不能"忍受"此标记的 Pod 调度上来。容忍度(Toleration) 则是 Pod 的"承受能力",声明自己能容忍哪些污点,从而可以被调度到对应节点 。默认情况下,控制平面节点会被打上污点,以防止用户的工作负载在可能资源紧张的控制平面上运行,确保集群管理组件自身稳定。对于单节点集群,我们通常需要移除这个限制。

📥 集群启停脚本

k8s-start.sh (集群启动脚本)

bash 复制代码
#!/bin/bash
set -e

echo "正在启动K8s集群..."

# 1. 启动Docker服务
echo "启动Docker服务..."
systemctl start docker
systemctl enable docker

# 2. 启动kubelet服务
echo "启动kubelet服务..."
systemctl enable kubelet
systemctl start kubelet

# 3. 检查并初始化Master节点
if [ ! -f /etc/kubernetes/admin.conf ]; then
    echo "正在初始化Kubernetes Master节点..."
    kubeadm init \
        --apiserver-advertise-address=$(hostname -I | awk '{print $1}') \
        --image-repository registry.aliyuncs.com/google_containers \
        --pod-network-cidr=10.244.0.0/16
    

    mkdir -p $HOME/.kube
    cp -i /etc/kubernetes/admin.conf $HOME/.kube/config
    chown $(id -u):$(id -g) $HOME/.kube/config
else
    echo "Master节点已存在,跳过初始化。"
fi

# 4. 安装Flannel网络插件
if ! kubectl get pods -n kube-system | grep -q flannel; then
    echo "正在安装Flannel网络插件..."
    kubectl apply -f https://raw.githubusercontent.com/coreos/flannel/master/Documentation/kube-flannel.yml
else
    echo "Flannel网络插件已安装。"
fi

# 5. 改进的污点移除逻辑:自动检测并移除污点
echo "正在检查并移除Master节点污点(单节点集群)..."

# 检查当前污点
TAINTS=$(kubectl describe node $(hostname) | grep -i taints | awk '{print $2}')
echo "当前污点状态: $TAINTS"

if [ "$TAINTS" != "<none>" ]; then
    # 尝试移除可能存在的两种污点键名
    kubectl taint nodes --all node-role.kubernetes.io/master:NoSchedule- 2>/dev/null || true
    kubectl taint nodes --all node-role.kubernetes.io/control-plane:NoSchedule- 2>/dev/null || true
    echo "污点移除命令执行完成。"
    
    # 验证污点是否已移除
    sleep 5
    NEW_TAINTS=$(kubectl describe node $(hostname) | grep -i taints | awk '{print $2}')
    if [ "$NEW_TAINTS" = "<none>" ]; then
        echo "✅ Master节点污点已成功移除。"
    else
        echo "⚠️  污点可能仍存在,当前状态: $NEW_TAINTS"
        echo "如需手动移除,请执行: kubectl taint nodes --all node-role.kubernetes.io/master:NoSchedule-"
    fi
else
    echo "✅ Master节点无污点,无需处理。"
fi

echo ""
echo "K8s集群启动完成!"
echo "节点状态:"
kubectl get nodes
echo ""
echo "系统Pod状态:"
kubectl get pods -n kube-system

k8s-stop.sh (集群停止脚本)

bash 复制代码
#!/bin/bash
set -e

echo "正在停止K8s集群..."

# 1. 获取节点名称
NODE_NAME=$(hostname)
echo "正在处理节点: $NODE_NAME"

# 2. 排空当前节点(优雅终止Pod)
echo "正在排空节点..."
kubectl drain $NODE_NAME --delete-emptydir-data --ignore-daemonsets --timeout=300s --force || {
    echo "⚠️  排空节点过程中可能出现警告,继续执行停止操作..."
}

# 3. 停止kubelet服务
echo "停止kubelet服务..."
systemctl stop kubelet

# 4. 停止Docker服务
echo "停止Docker服务..."
systemctl stop docker

echo "K8s集群已停止。"
echo "如需重新启动,请运行: ./k8s-start.sh"

🔧 脚本使用说明

  1. 保存脚本 :将内容分别保存为 k8s-start.shk8s-stop.sh

  2. 赋予执行权限

    bash 复制代码
    chmod +x k8s-start.sh k8s-stop.sh
  3. 使用脚本

    bash 复制代码
    # 启动集群
    ./k8s-start.sh
    
    # 停止集群
    ./k8s-stop.sh
相关推荐
YIN_O1 小时前
目标检测模型量化加速在 openEuler 上的实现
后端
盛小夏2点0版1 小时前
🐍「Python 终端彩色时钟」:彩虹渐变 + HSV 调色,30 行代码让命令行走起!
后端
YIN_O1 小时前
ResNet 图像分类在 openEuler 上的性能大揭秘
后端
程序员小假1 小时前
我们来说一说 Redis IO 多路复用模型
java·后端
兔子零10241 小时前
nginx 配置长跑(下):全局变量、调试思路与可观测性
后端·nginx
okseekw1 小时前
一篇吃透函数式编程:Lambda表达式与方法引用
java·后端
Lear1 小时前
【SQL】联表查询全面指南:掌握JOIN的艺术与科学
后端
油丶酸萝卜别吃1 小时前
在springboot项目中怎么发送请求,设置参数,获取另外一个服务上的数据
java·spring boot·后端
7哥♡ۣۖᝰꫛꫀꪝۣℋ1 小时前
SpringBoot 配置⽂件
java·spring boot·后端