日常更新

This commit is contained in:
2026-03-29 09:08:01 +08:00
parent 31709425e2
commit befdefd222
224 changed files with 7240 additions and 3297 deletions

View File

@@ -0,0 +1,216 @@
# 01-05-节点初始化与 k3s 自动安装Ansible 实践)
> 目标:给一组已经装好 OS、可以 SSH 的裸金属/虚机,**一键完成基础初始化 + 安装 k3s server/worker**,得到与 `01-01`、`01-02` 文档一致的集群(含 `/storage` 数据盘方案)。
>
> **状态:已验证**2026-03Fedora + K3s4 节点 61~64
> 部署环境详见 `00-02-部署环境说明.md`。
## 契约与真源
- **索引**`ansible/files/01-05/README.md`(执行真源为 `ansible/playbooks/verify/01-05.yml``deploy-lab.sh`)。
- **自动**`./ansible/bin/deploy-lab.sh k3s``./ansible/bin/verify.sh run 01-05`
## TL;DR
- **一键安装**`./ansible/bin/deploy-lab.sh k3s`
- **一键验收**`./ansible/bin/verify.sh run 01-05`(或直接 `./ansible/bin/verify.sh full`
- **关键前置**:控制端可 SSH 所有节点;`ansible/inventory.ini` 私钥路径存在且权限正确;(可选)每台节点已挂载 `/storage` 或启用 `K3S_PREPARE_STORAGE=true`
- **成功判据**:所有节点 `Ready`kube-system 核心组件就绪;后续按 `02-05` 可跑入口验证
- **失败排障**见本文「排障」小节SSH/私钥、/storage、firewalld、k3s service
## 1. 适用边界与前提
- 已完成:
- **控制机**(运行 ansible-playbook 的那台机器)已安装 Ansible
- Fedora / RHEL`sudo dnf install ansible`
- Debian / Ubuntu`sudo apt install ansible`
- 验证:`ansible --version``ansible-playbook --version`
- 每台目标机器已经安装好 Linux如 Fedora/CentOS/Debian 等);
- 能通过 SSH 无密码/密钥登录Ansible 能连通);
- 若使用 `scripts/ssh/setup-k3s-workers-ssh.sh` 为每节点配置独立密钥,需在 inventory 中为各 host 指定 `ansible_ssh_private_key_file`(见下文示例);
- 使用 **root** SSH 连接(`group_vars/all.yml``ansible_user: root`),配合 `scripts/ssh/setup-k3s-workers-ssh.sh` 为**所有节点**(含控制节点)配置 jack + root 的公钥;
- IP 规划、主机名已大致确定,例如:
- `ylc61`k3s serverIP `192.168.2.61`
- `ylc62` ~ `ylc64`k3s workerIP `192.168.2.62` ~ `192.168.2.64`
- **数据盘**:若使用 `/storage` 方案,每台节点须将**独立数据盘**挂载到 `/storage`(与 `/` 不同设备),详见 `00-04` 与下文「数据盘准备」。
- 不覆盖:
- 从「完全裸铁 + 无系统」开始的 PXE 装机;
- 高级 HA多 server + 外部 datastore——仍按 `01-07``03-08` 执行。
### 1.1 数据盘准备(手工,或与自动化二选一)
在运行 k3s 安装 playbook 之前,**每台**节点应满足:`mountpoint /storage` 为真,且 `findmnt -n -o SOURCE /``findmnt -n -o SOURCE /storage` **不相同**
**手工示例**(第二块盘为 `/dev/vdb`,请按 `lsblk` 实际设备名修改;**误选设备会清空该盘**
```bash
sudo parted -s /dev/vdb mklabel gpt mkpart primary ext4 0% 100%
sudo mkfs.ext4 -F /dev/vdb1
UUID=$(sudo blkid -s UUID -o value /dev/vdb1)
echo "UUID=$UUID /storage ext4 defaults,nofail 0 2" | sudo tee -a /etc/fstab
sudo mkdir -p /storage && sudo mount -a
```
XFS 用户将 `mkfs.ext4` / `fstab` 类型改为 `xfs` 即可Longhorn 支持 ext4/XFS
**自动化(可选)**:在 `group_vars/all.yml` 中设置 `k3s_prepare_storage: true``k3s_data_disk_device: /dev/vdb`(四台盘符一致时一条即可;不一致则用 `host_vars/<hostname>.yml` 覆盖),然后执行:
```bash
ansible-playbook -i inventory.ini playbooks/verify/01-05.yml
```
该 playbook 在 `/storage` 已是独立挂载时会跳过,避免重复执行。
### 1.2 推荐执行顺序10G + 32G 四节点)
1. (可选)`playbooks/verify/01-05.yml`
2. `playbooks/verify/01-05.yml`(可在 `group_vars` 中设 `k3s_verify_storage_mount: true` 强制校验 `/``/storage` 不同源)
3. (可选)`playbooks/verify/03-07.yml`Helm`03-07`
4. (可选)`playbooks/verify/03-05.yml`,或 `longhorn_apply_local_path_lab: true` 随 Longhorn 一并应用(真源:`files/kube-system/local-path-config-lab.json`,见 `03-05`
## 2. 目录结构
本仓库已有 `ansible/`
```text
ansible/
ansible.cfg # host_key_checking=False 等
inventory.ini
group_vars/
all.yml
playbooks/
verify/
01-05.yml # 标准 IPv4 安装(-e k3s_do_install=true可选准备数据盘-e k3s_do_prepare_storage=true
03-07.yml # 可选Helm 安装 Longhorn
03-05.yml # 可选:仅应用 local-path 实验室 ConfigMap-e local_path_apply_lab_config=true
files/
longhorn/values-lab.yaml # 实验室 Helm values
kube-system/local-path-config-lab.json
```
## 3. 示例 inventory
`ansible/inventory.ini`
```ini
[k3s_server]
ylc61 ansible_host=192.168.2.61 ansible_ssh_private_key_file=~/.ssh/id_ed25519_k3s_192.168.2.61
[k3s_worker]
ylc62 ansible_host=192.168.2.62 ansible_ssh_private_key_file=~/.ssh/id_ed25519_k3s_192.168.2.62
ylc63 ansible_host=192.168.2.63 ansible_ssh_private_key_file=~/.ssh/id_ed25519_k3s_192.168.2.63
ylc64 ansible_host=192.168.2.64 ansible_ssh_private_key_file=~/.ssh/id_ed25519_k3s_192.168.2.64
[k3s_nodes:children]
k3s_server
k3s_worker
```
> 提示:上面使用短主机名(如 `ylc61``ylc64`),应与各节点 hostname 及 `kubectl get nodes` 输出的 NAME 一致,便于配合 Cloudflare CDNplaybook 的 Init 阶段会为所有 k3s 节点写入 /etc/hosts 条目。
## 4. 全局变量
**唯一真源**[`ansible/group_vars/all.yml`](../ansible/group_vars/all.yml)(含 `ansible_user``k3s_data_dir``k3s_server_ip``k3s_manage_*` 等)。
若需安装后自动打 **control-plane/worker 角色标签**(供 `02-05``03-02` 的 M1/M3 使用),在同一文件中增加,例如:
- `k3s_manage_role_labels: true`
- `k3s_control_plane_nodenames: ["ylc61"]`
- `k3s_worker_nodenames: ["ylc62", "ylc63", "ylc64"]`
节点名必须与 `kubectl get nodes` 输出一致(使用短主机名 ylc61ylc64。未配置时仅打 enablelb/lbpool不打角色标签。
**CoreDNS 上游 DNS**(供 ACME 解析 Let's Encrypt`03-02` 常见问题):若宿主机 `/etc/resolv.conf` 为 IPv6Pod 网络仅 IPv4 时无法解析ACME 会失败。playbook 默认会将 CoreDNS `forward` 改为 IPv4
- `k3s_manage_coredns: true`(默认开启)
- `coredns_forward_servers: "223.5.5.5 8.8.8.8"`(可按环境修改)
禁用时设 `k3s_manage_coredns: false`
**存储挂载校验**(推荐实验室开启):
- `k3s_verify_storage_mount: true`:在 `01-05.yml` 安装 k3s`-e k3s_do_install=true`**之前**,断言 `/storage` 为挂载点且与 `/` 不同块设备;失败时提示查阅 `00-04`。已有「目录式假 /storage」的旧环境可临时设为 `false`
**数据盘自动化**(可选):
- `k3s_prepare_storage: true``k3s_data_disk_device: /dev/vdb`:由 `01-05.yml -e k3s_do_prepare_storage=true` 执行(见 §1.1)。
## 5. 执行流程概览
playbook 依次执行:
| 顺序 | 阶段 | 内容 |
|------|------|------|
| 1 | Init | 时区、基础包、/etc/hosts、**firewalld 开放 8472/udp全部节点与 6443/tcp仅 server** |
| 2 | Install server | 安装 k3s server`--data-dir=/storage` |
| 3 | Install agent | 逐台安装 worker`serial: 1`);随后在 **server**`kubectl wait` 各 worker Ready不在 worker 上 `delegate_to` server避免 SSH 路径异常) |
| 4 | Firewalld 基线 | 等待 flannel.1/cni0 出现(最多 120s加入 trusted zone |
| 5 | **CoreDNS可选** | 当 `k3s_manage_coredns: true` 时,将 forward 改为 IPv4223.5.5.5 8.8.8.8),避免 ACME 解析 Let's Encrypt 失败 |
| 6 | Traefik 标签 | 从集群动态获取节点名,打 enablelb/lbpool 标签 |
| 7 | 角色标签(可选) | 当 `k3s_manage_role_labels: true` 时,为控制节点打 control-plane、工作节点打 worker |
| 8 | 验证 | 输出 `kubectl get nodes``kubectl get pods -n kube-system`、curl 各节点 HTTP |
**关键实现点**
- **端口 8472/udp**flannel VXLAN 所需,必须在 Init 阶段开放,否则 worker 上 flannel 无法建立 overlay`flannel.1` / `cni0` 永远不会出现;
- **Firewalld 基线flannel.1/cni0 → trusted**FCOS/Fedora 默认 firewalld 转发策略较严格K3s 不会自动配置宿主机 firewalld 的 zone 接口归类。入口 PodTraefik/svclb-traefik可能调度到任意节点回包路径会经过该节点本地的 `flannel.1`/`cni0`。若某节点上 `flannel.1 ↔ cni0` 的转发被 firewalld 拦截,该节点上的入口流量就会异常,即使其它节点正常。详见 `01-02-k3s-工作节点.md`
- **Traefik 标签**:使用 `kubectl get nodes -o jsonpath` 获取实际节点名,不依赖 inventory 主机名与 K8s 节点名一致;
- **CoreDNS可选**:宿主机若使用 IPv6 DNS如运营商分配的 `240e:...`Pod 网络仅 IPv4 时 CoreDNS 无法访问上游,导致 Traefik ACME 无法解析 Let's Encrypt 域名。playbook 会将 `forward . /etc/resolv.conf` 改为 `forward . 223.5.5.5 8.8.8.8`,详见 `03-02` 常见问题。
- **角色标签(可选)**playbook 默认只打 enablelb/lbpool**不打** `node-role.kubernetes.io/control-plane``node-role.kubernetes.io/worker`。若需 `03-01` / `03-03` nginx 矩阵的 M1/M3 能调度,可开启 `k3s_manage_role_labels` 并配置控制节点/工作节点名列表(见下),或安装后在控制节点按 01-02 可选步骤手动打标。
- **Agent 安装**token 在 **Install server** 阶段于 server 上 `slurp`;各 worker 本机执行 `get.k3s.io` 安装 agent。**等待 worker Ready** 使用独立 play`hosts: k3s_server`)执行 `kubectl wait`,与「控制机 → server」的 SSH 路径一致,避免在 worker 任务内 `delegate_to` 控制机时出现 `UNREACHABLE [worker -> server]`(如对 `192.168.2.61:22` 超时)。
## 6. 使用方式
### 6.1 SSH 前置(若未配置)
先运行 `scripts/ssh/setup-k3s-workers-ssh.sh`,为所有 k3s 节点(含 server配置 jack + root 公钥及 inventory 所需的私钥。
### 6.2 执行 playbook
`ansible/` 目录下执行:
```bash
cd ansible
# (可选)先准备数据盘挂载 /storage
# ansible-playbook -i inventory.ini playbooks/verify/01-05.yml
# 标准 IPv4 安装
ansible-playbook -i inventory.ini playbooks/verify/01-05.yml
# 可选Helm 安装 Longhorn
# ansible-playbook -i inventory.ini playbooks/verify/03-07.yml
```
执行结束后playbook 会输出:
- `kubectl get nodes`
- `kubectl get pods -n kube-system -o wide`
- 各节点 IP 的 curl HTTP 测试结果
### 6.3 手动验证(可选)
在 server如 ylc61上执行
```bash
KUBECONFIG=/etc/rancher/k3s/k3s.yaml kubectl get nodes -o wide
KUBECONFIG=/etc/rancher/k3s/k3s.yaml kubectl get pods -n kube-system -o wide
```
确认 `/storage` 方案:
- server 与 worker 的 k3s 数据目录均为 `/storage`
- token 路径为 `/storage/server/token`
## 7. 下一步
集群就绪后,可继续阅读:
- `03-09-k3s-gitops-集群配置管理.md`:用 Argo CD/Flux 管理 Traefik、监控、应用清单
- `01-01``01-02` 中的验证命令与入口验证。
## 排障
- **Install k3s worker/server 长时间无输出或最终超时**:任务在拉取 `https://get.k3s.io` 并从 GitHub 下二进制worker 需能访问外网。可在 `ansible/group_vars/all.yml`**`k3s_install_mirror: cn`**(走安装脚本国内镜像),或调大 **`k3s_install_curl_max_time`** / **`k3s_install_task_timeout`**`curl` 已带 `--connect-timeout` / `--max-time`,超时后会失败退出而不是无限挂住。
- **worker 阶段 `UNREACHABLE [ylc62 -> ylc61]` / 连 `192.168.2.61:22` 超时**:多为在 worker 上下文中 `delegate_to` 控制机时连接行为与预期不符。当前 `01-05.yml` 已改为在 **`hosts: k3s_server`** 的独立 play 里 `kubectl wait` worker若仍失败在控制机单独 `ssh root@<server_ip>``kubectl get nodes` 排查。
- **Ansible 连不上节点**:先在控制端跑 `./ansible/bin/verify.sh preflight`;检查 `ansible/inventory.ini` 主机名/IP、`ansible_user`、私钥路径与权限600
- **/storage 校验失败**:确认每台节点 `/storage` 为独立挂载点;必要时先跑 `K3S_PREPARE_STORAGE=true ./ansible/bin/deploy-lab.sh k3s` 或单独跑 `ansible/playbooks/verify/01-05.yml`
- **kube-system 组件不就绪**:在 server 上 `journalctl -u k3s -n 200 --no-pager`,以及 `kubectl -n kube-system get pods -o wide`/`describe` 查看事件。