当前位置: 首页 > news >正文

【运维进阶】部署文件到受管主机

部署文件到受管主机

实验环境

[lth@controller ~ 21:13:54]$ mkdir web && cd web[lth@controller web 21:16:40]$ cat > ansible.cfg <<'EOF'
[defaults]
remote_user = lth
inventory = ./inventory[privilege_escalation]
become = True
become_user = root
become_method = sudo
become_ask_pass = False
EOF[lth@controller web 21:16:44]$ cat > inventory <<'EOF'
controller
node1
node2
node3
node4
EOF

修改文件并将其复制到主机

Files 模块库包含的模块允许您完成与Linux文件管理相关的大多数任务,如创建、复制、编辑和修改文件的权限和其他属性,下表列出了常用的Files模块库中使用的模块。

  • file:设置权限、所有权、SELinux上下文以及常规文件、符号链接、硬链接和目录的时间戳等属性。此模块还可以创建或删除常规文件、符号链接、硬链接和目录。
  • sefcontext,设置持久selinux上下文。
  • lineinfile:确保特定行位于某个文件中,或使用反向引用正则表达式来替换现有行。
  • replace:查找文件中行,一次性替换成对应内容。
  • blockinfile:插入、更新或删除多行文本块。
  • stat:检索文件的状态信息,类似于Linux stat命令。
  • copy:将文件从本地或远程计算机复制到受管节点上的某个位置。
  • synchronize:围绕rsync命令的一个程序,可加快和简化常见任务。
  • fetch:用于从远程计算机获取文件到控制节点。
file 模块

**示例:**创建文件或修改文件属性

[lth@controller web 21:16:56]$ vim playbook.yml 
[lth@controller web 21:17:10]$ cat playbook.yml 
---
- hosts: node1gather_facts: notasks:- name: Touch a file and set permissionsfile:path: /tmp/testfileowner: lthgroup: wheelmode: 0640state: touch[lth@controller web 21:17:26]$ ansible-playbook playbook.yml PLAY [node1] ****************************************************************************************TASK [Touch a file and set permissions] *************************************************************
changed: [node1]PLAY RECAP ******************************************************************************************
node1                      : ok=1    changed=1    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0[root@node1 ~ 21:18:21]# ls -l /tmp/testfile 
-rw-r----- 1 lth wheel 0 818 21:18 /tmp/testfile

mode选项: 必须使用前导0 (‘0644’ or ‘01777’) 或者引起来 (‘‘644’’ or ‘‘1777’’) 。如果直接写640,则会640当做10进制,并转换成二进制1 010 000 000,最终文件权限是-w- — --T。

lineinfile 模块

示例1:确保文件中存在特定行

[lth@controller web 21:22:35]$ vim playbook.yml 
[lth@controller web 21:22:40]$ cat playbook.yml 
---
- hosts: node1gather_facts: notasks:- name: add linelineinfile:path: /tmp/testfileline: 'Add this line to file'state: presentcreate: yes[lth@controller web 21:22:51]$ ansible-playbook playbook.yml PLAY [node1] ****************************************************************************************TASK [add line] *************************************************************************************
changed: [node1]PLAY RECAP ******************************************************************************************
node1                      : ok=1    changed=1    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0[root@node1 ~ 21:23:02]# ls -l /tmp/testfile 
-rw-r--r-- 1 root root 22 818 21:23 /tmp/testfile

还可以在特定位置插入:

  • insertbefore,最后一个匹配到前插入
---
- hosts: node1gather_facts: notasks:- name: add linelineinfile:path: /etc/httpd/conf/httpd.confline: 'Listen 82'insertbefore: 'Listen 80'state: present
  • insertafter,最后一个匹配到后插入
---
- hosts: node1gather_facts: notasks:- name: add linelineinfile:path: /etc/httpd/conf/httpd.confline: 'Listen 82'insertafter: 'Listen 80'state: present

示例2:替换文本行

---
- hosts: node1gather_facts: notasks:- name: replace linelineinfile:path: /tmp/testfileregexp: 'Add'line: 'replace'state: present
---
- hosts: node1gather_facts: notasks:- name: add linelineinfile:path: /etc/httpd/conf/httpd.confline: '#Listen 80'regexp: '^Listen 80'state: present

示例3:替换成多行文本

---
- hosts: node1gather_facts: notasks:- name: add linelineinfile:path: /tmp/testfileline: |line 1line 2regexp: 'replace'state: present 
replace 模块

该模块使用正则表达式匹配内容,将匹配的内容替换成指定的内容。匹配的多个地方都会被替换掉。

示例:

[lth@controller web 21:31:10]$ cat playbook.yml 
---
- hosts: node1gather_facts: notasks:- name: replace multi linereplace:path: /tmp/testfileregexp: '^Hello World.*'replace: 'Hello Lth'[lth@controller web 21:31:23]$ ansible-playbook playbook.ymlPLAY [node1] ************************************************************************************TASK [replace multi line] ***********************************************************************
ok: [node1]PLAY RECAP **************************************************************************************
node1                      : ok=1    changed=0    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0   [root@node1 ~ 21:31:51]# cat /tmp/testfile Hello WorldHello Lth
blockinfile 模块

示例:将文本块添加到现有文件

[lth@controller web 21:33:20]$ vim playbook.yml 
[lth@controller web 21:33:36]$ cat playbook.yml 
---
- hosts: node1gather_facts: notasks:- name: add lineblockinfile:path: /tmp/testfileblock: |line 1 in fileline 2 in filestate: present[lth@controller web 21:33:41]$ ansible-playbook playbook.yml        ......[root@node1 ~ 21:33:46]# cat /tmp/testfile 
Hello World
Hello Lth
# BEGIN ANSIBLE MANAGED BLOCK
line 1 in file
line 2 in file
# END ANSIBLE MANAGED BLOCK
stat 模块

**stat 模块检索文件的信息,类似于Linux stat命令。**参数提供检索文件属性、确定文件校验和等功能。

stat 模块返回一个包含文件状态数据的值的散列字典,允许您使用单独的变量引用各条信息。

示例:

[lth@controller web 21:38:52]$ vim playbook.yml 
[lth@controller web 21:38:59]$ cat playbook.yml ---- hosts: node1gather_facts: notasks:- stat:path: /tmp/testfilechecksum_algorithm: md5register: result- debug:msg: "/tmp/testfile md5 is {{ result.stat.checksum }}"- debug:var: result[lth@controller web 21:39:12]$ ansible-playbook playbook.ymlPLAY [node1] ****************************************************************************************TASK [stat] *****************************************************************************************ok: [node1]TASK [debug] ****************************************************************************************ok: [node1] => {"msg": "/tmp/testfile md5 is 610c7f16071ca402c0cba45e4b2af437"}TASK [debug] ****************************************************************************************ok: [node1] => {"result": {"ansible_facts": {"discovered_interpreter_python": "/usr/bin/python"}, "changed": false, "failed": false, "stat": {"atime": 1755169454.854485, "attr_flags": "", "attributes": [], "block_size": 4096, "blocks": 8, "charset": "us-ascii", "checksum": "610c7f16071ca402c0cba45e4b2af437", "ctime": 1755169447.1454144, "dev": 64768, "device_type": 0, "executable": false, "exists": true, "gid": 0, "gr_name": "root", "inode": 67588143, "isblk": false, "ischr": false, "isdir": false, "isfifo": false, "isgid": false, "islnk": false, "isreg": true, "issock": false, "isuid": false, "mimetype": "text/plain", "mode": "0644", "mtime": 1755169446.892412, "nlink": 1, "path": "/tmp/testfile", "pw_name": "root", "readable": true, "rgrp": true, "roth": true, "rusr": true, "size": 22, "uid": 0, "version": "1806842840", "wgrp": false, "woth": false, "writeable": true, "wusr": true, "xgrp": false, "xoth": false, "xusr": false}}}PLAY RECAP ******************************************************************************************node1                      : ok=3    changed=0    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0   
copy 模块

示例:将控制节点上文件拷贝到受管理节点,类似于Linux中scp命令。

[lth@controller web 21:40:05]$ vim playbook.yml 
[lth@controller web 21:40:10]$ cat playbook.yml 
---
- hosts: node1gather_facts: notasks:- name: copy /tmp/testfile to remote nodecopy:src: /tmp/testfiledest: /tmp[lth@controller web 21:40:17]$ echo "hello from controller" > /tmp/testfile
[lth@controller web 21:40:23]$ ansible-playbook playbook.yml PLAY [node1] ****************************************************************************************TASK [copy /tmp/testfile to remote node] ************************************************************
changed: [node1]PLAY RECAP ******************************************************************************************
node1                      : ok=1    changed=1    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0   [root@node1 ~ 21:42:47]# cat /tmp/testfile 
hello from controller

说明:此模块假定设置了force: yes,强制覆盖远程文件,类似scp命令。如果设置force: no, 则不会出现覆盖。

fetch 模块

从受管节点检索文件,例如将被管理节点文件先取到控制节点,然后用于分发到其他节点。诸如SSH公钥之类的文件。

示例:

[lth@controller web 21:42:43]$ vim playbook.yml 
[lth@controller web 21:42:47]$ cat playbook.yml 
---
- hosts: node1gather_facts: notasks:- name: fetch file from remote nodefetch:src: /tmp/testfiledest: /tmp
[lth@controller web 21:42:58]$ ansible-playbook playbook.yml[lth@controller web 21:43:13]$ tree /tmp/node1/
/tmp/node1/
└── tmp└── testfile1 directory, 1 file

使用JINJA2模板部署文件

JINJA2 模板介绍

Jinja2 就像个智能 “文本裁缝”,用{{ }}塞变量、{% %}做判断循环,能把固定模板和动态数据缝合成你要的样子,Ansible 配配置、网页写内容都离不开它,简单说就是 "让文本变聪明的小工具"~

示例1:部署web服务器,主页内容显示为Welcome to HOSTNAME。HOSTNAME为受管主机完全主机名。

playbook内容如下:

---
- name: Enable intranet serviceshosts: node1tasks:- name: ensure latest version of httpd yum:name: httpdstate: latest- name: test html page is installed# template模块: 复制文件到受管主机时,根据jinja2语法替换template:# 指定 Jinja2 模板来源src: index.html.j2# 指定要在目标主机上创建的文件dest: /var/www/html/index.html- name: httpd enabled and runningservice:name: httpdenabled: truestate: restarted
...

index.html.j2 内容如下:

Welcome to {{ ansible_fqdn }}

执行:

[lth@controller web 21:47:10]$ ansible-playbook playbook.yml PLAY [Enable intranet services] *********************************************************************TASK [Gathering Facts] ******************************************************************************ok: [node1]TASK [ensure latest version of httpd] ***************************************************************ok: [node1]TASK [test html page is installed] ******************************************************************changed: [node1]TASK [httpd enabled and running] ********************************************************************changed: [node1]PLAY RECAP ******************************************************************************************node1                      : ok=4    changed=2    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0   

剧本执行完成后,index.html内容如下:

Welcome to node1.xiexin.cloud
Jinja2 模板语法

Jinja2 模板由多个元素组成:数据、变量和表达式。在呈现Jinja2模板时, 这些变量和表达式被替换为对应的值。模板中使用的变量可以在playbook的vars部分中指定,也可以使用受管主机FACTS。

