开始之前
照着文档内容步骤操作时,不存在百分百能够实现应有的效果,遇到问题时 AI 是最好的老师。
服务器基础信息
配置信息仅作参考,可降低配置:
| 主机 | IP | 操作系统 | 配置 |
|---|---|---|---|
| 控制节点 | 192.168.5.210 | Ubuntu 22.04 | 4 核 8G |
| 部署节点 | 192.168.5.211 | Ubuntu 22.04 | 4 核 8G |
| 部署节点 | 192.168.5.212 | Ubuntu 22.04 | 4 核 8G |
集群版本信息:
| 服务 | 版本 |
|---|---|
| kubectl | v1.34.3 |
| Kubernetes | v1.34.3 |
| containerd | v1.7.28 |
初始化服务器设置(所有节点都要执行)
# 关闭swap
swapoff -a && sed -i '/swap/s/^/#/' /etc/fstab
# 关闭防火墙(或按需开放端口,简化操作直接关闭)
ufw disable && systemctl stop ufw && systemctl disable ufw
# 配置hosts文件
cat >> /etc/hosts << EOF
192.168.5.210 master
192.168.5.211 node01
192.168.5.212 node02
EOF
# 控制节点执行
hostnamectl set-hostname master
# node01 执行:hostnamectl set-hostname node01
# node02 执行:hostnamectl set-hostname node02
# 设置时间同步
timedatectl set-timezone Asia/Shanghai
systemctl enable --now systemd-timesyncd
# 配置NTP服务器
cat > /etc/systemd/timesyncd.conf << EOF
[Time]
NTP=ntp.aliyun.com
FallbackNTP=time1.cloud.tencent.com
EOF
# 重启服务并验证
systemctl restart systemd-timesyncd
timedatectl set-ntp true
# 添加内核模块
cat > /etc/modules-load.d/k8s.conf << EOF
overlay
br_netfilter
EOF
# 配置内核参数
cat > /etc/sysctl.d/k8s.conf << EOF
net.bridge.bridge-nf-call-iptables = 1
net.bridge.bridge-nf-call-ip6tables = 1
net.ipv4.ip_forward = 1
EOF
# 生效配置
sysctl --system
# 国内无法拉取对应的资源包,所以需要使用代理。
cat >> ~/.profile << 'EOF'
function proxy_off(){
unset http_proxy
unset https_proxy
unset all_proxy
echo -e "已关闭代理"
}
function proxy_on() {
export no_proxy="localhost,127.0.0.1,localaddress,.localdomain.com,192.168.*"
export https_proxy=http://192.168.5.10:7897 http_proxy=http://192.168.5.10:7897 all_proxy=socks5://192.168.13.228:7897
echo -e "已开启代理"
}
EOF
source .profile
# 更新系统包
apt update && apt upgrade -y
# 安装依赖工具
apt install -y wget apt-transport-https ca-certificates curl software-properties-common containerd
# 修改配置(启用SystemdCgroup)
sed -i 's/SystemdCgroup \= false/SystemdCgroup \= true/g' /etc/containerd/config.toml
# 重启containerd
systemctl restart containerd
systemctl enable containerd
# 开启代理
proxy_on
# 创建目录
sudo mkdir -p /etc/apt/keyrings
# 下载新仓库的GPG密钥
curl -fsSL https://pkgs.k8s.io/core:/stable:/v1.34/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.34/deb/ /' | sudo tee /etc/apt/sources.list.d/kubernetes.list
apt update
apt install -y kubelet kubeadm kubectl
# 锁定版本防止自动更新
apt-mark hold kubelet kubeadm kubectl
# 启动kubelet并设为开机启动
systemctl enable --now kubelet
# 配置 containerd 代理
mkdir -p /etc/systemd/system/containerd.service.d/
sudo tee /etc/systemd/system/containerd.service.d/http-proxy.conf << EOF
[Service]
Environment="HTTP_PROXY=http://192.168.5.10:7897"
Environment="HTTPS_PROXY=http://192.168.5.10:7897"
Environment="NO_PROXY=localhost,127.0.0.1,.cluster.local,.svc,192.168.*"
EOF
sudo systemctl daemon-reload
sudo systemctl restart containerd
# 关闭代理
proxy_off
控制节点配置(192.168.5.210)
# 如果部署失败,可执行以下命令删除集群和相关文件
# kubeadm reset -f
# rm -rf $HOME/.kube/config /etc/cni/net.d /var/lib/etcd/ /etc/kubernetes /opt/cni
# 初始化集群
kubeadm init \
--apiserver-advertise-address=192.168.5.210 \
--pod-network-cidr=10.244.0.0/16 \
--control-plane-endpoint=192.168.5.210
# 配置 kubectl
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 token create --print-join-command
工作节点配置(192.168.5.211 和 192.168.5.212)
# 消除 warning 提示
# crictl config runtime-endpoint unix:///run/containerd/containerd.sock
# crictl config image-endpoint unix:///run/containerd/containerd.sock
# 执行控制节点生成的 join 命令
kubeadm join 192.168.58.150:6443 --token 8fpwy8.pvjaijdmn \
--discovery-token-ca-cert-hash sha256:99a0701f38093958533
# 如果需要重新加入,先在 master 节点执行
kubectl delete node node01 # 删除 node01 节点
# node01 节点执行
kubeadm reset -f
rm -rf $HOME/.kube/config /etc/cni/net.d /var/lib/etcd/ /opt/cni
sudo ip link delete cni0
sudo ip link delete flannel.1
控制节点部署网络组件
# 安装 Flannel
proxy_on
wget https://github.com/flannel-io/flannel/releases/latest/download/kube-flannel.yml
# 在配置文件中找到 net-conf.json 部分,确保配置的地址和初始化集群时设置的一致
# vim kube-flannel.yml
net-conf.json: |
{
"Network": "10.244.0.0/16",
"Backend": {
"Type": "vxlan"
}
}
# 部署 flannel
kubectl apply -f kube-flannel.yml
# 部署之后控制节点显示 NotReady 状态,可查看日志
journalctl -u kubelet -n 50
# 如果日志一直都是显示 cni plugin not initialized,说明插件自动安装失败了,可手动下载二进制文件
# 安装插件操作所有节点都要执行
# 下载压缩包,文件版本按需选择
wget https://github.com/containernetworking/plugins/releases/download/v1.6.2/cni-plugins-linux-amd64-v1.6.2.tgz
sudo tar -zxvf cni-plugins-linux-amd64-v1.6.2.tgz -C /opt/cni/bin
ls -l /opt/cni/bin
# 重启生效
systemctl restart containerd
systemctl restart kubelet
kubectl rollout restart deployment coredns -n kube-system
# 如需重装 flannel,应先删除所有相关的资源
kubectl delete -f kube-flannel.yml
sudo rm -rf /etc/cni/net.d/* /opt/cni
sudo ip link delete cni0
sudo ip link delete flannel.1
sudo systemctl restart kubelet
部署 Metallb
# 安装 MetalLB
wget https://raw.githubusercontent.com/metallb/metallb/v0.14.5/config/manifests/metallb-native.yaml
kubectl apply -f
# 等待 MetalLB 就绪
kubectl wait --namespace metallb-system \
--for=condition=ready pod \
--selector=app=metallb \
--timeout=90s
# 配置地址池,IP 范围必须和宿主机在同一网段
cat <<EOF | kubectl apply -f -
apiVersion: metallb.io/v1beta1
kind: IPAddressPool
metadata:
name: default-pool
namespace: metallb-system
spec:
addresses:
- 192.168.5.220-192.168.5.240
---
apiVersion: metallb.io/v1beta1
kind: L2Advertisement
metadata:
name: default
namespace: metallb-system
EOF
部署 Higress 控制器
本文档采用 higress,集群资源有限的话,可使用 nginx ingress 控制器: Ingress 控制器 | Kubernetes
- Higress
# 下载安装脚本
curl -fsSL -o get_helm.sh https://raw.githubusercontent.com/helm/helm/master/scripts/get-helm-3
# 赋予脚本执行权限
chmod 700 get_helm.sh && ./get_helm.sh
# 验证安装
helm version
helm repo add higress.io https://higress.io/helm-charts
proxy_off
# cat /opt/higress-monitor.yaml
# 用于后续 Prometheus 监控
# ---start---
higress-core:
gateway:
podAnnotations:
prometheus.io/scrape: "true"
prometheus.io/port: "15020"
prometheus.io/path: "/stats/prometheus"
metrics:
exposedPort: 15020
# ---end---
# 执行部署
helm install higress -n higress-system higress.io/higress \
- f /opt/higress-monitor.yaml \
--create-namespace \
--set global.local=true \
--set higress-console.o11y.enabled=false
# 使用域名访问 higress-ui
# cat /opt/higress-ui.yaml
# ---start---
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: higress-console-ingress
namespace: higress-system
spec:
ingressClassName: higress
rules:
- host: higress.abcd.com # 绑定你想要的域名
http:
paths:
- path: /
pathType: Prefix
backend:
service:
name: higress-console
port:
number: 8080
# ---end---
# 部署
kubectl apply -f /opt/higress-ui.yaml
- nginx ingress
# 安装(v1.8.1稳定版)
cd /opt && wget https://raw.githubusercontent.com/kubernetes/ingress-nginx/controller-v1.9.4/deploy/static/provider/baremetal/deploy.yaml
kubectl apply -f /opt/deploy.yaml
# 配置 Ingress-Nginx 使用 MetalLB
kubectl patch svc ingress-nginx-controller -n ingress-nginx -p '{
"spec": {
"type": "LoadBalancer"
}
}'
集群的持久化存储
K8s集群借助 NFS 可解决容器化应用的数据持久化问题。容器本身是临时性的,重启后数据会丢失,而 NFS 提供网络共享存储,让多个 Pod 可以读写同一份数据,实现数据持久化和跨节点共享。同时 NFS 支持动态卷配置,简化存储管理,提高应用的高可用性和数据可靠性,是容器有状态应用部署的关键基础设施。
Provisioner是K8s存储系统的核心组件,负责自动创建和管理持久化存储卷。当应用申请PVC时,Provisioner自动在底层存储后端(如NFS、云存储)创建对应的PV,实现存储资源的动态分配和按需供给。它屏蔽了不同存储系统的差异,提供统一的存储管理接口,支持存储卷的自动创建、扩容、回收等全生命周期管理。
- 服务端部署
# 服务端 ip:192.168.5.20
# 服务器操作系统:Ubuntu 22.04
sudo apt update
sudo apt install nfs-kernel-server
sudo mkdir -p /data/nfs
sudo chmod 777 /data/nfs
# 编辑 /etc/exports 文件,添加以下内容
# “*”表示所有人均可访问,可替换为“192.168.5.0/24”
/data/nfs *(rw,sync,no_all_squash,no_root_squash,no_subtree_check)
# 使配置生效
sudo exportfs -a
# 开放端口
sudo ufw allow 2049
sudo systemctl enable --now nfs-server
- 集群部署 Provisioner。
# 控制节点操作
proxy_on
helm repo add nfs-subdir-external-provisioner https://kubernetes-sigs.github.io/nfs-subdir-external-provisioner/
proxy_off
helm install nfs-subdir-external-provisioner nfs-subdir-external-provisioner/nfs-subdir-external-provisioner \
--set nfs.server=192.168.5.20 \
--set nfs.path=/data/nfs \
--set storageClass.defaultClass=true \
--set storageClass.name=my-custom-nfs-storage # 将"my-custom-nfs-storage"替换为你想要的名称