基于 Kubeadm 方式搭建 Kubernetes 单 Master 集群
大纲
- 基于二进制包方式搭建 Kubernetes 单 Master 集群
- 基于 Kubeadm 方式搭建 Kubernetes 单 Master 集群
- 基于二进制包方式搭建 Kubernetes 多 Master 高可用集群
- 基于 Kubeadm 方式搭建 Kubernetes 多 Master 高可用集群
Kubernetes 集群架构介绍
集群部署架构分类
- 无中心节点架构的系统,比如:GlusterFS
- 有中心节点架构的系统,比如:HDFS、K8s
Kubernetes 核心概念
Kubernetes 三个核心概念(Pod、Controller、Service)的介绍如下:
Pod(最小部署单元)
- Pod 是 Kubernetes 中最小的调度和运行单元。
- 本质上是一组容器的集合(通常是一个容器)。
- 容器之间共享网络(IP、端口)和存储卷。
- Pod 的生命周期可以是短暂的,比如用于运行临时任务或被控制器自动重建。
Controller(控制器)
- 用于管理和自动化 Pod 的部署与副本数量。
- 支持无状态应用部署(如 Deployment)。
- 支持有状态应用部署(如 StatefulSet)。
- 可实现以下功能:
- 保证指定数量的 Pod 实例持续运行。
- 在多个节点上部署同一类 Pod(如 DaemonSet)。
- 支持一次性任务(Job)和定时任务(CronJob)。
Service(服务)
- 负责定义一组 Pod 的访问规则。
- 提供统一的访问入口(Cluster IP、NodePort、LoadBalancer 等),实现服务发现与负载均衡。
- 解决 Pod 动态 IP 和短生命周期带来的访问不稳定问题。
这三个核心概念的关系:
- Pod 是具体运行的实例。
- Controller 管理 Pod 的创建、副本和调度。
- Service 让外部或内部服务可以稳定地访问 Pod。
Kubernetes 集群架构概览

Kubernetes 集群架构组件

Master(主控节点):Kubernetes 集群控制节点,负责对集群进行调度管理,接受集群外的用户去集群操作请求。Master 由 API Server、Scheduler、Controller Manager、Etcd 存储系统组成- Scheduler:节点调度,选择 Node 节点来应用部署
- API Server:集群统一入口,以 RESTful 接口将数据交给 Etcd 进行存储
- Controller Manager:处理集群中的常规后台任务,一个资源对应一个控制器
- Etcd 存储系统:用于存储集群相关的数据
Node(工作节点):Kubernetes 集群工作节点,负责运行用户业务应用容器,Node 由 Kubelet、Kube-Proxy 和 Container Runtime 组成- Kubelet:负责 Pod 对应的容器的创建、启停管理,与 Master 节点协作,实现集群管理的基本功能
- Kube-Proxy:提供 Kubernetes 的通信与负载均衡功能的重要组件
Kubernetes 依赖容器运行时(Container Runtime)来管理和运行容器。
- 历史上,Kubernetes 主要使用 Docker 作为容器运行时。Kubernetes 通过内置的
dockershim组件与 Docker 实现兼容。 - 从 Kubernetes
1.20版本开始,官方宣布弃用内置的dockershim组件,逐步移除对 Docker 作为直接容器运行时的支持。 - 现代 Kubernetes 推荐使用符合 Container Runtime Interface (CRI) 标准的容器运行时,主要有:
- containerd:由 Docker 社区捐赠的轻量级容器运行时,稳定且高效,广泛使用。
- CRI-O:专门为 Kubernetes 设计的容器运行时,注重轻量和安全。
Etcd 是什么
- 在分布式系统中,Etcd 是一个高可用、强一致性的分布式键值存储系统,在 Kubernetes 等系统中扮演着核心元数据存储和协调中心的角色。
- Etcd 属于更底层的基础组件,使用 Raft 算法实现强一致性(满足 CAP 中的 C 和 P),提供了一致性的 KV 存储、watch、lease、事务等机制。
Kubernetes 集群搭建说明
集群搭建要求
搭建 Kubernetes 集群需要满足以下几个条件:
- 多台机器或虚拟机,建议操作系统 CentOS 7(64 位)
- 集群中所有机器之间的网络可以互通
- 系统内可以访问外网,需要拉取镜像
- 系统禁用 Swap 分区(必须)
- Master 节点的硬件配置要求
- 当 Master 节点只运行运行控制平面组件(如 API Server、Controller Manager 和 Scheduler)
- 2GB 或更多 RAM,2 个 CPU 或更多 CPU,硬盘 20GB 或更多
- 当 Master 节点运行控制平面组件,且承载用户 Pod 的调度和运行任务
- 6GB 或更多 RAM,6 个 CPU 或更多 CPU,硬盘 60GB 或更多
- 当 Master 节点只运行运行控制平面组件(如 API Server、Controller Manager 和 Scheduler)
- Node 节点的硬件配置要求
- 4GB 或更多 RAM,4 个 CPU 或更多 CPU,硬盘 40GB 或更多
集群搭建类型
Kubernetes 集群搭建类型分为单 Master 集群和多 Master 集群两种(如下图所示),为了提高集群的可用性,生产环境一般采用多 Master 集群方案。