变量和逻辑表达式置于分隔符之间:

  • {{ EXPR }},用于装载表达式,比如变量,运算表达式,比较表达式。
  • {% EXPR %},用于装载控制语句,比如iffor等。
  • {# #},用于装载注释,模板文件中的注释不会包含在最终生成文件中。
for 语句

Jinja2使用for语句来提供循环功能。

示例1:

---
- name: test templatehosts: node1vars:users:- tom- jack- Snoopy- lucytasks:- name: test templatetemplate:src: testfile.j2dest: /tmp/testfile
...

testfile.j2内容如下:

{% for user in users %}
{{ user }}
{% endfor %}

for用于声明循环,{% endfor %} 表示结束。user变量会遍历users变量中所有值。

生成的/tmp/testfile内容如下:

tom
jack
Snoopy
lucy

验证:

[lth@controller web 21:49:03]$ ansible-playbook playbook.yml PLAY [test template] *******************************************************************************TASK [Gathering Facts] *****************************************************************************ok: [node1]TASK [test template] *******************************************************************************changed: [node1]PLAY RECAP *****************************************************************************************node1                      : ok=2    changed=1    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0   [root@node1 ~ 21:49:17]# cat /tmp/testfile 
tom
jack
snoopy
lucy
filter 过滤器

Jinja2还提供filter,对输出的结果进行格式化输出。

  • “{{ output | to_json }}”,使用JSON格式输出。
  • “{{ output | to_yaml }}”,使用YAML格式输出。
  • “{{ output | to_nice_json }}”,使用人们更加可读的JSON格式输出。
  • “{{ output | to_nice_yaml }}”,使用人们更加可读的YAML格式输出。
  • “{{ output | from_json }}”,把output当做JSON格式解析。
  • “{{ output | from_yaml }}”,把output当做YAML格式解析。

字符串处理过滤器:

  • “{{ testvar | upper }}” ,将字符串转换成纯大写。
  • “{{ testvar | lower }}” ,将字符串转换成纯小写。
  • “{{ testvar | capitalize }}”,将字符串变成首字母大写,之后所有字母纯小写。
  • “{{ testvar | reverse }}”,将字符串反转。
  • “{{ testvar | first }}”,返回字符串的第一个字符。
  • “{{ testvar | last }}”,返回字符串的最后一个字符。
  • “{{ testvar | trim }}”,将字符串开头和结尾的空格去除。
  • “{{ testvar | center(width=30) }}”,将字符串放在中间,并且设置字符串的长度为30,字符串两边用空格补齐30位长。
  • “{{ testvar | length }}”,返回字符串长度,length与count等效,可以写为count。
  • “{{ testvar | list }}”,将字符串转换成列表,每个字符作为一个元素。

列表处理过滤器:

  • “{{ testvar | first }}”,返回列表中的第一个值。
  • “{{ testvar | last }}”,返回列表中的最后一个值。
  • “{{ testvar | min }}”,返回列表中最小的值。
  • “{{ testvar | max }}”,返回列表中最大的值。
  • “{{ testvar | sort }}”,将列表升序排序输出。
  • “{{ testvar | sort(reverse=true) }}”,将列表降序排序输出。
  • “{{ testvar | sum }}”,返回纯数字非嵌套列表中所有数字的和。
  • “{{ testvar | join }}”,将列表中的元素合并成一个字符串。
  • “{{ testvar | join(’ , ') }}”,将列表中的元素使用指定分隔符合并成一个字符串。
  • “{{ testvar | random }}”,从列表中随机返回一个元素。
  • “{{ testvar | unique }}”,去掉列表中重复的元素,重复的元素只留下一个。

数字处理过滤器

  • {{ ‘a’ | int }}",将对应的值转换成int类型,如果无法转换,默认返回0。使用int(default=6)或者int(6)时,如果无法转换则返回指定值6。
  • “{{ ‘a’ | float }}”,将对应的值转换成浮点型,如果无法转换,默认返回’0.0’。使用float(default=8.88)或者float(8.88)时,如果无法转换则返回默认值’8.88’。
  • “{{ testvar4 | abs }}”,获取对应数值的绝对值。
  • “{{ 12.5 | round }}”,四舍五入。
  • “{{ 3.1415926 | round(5) }}”,取小数点后五位。
  • “{{ 100 | random }}”,从0到100中随机返回一个随机数。
  • “{{ 10 | random(start=5) }}”,从5到10中随机返回一个随机数。
  • “{{ 15 | random(step=5) }}”,从0到15中随机返回一个随机数,这个随机数是5的倍数。
  • “{{ 15 | random(start=5,step=3) }}”,从5到15中随机返回一个随机数,步长为3。
http://www.lryc.cn/news/624463.html

相关文章:

  • Vue2篇——第六章 Vue 路由(VueRouter)全解析
  • 自信息,信息熵,交叉熵,KL散度,JS散度
  • 【自动化测试】Selenium详解-WebUI自动化测试
  • 代理模式深度解析:从静态代理到 Spring AOP 实现
  • MATLAB建模与可视化技术文档:从二维到三维
  • 当使用STL容器去存放数据时,是存放对象合适,还是存放对象指针(对象地址)合适?
  • Centos7使用lamp架构部署wordpress
  • 使用华为显卡训练深度学习模型的步骤
  • 计算机网络技术学习-day3《交换机配置》
  • 像素风球球大作战 HTML 游戏
  • 【opencv-Python学习笔记(6):阈值处理】
  • 如何平衡电竞酒店和高校宿舍对AI云电竞游戏盒子的不同需求?
  • 云计算- KubeVirt 实操指南:VM 创建 、存储挂载、快照、VMI全流程 | 容器到虚拟机(镜像转换/资源调度)
  • AI需要防火墙,云计算需要重新构想
  • 我们为什么需要时序数据库?
  • AI大模型实战:用自然语言处理技术高效处理日常琐事
  • 云计算核心技术之容器技术
  • 网站服务器使用免费SSL证书安全吗?
  • Orange的运维学习日记--45.Ansible进阶之文件部署
  • 公司无公网IP,如何将内网服务,给外面异地连接使用?远程办公可通过什么访问?
  • 力扣70:爬楼梯
  • 终端管理一体化
  • 【图像算法 - 17】慧眼识“果”:基于深度学习与OpenCV的苹果智能检测系统(附完整代码)
  • 哪里找最新AI工具官网?如何快速对比ChatGPT替代品?AI工具导航指南 - AIbase
  • 实现make/makefile
  • MyCAT完整实验报告
  • 项目实战——矿物识别系统(利用机器学习从化学元素数据中识别矿物,从数据到分类模型)
  • 把 AI 编程助手塞进「离线 U 盘」——零依赖的 LLM-Coder 随行编译器
  • 8.18 打卡 DAY 45 Tensorboard使用介绍
  • Nextcloud 私有云部署:cpolar 内网穿透服务实现安全远程文件访问