CentOS 8部署Kubernetes 1.18集群:从系统配置到网络部署全指南

发布时间:2026/8/13 8:41:28
CentOS 8部署Kubernetes 1.18集群:从系统配置到网络部署全指南 1. 项目概述与核心价值最近在整理内部技术资产翻出来一份几年前在CentOS 8上手动部署Kubernetes 1.18集群的详细记录。虽然现在Kubernetes版本已经迭代到了v1.30CentOS 8也早已停止维护但这个组合在特定场景下依然有很强的参考价值。很多企业的遗留系统、受控的离线环境或者一些对稳定性有极致要求的生产场景仍然可能被“锁定”在某个经过充分验证的特定版本上。部署一个Kubernetes集群远不是敲几行kubeadm init就能完事的尤其是在操作系统版本也相对“老”的情况下你会遇到各种依赖冲突、服务配置和网络问题。这份记录就是我当年踩了无数坑之后梳理出来的一套从零开始、手把手式的部署指南目标是把一个高可用的Kubernetes 1.18集群稳稳当当地跑在CentOS 8上。这个项目适合谁呢如果你是运维工程师、DevOps或正在学习K8s的开发者需要在一个相对“干净”但版本特定的Linux环境上搭建用于开发、测试甚至特定生产用途的Kubernetes集群那么这篇内容会非常有用。它不仅仅是一份命令清单我会详细解释每一条命令背后的意图、每一个配置项的作用以及当命令执行失败时你应该去哪里找线索、怎么排查。毕竟部署的成功只是一瞬间而理解整个系统如何协同工作才是应对日后各种运维挑战的关键。2. 环境准备与系统基础配置在真正开始安装Kubernetes组件之前我们必须为集群搭建一个稳固的“地基”。这个阶段的工作看似琐碎但至关重要它直接决定了后续安装过程是顺风顺水还是一路坎坷。很多初学者部署失败问题往往就出在基础环境没有配置好。2.1 操作系统与硬件要求首先我们明确一下基础环境。我使用的是CentOS 8.2内核版本为4.18.0。虽然CentOS 8的生命周期已结束但在这个时间点上它的软件包版本与Kubernetes 1.18有较好的兼容性。你需要准备至少两台机器一台Master控制节点一台Node工作节点当然三台可以构建一个更简单的高可用方案。每台机器建议配置2核CPU、4GB内存、20GB磁盘。这只是最低要求生产环境请根据实际负载大幅提高配置。第一件事是确保所有节点的主机名和网络配置正确且能相互通信。为每台机器设置一个易于识别的主机名例如k8s-master和k8s-node1。# 在Master节点执行 hostnamectl set-hostname k8s-master # 在Node节点执行 hostnamectl set-hostname k8s-node1然后编辑每台机器的/etc/hosts文件添加所有集群节点的IP和主机名映射。这一步极其重要因为Kubernetes的很多组件如kubelet、API Server会通过主机名进行通信如果DNS解析失败会导致集群状态异常。# 假设你的机器IP如下请替换为实际IP 192.168.1.100 k8s-master 192.168.1.101 k8s-node1配置完成后务必使用ping命令测试所有节点间的网络连通性确保能通过主机名和IP互相ping通。2.2 系统服务与防火墙配置CentOS 8默认使用firewalld作为防火墙而Kubernetes集群内部组件需要大量的端口互相通信。一个常见的做法是直接关闭防火墙和SELinux以简化初期部署但这在生产环境中是危险的。更推荐的做法是配置防火墙规则只开放必要的端口。对于Kubernetes 1.18Master节点需要开放6443API Server、2379-2380etcd、10250kubelet API、10251scheduler、10252controller manager等端口。Node节点需要开放10250、30000-32767NodePort服务范围等端口。为了教程的清晰和可复现性我们这里先采用关闭防火墙的策略但你必须清楚在生产环境中这是不可接受的。# 关闭防火墙 systemctl stop firewalld systemctl disable firewalld # 关闭SELinux需要重启生效或临时设置为permissive setenforce 0 sed -i s/^SELINUXenforcing$/SELINUXpermissive/ /etc/selinux/config注意这只是为了部署流程顺畅。在实际生产环境中你应该制定严格的防火墙策略仅允许可信来源访问特定端口并保持SELinux处于enforcing模式通过定制策略来保障安全。2.3 安装基础依赖与配置系统参数Kubernetes运行需要一些基础工具和优化的系统参数。首先安装必要的软件包dnf install -y yum-utils device-mapper-persistent-data lvm2接下来是几个关键的系统内核参数调整它们影响着容器的网络、桥接流量和内存管理。编辑/etc/sysctl.d/k8s.conf文件cat EOF | sudo tee /etc/sysctl.d/k8s.conf net.bridge.bridge-nf-call-ip6tables 1 net.bridge.bridge-nf-call-iptables 1 net.ipv4.ip_forward 1 vm.swappiness 0 EOF执行sysctl --system使配置生效。其中net.ipv4.ip_forward1是核心它允许Linux主机转发IP数据包这是Pod跨节点通信的基础。bridge-nf-call-iptables参数则确保iptables规则能正确应用于桥接设备上的流量这是Service网络正常工作的前提。最后关闭系统的Swap交换分区。Kubernetes设计认为内存不足时应通过调度Pod到其他节点或驱逐Pod来解决使用Swap会导致性能不可预测和调度复杂性。# 临时关闭 swapoff -a # 永久关闭注释掉/etc/fstab中swap相关的行 sed -i / swap / s/^\(.*\)$/#\1/g /etc/fstab3. 容器运行时与Kubernetes组件安装地基打牢后我们开始安装核心的“发动机”——容器运行时和Kubernetes组件。这里我们选择Docker作为容器运行时虽然现在containerd是更主流和轻量的选择但Kubernetes 1.18时代Docker的集成度和社区资料更丰富。使用kubeadm这个官方工具可以极大地简化安装过程。3.1 安装Docker容器运行时CentOS 8的默认仓库可能不包含我们需要的Docker版本。我们需要添加Docker的官方仓库。这里安装的是与K8s 1.18兼容性较好的docker-ce-19.03版本。# 添加Docker仓库 dnf config-manager --add-repohttps://download.docker.com/linux/centos/docker-ce.repo # 安装指定版本的Docker dnf install -y docker-ce-19.03.15 docker-ce-cli-19.03.15 containerd.io安装完成后需要配置Docker的cgroup驱动。Kubernetes推荐使用systemd作为cgroup驱动而非Docker默认的cgroupfs这有助于提高系统稳定性。创建或编辑/etc/docker/daemon.json{ exec-opts: [native.cgroupdriversystemd], log-driver: json-file, log-opts: { max-size: 100m }, storage-driver: overlay2, storage-opts: [ overlay2.override_kernel_checktrue ] }然后启动并设置Docker开机自启systemctl enable docker systemctl start docker你可以通过docker info | grep Cgroup来验证驱动是否已改为systemd。3.2 配置Kubernetes仓库并安装组件接下来安装kubelet、kubeadm和kubectl。由于国内网络访问Google仓库可能不稳定我们使用阿里云的镜像仓库。# 添加阿里云Kubernetes仓库 cat EOF /etc/yum.repos.d/kubernetes.repo [kubernetes] nameKubernetes baseurlhttps://mirrors.aliyun.com/kubernetes/yum/repos/kubernetes-el7-x86_64/ enabled1 gpgcheck1 repo_gpgcheck1 gpgkeyhttps://mirrors.aliyun.com/kubernetes/yum/doc/yum-key.gpg https://mirrors.aliyun.com/kubernetes/yum/doc/rpm-package-key.gpg EOF # 安装指定版本1.18.20是一个较稳定的补丁版本 dnf install -y kubelet-1.18.20 kubeadm-1.18.20 kubectl-1.18.20 --disableexcludeskubernetes--disableexcludeskubernetes参数很重要它确保在安装时不会因为仓库排除规则而跳过Kubernetes包。安装完成后设置kubelet开机自启但先不要启动等kubeadm init之后再启动systemctl enable kubelet3.3 配置kubeadm初始化参数在Master节点执行kubeadm init之前最好先通过配置文件来定义集群的初始化参数这样更清晰且易于版本管理。创建一个配置文件例如kubeadm-config.yamlapiVersion: kubeadm.k8s.io/v1beta2 kind: ClusterConfiguration kubernetesVersion: v1.18.20 controlPlaneEndpoint: k8s-master:6443 # 如果是单Master就写Master的IP或域名 networking: podSubnet: 10.244.0.0/16 # 为Flannel网络插件预留的Pod网段如果使用Calico等需修改 imageRepository: registry.aliyuncs.com/google_containers # 使用国内镜像加速 --- apiVersion: kubelet.config.k8s.io/v1beta1 kind: KubeletConfiguration cgroupDriver: systemd # 必须与Docker的cgroup驱动一致这个配置文件做了几件关键事指定了Kubernetes版本定义了控制平面的访问端点设置了Pod的网络CIDR这里以Flannel为例最关键的是指定了国内镜像仓库避免因拉取k8s.gcr.io镜像失败导致初始化卡住。同时它确保了kubelet使用systemdcgroup驱动。4. 初始化Master节点与部署网络插件万事俱备现在可以初始化Master节点了。这是将分散的组件组装成一个大脑的关键一步。4.1 执行kubeadm init初始化使用我们刚才创建的配置文件进行初始化kubeadm init --configkubeadm-config.yaml --upload-certs | tee kubeadm-init.log这个命令会做一系列工作检查系统状态、拉取控制平面镜像、生成各种证书和静态Pod清单文件如etcd、api-server等、启动控制平面组件。--upload-certs参数将证书密钥上传到集群为后续添加其他控制平面节点实现高可用做准备。tee命令将输出同时显示在屏幕并保存到文件便于后续排查。初始化成功的最关键标志是最后几行输出它会给出两条你必须执行的命令以及一条用于将Node节点加入集群的命令mkdir -p $HOME/.kube sudo cp -i /etc/kubernetes/admin.conf $HOME/.kube/config sudo chown $(id -u):$(id -g) $HOME/.kube/config # 以及类似下面的join命令务必记下来 kubeadm join k8s-master:6443 --token abcdef.0123456789abcdef \ --discovery-token-ca-cert-hash sha256:xxxxxxxx...请立即执行前两条mkdir和cp命令它们将管理员的Kubeconfig文件复制到你的家目录下这样kubectl命令才能正常工作。你可以运行kubectl get nodes查看此时Master节点应处于NotReady状态因为网络插件还没装。4.2 部署Pod网络插件CNIPod之间要能通信必须安装一个CNI容器网络接口插件。这里我们选择最经典的Flannel它简单可靠。注意Flannel的配置必须与我们在kubeadm-config.yaml中设置的podSubnet10.244.0.0/16匹配。# 下载Flannel的配置文件 wget https://raw.githubusercontent.com/coreos/flannel/master/Documentation/kube-flannel.yml # 如果网络问题可以找国内镜像或手动下载 # 应用这个配置文件 kubectl apply -f kube-flannel.yml应用后使用kubectl get pods -n kube-system来观察kube-flannel-ds-*这些Pod的状态。等待几分钟直到它们全部变为Running状态。此时再运行kubectl get nodes应该能看到Master节点的状态变成了Ready。实操心得如果Flannel Pod一直卡在Init或ContainerCreating最常见的原因是镜像拉取失败。可以手动使用docker pull拉取quay.io/coreos/flannel:v0.13.0镜像或者编辑kube-flannel.yml文件将其中的镜像地址替换为国内镜像如registry.cn-hangzhou.aliyuncs.com/google_containers/flannel。另一个常见问题是/run/flannel目录权限确保节点上该目录存在且可写。5. 添加Worker节点与基础功能验证现在大脑Master已经就绪我们需要给它添加手脚Worker Node。5.1 将Node节点加入集群在另一台已经完成了第2章和第3章所有步骤安装Docker、kubelet、kubeadm关闭Swap等的Node节点上执行之前在Master节点初始化成功后输出的那条kubeadm join命令。命令格式如下kubeadm join control-plane-host:control-plane-port --token token --discovery-token-ca-cert-hash sha256:hash加入过程可能需要一两分钟。你可以在Master节点上通过kubectl get nodes -w-w参数用于持续观察来查看Node节点的加入状态。当Node节点状态变为Ready就表示加入成功。如果忘记了join命令或token过期默认24小时可以在Master节点上重新生成# 生成新的token kubeadm token create --print-join-command5.2 验证集群基础功能节点就绪后我们需要验证集群的核心功能是否正常。运行以下命令进行一系列检查查看集群节点状态kubectl get nodes所有节点应为Ready。查看核心系统Pod状态kubectl get pods -n kube-system所有Pod特别是coredns应为Running。如果coredns卡在Pending通常是网络插件没装好。部署一个测试应用这是最直接的验证方式。# 部署一个Nginx Deployment kubectl create deployment nginx-test --imagenginx:1.14-alpine # 将其暴露为一个NodePort服务 kubectl expose deployment nginx-test --port80 --typeNodePort # 查看服务获取分配的NodePort例如 32645 kubectl get svc nginx-test然后你可以通过Node节点的IP:NodePort在浏览器中访问如果看到Nginx欢迎页说明Pod部署、Service网络和节点间通信全部正常。检查集群组件健康状态kubectl get componentstatus或kubectl get cs应显示scheduler、controller-manager等组件为Healthy。6. 常见问题深度排查与优化配置即便按照步骤操作你也可能会遇到一些问题。这里我汇总了几个最常见的问题及其排查思路这比成功的步骤更有价值。6.1 初始化失败镜像拉取问题问题现象kubeadm init卡在[pull-image]阶段或提示ImagePullBackOff。排查与解决检查网络确保节点能访问外网或你配置的国内镜像仓库。可以手动docker pull registry.aliyuncs.com/google_containers/kube-apiserver:v1.18.20测试。使用预拉取镜像kubeadm支持在初始化前先拉取所有所需镜像。kubeadm config images pull --configkubeadm-config.yaml镜像列表与替换如果某个镜像实在拉取不到可以使用docker tag命令将已拉取到的相似镜像重命名为目标镜像名或者寻找其他可靠的国内镜像源进行替换。6.2 Node节点NotReady问题现象Node加入后状态一直为NotReady。排查步骤在Node节点检查kubelet服务systemctl status kubelet -l。查看日志是否有明显错误。检查CNI插件Pod在Master上kubectl describe pod flannel-pod-name -n kube-system查看Events和容器状态。常见问题是镜像拉取失败或网络权限问题。检查Node节点上的网络接口在Node节点上运行ip addr show查看是否多了一个cni0的网桥以及每个Pod是否有一个veth开头的虚拟网卡。如果没有说明CNI插件没有正常工作。检查kubelet日志在Node节点上journalctl -xeu kubelet关注其中与CNI、cgroup相关的错误。一个经典错误是“cgroup驱动不匹配”确保Docker(daemon.json)和kubelet(kubeadm-config.yaml或/var/lib/kubelet/config.yaml)都配置为systemd。6.3 CoreDNS Pod处于Pending或CrashLoopBackOff状态问题现象kubectl get pods -n kube-system显示coredns pods没有运行。排查与解决首先检查网络插件CoreDNS依赖集群网络。确保Flannel等CNI插件所有Pod都已Running。检查Node的污点TaintMaster节点默认有污点node-role.kubernetes.io/master:NoSchedule这会导致普通Pod包括CoreDNS无法调度上去。如果你只有单节点集群既是Master又是Worker需要移除这个污点kubectl taint nodes --all node-role.kubernetes.io/master-查看CoreDNS Pod详情kubectl describe pod -n kube-system -l k8s-appkube-dns从Events中寻找线索。6.4 后续优化与配置建议集群跑起来后可以考虑做一些优化让它更易用、更稳定配置kubectl命令自动补全# Bash echo source (kubectl completion bash) ~/.bashrc # Zsh echo source (kubectl completion zsh) ~/.zshrc安装DashboardWeb UI虽然命令行是王道但Dashboard对于可视化查看资源状态很有帮助。注意安装后需要配置访问权限ServiceAccount、Token等切勿直接暴露到公网。kubectl apply -f https://raw.githubusercontent.com/kubernetes/dashboard/v2.0.0/aio/deploy/recommended.yaml配置日志与监控考虑部署EFKElasticsearch, Fluentd, Kibana栈收集日志以及Prometheus Grafana监控集群和应用的运行状态。这是生产级集群的标配。资源清理如果初始化失败需要重来可以执行kubeadm reset来清理节点。注意这会删除所有通过kubeadm创建的资源但不会清除iptables规则或CNI网络配置可能需要手动清理。部署一个Kubernetes集群就像搭积木每一步都有其明确的目的和依赖。从系统配置、运行时安装、组件初始化到网络部署环环相扣。我个人的体会是第一次部署时耐心地阅读每一行命令的输出和错误日志比盲目搜索答案更有效。理解每个组件的作用kubelet是节点代理kube-apiserver是总网关etcd是数据库kube-proxy负责网络规则能让你在遇到问题时快速定位方向。这个基于CentOS 8和Kubernetes 1.18的部署流程其方法论是通用的当你需要部署更新版本的K8s或其他Linux发行版时只需调整软件仓库地址、镜像版本和部分配置参数即可。