找回密码
立即注册
搜索
热搜: Java Python Linux Go
发回帖 发新帖

504

积分

0

好友

60

主题
发表于 4 天前 | 查看: 14| 回复: 0

Kubernetes已成为容器编排的事实标准,但构建一个可用于生产环境的K8s集群并非易事。初次部署时,许多人按照官方文档执行kubeadm init,表面看似顺利,但在上线后却面临各种棘手问题:证书过期导致集群瘫痪、etcd数据丢失无法恢复、选错网络插件致使性能低下、Master单点故障引发业务中断……本文将系统梳理在企业级实践中积累的经验,帮助您规避常见陷阱。

一、概述

1.1 企业级集群核心要求

  • 高可用:部署多副本Master节点,消除单点故障风险。
  • 可扩展:能够便捷地添加或移除Worker节点。
  • 安全:实施RBAC权限控制、网络策略隔离及镜像安全扫描。
  • 可观测:建立完善的监控、日志收集与告警体系。
  • 灾备:制定etcd定期备份与恢复策略,规划多集群容灾方案。

1.2 架构设计

一个典型的高可用K8s集群架构如下:

┌─────────────────┐
│   LoadBalancer  │
│  (VIP: 10.0.0.100)│
└────────┬────────┘
         │
┌────────▼────────┐ ┌────────▼────────┐ ┌────────▼────────┐
│    Master-1     │ │    Master-2     │ │    Master-3     │
│   (API+ETCD)    │ │   (API+ETCD)    │ │   (API+ETCD)    │
└─────────────────┘ └─────────────────┘ └─────────────────┘
┌─────────┐ ┌─────────┐ ┌─────────┐ ┌─────────┐
│ Node-1  │ │ Node-2  │ │ Node-3  │ │ Node-N  │
│ Kubelet │ │ Kubelet │ │ Kubelet │ │ Kubelet │
│   CNI   │ │   CNI   │ │   CNI   │ │   CNI   │
└─────────┘ └─────────┘ └─────────┘ └─────────┘

1.3 环境与规划

组件版本:

  • 操作系统: CentOS 7.9 / Ubuntu 20.04+
  • Kubernetes: 1.28+
  • Container Runtime: containerd 1.7+ (自K8s 1.24起,不再内置Docker支持)
  • 网络插件: Calico 3.26+
服务器规划: 角色 主机名 IP 配置
Master-1 k8s-master-1 10.0.0.11 4C8G 100G
Master-2 k8s-master-2 10.0.0.12 4C8G 100G
Master-3 k8s-master-3 10.0.0.13 4C8G 100G
Node-1 k8s-node-1 10.0.0.21 8C16G 200G
Node-2 k8s-node-2 10.0.0.22 8C16G 200G
Node-3 k8s-node-3 10.0.0.23 8C16G 200G
VIP - 10.0.0.100 负载均衡

二、详细部署步骤

2.1 系统初始化(所有节点执行)

◆ 基础配置
# 设置主机名(每台机器执行对应的)
hostnamectl set-hostname k8s-master-1

# 配置hosts
cat >> /etc/hosts << 'EOF'
10.0.0.11 k8s-master-1
10.0.0.12 k8s-master-2
10.0.0.13 k8s-master-3
10.0.0.21 k8s-node-1
10.0.0.22 k8s-node-2
10.0.0.23 k8s-node-3
10.0.0.100 k8s-api  # VIP
EOF

# 关闭防火墙与SELinux(生产环境建议配置安全组规则)
systemctl stop firewalld && systemctl disable firewalld
setenforce 0
sed -i 's/^SELINUX=enforcing$/SELINUX=disabled/' /etc/selinux/config

# 关闭swap
swapoff -a
sed -i '/ swap / s/^\(.*\)$/#\1/g' /etc/fstab
free -h # 验证Swap为0
◆ 内核参数优化
cat > /etc/modules-load.d/k8s.conf << 'EOF'
overlay
br_netfilter
EOF
modprobe overlay
modprobe br_netfilter

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
# 性能优化参数
net.ipv4.tcp_max_syn_backlog = 65535
net.core.somaxconn = 65535
net.ipv4.tcp_tw_reuse = 1
net.ipv4.tcp_fin_timeout = 30
fs.file-max = 655360
fs.inotify.max_user_watches = 524288
EOF
sysctl --system
◆ 安装Container Runtime

从K8s 1.24开始,推荐使用containerd作为容器运行时

# 安装containerd
yum install -y yum-utils device-mapper-persistent-data lvm2
yum-config-manager --add-repo https://download.docker.com/linux/centos/docker-ce.repo
yum install -y containerd.io

