k8s集群部署(Ubuntu22.04)

注意事项:

首先初学者没必要搞清楚所有组件作用,只需要部署上即可,事后可针对性去了解,文章结尾我也补充了各类节点的作用,大家了解即可,有疑问可留言,看到会回复(下述内容是我在搭建集群的笔记,所有略微潦草,兄弟们凑会看),如有帮助,还望点赞三联!!!

框架图

1. 环境准备

bash 复制代码
# 1. 主机名与 hosts
sudo hostnamectl set-hostname k8s-master   # 主节点
sudo hostnamectl set-hostname k8s-worker-01 # 从节点1
sudo hostnamectl set-hostname k8s-worker-02 # 从节点2

cat <<EOF | sudo tee -a /etc/hosts
192.168.44.200 k8s-master
192.168.44.201 k8s-worker-01
192.168.44.202 k8s-worker-02
EOF

# 2. 关闭 swap
sudo swapoff -a
sudo sed -i '/swap/s/^/#/' /etc/fstab
swapon --show    #应该什么都不输出


# 3. 内核模块与参数
cat <<EOF | sudo tee /etc/modules-load.d/k8s.conf
overlay
br_netfilter
EOF
sudo modprobe overlay && sudo modprobe br_netfilter

cat <<EOF | sudo tee /etc/sysctl.d/k8s.conf
net.bridge.bridge-nf-call-iptables  = 1
net.bridge.bridge-nf-call-ip6tables = 1
net.ipv4.ip_forward                 = 1
EOF
sudo sysctl --system

# 4. ⚠️ **必须安装 conntrack**(否则 kubeadm 预检失败)
sudo apt update && sudo apt install -y conntrack

#5. 配置时间同步
sudo apt update
sudo apt install -y chrony
sudo systemctl enable chrony --now
chronyc sources -v

#6. 安装必要工具
sudo apt install -y socat ebtables ethtool ipset curl updatesudo 

🚫 常见错误:未安装 conntrack → 报 [ERROR FileExisting-conntrack]

2. 安装容器运行时节点(由于此处使用的时k8sV1.31,所有无需安装docker)

bash 复制代码
# 1. 安装 containerd(来自 docker 官方源)
curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo gpg --dearmor -o /usr/share/keyrings/docker-archive-keyring.gpg
echo "deb [arch=$(dpkg --print-architecture) signed-by=/usr/share/keyrings/docker-archive-keyring.gpg] https://download.docker.com/linux/ubuntu $(lsb_release -cs) stable" | sudo tee /etc/apt/sources.list.d/docker.list > /dev/null
sudo apt update && sudo apt install -y containerd.io

# 2. 配置 containerd 使用 systemd cgroup
sudo mkdir -p /etc/containerd
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
sudo systemctl enable containerd

# 3. ✅ **配置 crictl 端点**(消除 WARN,确保后续命令可靠)
cat <<EOF | sudo tee /etc/crictl.yaml
runtime-endpoint: unix:///var/run/containerd/containerd.sock
image-endpoint: unix:///var/run/containerd/containerd.sock
timeout: 10
debug: false
EOF

🚫 常见错误:

  • 未配置 SystemdCgroup → 容器运行时状态异常。

  • 未配置 crictl 端点 → crictl ps 每次输出 WARN,且部分命令可能找不到容器。

3. 安装 kubeadm / kubelet / kubectl(所有节点)

⚠️ 关键:旧仓库 apt.kubernetes.io 已废弃(返回 404),必须使用新仓库 pkgs.k8s.io

bash 复制代码
# 1. 添加 Kubernetes 官方新仓库(以 v1.31 为例)
sudo mkdir -p /etc/apt/keyrings
curl -fsSL https://pkgs.k8s.io/core:/stable:/v1.31/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://pkgs.k8s.io/core:/stable:/v1.31/deb/ /" | sudo tee /etc/apt/sources.list.d/kubernetes.list

# 2. 安装并锁定版本
sudo apt update
sudo apt install -y kubelet kubeadm kubectl
sudo apt-mark hold kubelet kubeadm kubectl

一、kubeadm init 会自动创建的组件

kubeadm 初始化时会生成静态 Pod 清单并启动以下组件(它们以静态 Pod形式运行在 /etc/kubernetes/manifests/ 目录下,由 kubelet 直接管理):

|-------------------------|-----------------------------------|
| 组件 | 说明 |
| kube-apiserver | Kubernetes API 入口,所有组件和用户操作的唯一入口 |
| kube-controller-manager | 运行各种控制器(节点控制器、副本控制器等),确保集群状态与期望一致 |
| kube-scheduler | 负责将新创建的 Pod 调度到合适的节点 |
| etcd | 分布式键值存储,保存所有集群数据(如配置、状态) |