搭建单 Master 集群
术语说明
为了方便描述,本文使用 Node 节点 来替代 Kubernetes 的 Worker Node,使用 Master 节点 来替代 Master Node。
搭建目标
本节将基于 Kubeadm 方式搭建单 Master 的 Kubernetes 集群,核心目标如下
- (1) 在所有节点上分别安装 Docker、Kubeadm、Kubectl、Kubelet
- (2) 初始化 Kubernetes 的 Master 节点
- (3) 部署 CNI 网络插件(Flannel)
- (4) 将 Node 节点加入到 Kubernetes 集群中
- (5) 部署 Dashboard 可视化插件,可视化监控 Kubernetes 资源
版本说明
| 软件 | 版本 | 安装方式 |
|---|---|---|
| CentOS | 7.9 | 多个独立虚拟机 |
| Docker | 18.06.1 | YUM |
| Kubelet | 1.18.0 | YUM |
| Kubectl | 1.18.0 | YUM |
| Kubeadm | 1.18.0 | YUM |
| Dashboard | 2.0.3 | Kubernetes |
服务器规划

| Host 名称 | 角色 | IP | CPU 核数 | 内存 | 磁盘 |
|---|---|---|---|---|---|
| k8s-master | master | 192.168.31.61 | >= 2C | >=2G | >=20G |
| k8s-node1 | node(worker) | 192.168.31.62 | >= 4C | >=4G | >=40G |
| k8s-node2 | node(worker) | 192.168.31.63 | >= 4C | >=4G | >=40G |
| k8s-node3 | node(worker) | 192.168.31.64 | >= 4C | >=4G | >=40G |
操作系统初始化
t 特别注意
- 以下系统初始化操作都必须在所有节点(包括 Master 和 Node)上都执行一次,重点是安装 Docker、Kubeadm、Kubectl、Kubelet。
- 这里要求 Kubelet、Kubeadm、Kubectl 的版本与 Docker 的版本互相匹配(兼容),不建议安装最新版本的 Docker,因为 Kubernetes 对最新版的 Docker 兼容不够及时,容易导致使用 Kubeadm 方式搭建 Kubernetes 集群失败。
关闭防火墙
1 | # 临时关闭 |
关闭 selinux
1 | # 临时关闭 |
关闭 swap 分区
1 | # 临时关闭 |
系统时间同步(强烈建议使用 chrony 而不是 ntpdate)
1 | # 卸载ntpdate服务 |
设置主机名(比如 k8s-master、k8s-node1、k8s-node2、k8s-node3)
1 | # hostnamectl set-hostname <hostname> |
添加 hosts 配置信息
1 | # 添加hosts信息 |
将桥接的 IPv4 流量传递到 iptables 的链
1 | # 创建系统配置文件,并添加路由规则 |
安装特定版本的 Docker,这是由于 Kubernetes 默认的 CRI(容器运行时)为 Docker
1 | # 添加YUM源 |
安装特定版本的 Kubeadm、Kubectl、Kubelet
1 | # 添加YUm源 |
Kubelet、Kubeadm、Kubectl 的作用
| 组件 | 作用 | 使用场景 |
|---|---|---|
| Kubelet | 每个 Node 上的核心组件,负责管理 Pod 生命周期,与 API Server 通信,执行容器操作 | 每个 Node 上都必须运行 Kubelet,确保容器按 PodSpec 正确运行 |
| Kubectl | Kubernetes 的命令行客户端工具,用于与 API Server 通信,管理资源 | 查询资源(kubectl get)、创建资源(kubectl apply)、调试排查(kubectl logs) |
| Kubeadm | 用于快速部署和管理 Kubernetes 集群的工具 | 初始化主节点(kubeadm init)、加入工作节点(kubeadm join)、升级集群等 |
初始化 Master 节点
在 Master 节点上,通过 Kubeadm 初始化 Master 节点,命令行参数 --service-cidr 与 --pod-network-cidr 一般都不需要更改,其他参数请根据自己的实际情况进行修改,详细参数说明如下,点击查看详细的初始化日志信息
--apiserver-advertise-address:Master 节点的 IP 地址(需要自行更改),还可以指定为 Haproxy + Keepalived 的 VIP--kubernetes-version:Kubernetes 的版本号,必须与上面 Kubelet 的版本号一致--image-repository:由于默认拉取镜像的地址k8s.gcr.io在国内无法访问,所以需要指定阿里云镜像仓库地址--pod-network-cidr:指定 Pod Network 的地址范围,由于 Kubernetes 支持多种网络方案,而且不同网络方案对参数有各自要求,设置为10.244.0.0/16表示使用 Flannel 网络方案
1 | # 初始化Master节点 |
在 Master 节点配置 Kubectl 工具
1 | # 创建目录 |
Master 节点安装 CNI 网络插件
CNI 网络插件的安装细节
特别注意,网上有部分资料是在将 Node 节点加入到 Kubernetes 集群之后,才开始安装 CNI 网络插件的,本文给出的教程刚好相反。由于 kubectl apply 这个命令会创建一个 DaemonSet 类型的资源,而 DaemonSet 的特性是:会在 Kubernetes 集群中所有「可调度」的 Node 节点上运行一个 Pod 副本。所以,即使在安装 CNI 网络插件时,Node 节点还没加入 Kubernetes 集群,一旦执行 kubeadm join 操作,新加入的 Node 节点会被 Kubernetes 集群感知到,Kubelet 连接成功后,DaemonSet 就会在新 Node 节点上自动调度一个 Pod(比如 Flannel Pod)。换言之,在 Master 节点上,通过 kubectl apply 命令安装 CNI 网络插件后,默认会将 CNI 网络插件部署到整个 Kubernetes 集群的所有节点(包括 Master 和 Node),无需手动在每个节点上重复执行 kubectl apply 命令来安装 CNI 网络插件。
为什么必须安装 CNI 网络插件
- Kubernetes 本身不包含网络实现,但它要求集群中的所有 Pod 能够彼此通信(无论位于哪个节点),这是 Kubernetes 网络模型的基本要求。
- 通过 Kubeadm 搭建 Kubernetes 集群时,使用
kubeadm init初始化 Master 节点后,默认只有控制平面功能,没有网络功能。 - 当没有安装 CNI 网络插件时,Pod 会卡在
ContainerCreating状态,因为找不到网络(CNI)配置。 - 当安装 CNI 网络插件(如 Flannel)后,多个节点之间的 Pod 才能通信和正常运行。
在 Master 节点查看所有节点的运行状态,此时 Master 节点处于 NotReady(未就绪)状态,这是因为集群中尚未安装 Flannel 网络插件,安装完网络插件后状态会自动变为 Ready
1 | # 查看所有节点的运行状态 |
在 Master 节点安装 Flannel 网络插件,若 kubectl apply -f 命令执行后提示网络连接失败,可留意文章后面给出的解决方案
1 | # 安装Flannel网络插件 |
在 Master 节点查看 Pod 的运行状态,当所有 Pod 的运行状态都变更为 Running(可能需要等待十几分钟甚至几十分钟),则说明所有 Pod 都正常运行
1 | # 查询Pod的运行状态 |
特别注意
Flannel 网络插件安装完成后,需要耐心等待一段较长的时间(可能需要等待十几分钟甚至几十分钟),直到使用 kubectl get pods -n kube-system 命令查看到的所有 Pod 的运行状态都变更为 Running 为止,也就是说 Pod 的状态最终不能为 Pending,否则说明 Pod 的运行存在一定的问题,需要进一步定位错误原因。
在 Master 节点再次查看所有节点的运行状态,当 Master 节点的运行状态变更为 Ready 状态,就可以开始将 Node 节点加入集群了
1 | # 查看所有节点的运行状态 |
将 Node 节点加入到 Kubernetes 集群
在各个 Node 节点里分别执行以下命令(请自行更改,切忌直接复制执行),向 Kubernetes 集群添加新节点,该命令是上面 kubeadm init 命令执行完成后在终端记录下来的
1 | # 添加Node节点到集群 |
在 Master 节点执行以下命令,查看集群中所有 Node 节点的运行状态,当它们的运行状态都变更为 Ready 时(需要等待一段较长的时间),则表示所有 Node 节点都成功加入了集群
1 | # 查看所有节点的运行状态 |
特别注意
这里通过 kubeadm join 命令将各个 Node 节点加入集群后,需要等待一段较长的时间(可能十几分钟甚至几十分钟),才能看到集群中所有 Node 节点的运行状态从 NotReady 变更为 Ready。
测试 Kubernetes 集群是否正常运行
在 Master 节点执行以下命令,查看集群中所有节点的运行状态,当它们的运行状态都变更为 Ready 时,则表示 Kubernetes 集群已经成功搭建起来了
1 | # 查看所有节点的运行状态 |
在 Master 节点执行以下命令,目的是在 Kubernetes 集群里创建一个 Nginx 的 Deployment,验证 Kubernetes 集群是否正常运行
1 | # 创建Nginx |
通过浏览器访问 http://192.168.31.62:32517,请自行更改 IP 和端口;其中 IP 可以是任意节点的 IP 地址,端口由 kubectl get svc 命令可得知。若 Ngninx 容器在 Kubernetes 集群中创建并启动成功,则浏览器可以正常访问 Nginx 的首页(如下图所示),如下图所示:

若希望删除刚在 Kubernetes 集群创建的 Nginx 容器,可以在 Master 节点执行以下命令:
1 | # 删除Service |
部署 Dashboard 可视化插件
在 Kubernetes 集群部署 Dashboard 可视化插件的过程中,以下所有操作都是直接在 Master 节点里执行,后续不再累述。
Dashboard 简介
在 Kubernetes 社区中,有一个很受欢迎的 Dashboard 项目,它可以给用户提供一个可视化的 Web 界面来查看当前集群的各种信息。用户可以用 Kubernetes Dashboard 部署容器化的应用、监控应用的运行状态、执行故障排查任务以及管理 Kubernetes 各种资源。
特别注意
Dashboard 的版本必须与 Kubernetes 版本相匹配(兼容),否则 Dashboard 可能无法正常运行。
Dashboard 部署
通过 YAML 文件直接部署 Dashboard,这里的 Kubernetes 1.8 版本对应的 Dashboard 版本为 v2.0.3,两者的版本号必须匹配
1 | # 部署Dashboard |
查看 Dashboard 的运行状态,可以看到运行了 2 个 Pod 及 2 个 Service
1 | # 查看Pod的运行状态 |
特别注意
- 使用
kubectl -n kubernetes-dashboard get pods命令查看 Dashboard 的运行状态时,必须确保 Pod 的状态为Running,且RESTARTS = 0,否则 Dashboard 可能无法正常运行。当 Dashboard 无法正常运行,可以执行以下两个命令重启 Dashboard: - (1) 重启 Dashboard Metrics Scraper:
kubectl -n kubernetes-dashboard rollout restart deployment dashboard-metrics-scraper - (2) 重启 Dashboard:
kubectl -n kubernetes-dashboard rollout restart deployment kubernetes-dashboard
Dashboard 暴露服务
这里作为演示,使用 NodePort 方式将 Dashboard 的服务暴露在集群外,指定使用 30443 端口(可自定义)
1 | # 暴露Service |
或者下载 YAML 文件,手动更改 Service 部分的端口,并以 NodePort 方式进行部署
1 | # 下载YAML文件 |
Dashboard 认证方式登录
Dashboard 支持 Kubeconfig 和 Token 两种认证方式,这里选择 Token 认证方式登录,首先执行以下操作创建登录用户
1 | # 创建YAML配置文件,复制下面的配置内容到文件中 |
YAML 配置文件 dashboard-adminuser.yaml 的完整内容如下,指定了一个名称为 admin-user 的服务账号,并放在 kubernetes-dashboard 命名空间下,同时将 cluster-admin 角色绑定到 admin-user 账户,这样 admin-user 账户就有了管理员的权限。默认情况下,Kubeadm 创建集群时已经创建了 cluster-admin 角色,只需直接绑定即可
1 |
|
查看 admin-user 账户的 Token
1 | # 查看Token |
通过火狐浏览器访问 Dashboard 的登录界面,URL 是 https://<any_node_ip>:30443,其中 any_node_ip 可以是任意一个集群节点的 IP 地址。由于谷歌浏览器会强制使用 HTTPS 协议,这将导致无法访问 Dashboard 的登录页面,因此建议使用火狐浏览器进行访问