# 生成并修改配置
containerd config default > /etc/containerd/config.toml
sed -i 's/SystemdCgroup = false/SystemdCgroup = true/' /etc/containerd/config.toml
# 国内用户可替换sandbox镜像地址
sed -i 's|registry.k8s.io/pause:3.8|registry.aliyuncs.com/google_containers/pause:3.9|' /etc/containerd/config.toml

systemctl enable containerd && systemctl start containerd
ctr version # 验证
◆ 安装Kubernetes组件
# 添加阿里云仓库
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

yum install -y kubelet-1.28.0 kubeadm-1.28.0 kubectl-1.28.0
systemctl enable kubelet

2.2 配置高可用负载均衡(在Master节点)

高可用是生产集群的基石。常见的方案有云厂商SLB、HAProxy + Keepalived以及kube-vip。这里以自建的HAProxy + Keepalived方案为例,部署在Master-1和Master-2上。

yum install -y haproxy keepalived
◆ HAProxy配置 (/etc/haproxy/haproxy.cfg)
global
    log /dev/log local0
    log /dev/log local1 notice
    daemon

defaults
    mode                    tcp
    log                     global
    option                  tcplog
    option                  dontlognull
    timeout connect         5000
    timeout client          50000
    timeout server          50000

frontend kubernetes-apiserver
    bind *:6443
    mode tcp
    option tcplog
    default_backend kubernetes-apiserver

backend kubernetes-apiserver
    mode tcp
    option tcp-check
    balance roundrobin
    server k8s-master-1 10.0.0.11:6443 check fall 3 rise 2
    server k8s-master-2 10.0.0.12:6443 check fall 3 rise 2
    server k8s-master-3 10.0.0.13:6443 check fall 3 rise 2

listen stats
    bind *:8080
    mode http
    stats enable
    stats uri /stats
    stats auth admin:admin123
◆ Keepalived配置与健康检查

这是一个经典的运维/DevOps高可用方案。
Master-1 (MASTER角色) 配置 (/etc/keepalived/keepalived.conf):

global_defs {
    router_id LVS_K8S
}
vrrp_script check_haproxy {
    script "/etc/keepalived/check_haproxy.sh"
    interval 3
    weight -20
}
vrrp_instance VI_1 {
    state MASTER
    interface eth0  # 修改为实际网卡
    virtual_router_id 51
    priority 100
    advert_int 1
    authentication {
        auth_type PASS
        auth_pass K8SHA_KA
    }
    virtual_ipaddress {
        10.0.0.100/24  # VIP
    }
    track_script {
        check_haproxy
    }
}

Master-2 (BACKUP角色) 配置文件类似,需修改state BACKUPpriority 90

健康检查脚本 (/etc/keepalived/check_haproxy.sh):

#!/bin/bash
if ! pidof haproxy > /dev/null; then
    systemctl restart haproxy
    sleep 3
    if ! pidof haproxy > /dev/null; then
        exit 1
    fi
fi
exit 0
chmod +x /etc/keepalived/check_haproxy.sh
systemctl enable haproxy keepalived && systemctl start haproxy keepalived
# 验证VIP
ip addr show | grep 10.0.0.100

2.3 初始化Kubernetes集群

◆ 准备kubeadm配置文件 (kubeadm-config.yaml)

在Master-1上创建配置文件,特别注意certSANs字段需包含所有可能的访问地址。

apiVersion: kubeadm.k8s.io/v1beta3
kind: ClusterConfiguration
kubernetesVersion: v1.28.0
controlPlaneEndpoint: "10.0.0.100:6443" # VIP地址
imageRepository: registry.aliyuncs.com/google_containers # 国内镜像源
networking:
  dnsDomain: cluster.local
  serviceSubnet: "10.96.0.0/12"
  podSubnet: "10.244.0.0/16"
etcd:
  local:
    dataDir: /var/lib/etcd
apiServer:
  certSANs:
    - "10.0.0.100"
    - "10.0.0.11"
    - "10.0.0.12"
    - "10.0.0.13"
    - "k8s-api"
    - "k8s-master-1"
    - "k8s-master-2"
    - "k8s-master-3"
  extraArgs:
    audit-log-path: /var/log/kubernetes/audit.log
    audit-log-maxage: "30"
    audit-log-maxbackup: "3"
    audit-log-maxsize: "100"
controllerManager:
  extraArgs:
    bind-address: 0.0.0.0
scheduler:
  extraArgs:
    bind-address: 0.0.0.0
---
apiVersion: kubeadm.k8s.io/v1beta3
kind: InitConfiguration
localAPIEndpoint:
  advertiseAddress: 10.0.0.11 # 当前Master的IP
  bindPort: 6443
nodeRegistration:
  criSocket: unix:///var/run/containerd/containerd.sock
  taints:
  - effect: NoSchedule
    key: node-role.kubernetes.io/control-plane
