Files
Deploy-Laboratory/docs/01-05-节点初始化-ansible-实践.md
2026-03-29 09:08:01 +08:00

12 KiB
Raw Permalink Blame History

01-05-节点初始化与 k3s 自动安装Ansible 实践)

目标:给一组已经装好 OS、可以 SSH 的裸金属/虚机,一键完成基础初始化 + 安装 k3s server/worker,得到与 01-0101-02 文档一致的集群(含 /storage 数据盘方案)。

状态:已验证2026-03Fedora + K3s4 节点 61~64
部署环境详见 00-02-部署环境说明.md

契约与真源

  • 索引ansible/files/01-05/README.md(执行真源为 ansible/playbooks/verify/01-05.ymldeploy-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
  • 成功判据:所有节点 Readykube-system 核心组件就绪;后续按 02-05 可跑入口验证
  • 失败排障见本文「排障」小节SSH/私钥、/storage、firewalld、k3s service

1. 适用边界与前提

  • 已完成:
    • 控制机(运行 ansible-playbook 的那台机器)已安装 Ansible
      • Fedora / RHELsudo dnf install ansible
      • Debian / Ubuntusudo apt install ansible
      • 验证:ansible --versionansible-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.ymlansible_user: root),配合 scripts/ssh/setup-k3s-workers-ssh.sh所有节点(含控制节点)配置 jack + root 的公钥;
    • IP 规划、主机名已大致确定,例如:
      • ylc61k3s serverIP 192.168.2.61
      • ylc62 ~ ylc64k3s workerIP 192.168.2.62 ~ 192.168.2.64
    • 数据盘:若使用 /storage 方案,每台节点须将独立数据盘挂载到 /storage(与 / 不同设备),详见 00-04 与下文「数据盘准备」。
  • 不覆盖:
    • 从「完全裸铁 + 无系统」开始的 PXE 装机;
    • 高级 HA多 server + 外部 datastore——仍按 01-0703-08 执行。

1.1 数据盘准备(手工,或与自动化二选一)

在运行 k3s 安装 playbook 之前,每台节点应满足:mountpoint /storage 为真,且 findmnt -n -o SOURCE /findmnt -n -o SOURCE /storage 不相同

手工示例(第二块盘为 /dev/vdb,请按 lsblk 实际设备名修改;误选设备会清空该盘

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: truek3s_data_disk_device: /dev/vdb(四台盘符一致时一条即可;不一致则用 host_vars/<hostname>.yml 覆盖),然后执行:

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.ymlHelm03-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/

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

[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

提示:上面使用短主机名(如 ylc61ylc64),应与各节点 hostname 及 kubectl get nodes 输出的 NAME 一致,便于配合 Cloudflare CDNplaybook 的 Init 阶段会为所有 k3s 节点写入 /etc/hosts 条目。

4. 全局变量

唯一真源ansible/group_vars/all.yml(含 ansible_userk3s_data_dirk3s_server_ipk3s_manage_* 等)。

若需安装后自动打 control-plane/worker 角色标签(供 02-0503-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 Encrypt03-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: truek3s_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 逐台安装 workerserial: 1);随后在 serverkubectl 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 nodeskubectl get pods -n kube-system、curl 各节点 HTTP

关键实现点

  • 端口 8472/udpflannel VXLAN 所需,必须在 Init 阶段开放,否则 worker 上 flannel 无法建立 overlayflannel.1 / cni0 永远不会出现;
  • Firewalld 基线flannel.1/cni0 → trustedFCOS/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-planenode-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 使用独立 playhosts: 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/ 目录下执行:

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上执行

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-0101-02 中的验证命令与入口验证。

排障

  • Install k3s worker/server 长时间无输出或最终超时:任务在拉取 https://get.k3s.io 并从 GitHub 下二进制worker 需能访问外网。可在 ansible/group_vars/all.ymlk3s_install_mirror: cn(走安装脚本国内镜像),或调大 k3s_install_curl_max_time / k3s_install_task_timeoutcurl 已带 --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 查看事件。