背景描述
作为学习环境和非生产环境,搭建k8s集群的时候,可以不考虑高可用性。特别是工作中有时要求搭建一个k8s环境,仅仅是为了完成一些训练任务。提供的资源是一台或者两台昇腾服务器。服务器上CPU和内存资源都很大,而且还带有NPU卡。如果搭建k8s集群的时候,其中一台服务器单纯作为master节点的话,造成很大的资源浪费。因此就可以考虑单个服务器搭建一个k8s环境。
实现方式
方式1、初始化时添加--control-plane参数
在k8s中有两种类型的节点,一类是Control Plane Node(master)节点,用于部署k8s的重要组件,默认是不支持运行用户pod的。另一类是Worker Node(worker),用于运行用户pod。
默认情况下master节点为啥不能运行用户pod呢?
核心的原因是:Taint(污点)机制
当你执行 kubeadm init 不带 --control-plane 时:
bash
kubeadm init --pod-network-cidr=10.244.0.0/16
Kubernetes 自动给 Master 节点添加了 Taint(污点):
bash
节点污点:
├── key: node-role.kubernetes.io/master
│ ├── effect: NoSchedule # 不允许调度新的Pod
│ └── effect: NoExecute # 驱逐不兼容的Pod
Taint 的作用原理
bash
# 当调度器尝试将Pod调度到节点时,会检查:
# 1. Pod是否有对应的Toleration?
# 2. 如果没有,调度器就会拒绝调度
# Master节点默认的Taint:
node-role.kubernetes.io/master:NoSchedule
│
│ ┌──────────────────────────────┐
│ │ 调度器决策过程 │
├───►│ │
│ │ 1. Pod要调度到Master │
│ │ 2. 检查Taint: NoSchedule │
│ │ 3. Pod没有Toleration │
│ │ 4. ❌ 拒绝调度 │
│ └──────────────────────────────┘
│
└───► 原因:保护Master节点资源,
确保控制平面组件稳定运行
--control-plane 参数做了什么?
bash
# 不带 --control-plane 的结果
kubeadm init --pod-network-cidr=10.244.0.0/16
# 执行后
┌────────────────────────────────────────┐
│ Master 节点 │
├────────────────────────────────────────┤
│ 污点: node-role.kubernetes.io/master │
│ ├── NoSchedule ✓ │
│ └── NoExecute ✓ │
│ │
│ 标签: node-role.kubernetes.io/master │
│ │
│ 角色: control-plane │
└────────────────────────────────────────┘
bash
# 带 --control-plane 的结果
kubeadm init --control-plane --pod-network-cidr=10.244.0.0/16
# 执行后
┌────────────────────────────────────────┐
│ Master 节点 │
├────────────────────────────────────────┤
│ 污点: 无 (或仅保留 NoExecute) │
│ │
│ 标签: node-role.kubernetes.io/master │
│ node-role.kubernetes.io/control-plane
│ │
│ 角色: control-plane + worker │
└────────────────────────────────────────┘
方式2、去除污点
首先理解 Kubernetes 的 Taint(污点)机制:
| Effect | 含义 |
|---|---|
| NoSchedule | 新的 不支持 该污点的 Pod 不会被调度到该节点 |
| NoExecute | 现有的 不支持 该污点的 Pod 会被驱逐(驱逐到其他节点) |
两种方式的区别如下:
1、移除所有污点配置
bash
# 移除所有节点的污点配置
kubectl taint nodes --all node-role.kubernetes.io/master-
# 这个方式执行后,返回中会有error。原因是因为会遍历删除所有的节点,包括工作节点。
# 一般情况下工作节点上没有污点配置,所以移除报错了。
# 推荐使用下面的方式
# 只对 master 节点移除污点配置
kubectl taint nodes k8s-master01 node-role.kubernetes.io/master-
| 特性 | 说明 |
|---|---|
| 作用范围 | 集群中 所有 节点 |
| 移除内容 | 同时移除 NoSchedule 和 NoExecute |
| 效果 | ✅ 完全解除限制,所有 Pod 都可以调度到 Master<br>✅ 现有 Pod 不会被驱逐 |
bash
节点污点状态:
┌─────────────────────────────────────┐
│ NoSchedule ──► ✅ 已移除 │
│ NoExecute ──► ✅ 已移除 │
│ 允许调度 ──► ✅ 允许 │
└─────────────────────────────────────┘
2、仅移除 NoSchedule 污点
bash
kubectl taint nodes <master-node-name> node-role.kubernetes.io/master:NoSchedule-
| 特性 | 说明 |
|---|---|
| 作用范围 | 指定节点(需要知道节点名) |
| 移除内容 | 仅移除 No,保留ScheduleNo Execute |
| 效果 | ✅ 新的 Pod 可以调度到 Master<br>⚠️ 现有 Pod 仍可能被驱逐 |
bash
节点污点状态:
┌─────────────────────────────────────┐
│ NoSchedule ──► ✅ 已移除 │
│ NoExecute ──► ⚠️ 仍然存在 │
│ 允许调度 ──► ✅ 允许 │
└─────────────────────────────────────┘
所以个人觉得还是使用--all参数去除所有污点机制,毕竟也只是一个学习环境或者测试环境。
FAQ
1、如何查看污点配置信息
bash
# 查看节点污点
kubectl get nodes -o jsonpath='{range .items[*]}{.metadata.name}{"\n"}{range .spec.taints[*]}{"\t"}{.key}:{.effect}{"\n"}{end}{end}'
# 回显信息如下
k8s-master01
node-role.kubernetes.io/master:NoSchedule
k8s-worker01
# 或
kubectl describe nodes <node-name> | grep -A 10 "Taints"
# 回显信息如下
[root@k8s-master01 ~]# kubectl get nodes
NAME STATUS ROLES AGE VERSION
k8s-master01 Ready control-plane,master 5d21h v1.22.12
k8s-worker01 Ready <none> 5d20h v1.22.12
[root@k8s-master01 ~]# kubectl describe node k8s-master01 | grep -A 10 "Taints"
Taints: node-role.kubernetes.io/master:NoSchedule
Unschedulable: false
Lease:
HolderIdentity: k8s-master01
AcquireTime: <unset>
RenewTime: Thu, 04 Jun 2026 11:39:07 +0800
Conditions:
Type Status LastHeartbeatTime LastTransitionTime Reason Message
---- ------ ----------------- ------------------ ------ -------
NetworkUnavailable False Wed, 03 Jun 2026 19:14:45 +0800 Wed, 03 Jun 2026 19:14:45 +0800 CalicoIsUp Calico is running on this node
MemoryPressure False Thu, 04 Jun 2026 11:37:36 +0800 Fri, 29 May 2026 14:21:47 +0800 KubeletHasSufficientMemory kubelet has sufficient memory available
[root@k8s-master01 ~]#