将获取到的 Token 复制到登录界面的 Token 输入框中,这样就可以正常登录 Dashboard

Dashboard 配置登录超时
提示
Dashboard 默认登录超时时间是 15min,可以为 Dashboard 容器增加 --token-ttl 参数来自定义登录超时时间。
下载并打开对应的 YAML 配置文件
1 | # 下载YAML文件 |
然后找到 --auto-generate-certificates 配置项(如下所示),在它后面添加 --token-ttl=43200 配置项
1 | spec: |
最后更新配置信息
1 | # 更新配置信息 |
单 Master 集群搭建问题
集群搭建问题一
1 | [ERROR NumCPU]: the number of available CPUs 1 is less than the required 2 |
执行 kubeadm init 命令时,提示 CPU 核心数少于 2,可以添加命令参数 --ignore-preflight-errors=NumCPU 忽略警告
集群搭建问题二
1 | [ERROR Swap]: running with swap on is not supported. Please disable swap |
执行 kubeadm init 命令时,提示启用了 swap 分区,可以添加命令参数 --ignore-preflight-errors 'Swap' 忽略错误,强烈建议禁用 Swap 分区,而不是忽略该错误信息
集群搭建问题三
1 | [WARNING SystemVerification]: this Docker version is not on the list of validated versions: 19.03.1. Latest validated version: 18.09 |
执行 kubeadm init 命令时,提示 Docker 的版本过高,可能与 Kubernetes 的版本不兼容
集群搭建问题四
1 | The connection to the server raw.githubusercontent.com was refused - did you specify the right host or port? |
执行 kubectl apply -f https://raw.githubusercontent.com/xxx 命令时,提示网络链接失败,这是国内无法访问 raw.githubusercontent.com 导致,临时解决方法如下:
- 在
https://www.ipaddress.com网站上查询raw.githubusercontent.com域名的真实 IP 地址 - 更改系统的
/etc/hosts配置文件,添加一行内容185.199.108.133 raw.githubusercontent.com,将185.199.108.133替换为查询到真实的 IP 地址 - 重新执行
kubectl apply -f https://raw.githubusercontent.com/xxx命令即可
