Kubernetes 核心概念解析与集群部署实战(基于 Docker+Flannel)
Kubernetes 核心概念解析与集群部署实战(基于 Docker+Flannel)
在云原生技术飞速发展的今天,Kubernetes(简称 K8s)已成为容器编排领域的事实标准。无论是企业级应用的高可用部署,还是微服务架构的弹性伸缩,K8s 都能提供稳定、高效的解决方案。本文将从传统部署的痛点出发,带你深入理解 K8s 的核心设计与功能,并手把手教你搭建一套基于 Docker 和 Flannel 的 K8s 集群。
一、从部署演进看 K8s 的价值
在学习 K8s 之前,我们先回顾部署方式的演进历程,理解 K8s 解决的核心问题。
1.1 传统部署:物理机直接部署
互联网早期,应用直接部署在物理机上,这种方式存在明显缺陷:
- 资源无边界:无法为应用定义资源使用上限,导致资源分配不均(如一个应用占用过多 CPU,导致其他应用卡顿)。
- 应用相互影响:多个应用共享物理机资源,一个应用崩溃可能导致整台机器的其他应用受牵连。
- 扩展困难:若需提升应用性能,只能更换更强的物理机(垂直扩展),无法快速横向增加节点。
1.2 容器化部署:便利与挑战并存
Docker 等容器技术的出现,实现了 “一次打包,到处运行”,解决了环境一致性问题,但也带来了新的挑战:
- 故障自愈:若一个容器意外停机,如何自动启动新容器替补?
- 弹性伸缩:并发量突增时,如何快速增加容器数量;并发下降时,如何自动缩减容器?
- 负载均衡:多个容器提供同一服务时,如何将请求均匀分配到各个容器?
为解决这些 “容器编排” 问题,Swarm、Mesos、K8s 等工具应运而生,其中 K8s 因功能全面、社区活跃,成为主流选择。
1.3 K8s 核心优势:为何选择它?
K8s 是 Google 基于 Borg 系统(内部容器编排工具)的经验研发的开源项目,核心优势体现在以下 3 个方面:
- 负载均衡:自动为多容器服务分配请求,无需手动配置反向代理。
- 版本回退:若新发布的应用版本存在 bug,可一键回退到上一个稳定版本,降低故障影响。
- 存储编排:根据容器需求自动创建、挂载存储卷(如本地存储、云存储),无需手动管理存储资源。
二、K8s 核心概念与架构
要熟练使用 K8s,必须先理解其核心组件和抽象概念,这是后续部署和运维的基础。
2.1 K8s 集群架构:Master 与 Node 节点
K8s 集群由控制节点(Master) 和工作节点(Node) 组成,两者分工明确:
-
Master 节点
:集群的 “大脑”,负责集群管理、资源调度、决策等核心功能,包含 4 个关键组件:
- Etcd:分布式键值数据库,存储集群所有资源信息(如 Pod、Service 配置),是集群的 “数据中心”。
- API Server:K8s 的 “入口”,所有操作(如创建 Pod、查看节点状态)都通过 API Server 执行,同时负责身份认证和权限控制。
- Scheduler:调度器,根据节点资源(CPU、内存)和应用需求,决定将 Pod 部署到哪个 Node 节点。
- Controller Manager:控制器集合,负责维护集群状态(如 Pod 故障重启、副本数量保证)。
-
Node 节点
:集群的 “手脚”,负责运行容器,包含 3 个关键组件:
- Kubelet:维护容器生命周期,确保容器按照 Pod 配置运行,同时负责挂载存储卷和网络。
- Kube-proxy:网络代理,实现 Pod 之间的通信和外部访问(如 Service 的负载均衡)。
- Container Runtime:容器运行时,负责镜像管理和容器启动 / 停止,本文使用 Docker 作为运行时。
2.2 K8s 核心抽象:Label 与 Namespace
K8s 通过抽象概念简化容器管理,最常用的两个抽象是Label和Namespace:
- Label(标签):键值对形式的 “标签”,用于对 Pod、Service 等资源进行分类。例如,给所有 nginxPod 打
app: nginx
标签,后续可通过标签筛选资源(如kubectl get pod -l app=nginx
)。 - Namespace(命名空间):用于实现资源隔离,将集群划分为多个 “虚拟空间”。例如,
default
命名空间用于默认资源,kube-system
用于 K8s 系统组件,可避免不同团队的资源冲突。
三、K8s 集群部署实战(Docker+Flannel)
本节将以 “1 个 Master 节点 + 2 个 Node 节点” 为例,详细讲解 K8s 集群的搭建过程,使用 Docker 作为容器运行时,Flannel 作为网络插件(解决 Pod 跨节点通信问题)。
3.1 环境准备
3.1.1 服务器配置
节点角色 | 主机名 | IP 地址 | 配置要求 |
---|---|---|---|
Master | k8s-master.timinglee.org | 172.25.254.100 | 2 核 4G 以上(避免资源不足导致组件启动失败) |
Node1 | k8s-node1.timinglee.org | 172.25.254.10 | 2 核 2G 以上 |
Node2 | k8s-node2.timinglee.org | 172.25.254.20 | 2 核 2G 以上 |
3.1.2 基础环境配置(所有节点执行)
-
关闭防火墙和 SELinux:避免网络规则拦截 K8s 组件通信
systemctl stop firewalld && systemctl disable firewalld setenforce 0 && sed -i 's/^SELINUX=enforcing$/SELINUX=disabled/' /etc/selinux/config
-
禁用 Swap 分区:K8s 要求禁用 Swap,否则会影响资源调度
swapoff -a && systemctl mask swap.target # 永久禁用:注释/etc/fstab中的Swap行 sed -i '/swap/s/^/#/' /etc/fstab
-
配置主机名和本地解析:确保节点间能通过主机名通信
# Master节点设置主机名 hostnamectl set-hostname k8s-master.timinglee.org # Node1节点设置主机名 hostnamectl set-hostname k8s-node1.timinglee.org # Node2节点设置主机名 hostnamectl set-hostname k8s-node2.timinglee.org# 所有节点添加本地解析(编辑/etc/hosts) cat >> /etc/hosts << EOF 172.25.254.100 k8s-master.timinglee.org 172.25.254.10 k8s-node1.timinglee.org 172.25.254.20 k8s-node2.timinglee.org EOF
-
配置内核参数:开启 IP 转发和网桥过滤(K8s 网络依赖)
cat >> /etc/sysctl.d/k8s.conf << EOF net.bridge.bridge-nf-call-iptables = 1 net.bridge.bridge-nf-call-ip6tables = 1 net.ipv4.ip_forward = 1 EOF # 生效内核参数 sysctl --system
3.2 安装 Docker(所有节点执行)
K8s 通过 CRI(容器运行时接口)与 Docker 交互,需先安装 Docker 并配置镜像加速。
-
添加 Docker YUM 源:使用阿里云镜像源,提升下载速度
dnf config-manager --add-repo https://mirrors.aliyun.com/docker-ce/linux/rhel/9/x86_64/stable/
-
安装 Docker:
dnf install docker-ce -y
-
配置 Docker 镜像加速与 CRI 适配:
# 创建daemon.json文件 mkdir -p /etc/docker cat >> /etc/docker/daemon.json << EOF {"registry-mirrors": ["https://reg.westos.org/", "https://mirror.aliyuncs.com"],"exec-opts": ["native.cgroupdriver=systemd"] # 与K8s的cgroup驱动一致 } EOF
-
启动 Docker 并设置开机自启:
systemctl enable --now docker # 验证Docker状态 docker info | grep "Registry Mirrors"
3.3 安装 K8s 组件(所有节点执行)
K8s 核心组件包括 kubelet(节点代理)、kubeadm(集群初始化工具)、kubectl(命令行工具)。
-
添加 K8s YUM 源:使用阿里云 K8s 镜像源
cat >> /etc/yum.repos.d/k8s.repo << EOF [k8s] name=k8s baseurl=https://mirrors.aliyun.com/kubernetes-new/core/stable/v1.30/rpm/ gpgcheck=0 EOF
-
安装指定版本的 K8s 组件:本文使用 1.30.0 版本(稳定版)
dnf install kubelet-1.30.0 kubeadm-1.30.0 kubectl-1.30.0 -y
-
设置 kubelet 开机自启:
systemctl enable kubelet
3.4 安装 cri-dockerd(所有节点执行)
由于 Docker 默认不支持 CRI,需安装 cri-dockerd 作为中间层,实现 K8s 与 Docker 的 CRI 交互。
-
安装依赖包:
dnf install libcgroup-0.41-19.el8.x86_64.rpm -y
-
配置 cri-dockerd 服务:
cat >> /lib/systemd/system/cri-docker.service << EOF [Unit] Description=CRI Docker Service After=network-online.target firewalld.service docker.service Wants=network-online.target[Service] Type=notify ExecStart=/usr/bin/cri-dockerd --network-plugin=cni --pod-infra-container-image=reg.timinglee.org/k8s/pause:3.9 ExecReload=/bin/kill -s HUP $MAINPID Restart=always RestartSec=5 TimeoutSec=0[Install] WantedBy=multi-user.target EOF
-
启动 cri-dockerd 并设置开机自启:
systemctl daemon-reload systemctl enable --now cri-docker # 验证cri-dockerd状态 ll /var/run/cri-dockerd.sock # 应显示unix套接字文件
3.5 初始化 Master 节点(仅 Master 执行)
使用 kubeadm 初始化 Master 节点,生成集群配置,并将 kubectl 配置到当前用户。
-
初始化 Master:指定 CRI 套接字、Pod 网段(Flannel 默认使用 10.244.0.0/16)
kubeadm init \--pod-network-cidr=10.244.0.0/16 \--cri-socket=unix:///var/run/cri-dockerd.sock \--image-repository=reg.timinglee.org/k8s \--kubernetes-version=v1.30.0
-
配置 kubectl 权限:让当前用户(root)能使用 kubectl
echo "export KUBECONFIG=/etc/kubernetes/admin.conf" >> ~/.bash_profile source ~/.bash_profile
-
验证 Master 节点状态:此时节点为 NotReady(未安装网络插件)
kubectl get node # 输出应类似: # NAME STATUS ROLES AGE VERSION # k8s-master.timinglee.org NotReady control-plane 5m v1.30.0
3.6 安装 Flannel 网络插件(仅 Master 执行)
Flannel 是 K8s 常用的网络插件,负责实现 Pod 跨节点通信,安装后 Master 节点会变为 Ready 状态。
-
下载 Flannel 配置文件:
wget https://github.com/flannel-io/flannel/releases/latest/download/kube-flannel.yml
-
修改配置文件:替换镜像源为私有仓库(避免拉取失败)
# 替换flannel镜像地址 sed -i 's#flannel/flannel:v0.25.5#reg.timinglee.org/flannel/flannel:v0.25.5#' kube-flannel.yml sed -i 's#flannel/flannel-cni-plugin:v1.5.1-flannel1#reg.timinglee.org/flannel/flannel-cni-plugin:v1.5.1-flannel1#' kube-flannel.yml
-
部署 Flannel:
kubectl apply -f kube-flannel.yml # 验证Flannel Pod状态(确保Running) kubectl get pod -n kube-system | grep flannel
-
再次验证 Master 节点状态:此时应为 Ready
kubectl get node
3.7 Node 节点加入集群(仅 Node 执行)
Master 初始化完成后,会输出 Node 节点的加入命令(若忘记,可在 Master 执行kubeadm token create --print-join-command
重新生成)。
-
执行加入命令:替换
<token>
和
<ca-cert-hash>
为实际值
kubeadm join 172.25.254.100:6443 \--token <token> \--discovery-token-ca-cert-hash sha256:<ca-cert-hash> \--cri-socket=unix:///var/run/cri-dockerd.sock
-
验证集群节点状态(Master 执行):确保所有 Node 节点为 Ready
kubectl get node # 输出应类似: # NAME STATUS ROLES AGE VERSION # k8s-master.timinglee.org Ready control-plane 30m v1.30.0 # k8s-node1.timinglee.org Ready <none> 5m v1.30.0 # k8s-node2.timinglee.org Ready <none> 5m v1.30.0
3.8 集群功能验证
集群搭建完成后,通过部署一个 Nginx Pod 验证集群是否正常工作。
-
创建 Nginx Pod:
kubectl run test --image=nginx
-
查看 Pod 状态:确保 Pod 为 Running 状态
kubectl get pod # 输出应类似: # NAME READY STATUS RESTARTS AGE # test 1/1 Running 0 2m
-
访问 Nginx Pod:通过 Pod IP 访问 Nginx 服务
# 获取Pod IP POD_IP=$(kubectl get pod test -o jsonpath='{.status.podIP}') # 访问Nginx curl $POD_IP # 若返回Nginx默认页面,说明集群网络和容器运行正常
四、总结
本文从部署演进的角度引入 K8s,详细讲解了 K8s 的核心概念(Master/Node 架构、Label/Namespace),并通过实战完成了基于 Docker+Flannel 的 K8s 1.30.0 集群搭建。后续可基于该集群探索更多 K8s 功能,如 Deployment(无状态应用部署)、Service(服务暴露)、ConfigMap(配置管理)等。
若在部署过程中遇到问题,可通过以下方式排查:
- 查看组件日志:
journalctl -u kubelet -f
(kubelet 日志)、kubectl logs <pod-name> -n kube-system
(系统组件日志)。 - 检查网络连通性:确保节点间 6443(API Server)、2379(Etcd)、8472(Flannel)端口通畅。