最近在做 K8s 集群自动化部署时遇到一个特别经典的疑问:

Ansible 所有任务都是从控制节点发出的,Worker 节点要执行 kubeadm join,必须拿到 Master 生成的 join 令牌,怎么才能让 Worker 自动拿到 Master 的变量,再在自己本机执行加入命令?

相信很多跟我一样初学 Ansible、又要做 K8s 自动化的同学都会卡在这里。 今天用最通俗、最实战的方式讲清楚:答案就是 Ansible 魔法变量 —— hostvars


一、先把问题说透(你一定也遇到过)

K8s 集群部署流程:

  1. Master 节点执行 kubeadm init,初始化集群
  2. Master 生成 kubeadm join 令牌、证书、哈希
  3. Worker1、Worker2 必须在本机执行这个 join 命令,才能加入集群

痛点来了:

  • Ansible 控制节点只管发命令
  • 任务是跑在 Worker 上的
  • 令牌只存在 Master 上
  • 我不可能手动复制粘贴

那怎么实现: 让 Worker 自己去 “拿到” Master 的 join 命令 → 然后在 Worker 本机执行加入?


二、答案:Ansible 魔法变量 hostvars

1. 什么是 hostvars?

hostvars 是 Ansible 内置魔法变量,不需要定义、不需要赋值,直接用。

作用只有一句话: 让当前执行任务的机器(比如 Worker1),读取 inventory 里任意其他机器(比如 Master)的所有变量、 Facts、注册值。

直白翻译: 你在 Worker 上执行任务,但你能读到 Master 的变量!

这就是解决 K8s join 最核心的神器。


三、实战结构:一句话原理

Master 生成 join 命令 → 存为变量
Worker 执行任务时
用 {{ hostvars['master'].join_command }}
直接拿到 Master 的令牌
然后在 Worker 本机执行 kubeadm join

Ansible 控制节点只负责调度,不负责传递文件、不负责登录 Master 取内容。 一切靠 hostvars 跨主机读变量。


四、完整可运行 Playbook 示例(直接复制就能用)

1. 主机清单 inventory

[k8s_master]
master ansible_host=192.168.1.10

[k8s_worker]
worker1 ansible_host=192.168.1.11
worker2 ansible_host=192.168.1.12

2. Playbook 核心逻辑(重点看 hostvars)

---
- name: 1. 在 Master 生成 join 命令并保存为变量
  hosts: k8s_master
  tasks:
    - name: 生成 join 命令
      shell: kubeadm token create --print-join-command
      register: join_result

    - name: 将 join 命令设为全局变量(供 Worker 使用)
      set_fact:
        join_command: "{{ join_result.stdout }}"
---
- name: 2. Worker 节点跨主机获取变量并加入集群
  hosts: k8s_worker
  tasks:
    - name: 检查是否已经加入集群
      stat: path=/etc/kubernetes/kubelet.conf
      register: kubelet_conf

    - name: Worker 拿 Master 令牌加入 K8s
      shell: "{{ hostvars['master'].join_command }}"
      when: not kubelet_conf.stat.exists

五、最关键的一行代码

{{ hostvars['master'].join_command }}

含义解释

  • hostvars:Ansible 内置全局主机变量字典
  • 'master':你 inventory 里 Master 的主机名
  • join_command:Master 上用 set_fact 定义的变量

作用:在 Worker 执行任务时,直接读取 Master 的变量内容。


六、总结

  1. hostvars = 跨主机取变量的魔法
  2. 任务跑在 Worker,但能读 Master 的数据
  3. K8s Worker 加入集群 = hostvars 最经典实战场景
  4. 控制节点不登录、不拷贝、不中转,完全靠变量传递

一句话封神: Ansible 让 Worker 远程 “读取” Master 的令牌,再在本机执行 join,hostvars 就是那座桥。


七、学习心得

我从完全不懂 Ansible,到理解魔法变量、再到能写 K8s 自动化部署,最大的感悟就是: Ansible 不是让你在控制节点干所有事,而是让你用变量、模块、魔法变量,让目标机器自己做事。

hostvars 就是 Ansible 分布式能力的灵魂之一。


如果你也在学 RH294 或 K8s 自动化,欢迎点赞、收藏、关注,我会持续更新小白能看懂、能直接跑的实战博客!

Logo

汇聚全球AI编程工具,助力开发者即刻编程。

更多推荐