此外,kubeadm 还会:

  • 生成证书(CA、apiserver、etcd 等)和 kubeconfig 文件(如 admin.conf)。

  • 创建引导令牌(用于节点加入)。

  • 在集群中创建一些基础资源,如 kube-system 命名空间、ClusterRoleClusterRoleBinding 等。


二、kubeadm init 会默认部署(但依赖网络)的附加组件

kubeadm 在初始化完成后,会尝试部署两个附加组件,它们以常规 Pod(非静态)形式运行,但它们正常工作依赖于 Pod 网络插件:

|------------|---------------------------------------------|----------------|
| 组件 | 说明 | 依赖 |
| CoreDNS | 集群内部 DNS 服务,为 Service 和 Pod 提供域名解析 | 需要网络插件就绪才能正常运行 |
| kube-proxy | 在每个节点上运行,实现 Service 的负载均衡(iptables/IPVS 模式) | 需要网络插件就绪才能正常工作 |

这两个组件虽然由 kubeadm 自动部署,但如果 Pod 网络插件未安装,它们会一直处于 Pending 状态。因此在实际操作中,我们通常把它们视为"需要后续依赖条件"的组件。

4. 初始化主节点(仅主节点)

bash 复制代码
# 1. ⚠️ **确保 etcd 数据目录干净**(避免残留集群成员)
sudo rm -rf /var/lib/etcd

# 2. 执行初始化
sudo kubeadm init \
  --apiserver-advertise-address=192.168.44.200 \   #k8s主节点ip
  --pod-network-cidr=10.244.0.0/16 \
  --control-plane-endpoint=k8s-master:6443 \
  --upload-certs

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

# 4. ✅ **优化 etcd 配置**(移除 resources.requests,避免 CPU 争抢)
sudo sed -i '/resources/,/memory: 100Mi/d' /etc/kubernetes/manifests/etcd.yaml
sudo systemctl restart kubelet

🚫 常见错误:

  • 未清理 /var/lib/etcd → etcd 以多节点模式启动,不断选举、超时。

  • etcd.yaml 残留 resources.requests.cpu: 100m → 单核节点上 CPU 不足导致超时。

  • 证书/配置残留 → 可通过 kubeadm reset -f && rm -rf /etc/kubernetes /var/lib/etcd 彻底重置

5. 安装网络插件

推荐使用 Flannel(与你指定的 Pod CIDR 10.244.0.0/16 完全兼容,无需修改配置)。

注意:此处需要科技!!!

bash 复制代码
#注意:需要代理可以访问外网
kubectl apply -f https://github.com/flannel-io/flannel/releases/download/v0.28.1/kube-flannel.yml

🚫 常见错误:

  • 使用 Calico 但未修改 CIDR → Pod 无法获取 IP,节点 NotReady

  • curl 下载 calico.yaml 被墙或返回 HTML → 文件内容无效,kubectl apply 报验证错误。

(全tm是坑,兄弟们还是别去尝试calico了,官网都有问题)

6. 加入工作节点(仅从节点)

⚠️ 切记:不要加 --control-plane--certificate-key! 这些参数用于添加控制平面节点,普通工作节点必须省略。

bash 复制代码
# 1. 从节点上确保 containerd 配置正确,且 conntrack 已安装
sudo apt install -y conntrack
sudo rm -f /etc/containerd/config.toml
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

# 2. 主节点上生成 join 命令
kubeadm token create --print-join-command

# 3. 从节点上执行得到的 join 命令(示例)
sudo kubeadm join k8s-master:6443 --token xxx --discovery-token-ca-cert-hash sha256:xxx

🚫 常见错误:

  • 使用了带 --control-plane 的 join 命令 → 节点被标记为控制平面,且后续加入普通节点会报文件已存在、端口占用。

  • 从节点 containerd CRI 未正确配置 → 报 unknown service runtime.v1.RuntimeService

  • 忘记安装 conntrack → 预检失败。

7. 检查集群状态

bash 复制代码
kubectl get nodes -w
# 等待约 1 分钟,所有节点变为 Ready
kubectl get pods -A
# 所有系统组件(coredns, flannel)应为 Running




#状态如下即成功:
root@k8s-master:~/k8s# kubectl get nodes
NAME            STATUS   ROLES           AGE   VERSION
k8s-master      Ready    control-plane   9d    v1.31.14
k8s-worker-01   Ready    node            9d    v1.31.14
k8s-worker-02   Ready    node            9d    v1.31.14

8. 出现问题以后,如何重新添加节点

bash 复制代码
#第一步
1.1 将节点标记为不可调度并驱逐 Pod
这一步可以确保节点上的工作负载被优雅地迁移到其他节点(如果集群中有其他可用节点)。
在控制平面节点(例如 k8s-master)执行:

# 假设要删除的节点名为 k8s-worker-01
kubectl cordon k8s-worker-01
kubectl drain k8s-worker-01 --ignore-daemonsets --delete-emptydir-data

#删除节点
kubectl delete node k8s-worker-01

- --ignore-daemonsets:忽略 DaemonSet 管理的 Pod(它们会自动在其他节点重建)。
- --delete-emptydir-data:允许删除使用 emptyDir 的 Pod(数据会丢失,请确保无状态应用)。


#第二步
在要删除的节点(例如 k8s-worker-01)上以 root 执行以下命令,务必谨慎,确保没有重要数据。
#1.使用 kubeadm 重置节点
sudo kubeadm reset -f

#2.手动删除 Kubernetes 相关目录和文件
sudo rm -rf /etc/kubernetes
sudo rm -rf /var/lib/kubelet
sudo rm -rf /var/lib/etcd      # 如果该节点曾是控制平面,但工作节点一般无此目录
sudo rm -rf ~/.kube
sudo rm -f /etc/cni/net.d/*

#3.清理iptales规则
sudo iptables -F && sudo iptables -t nat -F && sudo iptables -t mangle -F && sudo iptables -X

#4.重启containerd
sudo systemctl restart containerd




#第三步
#1 安装必要工具(如果尚未安装)
sudo apt updatesudo apt install -y conntrack
#2 验证 containerd 配置
确保 containerd 使用 systemd cgroup 驱动,且 CRI 插件正常工作:
bash
#3 重新生成配置(如果之前有修改,可先备份)
sudo rm -f /etc/containerd/config.tomlsudo 
containerd config default | sudo tee /etc/containerd/config.toml
sudo sed -i 's/SystemdCgroup = false/SystemdCgroup = true/' /etc/containerd/config.tomlsudo 
systemctl restart containerd
#4 配置 crictl 端点(消除警告)
cat <<EOF | sudo tee /etc/crictl.yaml
runtime-endpoint: unix:///var/run/containerd/containerd.sock
image-endpoint: unix:///var/run/containerd/containerd.sock
timeout: 10
debug: false
EOF
#5 验证 crictl 可正常工作, 应输出 RuntimeName: containerd,无警告
sudo crictl version




#第四步
kubeadm token create --print-join-command

输出如下:
kubeadm join k8s-master:6443 --token xxxxx --discovery-token-ca-cert-hash sha256:xxxxx




#第五步
#在目标节点(已清理的节点)上以 root 执行刚刚复制的 join 命令:
sudo kubeadm join k8s-master:6443 --token xxxxx --discovery-token-ca-cert-hash sha256:xxxxx

#输入如下:
This node has joined the cluster:
* Certificate signing request was sent to apiserver and a response was received.
* The kubelet was informed of the new secure connection details.

#节点验证(主节点)
kubectl get nodes

各类组件作用

架构总览

一个典型的 K8s 集群如下图所示,清晰地展示了各组件的归属和协作关系:

控制平面 (Control Plane / Master Node) 组件

控制平面负责管理集群的全局决策(例如调度)、检测和响应集群事件。它可以在高可用配置中跨多台机器运行。

1. kube-apiserver

  • 作用:API 服务器是 Kubernetes 集群的前端和网关。它是所有 REST 操作的唯一入口,无论是来自外部用户(如 kubectl)、内部组件还是其他自动化工具。它的核心功能是验证和配置 API 对象(如 Pods, Services, ReplicaSets 等)。

  • 节点归属:控制平面节点。

  • 关键点:所有组件都不直接通信,而是通过 API Server 进行交互,它也是与 etcd 通信的唯一组件。

2. etcd

  • 作用:Kubernetes 的"大脑"和持久化存储中心。它是一个一致且高可用的键值 (Key-Value) 数据库,用于存储整个集群的所有配置数据和状态(即所有 API 对象的最新状态)。任何更改都必须通过 API Server 写入 etcd,任何读取操作也通过 API Server。

  • 节点归属:控制平面节点(通常在生产环境中,etcd 会以独立集群的方式运行在单独的主机上以保证安全性和性能)。

  • 关键点:它是 Kubernetes 集群状态的唯一真理源 (Single Source of Truth)。

3. kube-scheduler

  • 作用:调度器,负责为 Pod 分配节点。它监听 API Server 是否有新建的、尚未分配节点 (Node) 的 Pod,然后根据一系列调度策略(如资源请求、亲和性/反亲和性、数据位置等)为 Pod 选择一个最合适的 Worker Node 来运行。

  • 节点归属:控制平面节点。

  • 关键点:它只做调度决策,并不真正在节点上启动 Pod,那是 kubelet 的工作。

4. kube-controller-manager

  • 作用:运行着各种控制器 (Controller) 的守护进程。每个控制器都是一个独立的控制循环,负责监听集群状态(通过 API Server),并确保当前状态向期望状态转变。常见的控制器包括:

    • 节点控制器 (Node Controller):负责在节点出现故障时进行通知和响应。

    • 副本控制器 (Replication Controller):确保 Pod 的副本数符合 ReplicaSet 中的期望值。

    • 端点控制器 (Endpoints Controller):填充 Endpoints 对象(连接 Services 和 Pods)。

    • 服务账户和令牌控制器 (Service Account & Token Controllers):为新的命名空间创建默认账户和 API 访问令牌。

  • 节点归属:控制平面节点。

5. cloud-controller-manager (可选,主要用于云环境)

  • 作用:将与特定云平台交互的控制器逻辑从 kube-controller-manager 中解耦出来。这使得云厂商的代码和 Kubernetes 的核心代码可以独立演化。它负责管理与底层云基础设施(如负载均衡器、虚拟机、路由等)的交互。

  • 节点归属:控制平面节点。

  • 关键点:如果你在本地物理机或虚拟机环境下运行 Kubernetes(如使用 Kubeadm 自建集群),此组件通常不存在。


工作节点 (Worker Node) 组件

工作节点负责运行容器化的应用。每个节点上都必须运行以下组件。

1. kubelet

  • 作用:节点上的"代理" (Agent)。它是控制平面和节点之间的桥梁,负责管理其上 Pod 的生命周期。它接收来自 API Server 的 PodSpec(Pod 定义),并确保该 Pod 中描述的容器健康运行(通过底层的容器运行时)。它还会定期向 API Server 报告节点和 Pod 的状态。

  • 节点归属:每个工作节点(包括控制平面节点,如果它也被标记为可调度的话)。

  • 关键点:它是节点上最重要的组件,是 Pod 的实际"管理者"。

2. kube-proxy

  • 作用:网络代理,负责节点上的网络规则。它通过维护主机上的网络规则(如 Linux 的 iptables 或 ipvs),来实现 Kubernetes Service 的概念,如服务发现、负载均衡和将流量转发到正确的 Pod。

  • 节点归属:每个工作节点。

  • 关键点:它是实现 Service 四层负载均衡的关键。

3. 容器运行时 (Container Runtime)

  • 作用:负责运行容器的软件。Kubernetes 通过容器运行时接口 (CRI) 来与不同的运行时交互,从而运行和管理容器。最著名的例子是 Docker、containerd、CRI-O 等。

  • 节点归属:每个工作节点。

  • 关键点:kubelet 通过 CRI 与容器运行时通信,而不是直接管理容器。

总结

|--------------------|------------------------------------------------------------|
| 组件 | 角色 |
| kubectl | 命令行工具,用户通过它提交 Pod 定义文件。 |
| API Server | 集群的网关。所有请求都必须通过它,它负责认证、授权、校验,并将数据保存到 etcd。 |
| etcd | 集群的唯一可信数据源,存储所有集群数据(期望状态和当前状态)。 |
| Scheduler | 调度大师。监视未调度的 Pod,并根据策略为它选择一个最合适的 Node。 |
| Controller Manager | 大脑。内部包含多种控制器(如 Deployment Controller)。它们监控资源变化,确保系统状态符合期望。 |
| Kubelet | 节点代理。运行在每个 Node 上,负责与容器运行时交互,真正地启动/停止容器,并上报状态。 |
| Container Runtime | 容器引擎(如 containerd, CRI-O)。真正负责拉取镜像和运行容器的软件。 |

相关推荐
山北雨夜漫步2 小时前
Docker
运维·docker·容器
悠闲蜗牛�2 小时前
2026年边缘云原生实战:Kubernetes向边缘计算的全面演进
云原生·kubernetes·边缘计算
Elastic 中国社区官方博客2 小时前
推出 Elastic Serverless Plus 附加组件,支持 AWS PrivateLink 功能
大数据·elasticsearch·搜索引擎·云原生·serverless·全文检索·aws
切糕师学AI2 小时前
Kubernetes ReplicaSet 详解
云原生·容器·kubernetes
rider1892 小时前
基于docker安装yapi接口文档服务
docker·容器·yapi
峰顶听歌的鲸鱼21 小时前
Kubernetes-Pod
linux·运维·云原生·容器·kubernetes·云计算
赵鑫亿1 天前
ClawPanel v4.4.0 发布:AI 智能助手 + 模型兼容性修复 + UI 优化
人工智能·ui·docker·容器·qq·openclaw
切糕师学AI1 天前
Kubernetes 中的 Headless Service
云原生·容器·kubernetes
猫头虎1 天前
OpenClaw 常用操作命令完整速查手册:终端 CLI 操作指令详解|聊天斜杠指令详情
运维·git·容器·开源·github·aigc·ai编程