01 Kubernetes 集群部署操作指南

16 阅读6分钟

开始之前

照着文档内容步骤操作时,不存在百分百能够实现应有的效果,遇到问题时 AI 是最好的老师。

服务器基础信息

配置信息仅作参考,可降低配置:

主机IP操作系统配置
控制节点192.168.5.210Ubuntu 22.044 核 8G
部署节点192.168.5.211Ubuntu 22.044 核 8G
部署节点192.168.5.212Ubuntu 22.044 核 8G

集群版本信息:

服务版本
kubectlv1.34.3
Kubernetesv1.34.3
containerdv1.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,实现存储资源的动态分配和按需供给。它屏蔽了不同存储系统的差异,提供统一的存储管理接口,支持存储卷的自动创建、扩容、回收等全生命周期管理。

  1. 服务端部署
# 服务端 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
  1. 集群部署 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"替换为你想要的名称