简介:这是一份面向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和etcd;Worker节点上则运行着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-master,Worker节点叫k8s-node1。Ubuntu下执行:
hostnamectl set-hostname k8s-master然后在所有节点的/etc/hosts里加上:
192.168.1.10 k8s-master 192.168.1.11 k8s-node1为什么要禁用swap?Kubernetes的kubelet默认要求交换分区关闭,因为如果允许swap,Pod的内存配额管理会失真,可能出现明明设置了内存上限、实际却把数据换到磁盘里的情况。禁用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 容器运行时:为什么选择containerd
Kubernetes从1.24版本开始彻底移除了对Docker作为运行时(即dockershim)的支持,所以现在的部署方案基本都是用containerd。containerd本身是Docker生态里拆出来的容器运行时组件,性能更轻、资源占用更小,也是CNCF的毕业项目。
安装containerd有两种常见方式:用系统的apt源直接装,或者用Docker官方源装。我这里用apt:
sudo 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替换成镜像加速地址,这个看实际情况调整。改完配置后重启containerd:
sudo 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简单、好排查,但不支持NetworkPolicy;Calico功能强但组件更多、配置更复杂。如果选了Flannel,初始化时需要指定Pod网段为10.244.0.0/16,这个网段要和后面安装Flannel的默认配置保持一致。
sudo kubeadm init \ --apiserver-advertise-address=192.168.1.10 \ --pod-network-cidr=10.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.yaml:
apiVersion: 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 无法启动,状态是 activating | swap未关闭或systemd配置错误 | 确认swapoff -a和fstab已修改,systemctl daemon-reload后重启kubelet |
| coredns Pod 一直 Pending / CrashLoopBackOff | 没有安装CNI网络插件 | 检查Flannel或Calico是否成功apply,Pod网段是否与init参数一致 |
| Worker节点显示NotReady | CNI插件未初始化、镜像拉取失败 | kubectl describe node <名字>看Events,再定位到具体Pod看日志 |
| 加入集群时报token过期 | token默认24小时有效 | 用kubeadm token create --print-join-command重新生成 |
| Dashboard登录后无数据 | ServiceAccount权限不足 | 确认绑定了正确的ClusterRole,比如cluster-admin |
5.2 排查命令与思路
排查Kubernetes问题,很多时候不是不会看,而是看的地方不对。我自己的排查顺序一般是这样的:
先看节点是否就绪,kubectl get nodes确认范围。再看核心组件,kubectl get pods -n kube-system看控制面Pod是否正常。然后看具体Pod,kubectl 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插件版本记录下来,出问题时先比对版本兼容性。很多看起来诡异的故障,最后都是版本匹配问题。
最后再分享一个小技巧:部署之前,先把文档里的命令从头到尾读一遍,把每个命令大概改了什么内容记在心里,再去执行。不要拿着文档无脑复制粘贴,因为环境不同、版本不同,命令里需要调整的参数也不同。你提前想清楚每一步的意义,后面遇到报错才不会慌,这也是我从“会部署”到“会排查”之间,收获最大的一点。
本文还有配套的精品资源,点击获取