Add k3s cluster expansion documentation and scripts
- Complete expansion guide for 2/4/6 node scenarios - Quick join scripts for worker and master nodes - Health check and diagnostic scripts - Quick reference card for common operations
This commit is contained in:
5
.gitignore
vendored
Normal file
5
.gitignore
vendored
Normal file
@@ -0,0 +1,5 @@
|
||||
.claude/
|
||||
*.swp
|
||||
*.swo
|
||||
*~
|
||||
.DS_Store
|
||||
844
K3S-CLUSTER-EXPANSION.md
Normal file
844
K3S-CLUSTER-EXPANSION.md
Normal file
@@ -0,0 +1,844 @@
|
||||
# K3s 集群扩展指南
|
||||
|
||||
## 📋 目录
|
||||
- [当前集群状态](#当前集群状态)
|
||||
- [前置条件](#前置条件)
|
||||
- [架构设计方案](#架构设计方案)
|
||||
- [2节点集群(1 Master + 2 Worker)](#2节点集群1-master--2-worker)
|
||||
- [4节点集群(3 Master + 4 Worker)](#4节点集群3-master--4-worker)
|
||||
- [6节点集群(3 Master + 6 Worker)](#6节点集群3-master--6-worker)
|
||||
- [节点加入步骤](#节点加入步骤)
|
||||
- [高可用配置](#高可用配置)
|
||||
- [存储配置](#存储配置)
|
||||
- [验证和测试](#验证和测试)
|
||||
- [故障排查](#故障排查)
|
||||
|
||||
---
|
||||
|
||||
## 📊 当前集群状态
|
||||
|
||||
```
|
||||
Master 节点: vmus9
|
||||
IP 地址: 134.195.210.237
|
||||
k3s 版本: v1.34.3+k3s1
|
||||
节点令牌: K109d35a131f48b4d40b162398a828b766d60735f29dd7b4a37b030c1d1c0e26b23::server:72e04c3a9e3e762cbdefffc96f348a2d
|
||||
```
|
||||
|
||||
**重要**: 请妥善保管节点令牌,这是其他节点加入集群的凭证!
|
||||
|
||||
---
|
||||
|
||||
## ✅ 前置条件
|
||||
|
||||
### 所有新节点需要满足:
|
||||
|
||||
#### 1. 硬件要求
|
||||
```
|
||||
最低配置:
|
||||
- CPU: 2 核
|
||||
- 内存: 2GB (建议 4GB+)
|
||||
- 磁盘: 20GB (Longhorn 存储建议 50GB+)
|
||||
|
||||
推荐配置:
|
||||
- CPU: 4 核
|
||||
- 内存: 8GB
|
||||
- 磁盘: 100GB SSD
|
||||
```
|
||||
|
||||
#### 2. 操作系统
|
||||
```bash
|
||||
# 支持的系统
|
||||
- Ubuntu 20.04/22.04/24.04
|
||||
- Debian 10/11/12
|
||||
- CentOS 7/8
|
||||
- RHEL 7/8
|
||||
|
||||
# 检查系统版本
|
||||
cat /etc/os-release
|
||||
```
|
||||
|
||||
#### 3. 网络要求
|
||||
```bash
|
||||
# 所有节点之间需要能够互相访问
|
||||
# 需要开放的端口:
|
||||
|
||||
Master 节点:
|
||||
- 6443: Kubernetes API Server
|
||||
- 10250: Kubelet metrics
|
||||
- 2379-2380: etcd (仅 HA 模式)
|
||||
|
||||
Worker 节点:
|
||||
- 10250: Kubelet metrics
|
||||
- 30000-32767: NodePort Services
|
||||
|
||||
所有节点:
|
||||
- 8472: Flannel VXLAN (UDP)
|
||||
- 51820: Flannel WireGuard (UDP)
|
||||
```
|
||||
|
||||
#### 4. 系统准备
|
||||
在每个新节点上执行:
|
||||
|
||||
```bash
|
||||
# 1. 更新系统
|
||||
sudo apt update && sudo apt upgrade -y
|
||||
|
||||
# 2. 禁用 swap (k8s 要求)
|
||||
sudo swapoff -a
|
||||
sudo sed -i '/ swap / s/^/#/' /etc/fstab
|
||||
|
||||
# 3. 配置主机名 (每个节点不同)
|
||||
sudo hostnamectl set-hostname worker-node-1
|
||||
|
||||
# 4. 配置时间同步
|
||||
sudo apt install -y chrony
|
||||
sudo systemctl enable --now chrony
|
||||
|
||||
# 5. 安装必要工具
|
||||
sudo apt install -y curl wget git
|
||||
|
||||
# 6. 配置防火墙 (如果启用)
|
||||
# Ubuntu/Debian
|
||||
sudo ufw allow 6443/tcp
|
||||
sudo ufw allow 10250/tcp
|
||||
sudo ufw allow 8472/udp
|
||||
sudo ufw allow 51820/udp
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 🏗️ 架构设计方案
|
||||
|
||||
### 方案一:2节点集群(1 Master + 2 Worker)
|
||||
|
||||
**适用场景**: 开发/测试环境,小型应用
|
||||
|
||||
```
|
||||
┌─────────────────────────────────────────────────┐
|
||||
│ 负载均衡 (可选) │
|
||||
│ *.u9.net3w.com (Traefik) │
|
||||
└─────────────────────────────────────────────────┘
|
||||
│
|
||||
┌─────────────┼─────────────┐
|
||||
│ │ │
|
||||
┌───────▼──────┐ ┌────▼─────┐ ┌────▼─────┐
|
||||
│ Master │ │ Worker-1 │ │ Worker-2 │
|
||||
│ vmus9 │ │ │ │ │
|
||||
│ Control Plane│ │ 应用负载 │ │ 应用负载 │
|
||||
│ + etcd │ │ │ │ │
|
||||
│ 134.195.x.x │ │ 新节点1 │ │ 新节点2 │
|
||||
└──────────────┘ └──────────┘ └──────────┘
|
||||
```
|
||||
|
||||
**特点**:
|
||||
- ✅ 简单易维护
|
||||
- ✅ 成本低
|
||||
- ❌ Master 单点故障
|
||||
- ❌ 不适合生产环境
|
||||
|
||||
**资源分配建议**:
|
||||
- Master: 4C8G (运行控制平面 + 部分应用)
|
||||
- Worker-1: 4C8G (运行应用负载)
|
||||
- Worker-2: 4C8G (运行应用负载)
|
||||
|
||||
---
|
||||
|
||||
### 方案二:4节点集群(3 Master + 4 Worker)
|
||||
|
||||
**适用场景**: 生产环境,中等规模应用
|
||||
|
||||
```
|
||||
┌──────────────────────────────────────────────────┐
|
||||
│ 外部负载均衡 (必需) │
|
||||
│ HAProxy/Nginx/云厂商 LB │
|
||||
│ *.u9.net3w.com │
|
||||
└──────────────────────────────────────────────────┘
|
||||
│
|
||||
┌─────────────┼─────────────┬─────────────┐
|
||||
│ │ │ │
|
||||
┌───────▼──────┐ ┌────▼─────┐ ┌────▼─────┐ ┌─────▼────┐
|
||||
│ Master-1 │ │ Master-2 │ │ Master-3 │ │ Worker-1 │
|
||||
│ vmus9 │ │ │ │ │ │ │
|
||||
│ Control Plane│ │ Control │ │ Control │ │ 应用负载 │
|
||||
│ + etcd │ │ + etcd │ │ + etcd │ │ │
|
||||
└──────────────┘ └──────────┘ └──────────┘ └──────────┘
|
||||
┌──────────┐
|
||||
│ Worker-2 │
|
||||
│ 应用负载 │
|
||||
└──────────┘
|
||||
┌──────────┐
|
||||
│ Worker-3 │
|
||||
│ 应用负载 │
|
||||
└──────────┘
|
||||
┌──────────┐
|
||||
│ Worker-4 │
|
||||
│ 应用负载 │
|
||||
└──────────┘
|
||||
```
|
||||
|
||||
**特点**:
|
||||
- ✅ 高可用 (HA)
|
||||
- ✅ Master 节点冗余
|
||||
- ✅ 适合生产环境
|
||||
- ✅ 可承载中等规模应用
|
||||
- ⚠️ 需要外部负载均衡
|
||||
|
||||
**资源分配建议**:
|
||||
- Master-1/2/3: 4C8G (仅运行控制平面)
|
||||
- Worker-1/2/3/4: 8C16G (运行应用负载)
|
||||
|
||||
**etcd 集群**: 3 个 Master 节点组成 etcd 集群,可容忍 1 个节点故障
|
||||
|
||||
---
|
||||
|
||||
### 方案三:6节点集群(3 Master + 6 Worker)
|
||||
|
||||
**适用场景**: 大规模生产环境,高负载应用
|
||||
|
||||
```
|
||||
┌──────────────────────────────────────────────────┐
|
||||
│ 外部负载均衡 (必需) │
|
||||
│ HAProxy/Nginx/云厂商 LB │
|
||||
│ *.u9.net3w.com │
|
||||
└──────────────────────────────────────────────────┘
|
||||
│
|
||||
┌─────────────┼─────────────┬─────────────┐
|
||||
│ │ │ │
|
||||
┌───────▼──────┐ ┌────▼─────┐ ┌────▼─────┐ │
|
||||
│ Master-1 │ │ Master-2 │ │ Master-3 │ │
|
||||
│ vmus9 │ │ │ │ │ │
|
||||
│ Control Plane│ │ Control │ │ Control │ │
|
||||
│ + etcd │ │ + etcd │ │ + etcd │ │
|
||||
└──────────────┘ └──────────┘ └──────────┘ │
|
||||
│
|
||||
┌─────────────┬─────────────┬─────────────┘
|
||||
│ │ │
|
||||
┌───────▼──────┐ ┌────▼─────┐ ┌────▼─────┐
|
||||
│ Worker-1 │ │ Worker-2 │ │ Worker-3 │
|
||||
│ Web 应用层 │ │ Web 层 │ │ Web 层 │
|
||||
└──────────────┘ └──────────┘ └──────────┘
|
||||
┌──────────────┐ ┌──────────┐ ┌──────────┐
|
||||
│ Worker-4 │ │ Worker-5 │ │ Worker-6 │
|
||||
│ 数据库层 │ │ 缓存层 │ │ 存储层 │
|
||||
└──────────────┘ └──────────┘ └──────────┘
|
||||
```
|
||||
|
||||
**特点**:
|
||||
- ✅ 高可用 + 高性能
|
||||
- ✅ 可按功能分层部署
|
||||
- ✅ 支持大规模应用
|
||||
- ✅ Longhorn 存储性能最佳
|
||||
- ⚠️ 管理复杂度较高
|
||||
- ⚠️ 成本较高
|
||||
|
||||
**资源分配建议**:
|
||||
- Master-1/2/3: 4C8G (专用控制平面)
|
||||
- Worker-1/2/3: 8C16G (Web 应用层)
|
||||
- Worker-4: 8C32G (数据库层,高内存)
|
||||
- Worker-5: 8C16G (缓存层)
|
||||
- Worker-6: 4C8G + 200GB SSD (存储层)
|
||||
|
||||
**节点标签策略**:
|
||||
```bash
|
||||
# Web 层
|
||||
kubectl label nodes worker-1 node-role=web
|
||||
kubectl label nodes worker-2 node-role=web
|
||||
kubectl label nodes worker-3 node-role=web
|
||||
|
||||
# 数据库层
|
||||
kubectl label nodes worker-4 node-role=database
|
||||
|
||||
# 缓存层
|
||||
kubectl label nodes worker-5 node-role=cache
|
||||
|
||||
# 存储层
|
||||
kubectl label nodes worker-6 node-role=storage
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 🚀 节点加入步骤
|
||||
|
||||
### 场景 A: 加入 Worker 节点(适用于 2 节点方案)
|
||||
|
||||
#### 在新节点上执行:
|
||||
|
||||
```bash
|
||||
# 1. 设置 Master 节点信息
|
||||
export MASTER_IP="134.195.210.237"
|
||||
export NODE_TOKEN="K109d35a131f48b4d40b162398a828b766d60735f29dd7b4a37b030c1d1c0e26b23::server:72e04c3a9e3e762cbdefffc96f348a2d"
|
||||
|
||||
# 2. 安装 k3s agent (Worker 节点)
|
||||
curl -sfL https://get.k3s.io | K3S_URL=https://${MASTER_IP}:6443 \
|
||||
K3S_TOKEN=${NODE_TOKEN} \
|
||||
sh -
|
||||
|
||||
# 3. 验证安装
|
||||
sudo systemctl status k3s-agent
|
||||
|
||||
# 4. 检查节点是否加入
|
||||
# (在 Master 节点执行)
|
||||
kubectl get nodes
|
||||
```
|
||||
|
||||
#### 为 Worker 节点添加标签:
|
||||
|
||||
```bash
|
||||
# 在 Master 节点执行
|
||||
kubectl label nodes <worker-node-name> node-role.kubernetes.io/worker=worker
|
||||
kubectl label nodes <worker-node-name> workload=application
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
### 场景 B: 加入 Master 节点(适用于 4/6 节点 HA 方案)
|
||||
|
||||
#### 前提条件:需要外部负载均衡器
|
||||
|
||||
##### 1. 配置外部负载均衡器
|
||||
|
||||
**选项 1: 使用 HAProxy**
|
||||
|
||||
在一台独立服务器上安装 HAProxy:
|
||||
|
||||
```bash
|
||||
# 安装 HAProxy
|
||||
sudo apt install -y haproxy
|
||||
|
||||
# 配置 HAProxy
|
||||
sudo tee /etc/haproxy/haproxy.cfg > /dev/null <<EOF
|
||||
global
|
||||
log /dev/log local0
|
||||
log /dev/log local1 notice
|
||||
chroot /var/lib/haproxy
|
||||
stats socket /run/haproxy/admin.sock mode 660 level admin
|
||||
stats timeout 30s
|
||||
user haproxy
|
||||
group haproxy
|
||||
daemon
|
||||
|
||||
defaults
|
||||
log global
|
||||
mode tcp
|
||||
option tcplog
|
||||
option dontlognull
|
||||
timeout connect 5000
|
||||
timeout client 50000
|
||||
timeout server 50000
|
||||
|
||||
frontend k3s-api
|
||||
bind *:6443
|
||||
mode tcp
|
||||
default_backend k3s-masters
|
||||
|
||||
backend k3s-masters
|
||||
mode tcp
|
||||
balance roundrobin
|
||||
option tcp-check
|
||||
server master-1 134.195.210.237:6443 check fall 3 rise 2
|
||||
server master-2 <MASTER-2-IP>:6443 check fall 3 rise 2
|
||||
server master-3 <MASTER-3-IP>:6443 check fall 3 rise 2
|
||||
EOF
|
||||
|
||||
# 重启 HAProxy
|
||||
sudo systemctl restart haproxy
|
||||
sudo systemctl enable haproxy
|
||||
```
|
||||
|
||||
**选项 2: 使用 Nginx**
|
||||
|
||||
```bash
|
||||
# 安装 Nginx
|
||||
sudo apt install -y nginx
|
||||
|
||||
# 配置 Nginx Stream
|
||||
sudo tee /etc/nginx/nginx.conf > /dev/null <<EOF
|
||||
stream {
|
||||
upstream k3s_servers {
|
||||
server 134.195.210.237:6443 max_fails=3 fail_timeout=5s;
|
||||
server <MASTER-2-IP>:6443 max_fails=3 fail_timeout=5s;
|
||||
server <MASTER-3-IP>:6443 max_fails=3 fail_timeout=5s;
|
||||
}
|
||||
|
||||
server {
|
||||
listen 6443;
|
||||
proxy_pass k3s_servers;
|
||||
}
|
||||
}
|
||||
EOF
|
||||
|
||||
# 重启 Nginx
|
||||
sudo systemctl restart nginx
|
||||
```
|
||||
|
||||
##### 2. 在第一个 Master 节点(当前节点)启用 HA
|
||||
|
||||
```bash
|
||||
# 在当前 Master 节点执行
|
||||
export LB_IP="<负载均衡器IP>"
|
||||
|
||||
# 重新安装 k3s 为 HA 模式
|
||||
curl -sfL https://get.k3s.io | sh -s - server \
|
||||
--cluster-init \
|
||||
--tls-san=${LB_IP} \
|
||||
--write-kubeconfig-mode 644
|
||||
|
||||
# 获取新的 token
|
||||
sudo cat /var/lib/rancher/k3s/server/node-token
|
||||
```
|
||||
|
||||
##### 3. 加入第二个 Master 节点
|
||||
|
||||
```bash
|
||||
# 在新的 Master 节点执行
|
||||
export MASTER_IP="134.195.210.237" # 第一个 Master
|
||||
export LB_IP="<负载均衡器IP>"
|
||||
export NODE_TOKEN="<新的 token>"
|
||||
|
||||
curl -sfL https://get.k3s.io | sh -s - server \
|
||||
--server https://${MASTER_IP}:6443 \
|
||||
--token ${NODE_TOKEN} \
|
||||
--tls-san=${LB_IP} \
|
||||
--write-kubeconfig-mode 644
|
||||
```
|
||||
|
||||
##### 4. 加入第三个 Master 节点
|
||||
|
||||
```bash
|
||||
# 在第三个 Master 节点执行(同上)
|
||||
export MASTER_IP="134.195.210.237"
|
||||
export LB_IP="<负载均衡器IP>"
|
||||
export NODE_TOKEN="<token>"
|
||||
|
||||
curl -sfL https://get.k3s.io | sh -s - server \
|
||||
--server https://${MASTER_IP}:6443 \
|
||||
--token ${NODE_TOKEN} \
|
||||
--tls-san=${LB_IP} \
|
||||
--write-kubeconfig-mode 644
|
||||
```
|
||||
|
||||
##### 5. 验证 HA 集群
|
||||
|
||||
```bash
|
||||
# 检查所有 Master 节点
|
||||
kubectl get nodes
|
||||
|
||||
# 检查 etcd 集群状态
|
||||
kubectl get pods -n kube-system | grep etcd
|
||||
|
||||
# 检查 etcd 成员
|
||||
sudo k3s etcd-snapshot save --etcd-s3=false
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
### 场景 C: 混合加入(先加 Master 再加 Worker)
|
||||
|
||||
**推荐顺序**:
|
||||
1. 配置外部负载均衡器
|
||||
2. 转换第一个节点为 HA 模式
|
||||
3. 加入第 2、3 个 Master 节点
|
||||
4. 验证 Master 集群正常
|
||||
5. 依次加入 Worker 节点
|
||||
|
||||
---
|
||||
|
||||
## 💾 存储配置
|
||||
|
||||
### Longhorn 多节点配置
|
||||
|
||||
当集群有 3+ 节点时,Longhorn 可以提供分布式存储和数据冗余。
|
||||
|
||||
#### 1. 在所有节点安装依赖
|
||||
|
||||
```bash
|
||||
# 在每个节点执行
|
||||
sudo apt install -y open-iscsi nfs-common
|
||||
|
||||
# 启动 iscsid
|
||||
sudo systemctl enable --now iscsid
|
||||
```
|
||||
|
||||
#### 2. 配置 Longhorn 副本数
|
||||
|
||||
```bash
|
||||
# 在 Master 节点执行
|
||||
kubectl edit settings.longhorn.io default-replica-count -n longhorn-system
|
||||
|
||||
# 修改为:
|
||||
# value: "3" # 3 副本(需要至少 3 个节点)
|
||||
# value: "2" # 2 副本(需要至少 2 个节点)
|
||||
```
|
||||
|
||||
#### 3. 为节点添加存储标签
|
||||
|
||||
```bash
|
||||
# 标记哪些节点用于存储
|
||||
kubectl label nodes worker-1 node.longhorn.io/create-default-disk=true
|
||||
kubectl label nodes worker-2 node.longhorn.io/create-default-disk=true
|
||||
kubectl label nodes worker-3 node.longhorn.io/create-default-disk=true
|
||||
|
||||
# 排除某些节点(如纯计算节点)
|
||||
kubectl label nodes worker-4 node.longhorn.io/create-default-disk=false
|
||||
```
|
||||
|
||||
#### 4. 配置存储路径
|
||||
|
||||
```bash
|
||||
# 在每个存储节点创建目录
|
||||
sudo mkdir -p /var/lib/longhorn
|
||||
sudo chmod 700 /var/lib/longhorn
|
||||
```
|
||||
|
||||
#### 5. 访问 Longhorn UI
|
||||
|
||||
```bash
|
||||
# 创建 Ingress (如果还没有)
|
||||
kubectl apply -f k3s/my-blog/longhorn-ingress.yaml
|
||||
|
||||
# 访问: https://longhorn.u9.net3w.com
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## ✅ 验证和测试
|
||||
|
||||
### 1. 检查节点状态
|
||||
|
||||
```bash
|
||||
# 查看所有节点
|
||||
kubectl get nodes -o wide
|
||||
|
||||
# 查看节点详细信息
|
||||
kubectl describe node <node-name>
|
||||
|
||||
# 查看节点资源使用
|
||||
kubectl top nodes
|
||||
```
|
||||
|
||||
### 2. 测试 Pod 调度
|
||||
|
||||
```bash
|
||||
# 创建测试 Deployment
|
||||
kubectl create deployment nginx-test --image=nginx --replicas=6
|
||||
|
||||
# 查看 Pod 分布
|
||||
kubectl get pods -o wide
|
||||
|
||||
# 清理测试
|
||||
kubectl delete deployment nginx-test
|
||||
```
|
||||
|
||||
### 3. 测试存储
|
||||
|
||||
```bash
|
||||
# 创建测试 PVC
|
||||
cat <<EOF | kubectl apply -f -
|
||||
apiVersion: v1
|
||||
kind: PersistentVolumeClaim
|
||||
metadata:
|
||||
name: test-pvc
|
||||
spec:
|
||||
accessModes:
|
||||
- ReadWriteOnce
|
||||
storageClassName: longhorn
|
||||
resources:
|
||||
requests:
|
||||
storage: 1Gi
|
||||
EOF
|
||||
|
||||
# 检查 PVC 状态
|
||||
kubectl get pvc test-pvc
|
||||
|
||||
# 清理
|
||||
kubectl delete pvc test-pvc
|
||||
```
|
||||
|
||||
### 4. 测试高可用(仅 HA 集群)
|
||||
|
||||
```bash
|
||||
# 模拟 Master 节点故障
|
||||
# 在一个 Master 节点执行
|
||||
sudo systemctl stop k3s
|
||||
|
||||
# 在另一个节点检查集群是否正常
|
||||
kubectl get nodes
|
||||
|
||||
# 恢复节点
|
||||
sudo systemctl start k3s
|
||||
```
|
||||
|
||||
### 5. 测试网络连通性
|
||||
|
||||
```bash
|
||||
# 在 Master 节点创建测试 Pod
|
||||
kubectl run test-pod --image=busybox --restart=Never -- sleep 3600
|
||||
|
||||
# 进入 Pod 测试网络
|
||||
kubectl exec -it test-pod -- sh
|
||||
|
||||
# 在 Pod 内测试
|
||||
ping 8.8.8.8
|
||||
nslookup kubernetes.default
|
||||
|
||||
# 清理
|
||||
kubectl delete pod test-pod
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 🔧 故障排查
|
||||
|
||||
### 问题 1: 节点无法加入集群
|
||||
|
||||
**症状**: `k3s-agent` 服务启动失败
|
||||
|
||||
**排查步骤**:
|
||||
|
||||
```bash
|
||||
# 1. 检查服务状态
|
||||
sudo systemctl status k3s-agent
|
||||
|
||||
# 2. 查看日志
|
||||
sudo journalctl -u k3s-agent -f
|
||||
|
||||
# 3. 检查网络连通性
|
||||
ping <MASTER_IP>
|
||||
telnet <MASTER_IP> 6443
|
||||
|
||||
# 4. 检查 token 是否正确
|
||||
echo $NODE_TOKEN
|
||||
|
||||
# 5. 检查防火墙
|
||||
sudo ufw status
|
||||
```
|
||||
|
||||
**解决方案**:
|
||||
```bash
|
||||
# 重新安装
|
||||
sudo /usr/local/bin/k3s-agent-uninstall.sh
|
||||
curl -sfL https://get.k3s.io | K3S_URL=https://${MASTER_IP}:6443 \
|
||||
K3S_TOKEN=${NODE_TOKEN} sh -
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
### 问题 2: 节点状态为 NotReady
|
||||
|
||||
**症状**: `kubectl get nodes` 显示节点 NotReady
|
||||
|
||||
**排查步骤**:
|
||||
|
||||
```bash
|
||||
# 1. 检查节点详情
|
||||
kubectl describe node <node-name>
|
||||
|
||||
# 2. 检查 kubelet 日志
|
||||
# 在问题节点执行
|
||||
sudo journalctl -u k3s-agent -n 100
|
||||
|
||||
# 3. 检查网络插件
|
||||
kubectl get pods -n kube-system | grep flannel
|
||||
```
|
||||
|
||||
**解决方案**:
|
||||
```bash
|
||||
# 重启 k3s 服务
|
||||
sudo systemctl restart k3s-agent
|
||||
|
||||
# 如果是网络问题,检查 CNI 配置
|
||||
sudo ls -la /etc/cni/net.d/
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
### 问题 3: Pod 无法调度到新节点
|
||||
|
||||
**症状**: Pod 一直 Pending 或只调度到旧节点
|
||||
|
||||
**排查步骤**:
|
||||
|
||||
```bash
|
||||
# 1. 检查节点污点
|
||||
kubectl describe node <node-name> | grep Taints
|
||||
|
||||
# 2. 检查节点标签
|
||||
kubectl get nodes --show-labels
|
||||
|
||||
# 3. 检查 Pod 的调度约束
|
||||
kubectl describe pod <pod-name>
|
||||
```
|
||||
|
||||
**解决方案**:
|
||||
```bash
|
||||
# 移除污点
|
||||
kubectl taint nodes <node-name> node.kubernetes.io/not-ready:NoSchedule-
|
||||
|
||||
# 添加标签
|
||||
kubectl label nodes <node-name> node-role.kubernetes.io/worker=worker
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
### 问题 4: Longhorn 存储无法使用
|
||||
|
||||
**症状**: PVC 一直 Pending
|
||||
|
||||
**排查步骤**:
|
||||
|
||||
```bash
|
||||
# 1. 检查 Longhorn 组件
|
||||
kubectl get pods -n longhorn-system
|
||||
|
||||
# 2. 检查节点是否满足要求
|
||||
kubectl get nodes -o jsonpath='{.items[*].status.conditions[?(@.type=="Ready")].status}'
|
||||
|
||||
# 3. 检查 iscsid 服务
|
||||
sudo systemctl status iscsid
|
||||
```
|
||||
|
||||
**解决方案**:
|
||||
```bash
|
||||
# 在新节点安装依赖
|
||||
sudo apt install -y open-iscsi
|
||||
sudo systemctl enable --now iscsid
|
||||
|
||||
# 重启 Longhorn manager
|
||||
kubectl rollout restart deployment longhorn-driver-deployer -n longhorn-system
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
### 问题 5: etcd 集群不健康(HA 模式)
|
||||
|
||||
**症状**: Master 节点无法正常工作
|
||||
|
||||
**排查步骤**:
|
||||
|
||||
```bash
|
||||
# 1. 检查 etcd 成员
|
||||
sudo k3s etcd-snapshot ls
|
||||
|
||||
# 2. 检查 etcd 日志
|
||||
sudo journalctl -u k3s -n 100 | grep etcd
|
||||
|
||||
# 3. 检查 etcd 端口
|
||||
sudo netstat -tlnp | grep 2379
|
||||
```
|
||||
|
||||
**解决方案**:
|
||||
```bash
|
||||
# 从快照恢复(谨慎操作)
|
||||
sudo k3s server \
|
||||
--cluster-reset \
|
||||
--cluster-reset-restore-path=/var/lib/rancher/k3s/server/db/snapshots/<snapshot-name>
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 📚 快速参考
|
||||
|
||||
### 常用命令
|
||||
|
||||
```bash
|
||||
# 查看集群信息
|
||||
kubectl cluster-info
|
||||
kubectl get nodes -o wide
|
||||
kubectl get pods -A
|
||||
|
||||
# 查看节点资源
|
||||
kubectl top nodes
|
||||
kubectl describe node <node-name>
|
||||
|
||||
# 管理节点
|
||||
kubectl cordon <node-name> # 标记为不可调度
|
||||
kubectl drain <node-name> # 驱逐 Pod
|
||||
kubectl uncordon <node-name> # 恢复调度
|
||||
|
||||
# 删除节点
|
||||
kubectl delete node <node-name>
|
||||
|
||||
# 在节点上卸载 k3s
|
||||
# Worker 节点
|
||||
sudo /usr/local/bin/k3s-agent-uninstall.sh
|
||||
# Master 节点
|
||||
sudo /usr/local/bin/k3s-uninstall.sh
|
||||
```
|
||||
|
||||
### 节点标签示例
|
||||
|
||||
```bash
|
||||
# 角色标签
|
||||
kubectl label nodes <node> node-role.kubernetes.io/worker=worker
|
||||
kubectl label nodes <node> node-role.kubernetes.io/master=master
|
||||
|
||||
# 功能标签
|
||||
kubectl label nodes <node> workload=database
|
||||
kubectl label nodes <node> workload=web
|
||||
kubectl label nodes <node> workload=cache
|
||||
|
||||
# 区域标签
|
||||
kubectl label nodes <node> topology.kubernetes.io/zone=zone-a
|
||||
kubectl label nodes <node> topology.kubernetes.io/region=us-east
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 🎯 最佳实践
|
||||
|
||||
### 1. 节点命名规范
|
||||
```
|
||||
master-1, master-2, master-3
|
||||
worker-1, worker-2, worker-3, ...
|
||||
```
|
||||
|
||||
### 2. 逐步扩展
|
||||
- 先加入 1 个节点测试
|
||||
- 验证正常后再批量加入
|
||||
- 避免同时加入多个节点
|
||||
|
||||
### 3. 监控和告警
|
||||
```bash
|
||||
# 部署 Prometheus + Grafana
|
||||
kubectl apply -f https://raw.githubusercontent.com/prometheus-operator/kube-prometheus/main/manifests/setup/
|
||||
kubectl apply -f https://raw.githubusercontent.com/prometheus-operator/kube-prometheus/main/manifests/
|
||||
```
|
||||
|
||||
### 4. 定期备份
|
||||
```bash
|
||||
# 备份 etcd
|
||||
sudo k3s etcd-snapshot save --name backup-$(date +%Y%m%d-%H%M%S)
|
||||
|
||||
# 查看备份
|
||||
sudo k3s etcd-snapshot ls
|
||||
```
|
||||
|
||||
### 5. 资源预留
|
||||
```bash
|
||||
# 为系统组件预留资源
|
||||
kubectl apply -f - <<EOF
|
||||
apiVersion: v1
|
||||
kind: ResourceQuota
|
||||
metadata:
|
||||
name: system-quota
|
||||
namespace: kube-system
|
||||
spec:
|
||||
hard:
|
||||
requests.cpu: "2"
|
||||
requests.memory: 4Gi
|
||||
EOF
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 📞 获取帮助
|
||||
|
||||
- k3s 官方文档: https://docs.k3s.io
|
||||
- Longhorn 文档: https://longhorn.io/docs
|
||||
- Kubernetes 文档: https://kubernetes.io/docs
|
||||
|
||||
---
|
||||
|
||||
**文档版本**: v1.0
|
||||
**最后更新**: 2026-01-21
|
||||
**适用于**: k3s v1.34.3+k3s1
|
||||
161
QUICK-REFERENCE.md
Normal file
161
QUICK-REFERENCE.md
Normal file
@@ -0,0 +1,161 @@
|
||||
# K3s 集群扩展快速参考
|
||||
|
||||
## 🚀 快速开始
|
||||
|
||||
### 当前集群信息
|
||||
```
|
||||
Master IP: 134.195.210.237
|
||||
Token: K109d35a131f48b4d40b162398a828b766d60735f29dd7b4a37b030c1d1c0e26b23::server:72e04c3a9e3e762cbdefffc96f348a2d
|
||||
```
|
||||
|
||||
### 一键加入脚本
|
||||
|
||||
#### Worker 节点(最简单)
|
||||
```bash
|
||||
# 在新节点上执行
|
||||
sudo bash scripts/join-worker.sh
|
||||
```
|
||||
|
||||
#### Master 节点(HA 模式)
|
||||
```bash
|
||||
# 在新节点上执行
|
||||
sudo bash scripts/join-master.sh
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 📊 扩展方案对比
|
||||
|
||||
| 方案 | 节点配置 | 适用场景 | 高可用 | 成本 |
|
||||
|------|---------|---------|--------|------|
|
||||
| **2节点** | 1M + 2W | 开发/测试 | ❌ | 💰 |
|
||||
| **4节点** | 3M + 4W | 生产环境 | ✅ | 💰💰💰 |
|
||||
| **6节点** | 3M + 6W | 大规模生产 | ✅ | 💰💰💰💰 |
|
||||
|
||||
M = Master, W = Worker
|
||||
|
||||
---
|
||||
|
||||
## 🔧 手动加入命令
|
||||
|
||||
### Worker 节点
|
||||
```bash
|
||||
export MASTER_IP="134.195.210.237"
|
||||
export NODE_TOKEN="K109d35a131f48b4d40b162398a828b766d60735f29dd7b4a37b030c1d1c0e26b23::server:72e04c3a9e3e762cbdefffc96f348a2d"
|
||||
|
||||
curl -sfL https://get.k3s.io | K3S_URL=https://${MASTER_IP}:6443 \
|
||||
K3S_TOKEN=${NODE_TOKEN} sh -
|
||||
```
|
||||
|
||||
### Master 节点(需要先配置负载均衡器)
|
||||
```bash
|
||||
export FIRST_MASTER="134.195.210.237"
|
||||
export LB_IP="<负载均衡器IP>"
|
||||
export NODE_TOKEN="K109d35a131f48b4d40b162398a828b766d60735f29dd7b4a37b030c1d1c0e26b23::server:72e04c3a9e3e762cbdefffc96f348a2d"
|
||||
|
||||
curl -sfL https://get.k3s.io | sh -s - server \
|
||||
--server https://${FIRST_MASTER}:6443 \
|
||||
--token ${NODE_TOKEN} \
|
||||
--tls-san=${LB_IP} \
|
||||
--write-kubeconfig-mode 644
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## ✅ 验证命令
|
||||
|
||||
```bash
|
||||
# 查看节点
|
||||
kubectl get nodes -o wide
|
||||
|
||||
# 健康检查
|
||||
bash scripts/check-node-health.sh
|
||||
|
||||
# 查看节点详情
|
||||
kubectl describe node <node-name>
|
||||
|
||||
# 查看资源使用
|
||||
kubectl top nodes
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 🏷️ 节点标签
|
||||
|
||||
```bash
|
||||
# Worker 节点
|
||||
kubectl label nodes <node> node-role.kubernetes.io/worker=worker
|
||||
|
||||
# 功能标签
|
||||
kubectl label nodes <node> workload=web
|
||||
kubectl label nodes <node> workload=database
|
||||
kubectl label nodes <node> workload=cache
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 🔥 常见问题
|
||||
|
||||
### 节点无法加入?
|
||||
```bash
|
||||
# 检查网络
|
||||
ping 134.195.210.237
|
||||
telnet 134.195.210.237 6443
|
||||
|
||||
# 查看日志
|
||||
sudo journalctl -u k3s-agent -f
|
||||
```
|
||||
|
||||
### 节点 NotReady?
|
||||
```bash
|
||||
# 重启服务
|
||||
sudo systemctl restart k3s-agent
|
||||
|
||||
# 检查详情
|
||||
kubectl describe node <node-name>
|
||||
```
|
||||
|
||||
### 删除节点
|
||||
```bash
|
||||
# 在 Master 节点
|
||||
kubectl drain <node-name> --ignore-daemonsets
|
||||
kubectl delete node <node-name>
|
||||
|
||||
# 在要删除的节点
|
||||
sudo /usr/local/bin/k3s-agent-uninstall.sh
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 📚 详细文档
|
||||
|
||||
- 完整扩展指南: [K3S-CLUSTER-EXPANSION.md](K3S-CLUSTER-EXPANSION.md)
|
||||
- GitOps 自动部署: [README.md](README.md)
|
||||
|
||||
---
|
||||
|
||||
## 🎯 推荐流程
|
||||
|
||||
### 2节点扩展(开发环境)
|
||||
1. ✅ 准备 2 台新 VPS
|
||||
2. ✅ 执行 `join-worker.sh`
|
||||
3. ✅ 验证节点状态
|
||||
4. ✅ 测试应用部署
|
||||
|
||||
### 4节点扩展(生产环境)
|
||||
1. ✅ 配置外部负载均衡器
|
||||
2. ✅ 转换第一个节点为 HA 模式
|
||||
3. ✅ 加入 2 个 Master 节点
|
||||
4. ✅ 加入 4 个 Worker 节点
|
||||
5. ✅ 配置 Longhorn 多副本
|
||||
6. ✅ 测试高可用
|
||||
|
||||
### 6节点扩展(大规模)
|
||||
1. ✅ 同 4 节点方案
|
||||
2. ✅ 按功能分层部署
|
||||
3. ✅ 配置节点亲和性
|
||||
4. ✅ 优化资源分配
|
||||
|
||||
---
|
||||
|
||||
**快速帮助**: 遇到问题?运行 `bash scripts/check-node-health.sh` 进行诊断
|
||||
68
biji.md
Normal file
68
biji.md
Normal file
@@ -0,0 +1,68 @@
|
||||
k3s集群部署完成!
|
||||
|
||||
📊 部署总结
|
||||
|
||||
✅ 集群状态
|
||||
|
||||
- k3s版本: v1.34.3+k3s1
|
||||
- 节点状态: Ready (control-plane)
|
||||
- 运行中的Pods: 35个
|
||||
- 存储系统: Longhorn (分布式存储)
|
||||
- 证书管理: cert-manager + Let's Encrypt
|
||||
|
||||
🚀 已部署的服务
|
||||
|
||||
所有服务都已实现无状态化部署,数据和存储完全解耦:
|
||||
┌─────────────────┬───────────────────────────────┬────────────┬─────────────┬─────────────────┐
|
||||
│ 服务 │ 域名 │ 状态 │ 存储 │ HTTPS │
|
||||
├─────────────────┼───────────────────────────────┼────────────┼─────────────┼─────────────────┤
|
||||
│ WordPress博客 │ https://blog.u9.net3w.com │ ✅ Running │ 2Gi (MySQL) │ ✅ │
|
||||
├─────────────────┼───────────────────────────────┼────────────┼─────────────┼─────────────────┤
|
||||
│ Docker Registry │ https://registry.u9.net3w.com │ ✅ Running │ 20Gi │ ⏳ (证书申请中) │
|
||||
├─────────────────┼───────────────────────────────┼────────────┼─────────────┼─────────────────┤
|
||||
│ n8n工作流 │ https://n8n.u9.net3w.com │ ✅ Running │ 5Gi │ ✅ │
|
||||
├─────────────────┼───────────────────────────────┼────────────┼─────────────┼─────────────────┤
|
||||
│ Gitea代码仓库 │ https://git.u9.net3w.com │ ✅ Running │ 10Gi │ ✅ │
|
||||
├─────────────────┼───────────────────────────────┼────────────┼─────────────┼─────────────────┤
|
||||
│ Uptime Kuma监控 │ https://status.u9.net3w.com │ ✅ Running │ 2Gi │ ✅ │
|
||||
├─────────────────┼───────────────────────────────┼────────────┼─────────────┼─────────────────┤
|
||||
│ 导航页 │ https://nav.u9.net3w.com │ ✅ Running │ - │ ✅ │
|
||||
└─────────────────┴───────────────────────────────┴────────────┴─────────────┴─────────────────┘
|
||||
💾 存储配置
|
||||
|
||||
所有数据都使用Longhorn持久化存储,实现了容器与数据的完全解耦:
|
||||
- MySQL数据库: 2Gi独立存储卷
|
||||
- Docker镜像仓库: 20Gi独立存储卷
|
||||
- Gitea代码仓库: 10Gi独立存储卷
|
||||
- n8n工作流数据: 5Gi独立存储卷
|
||||
- Uptime Kuma监控数据: 2Gi独立存储卷
|
||||
|
||||
🔐 安全配置
|
||||
|
||||
- ✅ 自动HTTPS证书(Let's Encrypt)
|
||||
- ✅ Traefik Ingress Controller
|
||||
- ✅ Docker Registry认证(用户名: admin, 密码: 123456)
|
||||
|
||||
📝 常用命令
|
||||
|
||||
# 查看所有服务
|
||||
kubectl get pods -A
|
||||
|
||||
# 查看存储卷
|
||||
kubectl get pvc -A
|
||||
|
||||
# 查看域名和证书
|
||||
kubectl get ingress -A
|
||||
kubectl get certificate -A
|
||||
|
||||
# 查看Longhorn UI (可选)
|
||||
kubectl get svc -n longhorn-system
|
||||
|
||||
⚠️ 注意事项
|
||||
|
||||
1. Registry证书: registry.u9.net3w.com的SSL证书还在申请中,稍等几分钟会自动完成
|
||||
2. DNS解析: 确保所有*.u9.net3w.com子域名都已正确解析到 134.195.210.237
|
||||
3. 数据持久化: 所有数据都存储在Longhorn卷中,容器重启不会丢失数据
|
||||
|
||||
所有服务已成功实现无状态化部署,可以随时重启、扩容或迁移! 🎊
|
||||
|
||||
@@ -6,8 +6,8 @@ metadata:
|
||||
annotations:
|
||||
cert-manager.io/cluster-issuer: letsencrypt-prod
|
||||
traefik.ingress.kubernetes.io/router.entrypoints: websecure
|
||||
nginx.ingress.kubernetes.io/ssl-passthrough: "true"
|
||||
nginx.ingress.kubernetes.io/backend-protocol: "HTTPS"
|
||||
traefik.ingress.kubernetes.io/service.serversscheme: https
|
||||
traefik.ingress.kubernetes.io/service.serverstransport: insecure@file
|
||||
spec:
|
||||
tls:
|
||||
- hosts:
|
||||
|
||||
@@ -5,6 +5,10 @@ metadata:
|
||||
name: wordpress-service
|
||||
namespace: demo-space
|
||||
spec:
|
||||
sessionAffinity: ClientIP
|
||||
sessionAffinityConfig:
|
||||
clientIP:
|
||||
timeoutSeconds: 10800 # 3 hours
|
||||
ports:
|
||||
- port: 80
|
||||
selector:
|
||||
@@ -48,6 +52,9 @@ spec:
|
||||
}
|
||||
/* Force SSL for admin */
|
||||
define('FORCE_SSL_ADMIN', true);
|
||||
/* Redis session storage for multi-replica support */
|
||||
@ini_set('session.save_handler', 'redis');
|
||||
@ini_set('session.save_path', 'tcp://redis-service:6379');
|
||||
/* Fix cookie issues */
|
||||
@ini_set('session.cookie_httponly', true);
|
||||
@ini_set('session.cookie_secure', true);
|
||||
|
||||
@@ -9,6 +9,9 @@ metadata:
|
||||
annotations:
|
||||
# ▼▼▼ 关键注解:我要申请证书 ▼▼▼
|
||||
cert-manager.io/cluster-issuer: letsencrypt-prod
|
||||
# ▼▼▼ Traefik sticky session 配置 ▼▼▼
|
||||
traefik.ingress.kubernetes.io/affinity: "true"
|
||||
traefik.ingress.kubernetes.io/session-cookie-name: "wordpress-session"
|
||||
spec:
|
||||
rules:
|
||||
- host: blog.u9.net3w.com # 您的域名
|
||||
|
||||
40
k3s/my-blog/04-redis.yaml
Normal file
40
k3s/my-blog/04-redis.yaml
Normal file
@@ -0,0 +1,40 @@
|
||||
# 04-redis.yaml - Redis for WordPress session storage
|
||||
apiVersion: v1
|
||||
kind: Service
|
||||
metadata:
|
||||
name: redis-service
|
||||
namespace: demo-space
|
||||
spec:
|
||||
ports:
|
||||
- port: 6379
|
||||
targetPort: 6379
|
||||
selector:
|
||||
app: redis
|
||||
---
|
||||
apiVersion: apps/v1
|
||||
kind: Deployment
|
||||
metadata:
|
||||
name: redis
|
||||
namespace: demo-space
|
||||
spec:
|
||||
replicas: 1
|
||||
selector:
|
||||
matchLabels:
|
||||
app: redis
|
||||
template:
|
||||
metadata:
|
||||
labels:
|
||||
app: redis
|
||||
spec:
|
||||
containers:
|
||||
- name: redis
|
||||
image: redis:7-alpine
|
||||
ports:
|
||||
- containerPort: 6379
|
||||
resources:
|
||||
requests:
|
||||
memory: "64Mi"
|
||||
cpu: "100m"
|
||||
limits:
|
||||
memory: "128Mi"
|
||||
cpu: "200m"
|
||||
8
k3s/my-blog/Dockerfile
Normal file
8
k3s/my-blog/Dockerfile
Normal file
@@ -0,0 +1,8 @@
|
||||
# Custom WordPress image with Redis PHP extension
|
||||
FROM wordpress:latest
|
||||
|
||||
# Install Redis PHP extension
|
||||
RUN pecl install redis && docker-php-ext-enable redis
|
||||
|
||||
# Verify installation
|
||||
RUN php -m | grep redis
|
||||
22
php-test/Database.php
Normal file
22
php-test/Database.php
Normal file
@@ -0,0 +1,22 @@
|
||||
<?php
|
||||
require_once 'config.php';
|
||||
|
||||
class Database {
|
||||
private static ?PDO $instance = null;
|
||||
|
||||
public static function getConnection(): PDO {
|
||||
if (self::$instance === null) {
|
||||
try {
|
||||
$dsn = "mysql:host=" . DB_HOST . ";dbname=" . DB_NAME . ";charset=" . DB_CHARSET;
|
||||
self::$instance = new PDO($dsn, DB_USER, DB_PASS, [
|
||||
PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION,
|
||||
PDO::ATTR_DEFAULT_FETCH_MODE => PDO::FETCH_ASSOC,
|
||||
PDO::ATTR_EMULATE_PREPARES => false,
|
||||
]);
|
||||
} catch (PDOException $e) {
|
||||
die("数据库连接失败: " . $e->getMessage());
|
||||
}
|
||||
}
|
||||
return self::$instance;
|
||||
}
|
||||
}
|
||||
11
php-test/config.php
Normal file
11
php-test/config.php
Normal file
@@ -0,0 +1,11 @@
|
||||
<?php
|
||||
// 数据库配置
|
||||
define('DB_HOST', 'localhost');
|
||||
define('DB_NAME', 'test_db');
|
||||
define('DB_USER', 'root');
|
||||
define('DB_PASS', '');
|
||||
define('DB_CHARSET', 'utf8mb4');
|
||||
|
||||
// 错误报告设置(开发环境)
|
||||
error_reporting(E_ALL);
|
||||
ini_set('display_errors', 1);
|
||||
210
php-test/index.php
Normal file
210
php-test/index.php
Normal file
@@ -0,0 +1,210 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="zh-CN">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<title>PHP MySQL 测试表单</title>
|
||||
<style>
|
||||
* {
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
box-sizing: border-box;
|
||||
}
|
||||
body {
|
||||
font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif;
|
||||
background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
|
||||
min-height: 100vh;
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
padding: 20px;
|
||||
}
|
||||
.container {
|
||||
background: white;
|
||||
padding: 40px;
|
||||
border-radius: 10px;
|
||||
box-shadow: 0 10px 40px rgba(0,0,0,0.2);
|
||||
max-width: 500px;
|
||||
width: 100%;
|
||||
}
|
||||
h1 {
|
||||
color: #333;
|
||||
margin-bottom: 30px;
|
||||
text-align: center;
|
||||
}
|
||||
.form-group {
|
||||
margin-bottom: 20px;
|
||||
}
|
||||
label {
|
||||
display: block;
|
||||
margin-bottom: 8px;
|
||||
color: #555;
|
||||
font-weight: 500;
|
||||
}
|
||||
input, textarea {
|
||||
width: 100%;
|
||||
padding: 12px;
|
||||
border: 2px solid #e0e0e0;
|
||||
border-radius: 5px;
|
||||
font-size: 14px;
|
||||
transition: border-color 0.3s;
|
||||
}
|
||||
input:focus, textarea:focus {
|
||||
outline: none;
|
||||
border-color: #667eea;
|
||||
}
|
||||
textarea {
|
||||
resize: vertical;
|
||||
min-height: 100px;
|
||||
}
|
||||
button {
|
||||
width: 100%;
|
||||
padding: 14px;
|
||||
background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
|
||||
color: white;
|
||||
border: none;
|
||||
border-radius: 5px;
|
||||
font-size: 16px;
|
||||
font-weight: 600;
|
||||
cursor: pointer;
|
||||
transition: transform 0.2s;
|
||||
}
|
||||
button:hover {
|
||||
transform: translateY(-2px);
|
||||
}
|
||||
.message {
|
||||
padding: 15px;
|
||||
border-radius: 5px;
|
||||
margin-bottom: 20px;
|
||||
display: none;
|
||||
}
|
||||
.message.success {
|
||||
background: #d4edda;
|
||||
color: #155724;
|
||||
border: 1px solid #c3e6cb;
|
||||
display: block;
|
||||
}
|
||||
.message.error {
|
||||
background: #f8d7da;
|
||||
color: #721c24;
|
||||
border: 1px solid #f5c6cb;
|
||||
display: block;
|
||||
}
|
||||
.records {
|
||||
margin-top: 30px;
|
||||
padding-top: 30px;
|
||||
border-top: 2px solid #e0e0e0;
|
||||
}
|
||||
.records h2 {
|
||||
color: #333;
|
||||
margin-bottom: 15px;
|
||||
font-size: 20px;
|
||||
}
|
||||
.record-item {
|
||||
background: #f8f9fa;
|
||||
padding: 15px;
|
||||
border-radius: 5px;
|
||||
margin-bottom: 10px;
|
||||
border-left: 4px solid #667eea;
|
||||
}
|
||||
.record-item strong {
|
||||
color: #667eea;
|
||||
}
|
||||
.record-item p {
|
||||
margin: 5px 0;
|
||||
color: #555;
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<div class="container">
|
||||
<h1>📝 数据库测试表单</h1>
|
||||
|
||||
<?php
|
||||
require_once 'Database.php';
|
||||
|
||||
// 显示提交结果消息
|
||||
if (isset($_GET['status'])) {
|
||||
if ($_GET['status'] === 'success') {
|
||||
echo '<div class="message success">✅ 数据提交成功!</div>';
|
||||
} elseif ($_GET['status'] === 'error') {
|
||||
$error = htmlspecialchars($_GET['msg'] ?? '未知错误');
|
||||
echo '<div class="message error">❌ 提交失败: ' . $error . '</div>';
|
||||
}
|
||||
}
|
||||
?>
|
||||
|
||||
<form action="submit.php" method="POST">
|
||||
<div class="form-group">
|
||||
<label for="name">姓名 *</label>
|
||||
<input type="text" id="name" name="name" required placeholder="请输入您的姓名">
|
||||
</div>
|
||||
|
||||
<div class="form-group">
|
||||
<label for="email">邮箱 *</label>
|
||||
<input type="email" id="email" name="email" required placeholder="example@email.com">
|
||||
</div>
|
||||
|
||||
<div class="form-group">
|
||||
<label for="message">留言</label>
|
||||
<textarea id="message" name="message" placeholder="请输入您的留言..."></textarea>
|
||||
</div>
|
||||
|
||||
<button type="submit">提交数据</button>
|
||||
</form>
|
||||
|
||||
<div class="records">
|
||||
<h2>📊 最近提交的数据</h2>
|
||||
<?php
|
||||
try {
|
||||
$db = Database::getConnection();
|
||||
$stmt = $db->query("SELECT * FROM test_data ORDER BY created_at DESC LIMIT 5");
|
||||
$records = $stmt->fetchAll();
|
||||
|
||||
if (count($records) > 0) {
|
||||
foreach ($records as $record) {
|
||||
echo '<div class="record-item">';
|
||||
echo '<p><strong>姓名:</strong> ' . htmlspecialchars($record['name']) . '</p>';
|
||||
echo '<p><strong>邮箱:</strong> ' . htmlspecialchars($record['email']) . '</p>';
|
||||
if (!empty($record['message'])) {
|
||||
echo '<p><strong>留言:</strong> ' . htmlspecialchars($record['message']) . '</p>';
|
||||
}
|
||||
echo '<p><strong>提交时间:</strong> ' . $record['created_at'] . '</p>';
|
||||
echo '</div>';
|
||||
}
|
||||
} else {
|
||||
echo '<p style="color: #999; text-align: center;">暂无数据</p>';
|
||||
}
|
||||
} catch (Exception $e) {
|
||||
echo '<p style="color: #dc3545;">数据库查询失败: ' . htmlspecialchars($e->getMessage()) . '</p>';
|
||||
}
|
||||
?>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- 热更新脚本 -->
|
||||
<script>
|
||||
let lastModified = null;
|
||||
|
||||
function checkForUpdates() {
|
||||
fetch(window.location.href, {
|
||||
method: 'HEAD',
|
||||
cache: 'no-cache'
|
||||
})
|
||||
.then(response => {
|
||||
const modified = response.headers.get('Last-Modified');
|
||||
if (lastModified && modified && lastModified !== modified) {
|
||||
console.log('检测到文件更新,正在刷新页面...');
|
||||
window.location.reload();
|
||||
}
|
||||
lastModified = modified;
|
||||
})
|
||||
.catch(err => console.error('检查更新失败:', err));
|
||||
}
|
||||
|
||||
// 每2秒检查一次更新
|
||||
setInterval(checkForUpdates, 2000);
|
||||
checkForUpdates();
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
||||
13
php-test/schema.sql
Normal file
13
php-test/schema.sql
Normal file
@@ -0,0 +1,13 @@
|
||||
-- 创建数据库
|
||||
CREATE DATABASE IF NOT EXISTS test_db CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;
|
||||
|
||||
USE test_db;
|
||||
|
||||
-- 创建测试表
|
||||
CREATE TABLE IF NOT EXISTS test_data (
|
||||
id INT AUTO_INCREMENT PRIMARY KEY,
|
||||
name VARCHAR(100) NOT NULL,
|
||||
email VARCHAR(100) NOT NULL,
|
||||
message TEXT,
|
||||
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
|
||||
50
php-test/submit.php
Normal file
50
php-test/submit.php
Normal file
@@ -0,0 +1,50 @@
|
||||
<?php
|
||||
require_once 'Database.php';
|
||||
|
||||
header('Content-Type: application/json; charset=utf-8');
|
||||
|
||||
if ($_SERVER['REQUEST_METHOD'] !== 'POST') {
|
||||
header('Location: index.php');
|
||||
exit;
|
||||
}
|
||||
|
||||
try {
|
||||
// 获取表单数据
|
||||
$name = trim($_POST['name'] ?? '');
|
||||
$email = trim($_POST['email'] ?? '');
|
||||
$message = trim($_POST['message'] ?? '');
|
||||
|
||||
// 验证必填字段
|
||||
if (empty($name) || empty($email)) {
|
||||
throw new Exception('姓名和邮箱为必填项');
|
||||
}
|
||||
|
||||
// 验证邮箱格式
|
||||
if (!filter_var($email, FILTER_VALIDATE_EMAIL)) {
|
||||
throw new Exception('邮箱格式不正确');
|
||||
}
|
||||
|
||||
// 获取数据库连接
|
||||
$db = Database::getConnection();
|
||||
|
||||
// 准备SQL语句
|
||||
$sql = "INSERT INTO test_data (name, email, message) VALUES (:name, :email, :message)";
|
||||
$stmt = $db->prepare($sql);
|
||||
|
||||
// 绑定参数并执行
|
||||
$stmt->execute([
|
||||
':name' => $name,
|
||||
':email' => $email,
|
||||
':message' => $message
|
||||
]);
|
||||
|
||||
// 重定向到首页并显示成功消息
|
||||
header('Location: index.php?status=success');
|
||||
exit;
|
||||
|
||||
} catch (Exception $e) {
|
||||
// 重定向到首页并显示错误消息
|
||||
$errorMsg = urlencode($e->getMessage());
|
||||
header('Location: index.php?status=error&msg=' . $errorMsg);
|
||||
exit;
|
||||
}
|
||||
84
scripts/check-node-health.sh
Executable file
84
scripts/check-node-health.sh
Executable file
@@ -0,0 +1,84 @@
|
||||
#!/bin/bash
|
||||
#
|
||||
# 节点健康检查脚本
|
||||
# 使用方法: bash check-node-health.sh
|
||||
#
|
||||
|
||||
# 颜色输出
|
||||
RED='\033[0;31m'
|
||||
GREEN='\033[0;32m'
|
||||
YELLOW='\033[1;33m'
|
||||
BLUE='\033[0;34m'
|
||||
NC='\033[0m' # No Color
|
||||
|
||||
echo -e "${BLUE}================================${NC}"
|
||||
echo -e "${BLUE}K3s 集群健康检查${NC}"
|
||||
echo -e "${BLUE}================================${NC}"
|
||||
echo ""
|
||||
|
||||
# 1. 检查节点状态
|
||||
echo -e "${YELLOW}[1/8] 检查节点状态...${NC}"
|
||||
kubectl get nodes -o wide
|
||||
echo ""
|
||||
|
||||
# 2. 检查节点资源
|
||||
echo -e "${YELLOW}[2/8] 检查节点资源使用...${NC}"
|
||||
kubectl top nodes 2>/dev/null || echo -e "${YELLOW}⚠ metrics-server 未就绪${NC}"
|
||||
echo ""
|
||||
|
||||
# 3. 检查系统 Pods
|
||||
echo -e "${YELLOW}[3/8] 检查系统组件...${NC}"
|
||||
kubectl get pods -n kube-system
|
||||
echo ""
|
||||
|
||||
# 4. 检查 Longhorn
|
||||
echo -e "${YELLOW}[4/8] 检查 Longhorn 存储...${NC}"
|
||||
kubectl get pods -n longhorn-system | head -10
|
||||
echo ""
|
||||
|
||||
# 5. 检查 PVC
|
||||
echo -e "${YELLOW}[5/8] 检查持久化存储卷...${NC}"
|
||||
kubectl get pvc -A
|
||||
echo ""
|
||||
|
||||
# 6. 检查应用 Pods
|
||||
echo -e "${YELLOW}[6/8] 检查应用 Pods...${NC}"
|
||||
kubectl get pods -A | grep -v "kube-system\|longhorn-system\|cert-manager" | head -20
|
||||
echo ""
|
||||
|
||||
# 7. 检查 Ingress
|
||||
echo -e "${YELLOW}[7/8] 检查 Ingress 配置...${NC}"
|
||||
kubectl get ingress -A
|
||||
echo ""
|
||||
|
||||
# 8. 检查证书
|
||||
echo -e "${YELLOW}[8/8] 检查 SSL 证书...${NC}"
|
||||
kubectl get certificate -A
|
||||
echo ""
|
||||
|
||||
# 统计信息
|
||||
echo -e "${BLUE}================================${NC}"
|
||||
echo -e "${BLUE}集群统计信息${NC}"
|
||||
echo -e "${BLUE}================================${NC}"
|
||||
|
||||
TOTAL_NODES=$(kubectl get nodes --no-headers | wc -l)
|
||||
READY_NODES=$(kubectl get nodes --no-headers | grep " Ready " | wc -l)
|
||||
TOTAL_PODS=$(kubectl get pods -A --no-headers | wc -l)
|
||||
RUNNING_PODS=$(kubectl get pods -A --no-headers | grep "Running" | wc -l)
|
||||
TOTAL_PVC=$(kubectl get pvc -A --no-headers | wc -l)
|
||||
BOUND_PVC=$(kubectl get pvc -A --no-headers | grep "Bound" | wc -l)
|
||||
|
||||
echo -e "节点总数: ${GREEN}${TOTAL_NODES}${NC} (就绪: ${GREEN}${READY_NODES}${NC})"
|
||||
echo -e "Pod 总数: ${GREEN}${TOTAL_PODS}${NC} (运行中: ${GREEN}${RUNNING_PODS}${NC})"
|
||||
echo -e "PVC 总数: ${GREEN}${TOTAL_PVC}${NC} (已绑定: ${GREEN}${BOUND_PVC}${NC})"
|
||||
echo ""
|
||||
|
||||
# 健康评分
|
||||
if [ $READY_NODES -eq $TOTAL_NODES ] && [ $RUNNING_PODS -gt $((TOTAL_PODS * 80 / 100)) ]; then
|
||||
echo -e "${GREEN}✓ 集群健康状态: 良好${NC}"
|
||||
elif [ $READY_NODES -gt $((TOTAL_NODES / 2)) ]; then
|
||||
echo -e "${YELLOW}⚠ 集群健康状态: 一般${NC}"
|
||||
else
|
||||
echo -e "${RED}✗ 集群健康状态: 异常${NC}"
|
||||
fi
|
||||
echo ""
|
||||
113
scripts/generate-join-script.sh
Executable file
113
scripts/generate-join-script.sh
Executable file
@@ -0,0 +1,113 @@
|
||||
#!/bin/bash
|
||||
#
|
||||
# 快速配置脚本生成器
|
||||
# 为新节点生成定制化的加入脚本
|
||||
#
|
||||
|
||||
# 颜色输出
|
||||
GREEN='\033[0;32m'
|
||||
YELLOW='\033[1;33m'
|
||||
NC='\033[0m'
|
||||
|
||||
echo -e "${GREEN}================================${NC}"
|
||||
echo -e "${GREEN}K3s 节点加入脚本生成器${NC}"
|
||||
echo -e "${GREEN}================================${NC}"
|
||||
echo ""
|
||||
|
||||
# 获取当前配置
|
||||
MASTER_IP="134.195.210.237"
|
||||
NODE_TOKEN="K109d35a131f48b4d40b162398a828b766d60735f29dd7b4a37b030c1d1c0e26b23::server:72e04c3a9e3e762cbdefffc96f348a2d"
|
||||
|
||||
echo -e "${YELLOW}当前 Master 节点信息:${NC}"
|
||||
echo "IP: $MASTER_IP"
|
||||
echo "Token: ${NODE_TOKEN:0:20}..."
|
||||
echo ""
|
||||
|
||||
# 选择节点类型
|
||||
echo "请选择要加入的节点类型:"
|
||||
echo "1) Worker 节点 (推荐用于 2 节点方案)"
|
||||
echo "2) Master 节点 (用于 HA 高可用方案)"
|
||||
echo ""
|
||||
read -p "请输入选项 (1 或 2): " NODE_TYPE
|
||||
|
||||
if [ "$NODE_TYPE" == "1" ]; then
|
||||
SCRIPT_NAME="join-worker-custom.sh"
|
||||
echo ""
|
||||
echo -e "${GREEN}生成 Worker 节点加入脚本...${NC}"
|
||||
|
||||
cat > $SCRIPT_NAME << 'EOFWORKER'
|
||||
#!/bin/bash
|
||||
set -e
|
||||
|
||||
# 配置信息
|
||||
MASTER_IP="134.195.210.237"
|
||||
NODE_TOKEN="K109d35a131f48b4d40b162398a828b766d60735f29dd7b4a37b030c1d1c0e26b23::server:72e04c3a9e3e762cbdefffc96f348a2d"
|
||||
|
||||
echo "开始加入 Worker 节点..."
|
||||
|
||||
# 系统准备
|
||||
swapoff -a
|
||||
sed -i '/ swap / s/^/#/' /etc/fstab
|
||||
apt-get update -qq
|
||||
apt-get install -y curl open-iscsi nfs-common
|
||||
systemctl enable --now iscsid
|
||||
|
||||
# 安装 k3s agent
|
||||
curl -sfL https://get.k3s.io | K3S_URL=https://${MASTER_IP}:6443 \
|
||||
K3S_TOKEN=${NODE_TOKEN} sh -
|
||||
|
||||
echo "Worker 节点加入完成!"
|
||||
echo "在 Master 节点执行: kubectl get nodes"
|
||||
EOFWORKER
|
||||
|
||||
chmod +x $SCRIPT_NAME
|
||||
|
||||
elif [ "$NODE_TYPE" == "2" ]; then
|
||||
SCRIPT_NAME="join-master-custom.sh"
|
||||
echo ""
|
||||
read -p "请输入负载均衡器 IP: " LB_IP
|
||||
|
||||
echo -e "${GREEN}生成 Master 节点加入脚本...${NC}"
|
||||
|
||||
cat > $SCRIPT_NAME << EOFMASTER
|
||||
#!/bin/bash
|
||||
set -e
|
||||
|
||||
# 配置信息
|
||||
FIRST_MASTER_IP="134.195.210.237"
|
||||
LB_IP="$LB_IP"
|
||||
NODE_TOKEN="K109d35a131f48b4d40b162398a828b766d60735f29dd7b4a37b030c1d1c0e26b23::server:72e04c3a9e3e762cbdefffc96f348a2d"
|
||||
|
||||
echo "开始加入 Master 节点 (HA 模式)..."
|
||||
|
||||
# 系统准备
|
||||
swapoff -a
|
||||
sed -i '/ swap / s/^/#/' /etc/fstab
|
||||
apt-get update -qq
|
||||
apt-get install -y curl open-iscsi nfs-common
|
||||
systemctl enable --now iscsid
|
||||
|
||||
# 安装 k3s server
|
||||
curl -sfL https://get.k3s.io | sh -s - server \\
|
||||
--server https://\${FIRST_MASTER_IP}:6443 \\
|
||||
--token \${NODE_TOKEN} \\
|
||||
--tls-san=\${LB_IP} \\
|
||||
--write-kubeconfig-mode 644
|
||||
|
||||
echo "Master 节点加入完成!"
|
||||
echo "在任意 Master 节点执行: kubectl get nodes"
|
||||
EOFMASTER
|
||||
|
||||
chmod +x $SCRIPT_NAME
|
||||
else
|
||||
echo "无效的选项"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
echo ""
|
||||
echo -e "${GREEN}✓ 脚本已生成: $SCRIPT_NAME${NC}"
|
||||
echo ""
|
||||
echo "使用方法:"
|
||||
echo "1. 将脚本复制到新节点"
|
||||
echo "2. 在新节点上执行: sudo bash $SCRIPT_NAME"
|
||||
echo ""
|
||||
137
scripts/join-master.sh
Executable file
137
scripts/join-master.sh
Executable file
@@ -0,0 +1,137 @@
|
||||
#!/bin/bash
|
||||
#
|
||||
# K3s Master 节点快速加入脚本 (用于 HA 集群)
|
||||
# 使用方法: sudo bash join-master.sh
|
||||
#
|
||||
|
||||
set -e
|
||||
|
||||
# 颜色输出
|
||||
RED='\033[0;31m'
|
||||
GREEN='\033[0;32m'
|
||||
YELLOW='\033[1;33m'
|
||||
NC='\033[0m' # No Color
|
||||
|
||||
echo -e "${GREEN}================================${NC}"
|
||||
echo -e "${GREEN}K3s Master 节点加入脚本 (HA)${NC}"
|
||||
echo -e "${GREEN}================================${NC}"
|
||||
echo ""
|
||||
|
||||
# 检查是否为 root
|
||||
if [ "$EUID" -ne 0 ]; then
|
||||
echo -e "${RED}错误: 请使用 sudo 运行此脚本${NC}"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# 配置信息
|
||||
FIRST_MASTER_IP="134.195.210.237"
|
||||
NODE_TOKEN="K109d35a131f48b4d40b162398a828b766d60735f29dd7b4a37b030c1d1c0e26b23::server:72e04c3a9e3e762cbdefffc96f348a2d"
|
||||
|
||||
echo -e "${YELLOW}第一个 Master 节点 IP: ${FIRST_MASTER_IP}${NC}"
|
||||
echo ""
|
||||
|
||||
# 获取负载均衡器 IP
|
||||
read -p "请输入负载均衡器 IP 地址: " LB_IP
|
||||
if [ -z "$LB_IP" ]; then
|
||||
echo -e "${RED}错误: 负载均衡器 IP 不能为空${NC}"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
echo -e "${YELLOW}负载均衡器 IP: ${LB_IP}${NC}"
|
||||
echo ""
|
||||
|
||||
# 1. 检查网络连通性
|
||||
echo -e "${YELLOW}[1/6] 检查网络连通性...${NC}"
|
||||
if ping -c 2 ${FIRST_MASTER_IP} > /dev/null 2>&1; then
|
||||
echo -e "${GREEN}✓ 可以连接到第一个 Master 节点${NC}"
|
||||
else
|
||||
echo -e "${RED}✗ 无法连接到第一个 Master 节点 ${FIRST_MASTER_IP}${NC}"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
if ping -c 2 ${LB_IP} > /dev/null 2>&1; then
|
||||
echo -e "${GREEN}✓ 可以连接到负载均衡器${NC}"
|
||||
else
|
||||
echo -e "${RED}✗ 无法连接到负载均衡器 ${LB_IP}${NC}"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# 2. 检查端口
|
||||
echo -e "${YELLOW}[2/6] 检查端口...${NC}"
|
||||
if timeout 5 bash -c "cat < /dev/null > /dev/tcp/${FIRST_MASTER_IP}/6443" 2>/dev/null; then
|
||||
echo -e "${GREEN}✓ Master 节点端口 6443 可访问${NC}"
|
||||
else
|
||||
echo -e "${RED}✗ Master 节点端口 6443 无法访问${NC}"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# 3. 系统准备
|
||||
echo -e "${YELLOW}[3/6] 准备系统环境...${NC}"
|
||||
|
||||
# 禁用 swap
|
||||
swapoff -a
|
||||
sed -i '/ swap / s/^/#/' /etc/fstab
|
||||
echo -e "${GREEN}✓ 已禁用 swap${NC}"
|
||||
|
||||
# 安装依赖
|
||||
apt-get update -qq
|
||||
apt-get install -y curl open-iscsi nfs-common > /dev/null 2>&1
|
||||
systemctl enable --now iscsid > /dev/null 2>&1
|
||||
echo -e "${GREEN}✓ 已安装必要依赖${NC}"
|
||||
|
||||
# 4. 设置主机名
|
||||
echo -e "${YELLOW}[4/6] 配置主机名...${NC}"
|
||||
read -p "请输入此节点的主机名 (例如: master-2): " HOSTNAME
|
||||
if [ -n "$HOSTNAME" ]; then
|
||||
hostnamectl set-hostname $HOSTNAME
|
||||
echo -e "${GREEN}✓ 主机名已设置为: $HOSTNAME${NC}"
|
||||
else
|
||||
echo -e "${YELLOW}⚠ 跳过主机名设置${NC}"
|
||||
fi
|
||||
|
||||
# 5. 安装 k3s server
|
||||
echo -e "${YELLOW}[5/6] 安装 k3s server (HA 模式)...${NC}"
|
||||
echo -e "${YELLOW}这可能需要几分钟时间...${NC}"
|
||||
|
||||
curl -sfL https://get.k3s.io | sh -s - server \
|
||||
--server https://${FIRST_MASTER_IP}:6443 \
|
||||
--token ${NODE_TOKEN} \
|
||||
--tls-san=${LB_IP} \
|
||||
--write-kubeconfig-mode 644 > /dev/null 2>&1
|
||||
|
||||
if [ $? -eq 0 ]; then
|
||||
echo -e "${GREEN}✓ k3s server 安装成功${NC}"
|
||||
else
|
||||
echo -e "${RED}✗ k3s server 安装失败${NC}"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# 6. 验证安装
|
||||
echo -e "${YELLOW}[6/6] 验证安装...${NC}"
|
||||
sleep 15
|
||||
|
||||
if systemctl is-active --quiet k3s; then
|
||||
echo -e "${GREEN}✓ k3s 服务运行正常${NC}"
|
||||
else
|
||||
echo -e "${RED}✗ k3s 服务未运行${NC}"
|
||||
echo -e "${YELLOW}查看日志: sudo journalctl -u k3s -f${NC}"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
echo ""
|
||||
echo -e "${GREEN}================================${NC}"
|
||||
echo -e "${GREEN}✓ Master 节点加入成功!${NC}"
|
||||
echo -e "${GREEN}================================${NC}"
|
||||
echo ""
|
||||
echo -e "${YELLOW}下一步操作:${NC}"
|
||||
echo -e "1. 在任意 Master 节点执行以下命令查看节点状态:"
|
||||
echo -e " ${GREEN}kubectl get nodes${NC}"
|
||||
echo ""
|
||||
echo -e "2. 检查 etcd 集群状态:"
|
||||
echo -e " ${GREEN}kubectl get pods -n kube-system | grep etcd${NC}"
|
||||
echo ""
|
||||
echo -e "3. 查看节点详细信息:"
|
||||
echo -e " ${GREEN}kubectl describe node $HOSTNAME${NC}"
|
||||
echo ""
|
||||
echo -e "4. 更新负载均衡器配置,添加此节点的 IP"
|
||||
echo ""
|
||||
116
scripts/join-worker.sh
Executable file
116
scripts/join-worker.sh
Executable file
@@ -0,0 +1,116 @@
|
||||
#!/bin/bash
|
||||
#
|
||||
# K3s Worker 节点快速加入脚本
|
||||
# 使用方法: sudo bash join-worker.sh
|
||||
#
|
||||
|
||||
set -e
|
||||
|
||||
# 颜色输出
|
||||
RED='\033[0;31m'
|
||||
GREEN='\033[0;32m'
|
||||
YELLOW='\033[1;33m'
|
||||
NC='\033[0m' # No Color
|
||||
|
||||
echo -e "${GREEN}================================${NC}"
|
||||
echo -e "${GREEN}K3s Worker 节点加入脚本${NC}"
|
||||
echo -e "${GREEN}================================${NC}"
|
||||
echo ""
|
||||
|
||||
# 检查是否为 root
|
||||
if [ "$EUID" -ne 0 ]; then
|
||||
echo -e "${RED}错误: 请使用 sudo 运行此脚本${NC}"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# 配置信息
|
||||
MASTER_IP="134.195.210.237"
|
||||
NODE_TOKEN="K109d35a131f48b4d40b162398a828b766d60735f29dd7b4a37b030c1d1c0e26b23::server:72e04c3a9e3e762cbdefffc96f348a2d"
|
||||
|
||||
echo -e "${YELLOW}Master 节点 IP: ${MASTER_IP}${NC}"
|
||||
echo ""
|
||||
|
||||
# 1. 检查网络连通性
|
||||
echo -e "${YELLOW}[1/6] 检查网络连通性...${NC}"
|
||||
if ping -c 2 ${MASTER_IP} > /dev/null 2>&1; then
|
||||
echo -e "${GREEN}✓ 网络连通正常${NC}"
|
||||
else
|
||||
echo -e "${RED}✗ 无法连接到 Master 节点 ${MASTER_IP}${NC}"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# 2. 检查端口
|
||||
echo -e "${YELLOW}[2/6] 检查 Master 节点端口 6443...${NC}"
|
||||
if timeout 5 bash -c "cat < /dev/null > /dev/tcp/${MASTER_IP}/6443" 2>/dev/null; then
|
||||
echo -e "${GREEN}✓ 端口 6443 可访问${NC}"
|
||||
else
|
||||
echo -e "${RED}✗ 端口 6443 无法访问,请检查防火墙${NC}"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# 3. 系统准备
|
||||
echo -e "${YELLOW}[3/6] 准备系统环境...${NC}"
|
||||
|
||||
# 禁用 swap
|
||||
swapoff -a
|
||||
sed -i '/ swap / s/^/#/' /etc/fstab
|
||||
echo -e "${GREEN}✓ 已禁用 swap${NC}"
|
||||
|
||||
# 安装依赖
|
||||
apt-get update -qq
|
||||
apt-get install -y curl open-iscsi nfs-common > /dev/null 2>&1
|
||||
systemctl enable --now iscsid > /dev/null 2>&1
|
||||
echo -e "${GREEN}✓ 已安装必要依赖${NC}"
|
||||
|
||||
# 4. 设置主机名
|
||||
echo -e "${YELLOW}[4/6] 配置主机名...${NC}"
|
||||
read -p "请输入此节点的主机名 (例如: worker-1): " HOSTNAME
|
||||
if [ -n "$HOSTNAME" ]; then
|
||||
hostnamectl set-hostname $HOSTNAME
|
||||
echo -e "${GREEN}✓ 主机名已设置为: $HOSTNAME${NC}"
|
||||
else
|
||||
echo -e "${YELLOW}⚠ 跳过主机名设置${NC}"
|
||||
fi
|
||||
|
||||
# 5. 安装 k3s agent
|
||||
echo -e "${YELLOW}[5/6] 安装 k3s agent...${NC}"
|
||||
echo -e "${YELLOW}这可能需要几分钟时间...${NC}"
|
||||
|
||||
curl -sfL https://get.k3s.io | K3S_URL=https://${MASTER_IP}:6443 \
|
||||
K3S_TOKEN=${NODE_TOKEN} \
|
||||
sh - > /dev/null 2>&1
|
||||
|
||||
if [ $? -eq 0 ]; then
|
||||
echo -e "${GREEN}✓ k3s agent 安装成功${NC}"
|
||||
else
|
||||
echo -e "${RED}✗ k3s agent 安装失败${NC}"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# 6. 验证安装
|
||||
echo -e "${YELLOW}[6/6] 验证安装...${NC}"
|
||||
sleep 10
|
||||
|
||||
if systemctl is-active --quiet k3s-agent; then
|
||||
echo -e "${GREEN}✓ k3s-agent 服务运行正常${NC}"
|
||||
else
|
||||
echo -e "${RED}✗ k3s-agent 服务未运行${NC}"
|
||||
echo -e "${YELLOW}查看日志: sudo journalctl -u k3s-agent -f${NC}"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
echo ""
|
||||
echo -e "${GREEN}================================${NC}"
|
||||
echo -e "${GREEN}✓ Worker 节点加入成功!${NC}"
|
||||
echo -e "${GREEN}================================${NC}"
|
||||
echo ""
|
||||
echo -e "${YELLOW}下一步操作:${NC}"
|
||||
echo -e "1. 在 Master 节点执行以下命令查看节点状态:"
|
||||
echo -e " ${GREEN}kubectl get nodes${NC}"
|
||||
echo ""
|
||||
echo -e "2. 为节点添加标签 (在 Master 节点执行):"
|
||||
echo -e " ${GREEN}kubectl label nodes $HOSTNAME node-role.kubernetes.io/worker=worker${NC}"
|
||||
echo ""
|
||||
echo -e "3. 查看节点详细信息:"
|
||||
echo -e " ${GREEN}kubectl describe node $HOSTNAME${NC}"
|
||||
echo ""
|
||||
68
笔记/biji.md
Normal file
68
笔记/biji.md
Normal file
@@ -0,0 +1,68 @@
|
||||
k3s集群部署完成!
|
||||
|
||||
📊 部署总结
|
||||
|
||||
✅ 集群状态
|
||||
|
||||
- k3s版本: v1.34.3+k3s1
|
||||
- 节点状态: Ready (control-plane)
|
||||
- 运行中的Pods: 35个
|
||||
- 存储系统: Longhorn (分布式存储)
|
||||
- 证书管理: cert-manager + Let's Encrypt
|
||||
|
||||
🚀 已部署的服务
|
||||
|
||||
所有服务都已实现无状态化部署,数据和存储完全解耦:
|
||||
┌─────────────────┬───────────────────────────────┬────────────┬─────────────┬─────────────────┐
|
||||
│ 服务 │ 域名 │ 状态 │ 存储 │ HTTPS │
|
||||
├─────────────────┼───────────────────────────────┼────────────┼─────────────┼─────────────────┤
|
||||
│ WordPress博客 │ https://blog.u9.net3w.com │ ✅ Running │ 2Gi (MySQL) │ ✅ │
|
||||
├─────────────────┼───────────────────────────────┼────────────┼─────────────┼─────────────────┤
|
||||
│ Docker Registry │ https://registry.u9.net3w.com │ ✅ Running │ 20Gi │ ⏳ (证书申请中) │
|
||||
├─────────────────┼───────────────────────────────┼────────────┼─────────────┼─────────────────┤
|
||||
│ n8n工作流 │ https://n8n.u9.net3w.com │ ✅ Running │ 5Gi │ ✅ │
|
||||
├─────────────────┼───────────────────────────────┼────────────┼─────────────┼─────────────────┤
|
||||
│ Gitea代码仓库 │ https://git.u9.net3w.com │ ✅ Running │ 10Gi │ ✅ │
|
||||
├─────────────────┼───────────────────────────────┼────────────┼─────────────┼─────────────────┤
|
||||
│ Uptime Kuma监控 │ https://status.u9.net3w.com │ ✅ Running │ 2Gi │ ✅ │
|
||||
├─────────────────┼───────────────────────────────┼────────────┼─────────────┼─────────────────┤
|
||||
│ 导航页 │ https://nav.u9.net3w.com │ ✅ Running │ - │ ✅ │
|
||||
└─────────────────┴───────────────────────────────┴────────────┴─────────────┴─────────────────┘
|
||||
💾 存储配置
|
||||
|
||||
所有数据都使用Longhorn持久化存储,实现了容器与数据的完全解耦:
|
||||
- MySQL数据库: 2Gi独立存储卷
|
||||
- Docker镜像仓库: 20Gi独立存储卷
|
||||
- Gitea代码仓库: 10Gi独立存储卷
|
||||
- n8n工作流数据: 5Gi独立存储卷
|
||||
- Uptime Kuma监控数据: 2Gi独立存储卷
|
||||
|
||||
🔐 安全配置
|
||||
|
||||
- ✅ 自动HTTPS证书(Let's Encrypt)
|
||||
- ✅ Traefik Ingress Controller
|
||||
- ✅ Docker Registry认证(用户名: admin, 密码: 123456)
|
||||
|
||||
📝 常用命令
|
||||
|
||||
# 查看所有服务
|
||||
kubectl get pods -A
|
||||
|
||||
# 查看存储卷
|
||||
kubectl get pvc -A
|
||||
|
||||
# 查看域名和证书
|
||||
kubectl get ingress -A
|
||||
kubectl get certificate -A
|
||||
|
||||
# 查看Longhorn UI (可选)
|
||||
kubectl get svc -n longhorn-system
|
||||
|
||||
⚠️ 注意事项
|
||||
|
||||
1. Registry证书: registry.u9.net3w.com的SSL证书还在申请中,稍等几分钟会自动完成
|
||||
2. DNS解析: 确保所有*.u9.net3w.com子域名都已正确解析到 134.195.210.237
|
||||
3. 数据持久化: 所有数据都存储在Longhorn卷中,容器重启不会丢失数据
|
||||
|
||||
所有服务已成功实现无状态化部署,可以随时重启、扩容或迁移! 🎊
|
||||
|
||||
94
笔记/gitops.md
Normal file
94
笔记/gitops.md
Normal file
@@ -0,0 +1,94 @@
|
||||
完美!GitOps 自动部署环境已经完全配置好了!
|
||||
|
||||
🎉 GitOps 实现条件评估结果
|
||||
|
||||
✅ 所有条件已满足!
|
||||
┌────────────────┬──────┬──────────────────────────────┐
|
||||
│ 条件 │ 状态 │ 说明 │
|
||||
├────────────────┼──────┼──────────────────────────────┤
|
||||
│ k3s 集群 │ ✅ │ v1.34.3+k3s1 运行中 │
|
||||
├────────────────┼──────┼──────────────────────────────┤
|
||||
│ Git 仓库 │ ✅ │ 本地仓库已初始化,配置已提交 │
|
||||
├────────────────┼──────┼──────────────────────────────┤
|
||||
│ Gitea 代码托管 │ ✅ │ https://git.u9.net3w.com │
|
||||
├────────────────┼──────┼──────────────────────────────┤
|
||||
│ ArgoCD │ ✅ │ https://argocd.u9.net3w.com │
|
||||
├────────────────┼──────┼──────────────────────────────┤
|
||||
│ 自动同步配置 │ ✅ │ argocd-app.yaml 已创建 │
|
||||
├────────────────┼──────┼──────────────────────────────┤
|
||||
│ HTTPS 证书 │ ✅ │ Let's Encrypt 自动签发 │
|
||||
└────────────────┴──────┴──────────────────────────────┘
|
||||
🚀 下一步操作指南
|
||||
|
||||
1️⃣ 访问 Gitea 创建仓库
|
||||
|
||||
访问: https://git.u9.net3w.com
|
||||
1. 注册账号(首次访问)
|
||||
2. 创建新仓库: k3s-configs
|
||||
3. 记录仓库 URL
|
||||
|
||||
2️⃣ 推送代码到 Gitea
|
||||
|
||||
# 添加远程仓库(替换为你的用户名)
|
||||
git remote add origin
|
||||
https://git.u9.net3w.com/你的用户名/k3s-configs.git
|
||||
|
||||
# 推送代码
|
||||
git push -u origin master
|
||||
|
||||
3️⃣ 配置 ArgoCD
|
||||
|
||||
访问: https://argocd.u9.net3w.com
|
||||
用户名: admin
|
||||
密码: R5ALO8NIRi4KoN8Q
|
||||
|
||||
步骤:
|
||||
1. Settings → Repositories → Connect Repo
|
||||
2. 填入 Gitea 仓库信息
|
||||
3. 应用 ArgoCD Application:
|
||||
kubectl apply -f k3s/argocd-app.yaml
|
||||
|
||||
4️⃣ 测试自动部署
|
||||
|
||||
# 修改任意配置文件
|
||||
vim k3s/my-blog/02-wordpress.yaml
|
||||
|
||||
# 提交并推送
|
||||
git add .
|
||||
git commit -m "Test auto-sync"
|
||||
git push
|
||||
|
||||
# ArgoCD 会在 3 分钟内自动同步到集群!
|
||||
|
||||
📊 当前部署状态
|
||||
|
||||
✅ k3s 集群: 运行中 (35+ pods)
|
||||
✅ ArgoCD: https://argocd.u9.net3w.com
|
||||
✅ Gitea: https://git.u9.net3w.com
|
||||
✅ WordPress: https://blog.u9.net3w.com
|
||||
✅ Docker Registry: https://registry.u9.net3w.com
|
||||
✅ n8n: https://n8n.u9.net3w.com
|
||||
✅ Uptime Kuma: https://status.u9.net3w.com
|
||||
✅ 导航页: https://nav.u9.net3w.com
|
||||
|
||||
🎯 GitOps 工作流
|
||||
|
||||
┌─────────────┐ ┌─────────────┐ ┌─────────────┐
|
||||
│ 修改 YAML │ ───> │ Git Push │ ───> │ Gitea │
|
||||
└─────────────┘ └─────────────┘
|
||||
│
|
||||
▼
|
||||
┌─────────────┐ ┌─────────────┐ ┌─────────────┐
|
||||
│ k3s 集群 │ <─── │ ArgoCD │ <─── │ 自动检测 │
|
||||
│ 更新完成 │ │ 自动同步 │ │ 变更 │
|
||||
└─────────────┘ └─────────────┘
|
||||
|
||||
所有实现条件已满足! 你现在可以实现:
|
||||
- ✅ 更新 YAML 到 Git
|
||||
- ✅ 自动同步到生产环境
|
||||
- ✅ 版本控制和快速回滚
|
||||
- ✅ 完整的审计追踪
|
||||
|
||||
详细使用说明请查看 README.md 文件!🎊
|
||||
|
||||
✻ Churned for 4m 47s
|
||||
Reference in New Issue
Block a user