◆ 初始化第一个Master节点
# 预拉取镜像
kubeadm config images pull --config kubeadm-config.yaml
# 初始化集群
kubeadm init --config=kubeadm-config.yaml --upload-certs

初始化成功后,会输出用于加入集群的命令,请妥善保存。

# 配置kubectl
mkdir -p $HOME/.kube
cp -i /etc/kubernetes/admin.conf $HOME/.kube/config
chown $(id -u):$(id -g) $HOME/.kube/config
kubectl get nodes # 验证
◆ 加入其他Master及Worker节点
  • 加入其他Master (在Master-2, Master-3上执行):
    kubeadm join 10.0.0.100:6443 \
    --token <token> \
    --discovery-token-ca-cert-hash sha256:<hash> \
    --control-plane \
    --certificate-key <certificate-key>

    同样需要复制admin.conf以使用kubectl。

  • 加入Worker节点 (在所有Node上执行):
    kubeadm join 10.0.0.100:6443 \
    --token <token> \
    --discovery-token-ca-cert-hash sha256:<hash>

2.4 安装CNI网络插件

集群初始化后,节点状态为NotReady,需安装网络插件。

# 安装Calico
kubectl apply -f https://raw.githubusercontent.com/projectcalico/calico/v3.26.1/manifests/calico.yaml
# 如果Pod CIDR不是默认的192.168.0.0/16,需要设置环境变量
# kubectl set env daemonset/calico-node -n kube-system CALICO_IPV4POOL_CIDR="10.244.0.0/16"
kubectl get pods -n kube-system -w # 等待Pod就绪
kubectl get nodes # 所有节点应变为Ready状态

2.5 基础功能验证

# 查看集群状态
kubectl get nodes -o wide
kubectl get pods -n kube-system

# 创建测试应用
kubectl run nginx --image=nginx:alpine
kubectl expose pod nginx --port=80 --type=NodePort
kubectl get svc nginx # 获取NodePort,通过<NodeIP>:<NodePort>访问

# 清理测试资源
kubectl delete pod,svc nginx

三、关键配置与避坑指南

3.1 证书过期管理(坑1)

K8s组件证书默认有效期为1年,过期将导致集群不可用。

# 查看证书有效期
kubeadm certs check-expiration

# 手动更新所有证书
cp -r /etc/kubernetes/pki /etc/kubernetes/pki.bak # 备份
kubeadm certs renew all
# 重启控制平面静态Pod
crictl pods --namespace kube-system | grep -E 'kube-apiserver|kube-controller|kube-scheduler|etcd' | awk '{print $1}' | xargs crictl rmp -f
cp /etc/kubernetes/admin.conf $HOME/.kube/config # 更新kubeconfig

# 推荐:设置每月自动更新的Cron任务
# 文件 /etc/cron.monthly/k8s-cert-renew
#!/bin/bash
kubeadm certs renew all
crictl pods --namespace kube-system | grep -E 'kube-apiserver|kube-controller|kube-scheduler' | awk '{print $1}' | xargs crictl rmp -f

3.2 etcd数据备份与恢复(坑2)

etcd存储了集群所有状态数据,必须定期备份。

#!/bin/bash
# /opt/scripts/etcd_backup.sh
BACKUP_DIR="/data/etcd-backup"
DATE=$(date +%Y%m%d_%H%M%S)
ETCDCTL_API=3
mkdir -p ${BACKUP_DIR}
etcdctl snapshot save ${BACKUP_DIR}/etcd-snapshot-${DATE}.db \
  --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
# 验证备份文件
etcdctl snapshot status ${BACKUP_DIR}/etcd-snapshot-${DATE}.db
# 清理旧备份(保留7天)
find ${BACKUP_DIR} -name "*.db" -mtime +7 -delete

通过Cron设置每日备份:0 2 * * * /opt/scripts/etcd_backup.sh >> /var/log/etcd-backup.log 2>&1

3.3 集群健康检查脚本

#!/bin/bash
# k8s_health_check.sh
echo "========================================"
echo "K8s集群健康检查 $(date)"
echo "========================================"
echo ""
echo "=== 节点状态 ==="
kubectl get nodes -o wide
echo ""
echo "=== 系统Pod状态 ==="
kubectl get pods -n kube-system -o wide | grep -v Running
echo ""
echo "=== 异常Pod ==="
kubectl get pods -A | grep -v Running | grep -v Completed
echo ""
echo "=== etcd健康状态 ==="
kubectl exec -n kube-system etcd-k8s-master-1 -- 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 \
  endpoint health
echo ""
echo "=== 证书有效期 ==="
kubeadm certs check-expiration 2>/dev/null
echo ""
echo "=== 资源使用 ==="
kubectl top nodes 2>/dev/null || echo "需要安装metrics-server"
echo "========================================"

3.4 10大常见避坑总结

