Kubernetes通常简称为K8s,因为首字母K和尾字母s之间有8个字符。它是一套面向容器化应用的开源调度系统,负责把一组机器抽象成统一的计算资源池,并根据声明式配置自动完成应用的部署、扩缩容、自愈和滚动更新。安装部署Kubernetes的过程,本质上是把控制平面组件、节点组件、容器运行时和网络插件四类软件组合起来。很多教程只给命令,不解释组件依赖,导致一旦报错就无从下手。本文使用kubeadm作为安装工具,按准备、初始化、加入节点、排查问题的顺序展开,目标是让集群真正达到节点Ready、Pod可以正常调度和访问的状态。

一、先理解Kubernetes的组件结构
Kubernetes集群由控制平面和工作节点组成。控制平面负责保存集群状态、接收用户请求、决定Pod调度位置,工作节点负责真正运行容器。控制平面的核心组件包括kube-apiserver、etcd、kube-scheduler和kube-controller-manager。其中kube-apiserver是所有操作的统一入口,kubectl命令和节点上的kubelet都通过它读写集群状态;etcd是一个高可用的键值存储,保存了Deployment、Service、ConfigMap等全部对象;kube-scheduler监视没有被调度的Pod,并根据资源、亲和性等策略选择一个合适节点;kube-controller-manager内部包含多个控制器,例如节点控制器、副本控制器、端点控制器,它们不断把实际状态调整到用户声明的期望状态。
工作节点上必须运行三个基础组件。kubelet是节点代理,它接收kube-apiserver下发的Pod定义,并调用容器运行时创建或销毁容器。kube-proxy负责实现Service的网络规则,让集群内外的流量能够访问到Pod。容器运行时可以是containerd、CRI-O或者其他符合CRI标准的实现。从Kubernetes 1.24版本开始,官方不再内置Docker Engine作为默认运行时,因此新集群建议直接使用containerd,这样链路更短,排查问题也更直接。使用kubeadm安装时,控制平面组件会以静态Pod的形式运行在kube-system命名空间,而kubelet和容器运行时则是系统级服务。
除了这些基础组件,Pod网络插件也是必须单独安装的。kubeadm不会默认安装CNI插件,所以刚执行完kubeadm init时,控制平面节点会一直处于NotReady状态,CoreDNS也会显示Pending。Flannel是最容易上手的插件,它用VXLAN或host-gateway方式打通跨节点网络;Calico提供更细粒度的网络策略;Cilium则基于eBPF,适合对性能和可观测性要求较高的场景。对于学习和中小规模集群,Flannel足够稳定,但要注意它的Pod网段必须与kubeadm init中的--pod-network-cidr参数一致。
# 查看控制平面组件对应的静态Pod kubectl get pods -n kube-system -o wide # 查看节点状态,刚初始化后通常为NotReady kubectl get nodes
二、安装前的环境准备与配置细节
正式安装前,最容易被忽略的是系统级配置。首先是关闭swap。kubelet从设计上就不支持使用swap,如果系统启用了swap分区,kubelet可能启动失败,或者节点会反复告警。临时关闭可以执行swapoff -a,永久关闭需要编辑/etc/fstab,把包含swap字样的行注释掉。其次是内核网络参数。Kubernetes要求节点启用net.bridge.bridge-nf-call-iptables和net.ipv4.ip_forward,否则跨节点Pod流量经过网桥时会被iptables规则丢弃,表现就是Pod之间ping不通。这些参数需要写入/etc/sysctl.d/目录下的配置文件,并执行sysctl --system使其生效。同时还要加载overlay和br_netfilter内核模块,containerd的存储和网络都依赖它们。
容器运行时的安装顺序在kubeadm之前。以containerd为例,可以先通过系统包管理器安装containerd.io,然后生成默认配置。containerd默认使用systemd作为cgroup驱动,但早期版本或某些安装方式会使用cgroupfs,这会导致kubelet与容器运行时看待cgroup层级的方式不一致,最终表现为Pod启动后立刻退出或节点资源统计异常。建议统一使用systemd cgroup驱动,并修改containerd的sandbox_image地址。国内环境拉取registry.k8s.io/pause镜像经常超时,可以把沙箱镜像替换为registry.aliyuncs.com/google_containers/pause:3.9。配置修改完成后执行systemctl restart containerd,并用systemctl status containerd确认服务正常。
# 关闭swap sudo swapoff -a sudo sed -i '/swap/s/^/#/' /etc/fstab # 加载内核模块 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
然后安装kubeadm、kubelet和kubectl。这三个包必须保持版本一致,否则kubeadm初始化时会对版本做校验。Debian系可以添加Kubernetes官方的apt源,Red Hat系可以使用yum源。国内访问apt.kubernetes.io可能不稳定,可以使用阿里云镜像源。安装完成后,不要急着执行初始化,先固定软件包版本,防止系统升级时把这些组件带到不兼容的新版本。通常设置sudo apt-mark hold kubelet kubeadm kubectl即可。另外,每台机器的hostname和/etc/hosts要配置正确,控制平面节点建议至少2核2GB内存,否则apiserver和etcd会频繁OOM。
三、使用kubeadm初始化控制平面并加入工作节点
环境准备好后,在控制平面节点执行kubeadm init。初始化命令最重要的是三个参数。--apiserver-advertise-address指定其他节点访问控制平面的IP地址,云主机上不要填成内网环回地址;--pod-network-cidr指定Pod网络的地址段,Flannel默认使用10.244.0.0/16,Calico默认使用192.168.0.0/16;--image-repository可以替换为国内镜像仓库,避免拉取kube-apiserver、etcd等镜像失败。完整的初始化过程包括预检、生成证书、启动控制平面静态Pod、上传kubelet配置、创建默认插件等步骤。如果中途失败,先执行kubeadm reset清理残留,再根据错误日志修正后重试。
初始化成功后,命令输出中会有一段kubeadm join命令,它包含token和CA证书哈希,用于工作节点加入集群。这段命令默认有效期24小时,过期后可以在控制平面执行kubeadm token create --print-join-command重新生成。控制平面节点还需要配置kubectl访问权限。普通用户应当把/etc/kubernetes/admin.conf复制到自己的家目录下,并设置KUBECONFIG环境变量或直接覆盖~/.kube/config。此时执行kubectl get nodes,会看到控制平面节点是NotReady状态,这是因为还没有部署Pod网络插件。
# 控制平面初始化,使用阿里云镜像并指定Pod网段 sudo kubeadm init \ --apiserver-advertise-address=192.168.10.10 \ --image-repository registry.aliyuncs.com/google_containers \ --pod-network-cidr=10.244.0.0/16 # 为普通用户配置kubectl mkdir -p $HOME/.kube sudo cp -i /etc/kubernetes/admin.conf $HOME/.kube/config sudo chown $(id -u):$(id -g) $HOME/.kube/config # 安装Flannel网络插件 kubectl apply -f https://raw.githubusercontent.com/flannel-io/flannel/master/Documentation/kube-flannel.yml # 在工作节点执行join命令 sudo kubeadm join 192.168.10.10:6443 --token 示例token \ --discovery-token-ca-cert-hash sha256:示例哈希
工作节点加入后,通常需要等待一到两分钟,节点才会变成Ready。这个过程中,kubelet会启动,容器运行时拉取pause镜像,Flannel或Calico的Pod会被调度到节点上,同时CNI配置写入/etc/cni/net.d目录。可以用kubectl get pods -n kube-system -o wide观察网络插件Pod是否正常。如果工作节点一直处于NotReady,先检查节点上的kubelet日志和网络插件Pod日志,常见原因是容器运行时没有启动、cgroup驱动不一致,或者防火墙阻断了工作节点到控制平面6443端口的连接。
四、安装部署中的常见问题与排查方法
第一个高频问题是kubeadm init报端口占用。kubeadm预检阶段会检查6443、10250等端口,如果之前初始化失败或已有其他进程监听,就会直接退出。处理方式通常是先找到进程并结束,或者执行kubeadm reset清理旧集群,再重新初始化。第二个高频问题是镜像拉取超时。即使使用了国内镜像仓库,某些辅助镜像仍可能拉取缓慢,可以先用kubeadm config images pull验证镜像是否全部能下载,再执行init。第三个问题是节点NotReady。NotReady不等于节点故障,多数情况是CNI插件没有安装或插件Pod没有就绪,先看kube-system命名空间下的Pod状态,再查看节点上的/var/log/syslog或journalctl -u kubelet。
第四个问题是CoreDNS一直处于Pending或CrashLoopBackOff。如果CNI插件未就绪,CoreDNS不会获得Pod IP,自然无法运行。如果网络插件已经正常,CoreDNS仍然崩溃,可以用kubectl logs -n kube-system查看CoreDNS日志,常见原因包括CoreDNS版本与Kubernetes版本不匹配,以及/etc/resolv.conf中的上游DNS配置错误。第五个问题是kubelet启动失败。执行systemctl status kubelet通常能看到明确原因,比如swap未关闭、容器运行时socket不存在、cgroup驱动配置文件错误等。kubelet的配置文件位于/var/lib/kubelet/config.yaml,里面的cgroupDriver字段必须与containerd保持一致。
更系统的排查可以从三个层面展开。节点层使用systemctl和journalctl查看kubelet、containerd服务状态;集群层使用kubectl describe node查看节点条件和事件,用kubectl get events -n kube-system查看集群事件;Pod层使用kubectl describe pod查看Pod调度和启动过程。网络问题还可以在工作节点上执行ip addr查看CNI虚拟网卡,用ip route查看Pod网段路由。升级集群时要避免跨多个大版本直接跳升,并且升级前先用kubeadm upgrade plan确认目标版本。卸载集群可以使用kubeadm reset,但之后还需要清理CNI配置目录、容器镜像和iptables规则,否则重新安装时仍可能残留旧状态。
Kubernetes的安装部署并不复杂,关键在于理解kubelet、容器运行时、控制平面组件和CNI插件之间的依赖顺序。只要把系统参数、运行时配置、镜像仓库和网络插件这四件事处理清楚,大部分安装问题都可以在十分钟内定位。
Kuberneteskubeadm集群部署修改时间:2026-10-05 01:42:33