Kubernetes集群部署实战:kubeadm从初始化到节点就绪全流程
简介这是一份面向Kubernetes初学者和运维工程师的部署参考手册覆盖单机部署、集群部署、kubeadm、kops、Kubespray、Azure、Windows、LinuxKit、kubeasz等多种落地方式并针对国内环境给出镜像加速和排障思路。资源为单个PDF文档大小3.91MB结构紧凑查阅方便。目前已有178人学习下载。内容不仅说明kubectl的安装方法还整理Etcd、Docker、Go、CNI、CSI等依赖组件的版本对照表并详细展开Kubernetes-The-Hard-Way手动部署高可用集群的完整流程包括创建计算资源、配置证书、生成配置和密钥、部署Etcd群集、控制节点、计算节点以及配置Kubectl、网络路由、DNS和烟雾测试等关键环节同时涵盖Dashboard、监控、日志、Cluster Autoscaler等附加组件。对于想理解部署原理、快速搭建生产或测试集群的读者这份指南能提供从环境准备到验证落地的完整参考减少踩坑成本。1. 部署前的整体思路先想清楚再动手Kubernetes这个词这两年几乎成了后端和运维岗位的标配技能但真到了要自己动手部署一套集群的时候很多人才发现网上教程虽然多能一条龙跑通的却没几个。我最早折腾K8s时也踩了不少坑后来把部署流程固定成一套可复用的操作模板从裸机到集群可用基本能稳定控制在一个小时内。这篇内容就是把我平时部署Kubernetes的完整流程、每个关键步骤背后的原因、以及那些容易让人卡壳的坑整理出来给正准备上手或者已经踩坑的人一个参考。先说清楚这套部署方案解决什么问题。Kubernetes部署大致分三种云厂商托管版、一键工具版、手动部署版。托管版省心但没法真正理解底层原理一键工具像minikube、k3s适合本地开发和快速体验但和真实的生产环境相差太远手动部署能让你把每个组件的作用、每个配置项的含义都摸清楚也是面试时最容易被人追问的部分。这里说的手动部署用的是kubeadm它是目前社区最主流、也最接近生产环境的部署方式既能用于学习也能用于正式环境。部署之前你还要对Kubernetes集群有个整体认知。一个标准的K8s集群至少包含两类节点Master节点和控制面负责整个集群的调度、状态维护和API受理Worker节点实际跑业务容器的机器。控制面里跑的组件主要是API Server、Controller Manager、Scheduler和etcdWorker节点上则运行着kubelet、kube-proxy和容器运行时。很多新手一开始就被这一堆组件名吓住其实不用背你先记住一个核心逻辑所有操作都通过API Server下发etcd负责存状态Scheduler决定Pod放哪台机器kubelet是每台机器上的“执行者”。后面的所有部署步骤都是为了让这些组件正确协作。我还要强调一点不建议一上来就在生产服务器上折腾。我自己第一次部署是在虚拟机里做的一台4核8G的机器就能搭出单节点集群先把流程跑通、把常见报错都见一遍再去碰真实环境会从容很多。部署前最好把所有机器的时间同步做好不然证书和通信都会出问题这个细节后面会反复提到。2. 基础环境准备这些细节决定成败2.1 节点规划与系统要求部署Kubernetes对硬件的要求并不夸张但如果配置太低体验会非常痛苦。我建议的最小配置是Master节点至少2核4G内存Worker节点至少2核2G磁盘剩余空间不少于20G。生产环境一般建议Master节点4核8G起步etcd所在节点对磁盘IO有一定要求SSD是必须的。系统方面Ubuntu 22.04 LTS和CentOS 7.9是两类比较典型的选择。这篇操作以Ubuntu 22.04为例CentOS的差异主要在软件包管理器上后面需要的地方我会单独提示。无论用哪个系统务必提前确认主机名不重复、且每个节点能通过主机名互相解析。你可以用/etc/hosts写入静态解析也可以提前配好内部DNS这一步不做后面kubeadm init和节点加入大概率会报证书或通信错误。2.2 主机名解析与交换分区处理先设置主机名比如Master节点叫k8s-masterWorker节点叫k8s-node1。Ubuntu下执行hostnamectl set-hostname k8s-master然后在所有节点的/etc/hosts里加上192.168.1.10 k8s-master 192.168.1.11 k8s-node1为什么要禁用swapKubernetes的kubelet默认要求交换分区关闭因为如果允许swapPod的内存配额管理会失真可能出现明明设置了内存上限、实际却把数据换到磁盘里的情况。禁用swap执行一次swapoff -a sed -i / swap / s/^/#/ /etc/fstab注意swapoff -a只对当前会话生效修改fstab才能保证重启后依然关闭。很多教程会漏掉fstab这步导致重启后kubelet起不来这是新手最容易踩的坑之一。2.3 加载内核模块与网络参数Kubernetes的网络离不开iptables和流量转发提前加载好内核模块可以省掉后面很多麻烦。先创建配置文件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 --systemnet.ipv4.ip_forward必须为1它决定了节点能不能作为路由器转发Pod网段的流量。net.bridge.bridge-nf-call-iptables为1是让iptables规则对桥接流量也生效这是K8s Service和NetworkPolicy正常工作的重要前提。设置完可以用sysctl net.ipv4.ip_forward检查一下。3. 核心组件部署实操从初始化到节点就绪3.1 容器运行时为什么选择containerdKubernetes从1.24版本开始彻底移除了对Docker作为运行时即dockershim的支持所以现在的部署方案基本都是用containerd。containerd本身是Docker生态里拆出来的容器运行时组件性能更轻、资源占用更小也是CNCF的毕业项目。安装containerd有两种常见方式用系统的apt源直接装或者用Docker官方源装。我这里用aptsudo apt-get update sudo apt-get install -y containerd装完需要修改配置关键就两处。第一是将SystemdCgroup设为true因为Kubernetes默认使用cgroupfs时在特定系统上会出现资源管理不一致的问题改成systemd能与服务管理器协同得更好sudo mkdir -p /etc/containerd containerd config default | sudo tee /etc/containerd/config.toml sudo sed -i s/SystemdCgroup false/SystemdCgroup true/g /etc/containerd/config.toml第二是容器镜像的仓库地址。国内网络环境下直接从默认仓库拉取pause等基础镜像会非常慢甚至超时所以一般会把sandbox_image替换成镜像加速地址这个看实际情况调整。改完配置后重启containerdsudo systemctl restart containerd sudo systemctl enable containerd3.2 安装kubeadm、kubelet、kubectl这三个组件最好不要用系统自带的旧版本否则版本不一致会出很多怪问题。安装时先把Kubernetes的apt仓库配好sudo apt-get update sudo apt-get install -y apt-transport-https ca-certificates curl gpg curl -fsSL https://pkgs.k8s.io/core:/stable:/v1.29/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.29/deb/ / | sudo tee /etc/apt/sources.list.d/kubernetes.list sudo apt-get update sudo apt-get install -y kubelet kubeadm kubectl sudo apt-mark hold kubelet kubeadm kubectl最后那行apt-mark hold很关键它防止这三个组件被意外升级。Kubernetes小版本升级会引入API变化生产环境里最忌讳的就是某个依赖被系统自动更新后整个集群状态全乱。安装完成后用kubeadm version验证一下版本。注意从Kubernetes 1.28开始kubelet默认要求给节点设置一个稳定的主机名重复的、带下划线的主机名都会导致注册失败所以前面2.2节设置主机名非常重要。3.3 初始化Master节点与网络插件选择环境准备好以后在Master节点执行初始化命令。这里网络插件的选择直接影响后面的初始化参数我先说结论学习环境用Flannel足够生产生产环境优先Calico。Flannel简单、好排查但不支持NetworkPolicyCalico功能强但组件更多、配置更复杂。如果选了Flannel初始化时需要指定Pod网段为10.244.0.0/16这个网段要和后面安装Flannel的默认配置保持一致。sudo kubeadm init \ --apiserver-advertise-address192.168.1.10 \ --pod-network-cidr10.244.0.0/16--apiserver-advertise-address要填Master节点实际IP--pod-network-cidr是分配给Pod的虚拟网段不能和物理网络冲突。初始化成功后会输出两段重要信息一段是配置kubectl的命令一段是加入集群的token命令。按提示执行mkdir -p $HOME/.kube sudo cp -i /etc/kubernetes/admin.conf $HOME/.kube/config sudo chown $(id -u):$(id -g) $HOME/.kube/configkubectl配置好以后安装网络插件。Flannel的部署文件是kubectl apply -f https://raw.githubusercontent.com/flannel-io/flannel/master/Documentation/kube-flannel.yml装完等待片刻用kubectl get pods -n kube-flannel查看状态如果全是Running说明Master节点的控制面和网络都通了。如果出现CrashLoopBackOff大概率是IP转发没开或者Pod网段和物理网段冲突回到第2.3节检查。3.4 Worker节点加入集群初始化成功后Master节点会输出一段kubeadm join命令里面带着token和证书哈希。Workder节点执行那条命令就行。如果当时没保存或token过期了可以用下面的命令重新生成kubeadm token create --print-join-command这条命令会生成新的token和完整的join命令复制到Worker节点执行。加入成功后在Master节点查看节点状态kubectl get nodes如果节点处于NotReady而不是Ready先别急着查一堆东西优先怀疑是网络插件没装或者Pod网段没通用kubectl describe node 节点名查看节点状态里的原因和事件这个命令能给出大量有效线索。4. Dashboard部署与访问配置可视化管理的最后一步4.1 部署Dashboard组件很多新手部署完集群第一反应是想看看Node信息、Pod状态但kubectl用起来毕竟不直观。Kubernetes官方提供了一个Web控制台叫Dashboard部署它能让整个集群的状态一目了然。我平时用的部署命令是kubectl apply -f https://raw.githubusercontent.com/kubernetes/dashboard/v2.7.0/aio/deploy/recommended.yaml这份yaml是官方维护的推荐版本里面包含了Deployment、Service、ServiceAccount等所有资源一条命令就能装完。装好后Dashboard默认跑在kubernetes-dashboard命名空间下可以用kubectl get pods -n kubernetes-dashboard确认所有Pod都是Running状态。4.2 Token获取与访问方式Dashboard默认不允许外部直接访问这是出于安全考虑。平时的开发和验证环境比较方便的方式是用kubectl proxy在未来Master节点上开启一个本地代理kubectl proxy然后在本机浏览器访问http://localhost:8001/api/v1/namespaces/kubernetes-dashboard/services/https:kubernetes-dashboard:/proxy/但这样访问还需要登录凭据。Dashboard支持Token登录你需要创建一个拥有管理员权限的ServiceAccount。新建一个yaml文件比如admin-user.yamlapiVersion: v1 kind: ServiceAccount metadata: name: admin-user namespace: kubernetes-dashboard --- apiVersion: rbac.authorization.k8s.io/v1 kind: ClusterRoleBinding metadata: name: admin-user roleRef: apiGroup: rbac.authorization.k8s.io kind: ClusterRole name: cluster-admin subjects: - kind: ServiceAccount name: admin-user namespace: kubernetes-dashboard然后执行kubectl create -f admin-user.yaml kubectl -n kubernetes-dashboard create token admin-user第二行命令会输出一长串token把它粘贴到Dashboard的登录页面就能进去了。安全提示cluster-admin是集群最高权限角色生产环境不建议随便创建这类ServiceAccount并把token交给无关人员。临时排查问题用完后建议直接删除这个ServiceAccount和ClusterRoleBinding。另外千万不要把Dashboard用NodePort方式直接暴露到公网除非你配置了完善的认证和TLS证书否则这是把集群的钥匙递给别人。5. 部署高频问题与排查实战我踩过的那些坑5.1 常见报错速查表为了节省大家排查时间我把部署过程中最高频的几个问题整理成表格每一条都是我在真实操作中遇过的现象直接原因解决办法kubeadm init 时卡在拉取镜像网络问题导致镜像仓库不可达配置镜像加速地址或提前kubeadm config images pull验证kubelet 无法启动状态是 activatingswap未关闭或systemd配置错误确认swapoff -a和fstab已修改systemctl daemon-reload后重启kubeletcoredns Pod 一直 Pending / CrashLoopBackOff没有安装CNI网络插件检查Flannel或Calico是否成功applyPod网段是否与init参数一致Worker节点显示NotReadyCNI插件未初始化、镜像拉取失败kubectl describe node 名字看Events再定位到具体Pod看日志加入集群时报token过期token默认24小时有效用kubeadm token create --print-join-command重新生成Dashboard登录后无数据ServiceAccount权限不足确认绑定了正确的ClusterRole比如cluster-admin5.2 排查命令与思路排查Kubernetes问题很多时候不是不会看而是看的地方不对。我自己的排查顺序一般是这样的先看节点是否就绪kubectl get nodes确认范围。再看核心组件kubectl get pods -n kube-system看控制面Pod是否正常。然后看具体Podkubectl describe pod pod名字 -n 命名空间能告诉你为什么Pending、为什么ImagePullBackOff。如果describe里看不到有效信息就看日志kubectl logs pod名字 -n 命名空间 --previous。这套流程走完80%的部署问题都能定位到根因。有一个容易被忽略的地方网络插件版本的兼容性。比如Kubernetes 1.29搭配过老版本的Calico可能出现Pod网络不通、CoreDNS反复重启。遇到这类问题先去查CNI插件的官方文档对K8s版本的兼容矩阵很多莫名其妙的网络问题都是版本不匹配引起的。5.3 证书有效期与控制面更新问题如果你打算用这套部署长期跑下去证书的事情必须提前了解。kubeadm默认签发的证书有效期是1年到期后kube-apiserver之间的通信会失败。可以用以下命令查看证书过期时间kubeadm certs check-expiration在过期前执行kubeadm certs renew all然后把新的admin.conf拷贝到本地cp /etc/kubernetes/admin.conf $HOME/.kube/config再重启相关组件让新证书生效。很多生产环境的K8s集群长时间没人管某天突然API调不通原因往往就是这个。建议把证书检查写进周期运维清单每季度看一次就够。6. 部署完之后的收尾学习路线与生产注意事项6.1 从部署到进阶接下来该练习什么集群能跑起来、Dashboard能登录只代表部署成功真正考验能力的是后面的操作。我个人建议按这个顺序练习先创建两个nginx Deployment试试kubectl scale扩容缩容然后写Service暴露服务理解ClusterIP、NodePort的区别再试试把Pod从一个节点迁移到另一个节点看看驱逐和调度过程有精力的话折腾一下ConfigMap和Secret理解配置管理的方式。这些操作做完你对Kubernetes的理解会从“会部署”上升到“会用”。很多人面试时被问Kubernetes其实就是从这些基础操作开始展开的比如Pod的调度策略、Service的负载均衡原理、Deployment的滚动更新过程。部署只是第一关真正的分水岭在于你能否描述清楚一个请求从Service到Pod再到容器的完整链路。6.2 生产环境必须要补的功课如果这套集群接下来要承接真实业务有几件事必须在业务上线前做完etcd的自动备份这是集群的“数据保险”Master节点的多副本部署单Master在生产环境里就是单点故障日志和监控体系至少要有资源监控和组件状态告警不然集群挂了可能比业务先挂还晚发现。轻量级日志方案可以试试Grafana Loki加上Promtail部署简单、资源占用低配合Grafana展示很适合中小规模集群。告警方面kube-prometheus-stack是社区最常用的全家桶第一次装会觉得组件多但装完确实能省很多操心。6.3 个人体会这套流程的价值在哪里回过头看kubeadm这套部署方式最大的价值不是“能自动装好”而是它把Kubernetes各组件的启动参数、证书关系、网络配置全部暴露给你了。用托管版集群永远看不到这些细节而恰恰是这些细节决定了你在集群出问题时能不能快速找到方向。我在实际使用中养成的习惯是每次部署都把系统版本、内核版本、Kubernetes版本、CNI插件版本记录下来出问题时先比对版本兼容性。很多看起来诡异的故障最后都是版本匹配问题。最后再分享一个小技巧部署之前先把文档里的命令从头到尾读一遍把每个命令大概改了什么内容记在心里再去执行。不要拿着文档无脑复制粘贴因为环境不同、版本不同命令里需要调整的参数也不同。你提前想清楚每一步的意义后面遇到报错才不会慌这也是我从“会部署”到“会排查”之间收获最大的一点。本文还有配套的精品资源点击获取