问题描述 解决方案
1 证书1年过期,集群瘫痪 设置自动更新Cron任务
2 etcd数据丢失,集群无法恢复 每日定时备份etcd数据
3 Master单点故障 部署3节点高可用架构
4 Flannel网络性能不佳 生产环境推荐改用Calico
5 网络插件CIDR配置不匹配 确保kubeadm-config.yamlpodSubnet与CNI插件配置一致
6 containerd未配置SystemdCgroup 配置文件中设置SystemdCgroup = true
7 未关闭swap导致kubelet启动失败 初始化前务必关闭swap
8 国内环境拉取官方镜像失败 使用阿里云等国内镜像源
9 证书SAN列表不全,API访问失败 初始化时在certSANs中列出所有IP和域名
10 跨大版本升级导致兼容性问题 遵循官方指南,逐次小版本升级

四、生产环境最佳实践

4.1 节点与资源规划建议

集群规模参考:

  • 小型集群 (<50 Pods): 3 Master, 3+ Worker, etcd内置。
  • 中型集群 (50-500 Pods): 3 Master, 10+ Worker, etcd内置。
  • 大型集群 (>500 Pods): 3 Master, 50+ Worker,考虑外置5节点etcd集群。

资源配置:

  • Master节点: 小型4C8G,中型8C16G,大型16C32G。
  • Worker节点: 通用型8C16G,计算密集16C32G,内存密集8C64G。

4.2 基础安全加固

# 1. 应用最小权限RBAC
kubectl create clusterrolebinding ops-admin \
  --clusterrole=admin \
  --user=ops@example.com

# 2. 配置默认拒绝所有流量的网络策略
cat <<EOF | kubectl apply -f -
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
  name: default-deny-all
  namespace: default
spec:
  podSelector: {}
  policyTypes:
  - Ingress
  - Egress
EOF

# 3. 启用Pod安全标准 (PSA)
kubectl label namespace default pod-security.kubernetes.io/enforce=restricted

4.3 版本升级注意事项

升级应遵循“先Master后Node,逐版本进行”的原则。

# 查看可升级版本
yum list --showduplicates kubeadm

# 升级流程示例 (1.28 -> 1.29)
# 1. 升级第一个Master的kubeadm
yum install -y kubeadm-1.29.0
# 2. 检查升级计划
kubeadm upgrade plan
# 3. 执行升级
kubeadm upgrade apply v1.29.0
# 4. 升级其他Master
kubeadm upgrade node
# 5. 升级所有节点的kubelet和kubectl
yum install -y kubelet-1.29.0 kubectl-1.29.0
systemctl daemon-reload && systemctl restart kubelet

4.4 故障排查与监控部署

◆ 常用排查命令
kubectl describe node <node-name>   # 节点详情
kubectl describe pod <pod-name>     # Pod详情与事件
kubectl logs <pod-name> [-c <container>] # 查看日志
kubectl exec -it <pod-name> -- sh   # 进入容器
kubectl get events --sort-by='.lastTimestamp' # 查看集群事件
journalctl -u kubelet -f            # 查看kubelet日志
◆ 部署基础监控(metrics-server)
kubectl apply -f https://github.com/kubernetes-sigs/metrics-server/releases/download/v0.6.4/components.yaml
# 若因证书问题无法连接,可编辑部署添加 `--kubelet-insecure-tls` 参数(仅限测试或内网环境)
# kubectl edit deployment metrics-server -n kube-system
kubectl top nodes  # 验证资源监控

五、总结

构建企业级Kubernetes集群是一项系统工程,关键在于前期规划与对细节的把握。牢记高可用是基础、数据备份是保险、证书管理需重视、网络选择要谨慎、升级过程应稳妥。在掌握本篇部署与避坑要点后,可进一步探索GitOps(ArgoCD)、服务网格(Istio)、多集群管理等进阶主题,构建更加强大和智能的云原生基础设施。

附录:常用端口与命令速查

  • kube-apiserver: 6443
  • etcd: 2379 (client), 2380 (peer)
  • kubelet: 10250
    
    # 集群管理
    kubeadm token create --print-join-command  # 生成新join命令
    kubeadm reset                              # 重置节点

资源查看

kubectl get pods -A -o wide
kubectl get svc,deploy,sts -A




上一篇:SAM 3D应用实战:从单图生成可编辑的3D人体模型
下一篇:Linux无线网络开发实战:基于udhcpd实现DHCP IP-MAC绑定
您需要登录后才可以回帖 登录 | 立即注册

手机版|小黑屋|网站地图|云栈社区 ( 苏ICP备2022046150号-2 )

GMT+8, 2025-12-13 23:08 , Processed in 0.107389 second(s), 39 queries , Gzip On.

Powered by Discuz! X3.5

© 2025-2025 云栈社区.

快速回复 返回顶部 返回列表