1. 三节点Kubernetes集群部署实战
最近在阿里云上部署了一套三节点的Kubernetes集群,过程中踩了不少坑,也积累了一些实战经验。不同于单机测试环境,生产级集群的搭建需要考虑网络规划、资源分配、高可用等实际问题。下面我就把这次部署的完整过程记录下来,重点分享那些官方文档里不会写的实操细节。
这次部署使用的是阿里云ECS实例,配置为3台4核8G的通用计算型实例,操作系统选用CentOS 7.9。选择这个组合主要考虑到:1) CentOS 7在企业环境仍占主流 2) 4核8G配置适合中小规模应用 3) 阿里云内网带宽充足,适合集群通信。如果你使用其他云平台或配置,大部分步骤也是通用的。
2. 基础环境准备
2.1 系统初始化配置
首先在三台服务器上执行以下基础配置(以master节点为例):
bash复制# 设置主机名
hostnamectl set-hostname k8s-master
# 配置静态hosts解析
cat >> /etc/hosts <<EOF
192.168.1.100 k8s-master
192.168.1.101 k8s-worker1
192.168.1.102 k8s-worker2
EOF
这里有几个关键点需要注意:
- 主机名必须符合DNS命名规范(小写、无下划线)
- 使用内网IP保证通信效率和安全
- 所有节点必须能互相解析主机名
重要提示:生产环境建议使用DNS服务而非hosts文件,这里仅作演示用途
2.2 内核参数调优
Kubernetes对Linux内核有特殊要求,需要调整以下参数:
bash复制# 禁用swap
swapoff -a
sed -i '/ swap / s/^\(.*\)$/#\1/g' /etc/fstab
# 修改内核参数
cat > /etc/sysctl.d/k8s.conf <<EOF
net.bridge.bridge-nf-call-ip6tables = 1
net.bridge.bridge-nf-call-iptables = 1
net.ipv4.ip_forward = 1
EOF
sysctl --system
这些修改的作用分别是:
- 禁用swap:Kubernetes设计上要求禁用swap以保证调度准确性
- 开启网桥流量转发:让Pod网络能正常工作
- 开启IP转发:支持Service网络
3. 容器运行时安装与配置
3.1 Containerd安装
我们选择containerd作为容器运行时(比Docker更轻量):
bash复制# 安装依赖
yum install -y yum-utils device-mapper-persistent-data lvm2
# 添加docker-ce仓库(containerd包含在其中)
yum-config-manager --add-repo https://mirrors.aliyun.com/docker-ce/linux/centos/docker-ce.repo
# 安装containerd
yum install -y containerd.io
# 生成默认配置
containerd config default > /etc/containerd/config.toml
# 修改配置使用阿里云镜像加速
sed -i 's#registry.k8s.io#registry.aliyuncs.com/google_containers#g' /etc/containerd/config.toml
# 启动服务
systemctl enable containerd && systemctl start containerd
3.2 Cgroup驱动配置
检查系统使用的cgroup驱动:
bash复制docker info | grep Cgroup
# 如果显示cgroupfs需要修改containerd配置
# 修改/etc/containerd/config.toml
[plugins."io.containerd.grpc.v1.cri".containerd.runtimes.runc.options]
SystemdCgroup = true
然后重启containerd服务:
bash复制systemctl restart containerd
4. Kubernetes组件安装
4.1 配置阿里云Kubernetes源
bash复制cat > /etc/yum.repos.d/kubernetes.repo <<EOF
[kubernetes]
name=Kubernetes
baseurl=https://mirrors.aliyun.com/kubernetes/yum/repos/kubernetes-el7-x86_64/
enabled=1
gpgcheck=1
repo_gpgcheck=1
gpgkey=https://mirrors.aliyun.com/kubernetes/yum/doc/yum-key.gpg https://mirrors.aliyun.com/kubernetes/yum/doc/rpm-package-key.gpg
EOF
4.2 安装kubeadm/kubelet/kubectl
bash复制# 安装指定版本(这里选择1.28.2)
yum install -y kubelet-1.28.2 kubeadm-1.28.2 kubectl-1.28.2
# 设置kubelet开机启动(先不启动)
systemctl enable kubelet
注意:不要立即启动kubelet,需要在kubeadm init后再启动
5. 集群初始化
5.1 Master节点初始化
bash复制kubeadm init \
--image-repository=registry.aliyuncs.com/google_containers \
--kubernetes-version=v1.28.2 \
--pod-network-cidr=10.244.0.0/16 \
--service-cidr=10.96.0.0/12 \
--apiserver-advertise-address=192.168.1.100
初始化成功后,按照提示执行:
bash复制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 网络插件安装
我们选择Flannel作为网络插件:
bash复制kubectl apply -f https://raw.githubusercontent.com/flannel-io/flannel/master/Documentation/kube-flannel.yml
5.3 Worker节点加入集群
在worker节点执行master初始化成功后输出的join命令:
bash复制kubeadm join 192.168.1.100:6443 --token xxxx \
--discovery-token-ca-cert-hash sha256:xxxx
6. 常见问题排查
6.1 kubeadm init卡住问题
如果kubeadm init长时间卡在[preflight]阶段,通常是镜像拉取失败导致。可以手动拉取镜像:
bash复制# 查看所需镜像列表
kubeadm config images list --image-repository=registry.aliyuncs.com/google_containers
# 手动拉取镜像
for image in $(kubeadm config images list --image-repository=registry.aliyuncs.com/google_containers); do
ctr -n k8s.io images pull $image
done
6.2 Node NotReady状态
如果节点长时间处于NotReady状态,检查:
- 网络插件是否安装成功
- kubelet服务是否正常运行
- 防火墙是否关闭或放行必要端口
bash复制# 查看kubelet日志
journalctl -xeu kubelet
# 检查网络插件Pod状态
kubectl get pods -n kube-system
7. 生产环境优化建议
- 证书管理:kubeadm默认证书有效期1年,建议使用--cert-dir参数指定证书目录并定期更新
- 高可用:生产环境应部署多master节点,使用负载均衡器接入
- 监控:部署Prometheus-Operator监控集群状态
- 备份:定期备份etcd数据
bash复制# etcd备份示例
ETCDCTL_API=3 etcdctl \
--endpoints=https://127.0.0.1:2379 \
--cacert=/etc/kubernetes/pki/etcd/ca.crt \
--cert=/etc/kubernetes/pki/etcd/server.crt \
--key=/etc/kubernetes/pki/etcd/server.key \
snapshot save snapshot.db
8. 集群验证
部署完成后,运行以下命令验证集群状态:
bash复制# 查看节点状态
kubectl get nodes -o wide
# 查看系统Pod状态
kubectl get pods -n kube-system
# 部署测试应用
kubectl create deployment nginx --image=nginx
kubectl expose deployment nginx --port=80 --type=NodePort
# 访问测试
curl $(kubectl get svc nginx -o jsonpath='{.spec.clusterIP}')
这次部署最大的收获是:在云环境部署Kubernetes时,网络配置往往是最容易出问题的地方。特别是跨可用区部署时,需要特别注意网络安全组的配置。另外,合理规划CIDR范围也很重要,避免与现有网络冲突。