CentOS 7.9上k8s v1.15.1初始化踩坑实录:从preflight报错到集群就绪

那天下午,当我决定在测试环境的CentOS 7.9服务器上部署一个Kubernetes v1.15.1集群时,完全没想到接下来会经历一场持续8小时的"排错马拉松"。作为一个有三年运维经验的工程师,我本以为这不过是又一次常规的安装过程,直到终端上赫然出现那个红色错误提示:"error execution phase preflight"...

1. 初遇preflight报错:系统检查的当头一棒

记得第一次执行kubeadm init命令时,那种自信满满的感觉。我按照官方文档准备了标准的初始化配置:

apiVersion: kubeadm.k8s.io/v1beta2
kind: InitConfiguration
nodeRegistration:
  criSocket: /var/run/dockershim.sock
  name: k8s-master
---
apiVersion: kubeadm.k8s.io/v1beta2
kind: ClusterConfiguration
kubernetesVersion: v1.15.1
networking:
  podSubnet: "192.168.0.0/16"

然而命令刚执行不到3秒,终端就被红色错误信息占据:

[preflight] Some fatal errors occurred:
    [ERROR Swap]: running with swap on is not supported. Please disable swap
    [ERROR SystemVerification]: this Docker version is not on the validated list: 18.03.1-ce

第一个教训:Kubernetes对运行环境有着严格的要求,preflight检查就是它的"安检系统"。我意识到必须解决这两个问题才能继续:

  1. Swap分区问题:现代Linux系统默认会启用swap,但k8s认为这会干扰内存管理
  2. Docker版本兼容性:不是所有Docker版本都能与k8s和谐共处

2. 攻克Swap难题:内存管理的第一个门槛

禁用swap听起来简单,但实际操作中我发现CentOS 7.x的swap配置有几个需要注意的细节:

# 临时禁用所有swap设备
sudo swapoff -a

# 永久禁用需要修改fstab
sudo sed -i '/swap/s/^/#/' /etc/fstab

# 检查是否还有活跃的swap
free -h

注意:某些云主机可能会自动挂载swap文件,需要额外检查/proc/swaps内容

我遇到的一个坑是:即使注释了fstab中的swap条目,重启后swap仍然存在。后来发现是系统d的swap单元在作祟,还需要执行:

sudo systemctl mask swap.target

验证步骤必不可少,我使用以下命令确认swap已完全禁用:

cat /proc/swaps | wc -l  # 应该返回0
grep -i swap /etc/fstab  # 所有swap行应该被注释

3. Docker版本迷局:兼容性矩阵的深度解析

第二个错误提示我的Docker 18.03.1-ce不在验证列表中,而最新验证版本是18.09。这引出了三个关键问题:

  1. 为什么k8s对Docker版本如此敏感?
  2. 如何安全升级Docker版本?
  3. 版本差异会带来哪些潜在影响?

3.1 彻底清理旧版Docker

在CentOS 7上完全卸载Docker需要执行以下步骤:

# 停止服务
sudo systemctl stop docker

# 卸载软件包
sudo yum remove -y docker \
    docker-client \
    docker-client-latest \
    docker-common \
    docker-latest \
    docker-latest-logrotate \
    docker-logrotate \
    docker-engine

# 清理残留文件和目录
sudo rm -rf /var/lib/docker
sudo rm -rf /etc/docker

3.2 安装特定版本Docker

Kubernetes v1.15.1官方验证的Docker版本是18.09,安装过程需要特别注意:

# 添加Docker仓库
sudo yum-config-manager --add-repo https://download.docker.com/linux/centos/docker-ce.repo

# 查看可用版本
yum list docker-ce --showduplicates | sort -r

# 安装指定版本
sudo yum install -y docker-ce-18.09.9 docker-ce-cli-18.09.9 containerd.io

# 配置cgroup驱动为systemd
sudo mkdir /etc/docker
cat <<EOF | sudo tee /etc/docker/daemon.json
{
  "exec-opts": ["native.cgroupdriver=systemd"]
}
EOF

# 启动服务
sudo systemctl enable --now docker

版本验证命令:

docker version --format '{{.Server.Version}}'  # 应该返回18.09.9

4. 参数弃用陷阱:kubeadm的变迁之路

当解决完前两个问题再次初始化时,又遇到了新错误:

Flag --experimental-upload-certs has been deprecated, use --upload-certs instead

这个错误揭示了Kubernetes版本演进中的一个重要现象:CLI参数的不断演化。v1.15.1正处于kubeadm参数规范化的过渡期,许多实验性参数被重新命名。

正确的初始化命令应该如下:

kubeadm init \
    --config=kubeadm-config.yaml \
    --upload-certs \
    | tee kubeadm-init.log

经验分享:kubeadm的配置最好通过配置文件而非命令行参数传递,这样更容易维护和版本控制

5. 集群初始化后的关键配置

当终于看到"Your Kubernetes control-plane has initialized successfully"的绿色提示时,还有几个必须完成的步骤:

5.1 配置kubectl访问

mkdir -p $HOME/.kube
sudo cp -i /etc/kubernetes/admin.conf $HOME/.kube/config
sudo chown $(id -u):$(id -g) $HOME/.kube/config

5.2 安装网络插件

对于v1.15.1,Calico 3.10是个稳定选择:

kubectl apply -f https://docs.projectcalico.org/v3.10/manifests/calico.yaml

验证网络插件状态:

watch kubectl get pods -n kube-system  # 等待所有pod变为Running

5.3 节点加入集群

生成新的token(默认token 24小时后过期):

kubeadm token create --print-join-command

6. 那些容易被忽视的后续优化

集群运行起来后,我还在生产环境中总结了几个优化点:

内核参数调优

cat <<EOF | sudo tee /etc/sysctl.d/k8s.conf
net.bridge.bridge-nf-call-ip6tables = 1
net.bridge.bridge-nf-call-iptables = 1
vm.swappiness = 0
EOF
sudo sysctl --system

日志轮转配置

cat <<EOF | sudo tee /etc/logrotate.d/docker
/var/lib/docker/containers/*/*.log {
    rotate 7
    daily
    compress
    delaycompress
    missingok
    copytruncate
}
EOF

这次部署经历让我深刻体会到:在CentOS 7上部署较旧版本的Kubernetes就像进行一场考古发掘,每个工具版本的选择都需要精确匹配,每个配置参数背后都可能藏着版本变迁的故事。

更多推荐