14 10 月 2026

机器从一台变到五台、十台,SSH 挨个敲命令就崩溃了:改配置要登十次、发个文件要 scp 十次、装个软件要重复十遍。

Ansible 是解决这个问题最省事的工具:不用装客户端(agentless)、YAML 写剧本、一条命令管所有机器。这篇从零开始,一小时上手。

需要云服务器可以看看财富云计算:一键开服面板,NAT 型无独立公网 IP,价格比独立 IP 机型省一半以上,主流游戏快速部署,批量开服批量管理。

一、Ansible 是什么

特性说明
无客户端目标机器不用装任何东西,SSH 通就行
YAML 剧本Playbook 可读可维护,能进 Git
幂等性同一个任务跑十遍和跑一遍结果一样,不会重复装
模块化装软件、改配置、起服务都有现成模块
规模不限3 台和 300 台用法一样

架构:控制节点(装 Ansible 的机器)→ SSH → 被管理节点。文件推送、命令执行、服务管理全走 SSH。

二、安装与配置

安装(控制节点)

# Ubuntu/Debian
apt install -y ansible

# CentOS/RHEL
yum install -y ansible

# 或用 pip(版本最新)
pip install ansible

配置 hosts 清单

# /etc/ansible/hosts 或项目里的 hosts

[gameservers]
palworld ansible_host=192.168.1.11 ansible_user=root
ark       ansible_host=192.168.1.12 ansible_user=root
terraria  ansible_host=192.168.1.13 ansible_user=root

[webservers]
web1 ansible_host=192.168.1.21
web2 ansible_host=192.168.1.22

# 分组套分组
[all_servers:children]
gameservers
webservers

配 SSH 密钥(免密是前提)

# 控制节点生成密钥
ssh-keygen -t ed25519

# 分发到所有被管机器
ssh-copy-id root@192.168.1.11
ssh-copy-id root@192.168.1.12
ssh-copy-id root@192.168.1.13

# 测试连通
ansible all -m ping
# 返回 SUCCESS 就通了

三、Ad-Hoc 命令:临时操作

不写剧本,直接命令行执行,适合一次性任务:

# 所有机器执行命令
ansible all -m shell -a "uptime"

# 指定分组
ansible gameservers -m shell -a "systemctl status palworld"

# 装软件(yum/apt 模块自动选包管理器)
ansible webservers -m yum -a "name=nginx state=present"
ansible webservers -m apt -a "name=nginx state=present"

# 起服务
ansible webservers -m systemd -a "name=nginx state=started enabled=yes"

# 拷文件
ansible all -m copy -a "src=/etc/hosts dest=/tmp/hosts"

# 看所有机器的内存
ansible all -m shell -a "free -m | grep Mem" 

# 单台机器
ansible palworld -m shell -a "df -h /"

-m shell 和 -a:模块 + 参数。shell 模块最灵活但非幂等,优先用专用模块(yum、copy、systemd、file)。

四、Playbook:把操作固化成剧本

第一个 Playbook:装 Nginx

# site.yml
---
- name: 配置 Web 服务器
  hosts: webservers
  become: yes              # 用 root 执行
  
  tasks:
    - name: 安装 Nginx
      apt:
        name: nginx
        state: present
        update_cache: yes
    
    - name: 启动并设为开机自启
      systemd:
        name: nginx
        state: started
        enabled: yes
    
    - name: 写入欢迎页
      copy:
        content: "<h1>由 Ansible 部署</h1>"
        dest: /var/www/html/index.html
        mode: '0644'
      notify: reload nginx    # 有变更时触发 handler

  handlers:
    - name: reload nginx
      systemd:
        name: nginx
        state: reloaded

执行:

ansible-playbook site.yml

# 检查语法(不执行)
ansible-playbook site.yml --syntax-check

# 模拟执行,看会改什么
ansible-playbook site.yml --check

# 只跑打了标签的任务
ansible-playbook site.yml --tags nginx

# 指定分组
ansible-playbook site.yml -l web1

幂等性验证

ansible-playbook site.yml     # 第一次: changed=4
ansible-playbook site.yml     # 第二次: changed=0(没有变化!)

第二次跑 changed=0 才是合格的 Playbook——意味着重复执行安全,可以放心进 CI/CD。

五、常用模块速查

模块作用示例
apt/yum/dnf装软件apt: name=nginx state=present
systemd服务管理systemd: name=nginx state=restarted
copy推文件copy: src=nginx.conf dest=/etc/nginx/
template模板渲染template: src=nginx.conf.j2 dest=/etc/nginx/nginx.conf
file文件属性file: path=/data state=directory owner=steam
lineinfile改单行lineinfile: path=/etc/ssh/sshd_config regexp=^Port line="Port 22222"
command/shell跑命令shell: systemctl daemon-reload
user用户管理user: name=steam system=yes
cron定时任务cron: name=backup minute=0 hour=4 job=/opt/backup.sh
unarchive解压unarchive: src=x.tar.gz dest=/opt/
get_url下载get_url: url=... dest=/tmp/
wait_for等端口wait_for: port=8211 delay=10

六、实战:批量部署游戏服

场景:三台新机器,都要装 SteamCMD + 部署幻兽帕鲁。

# deploy-gameservers.yml
---
- name: 部署幻兽帕鲁服务器
  hosts: gameservers
  become: yes
  vars:
    steam_user: steam
    install_dir: /opt/games/palworld/server

  tasks:
    - name: 安装依赖
      apt:
        name:
          - lib32gcc-s1        # SteamCMD 32 位依赖
          - curl
          - tar
        state: present
        update_cache: yes

    - name: 创建 steam 用户
      user:
        name: "{{ steam_user }}"
        system: yes
        shell: /bin/bash
        create_home: no

    - name: 创建安装目录
      file:
        path: "{{ install_dir }}"
        state: directory
        owner: "{{ steam_user }}"
        group: "{{ steam_user }}"
        mode: '0755'

    - name: 下载 SteamCMD
      get_url:
        url: https://steamcdn-a.akamaihd.net/client/installer/steamcmd_linux.tar.gz
        dest: /tmp/steamcmd_linux.tar.gz

    - name: 解压 SteamCMD
      unarchive:
        src: /tmp/steamcmd_linux.tar.gz
        dest: /opt/steamcmd
        remote_src: yes
        creates: /opt/steamcmd/steamcmd.sh

    - name: 安装幻兽帕鲁服务端(耗时较长)
      shell: |
        /opt/steamcmd/steamcmd.sh \
          +force_install_dir {{ install_dir }} \
          +login anonymous \
          +app_update 2394010 validate \
          +quit
      become_user: "{{ steam_user }}"
      args:
        creates: "{{ install_dir }}/Pal/Binaries/Linux/PalServer-Linux-Shipping"

    - name: 部署 systemd 服务
      template:
        src: palworld.service.j2
        dest: /etc/systemd/system/palworld.service
      notify: restart palworld

    - name: 开放防火墙端口
      ufw:
        rule: allow
        port: "8211"
        proto: udp

  handlers:
    - name: restart palworld
      systemd:
        name: palworld
        state: restarted
        enabled: yes
        daemon_reload: yes

模板文件(palworld.service.j2):

[Unit]
Description=Palworld Server
After=network.target

[Service]
Type=simple
User={{ steam_user }}
WorkingDirectory={{ install_dir }}
ExecStart={{ install_dir }}/Pal/Binaries/Linux/PalServer-Linux-Shipping
Restart=on-failure
MemoryMax=10G

[Install]
WantedBy=multi-user.target

一条命令,十台机器同时装好游戏服。这就是 Ansible 的价值。

七、变量与分组差异化

不同机器配置不同?用变量:

# group_vars/gameservers.yml(对这个组的所有机器生效)
---
server_name: "我的游戏服"
max_players: 16
port: 8211

# group_vars/webservers.yml
---
http_port: 80
https_port: 443

Playbook 里引用:{{ server_name }}。

按机器覆盖:

# hosts
[gameservers]
palworld server_name="帕鲁主服" max_players=32
ark       server_name="方舟服" max_players=20

八、与手动运维的边界

用 Ansible:

  • 批量装软件、改配置、起服务
  • 环境标准化(新机器一键就绪)
  • 安全加固批量执行(改 SSH 端口、装 fail2ban)
  • 定时巡检(配合 cron 跑 playbook)

不用 Ansible:

  • 一次性命令(ansible -m shell 直接搞定)
  • 复杂交互式操作
  • 实时日志排查(还是 SSH 上去看)

Ansible vs Shell 脚本:Shell 脚本也能批量,但 Ansible 的幂等性、可读性、错误处理是脚本比不了的。机器超过 3 台就值得上 Ansible。

九、常见问题

Q:SSH 连接超时/失败?
检查:密钥分发了吗、端口是 22 吗、防火墙放行了吗、ansible_python_interpreter 路径对吗(/usr/bin/python3)。

Q:目标机器没装 Python?
主流系统都自带。极简镜像可能没有,apt install -y python3。Ansible 需要目标机有 Python。

Q:playbook 执行一半失败?
Ansible 默认出错即停。--limit 排除问题机器,修好后重跑(幂等保证安全)。

Q:密码怎么管?
用 ansible-vault 加密敏感变量:

ansible-vault create secrets.yml     # 创建加密文件
ansible-vault edit secrets.yml       # 编辑
ansible-playbook site.yml --ask-vault-pass

Q:NAT 型服务器没有公网 IP,能用 Ansible 管吗?
可以——只要你的控制节点能 SSH 到它们(内网/专线/跳板机)。内网互通就行,不需要公网 IP。

Q:执行结果 changed 和 ok 什么区别?
changed = 实际修改了系统;ok = 检查过,无需修改(幂等生效)。全 ok 说明系统已符合预期状态。

小结

Ansible 上手路径:配 hosts + SSH 密钥 → ad-hoc 命令试手 → 写第一个 playbook → 把重复操作固化。管三台以上机器,它是回报率最高的投资。机器多了之后,配合 Git 管理 playbook,环境变更就有迹可循。

更多运维内容见财富云计算知识库:Shell 脚本、systemd 服务、crontab、rsync 备份全系列。需要云服务器可以看看财富云计算:一键开服面板,NAT 型无独立公网 IP,价格比独立 IP 机型省一半以上。

延伸阅读
  1. 网站环境怎么选:LNMP 手动 / 宝塔面板 / Docker / 云开发
  2. 问卷表单系统搭建:SurveyKing / Formbricks,数据自己收
  3. 图床搭建:Lsky Pro / Lychee,自托管图片托管方案
  4. 邮件列表搭建:listmonk 自托管 Newsletter,把读者握在自己手里
  5. 文档站点搭建:MkDocs / VuePress / Docsify,产品文档与技术手册方案
  6. RSS 阅读器搭建:FreshRSS 自托管,把信息流拿回自己手里
  7. 短链接服务搭建:Shlink 自托管,链接数据自己掌握
  8. 网站状态监控页搭建:Uptime Kuma,服务器挂了第一时间知道
更多阅读
  1. 上一篇:Linux 性能分析三板斧:top、vmstat、iostat 深入实战
  2. 下一篇:服务器日常巡检清单与自动化脚本:每天 5 分钟保平安
发表评论 4