1 介绍Ansible
Ansible是python开发的、开源的批量自动化运维工具
官方网站:https://www.ansible.com https://docs.ansible.com/
1.1 Ansible的概念和架构 通过inventor定义Managed node,并由SSH与python进行连通
1.管理机上管理被管机
2.inventory(清单)分组被管机
基于SSH、PowerShell进行PUSH ad-hoc或基于YML文件Playbook
Python模块、插件、API
1.2 Absible的优势 **简单明了:**Ansible playbook,更好的对任务进行排序编写 **功能强大:**3000多个模块,配置管理、工作流自动化、网络自动化 **无需代理:**通过SSH管理,而puppet、saltstack需要装客户端 与其他系统轻松集成 ,如jenkins **跨平台支持:**win、linux、unix、网络设备,虚拟机、物理机、云主机、容器
1.3 在控制节点上安装Ansible 1.Ansible自动化平台2概述-Ansible Core 红帽Ansible自动化平台2包含多个不同的组件,共同提供了一整套集成的自动化工具和资源 ** Ansible Core 提供用于运行Ansible Playbook的基本功能。
定义了用于在YAML文本文件中编写Ansible Playbook的自动化语言
提供了自动化代码所需的关键功能,如循环、条件和其他Ansible命令
提供了驱动自动化所需的框架和基本命令行工具 红帽Ansible自动化平台2 在ansible-core RPM软件包及其ee-minimal-rhel8和ee-supported-rhel8自动化执行环境中提供Ansible Core 2.13
2.Ansible自动化平台2概述-Ansible内容集合 在过去,Ansible提供了大量模块作为核心软件包的一部分;这种方法在Ansible社区中被称为“自带电池”。Ansible中包含的模块数量呈指数级增长。这导致了支持方面的一些挑战,特别是因为用户有时希望使用比Ansible特定版本中附带模块版本更早或更高的模块 上游开发人员决定将大多数模块重新整理为单独的Ansible collection(内容集合),这些资源collection相关的模块角色和插件构成,由同一组开发人员提供支持。
Ansible Core本身仅限于由ansible.builtin、Ansible collection(内容集合)提供的一小组模块,该集合始终是Ansible Core的一部分 订阅红帽Ansible自动化平台2后,可获得红帽提供的120多个认证内容集合的访问权限,另外还可通过AnsibleGalaxy获得很多受社区支持的集合
3.Ansible自动化平台2概述-自动化内容导航器 红帽Ansible自动化平台2还可提供新的顶级工具(自动化内容导航(ansble-navigator))来开发和测试Ansible Playbook。该工具可取代并扩展多个命令行实用程序的功能,包括ansible-playbook、ansible-inventory、ansible-config 通过在容器中运行playbook,将运行Ansible的控制节点与运行它的自动化执行环境分隔开来。这样一来,可以更轻松地为自动化代码提供完整的工作环境,以部署到生产环境中
4.Ansible自动化平台2概述-自动化执行环境 自动化执行环境是一种容器镜像,包含Ansible Core、Ansible内容集合以及运行playbook所需的任何Python库、可执行文件或其他依赖项 使用ansible-navigator运行playbook时,可选择用于运行该playbook的自动化执行环境
当代码运行时,可以向自动化控制器提供playbook和自动化执行环境,并且也知道其具有正确运行playbook所需的一切
5.Ansible自动化平台2概述-准备控制节点 要运行Ansible Playbook,需在控制节点安装自动化内容导航器(ansible-navigator),然后下载执行环境
由Ansible托管的主机无需安装ansible-navigator,该工具只需安装在运行Ansible Playbook的控制节点
安装ansible-core软件包前,先要在控制节点上安装Python3.8或更高版本 需要有效的红帽Ansible自动化平台订阅,才能在控制节点上安装自动化内容导航器
如果已在红帽客户门户中为您的组织激活了简单内容访问,则您无需再将订阅连接到系统
7.Ansible自动化平台2概述-安装Ansible
1 2 3 4 5 6 7 方法1: [kiosk@foundation0 ~]$ ssh student@workstation 方法2:--考试推荐使用 [kiosk@foundation0 ~]$ ssh root@workstation [root@workstation ~]$ ssh student@localhost
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 - workstation [student@workstation ~]$ lab start intro-install [student@workstation ~]$ sudo dnf search ansible [sudo ] password for student: ansible-navigator.noarch : Red Hat Ansible Automation Platform CLI ansible-core.x86_64 : SSH-based configuration management, deployment, and task execution system [student@workstation ~]$ sudo dnf -y install ansible-navigator.noarch ansible-core.x86_64 [student@workstation ~]$ rpm -q ansible-navigator ansible-navigator-2.1.0-1.el9ap.noarch [student@workstation ~]$ rpm -q ansible-core ansible-core-2.13.0-2.el9ap.x86_64 [student@workstation ~]$ rpm -qc ansible-core /etc/ansible/ansible.cfg /etc/ansible/hosts [student@workstation ~]$ rpm -qc ansible-navigator
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 [student@workstation ~]$ ansible --version ansible [core 2.13.0] config file = /etc/ansible/ansible.cfg configured module search path = ['/home/student/.ansible/plugins/modules' , '/usr/share/ansible/plugins/modules' ] ansible python module location = /usr/lib/python3.9/site-packages/ansible ansible collection location = /home/student/.ansible/collections:/usr/share/ansible/collections executable location = /bin/ansible python version = 3.9.10 (main, Feb 9 2022, 00:00:00) [GCC 11.2.1 20220127 (Red Hat 11.2.1-9)] jinja version = 3.0.3 libyaml = True [student@workstation ~]$ ansible-navigator --version ansible-navigator 2.1.0 [student@workstation ~]$ ls -a . .ansible .ansible-navigator.yml .bash_logout .bashrc .config Documents .grading .jupyter Music Pictures .ssh .venv .. ansible-navigator.log .bash_history .bash_profile .cache Desktop Downloads .ipython .local .npm Public Templates Videos [student@workstation ~]$ cat .ansible-navigator.yml --- ansible-navigator: execution-environment: image: utility.lab.example.com/ee-supported-rhel8:latest pull: policy: missing
8.Ansible自动化平台2概述-登录镜像仓库
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 [student@workstation ~]$ mkdir ~/.config/containers [student@workstation ~]$ cp /etc/containers/registries.conf ~/.config/containers [student@workstation ~]$ vim ~/.config/containers/registries.conf unqualified-search-registries = ["utility.lab.example.com" ] [[registry]] insecure = true blocked = false location = "utility.lab.example.com" [student@workstation ~]$ podman --version podman version 4.0.2 [student@workstation ~]$ ping utility PING utility.lab.example.com (172.25.250.220) 56(84) bytes of data. 64 bytes from utility.lab.example.com (172.25.250.220): icmp_seq=1 ttl=64 time =0.496 ms 64 bytes from utility.lab.example.com (172.25.250.220): icmp_seq=2 ttl=64 time =0.456 ms ...... [student@workstation ~]$ podman login -u admin -p redhat utility.lab.example.com Login Succeeded! [student@workstation ~]$ ansible-navigator collections [student@workstation ~]$ ansible-navigator images esc退出
2 部署Ansible 2.1 构建Ansible清单 系统默认的清单文件 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 1.使用文本文件定义静态主机清单 2.通过外部信息提供程序,使用Ansible插件按需生成动态主机清单 [test ] 172.25.250.10 servera servera.lab.exaple.com [web] servera.example.com serverb.example.com [webservers] web[1:50].example.com [test ] 172.25.250.10 servera servera.lab.exaple.com [web] servera.example.com serverb.example.com [servers:children] test web [START:END] 192.168.[0:15].[0:255] server[a:c].example.com server[01:15].example.com all: ungrouped:
1 2 3 4 5 [student@workstation ~]$ rpm -q ansible-core ansible-core-2.13.0-2.el9ap.x86_64 [student@workstation ~]$ rpm -qc ansible-core /etc/ansible/ansible.cfg /etc/ansible/hosts
自定义清单文件 1 2 3 4 5 6 1.创建工作目录 [student@workstation ~]$ mkdir ~/ansible [student@workstation ~]$ cd ~/ansible/ [student@workstation ansible]$ pwd /home/student/ansible
1 2 3 4 [student@workstation ansible]$ ansible-doc -t inventory -l [student@workstation ansible]$ ansible-doc -t inventory ini [student@workstation ~]$ ansible-navigator doc -t inventory ini
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 2.编辑清自定义单文件+嵌套组 [student@workstation ansible]$ vim inventory servera [web] server[b:c] 172.25.250:[10:15] [db] server[d:z].lab.example.com [servers:children] web db
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 3.验证清单: 1.ansible-navigator inventory以stdout模式运行 2.第一条传统Ansible的验证方式,第二条使用Ansible自动化平台2的方式 -RHEL8 & 9 -i inventory --list-hosts --graph $ ansible all -i inventory --list-hosts *$ ansible-inventory --graph -i inventory [student@workstation ansible]$ ansible-inventory --graph -i /home/student/ansible/inventory -RHEL 9 $ ansible-navigator inventory -i inventory -m stdout --list $ ansible-navigator inventory -i inventory -m stdout --graph $ ansible-navigator inventory -i inventory -m stdout --graph webservers 重要:清单中含有名称相同的主机和主机组,ansible命令显示警告并以主机作为其目标,组被忽略
覆盖清单位置 1 2 3 4 5 6 7 8 9 10 11 12 13 14 /home/student/ansible/inventory 优 /etc/ansible/hosts 劣 [student@workstation /]$ ansible-inventory --graph @all: |--@ungrouped: [student@workstation /]$ pwd / [student@workstation ansible]$ ansible-inventory --graph @all: |--@ungrouped: [student@workstation ansible]$ pwd /home/student/ansible
多清单 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 [student@workstation ansible]$ vim inventory servera [web] serverb serverc [db] serverd [servers:children] web db [student@workstation ansible]$ ansible-inventory --graph -i inventory @all: |--@servers: | |--@db: | | |--serverd | |--@web: | | |--serverb | | |--serverc |--@ungrouped: | |--servera [student@workstation ansible]$ cp inventory inventory2 [student@workstation ansible]$ vim inventory2 servere [student@workstation ansible]$ mkdir invdir [student@workstation ansible]$ mv inv* invdir/ mv : cannot move 'invdir' to a subdirectory of itself, 'invdir/invdir' [student@workstation ansible]$ ls invdir/ inventory inventory2 [student@workstation ansible]$ ll total 0 drwxr-xr-x. 2 student student 41 Mar 8 00:05 invdir [student@workstation ansible]$ tree . └── invdir ├── inventory └── inventory2 1 directory, 2 files [student@workstation ansible]$ ansible-inventory --graph -i invdir/ @all: |--@servers: | |--@db: | | |--serverd | |--@web: | | |--serverb | | |--serverc |--@ungrouped: | |--servera | |--servere
2.2 管理Ansible配置文件 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 [student@workstation ansible]$ mv invdir/inventory . [student@workstation ansible]$ ls invdir inventory [student@workstation ansible]$ rm -rf inv invdir/ inventory [student@workstation ansible]$ rm -rf invdir/ [student@workstation ansible]$ ls inventory [student@workstation ansible]$ ansible-inventory --graph -i inventory @all: |--@servers: | |--@db: | | |--serverd | |--@web: | | |--serverb | | |--serverc |--@ungrouped: | |--servera
配置Ansible 1 2 3 4 /etc/ansible/ansible.cfg 用于配置多个Ansible工具的行为 ~/.ansible-navigator.yml 用于更改ansible-navigator命令默认选项
1 2 3 4 5 6 7 8 9 [student@workstation ansible]$ rpm -qc ansible-core /etc/ansible/ansible.cfg /etc/ansible/hosts [student@workstation ~]$ ls -a . ansible .bash_history .bashrc Desktop .grading .lesshst .npm .ssh Videos .. ansible-navigator.log .bash_logout .cache Documents .ipython .local Pictures Templates .viminfo .ansible .ansible-navigator.yml .bash_profile .config Downloads .jupyter Music Public .venv [student@workstation ~]$ ls -a ~/.ansible-navigator.yml /home/student/.ansible-navigator.yml
管理Ansible设置
指令
描述
inventory
指定清单文件的路径。
remote_user
指定Ansible用于连接受管主机的用户名。如果未指定,则使用当前用户的名称。(在由ansible-navigator 运行的基于容器的自动化执行环境中,始终为 root。)
ask_pass
指示是否提示输入SSH 密码。 (可以是 false,如果使用SSH公钥身份验证,则此为默认值。)
become
指定连接后是否在受管主机上自动切换用户(一般切换为root)。这也可以通过play来指定
become_method
指定如何切换用户(通常为 sudo,此为默认值,但也可选择su)
become_user
指定要在受管主机上切换到哪个用户(通常为 root,此为默认值)
become_ask_pass
指示是否提示输入become_method参数密码。默认为false
自定义配置文件 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 1.普通用户身份远程 [student@workstation ~]$ cat /etc/ansible/ansible.cfg | grep ansible.cfg [student@workstation ~]$ ansible-config init --disabled > /home/student/ansible/ansible.cfg [student@workstation ~]$ pwd /home/student [student@workstation ~]$ cd /home/student/ansible/ [student@workstation ansible]$ ls ansible.cfg inventory [student@workstation ansible]$ ansible --version ansible [core 2.13.0] config file = /home/student/ansible/ansible.cfg [student@workstation ansible]$ cd / [student@workstation /]$ ansible --version ansible [core 2.13.0] config file = /etc/ansible/ansible.cfg [student@workstation /]$ cp /home/student/ansible/ansible.cfg ~/.ansible.cfg [student@workstation /]$ ansible --version ansible [core 2.13.0] config file = /home/student/.ansible.cfg 1.[defaults]---用于设置Ansible操作的默认值 2.[privilege_escalation]---用于配置Ansible如何在受管主机上执行特权升级 [student@workstation ansible]$ pwd /home/student/ansible [student@workstation ansible]$ vim ansible.cfg [defaults] inventory=/home/student/ansible/inventory remote_user=student host_key_checking=false [privilege_escalation] become=true 备注:剪切操作 dd +p [student@workstation ansible]$ ansible-inventory --graph @all: |--@servers: | |--@db: | | |--serverd | |--@web: | | |--serverb | | |--serverc |--@ungrouped: | |--servera [student@workstation ansible]$ ansible -m ping all servera | FAILED! => { "msg" : "Missing sudo password" } serverd | FAILED! => { "msg" : "Missing sudo password" } serverc | FAILED! => { "msg" : "Missing sudo password" } serverb | FAILED! => { "msg" : "Missing sudo password" } [workstation] [student@workstation ansible]$ for i in {a..d};do ssh root@server$i 'sed -i s/^%wheel.*$/"%wheel ALL=(ALL) NOPASSWD: ALL"/ /etc/sudoers' ;done [student@workstation ansible]$ for i in {a..d};do ssh root@server$i 'grep ^%wheel /etc/sudoers' ;done %wheel ALL=(ALL) NOPASSWD: ALL %wheel ALL=(ALL) NOPASSWD: ALL %wheel ALL=(ALL) NOPASSWD: ALL %wheel ALL=(ALL) NOPASSWD: ALL [student@workstation ansible]$ ansible all -m ping serverd | SUCCESS => { "ansible_facts" : { "discovered_interpreter_python" : "/usr/bin/python3" }, "changed" : false , "ping" : "pong" } serverc | SUCCESS => { "ansible_facts" : { "discovered_interpreter_python" : "/usr/bin/python3" }, "changed" : false , "ping" : "pong" } servera | SUCCESS => { "ansible_facts" : { "discovered_interpreter_python" : "/usr/bin/python3" }, "changed" : false , "ping" : "pong" } serverb | SUCCESS => { "ansible_facts" : { "discovered_interpreter_python" : "/usr/bin/python3" }, "changed" : false , "ping" : "pong" }
1 2 3 4 5 6 7 8 9 2.# ansible配置文件可以存在于不同位置其中包括: $ /etc/ansible/ansible.cfg $ ~/.ansible.cfg $ ~/ansible/ansible.cfg $ grep ANSIBLE_CONFIG /etc/profile export ANSIBLE_CONFIG=/opt/ansible.cfg (此时/opt下需要有ansible.cfg配置文件)source /etc/profile 加载优先级 :变量>当前目录>用户家目录>/etc
1 2 3 4 5 6 7 8 9 10 11 12 13 3.# 其他指定远程用户及密码的方法,以root用户身份远程 方法一: ansible.cfg remote_user=root inventory [all:vars] ansible_password=redhat 方法二: inventory [all:vars] ansible_user=root ansible_password=redhat
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 4.# 练习 根据以上笔记将清单路径记录至inventory=后,要求远程用户为普通用户,并查看清单主机模式结构。 1.创建工作目录,创建并完善清单 2.在工作目录中制作配置文件,并完善 3.保证远程和sudo 都免密 [workstation] $ for i in {a..d};do ssh root@server$i 'sed -i s/^%wheel.*$/"%wheel ALL=(ALL) NOPASSWD: ALL"/ /etc/sudoers' ;done $ for i in {a..d};do ssh root@server$i 'grep ^%wheel /etc/sudoers' ;done 4.测试远程部署 $ ansible all -m ping servera | SUCCESS => { "ansible_facts" : { "discovered_interpreter_python" : "/usr/libexec/platform-python" }, "changed" : false , "ping" : "pong"
管理自动化内容导航器的设置 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 1.如果设置了ANSIBLE NAVIGATOR_CONFIG环境变量,则使用所指定位置处的配置文件 2.当前Ansible项目目录中的ansible-navigator.yml文件 3.~/.ansible-navigator.yml文件(主目录中)。请注意,其文件名开头有一个“点” [student@workstation ~]$ rpm -ql ansible-navigator | grep temp /usr/lib/python3.9/site-packages/ansible_navigator/actions/__pycache__/template.cpython-39.opt-1.pyc /usr/lib/python3.9/site-packages/ansible_navigator/actions/__pycache__/template.cpython-39.pyc /usr/lib/python3.9/site-packages/ansible_navigator/actions/template.py /usr/lib/python3.9/site-packages/ansible_navigator/package_data/settings-sample.template.yml [student@workstation ~]$ vim /usr/lib/python3.9/site-packages/ansible_navigator/package_data/settings-sample.template.yml
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 [student@workstation ~]$ vim ~/.ansible-navigator.yml --- ansible-navigator: execution-environment: image: utility.lab.example.com/ee-supported-rhel8:latest pull: policy: missing $ vim ~/.ansible-navigator.yml --- ansible-navigator: execution-environment: image: utility.lab.example.com/ee-supported-rhel8:latest pull: arguments: - "--tls-verify=false" policy: missing playbook-artifact: enable : false
1 2 3 4 5 6 7 8 9 10 11 1.配置链接: 如何选择远程的用户 2.清单位置: 相对路径、绝对路径、多清单等。 3.链接设置 remote_user= ,~/.ansible-navigator.yml中playbook-artifact: 4.ssh免密 ssh-key-gen,ssh-copy-id 5.升级特权 visudo,/etc/sudoers
2.3 编写和运行Playbook Play是针对清单中选定的主机运行的一组有序任务
Playbook是一个文本文件,其中包含由一个或多个按特定顺序运行的play组成的列表
临时命令可以作为一次性命令对一组目标主机运行一项简单的任务
Playbook可以通过轻松重复的方式对一组目标主机执行多项复杂的任务
Playbook-yaml语法 1.playbook是使用YAML语法编写的文本文件,格式为.yml
2.严格缩进,空格 3.YAML文件以—开头,…. 结束,可以省略
4.使用”-“(减号加一个或多个空格)作为列表项
5.#注释
1 2 3 4 5 6 7 8 9 10 11 $ ansible-doc -l | grep yum $ ansible-doc yum $ vim ~/ansible/web.yml --- - name: install httpd hosts: servera tasks: - name: Install Apache ansible.builtin.yum: name: httpd state: latest
练习:写一个在servera上部署整套httpd服务的剧本
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 [student@workstation ~]$ cd ansible [student@workstation ansible]$ pwd /home/student/ansible [student@workstation ansible]$ vim inventory [dev] servera serverb [test ] serverc serverd [student@workstation ansible]$ ansible-inventory --graph @all: |--@dev: | |--servera | |--serverb |--@test : | |--serverc | |--serverd |--@ungrouped: [student@workstation ansible]$ vim soft.yml --- - name: install web server hosts: servera tasks: - name: Install the latest version of Apache ansible.builtin.yum: name: httpd state: latest [student@workstation ansible]$ cd /home/student/ansible [student@workstation ansible]$ ansible-navigator run web.yml --syntax-check -m stdout playbook: /home/student/ansible/web.yml [student@workstation ansible]$ ansible-navigator run soft.yml -m stdout
关闭运行playbook时生成的日志 1 2 3 4 5 6 7 8 9 [student@workstation ansible]$ vim ~/.ansible-navigator.yml --- ansible-navigator: execution-environment: image: utility.lab.example.com/ee-supported-rhel8:latest pull: policy: missing playbook-artifact: enable : false
调整tab键缩进
1.为了方便后期编写剧本,建议调节缩进(可选)
2.整体缩进–方便对齐yaml语法文本缩进(必选)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 vim ~/.vimrc set tabstop=2 set nu set autoindent set cursorcolumn set cursorline :set all ctrl+v , jjj(+G) ,I,(空格、空格),esc 分解: 1.光标放在需要调节的行上 2.按ctrl+v,用方向键或G选定需要调节的列 3.输入I进入插入模式 4.空格空格,调节需要的缩进 5.按esc同步所有列
查找用于任务的模块 用Ansible进行部署任务时,可针对管理员任务需求,选择对应功能模块,通过以下方法可以查询模块帮助,以便编写临时命令及playbook
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 -RHEL<=8 [student@workstation ansible]$ ansible-doc -l [student@workstation ansible]$ ansible-doc -l | grep yum yum Manages packages with the `y... yum_repository Add or remove YUM repositori... [student@workstation ansible]$ ansible-doc yum -RHEL=9 $ ansible-navigator collections $ ansible-navigator doc ansible.posix.firewalld $ ansible-navigator doc ansible.posix.firewalld -m stdout [student@workstation ansible]$ ansible-navigator collections -m stdout | grep firewalld - full_name: ansible.posix.firewalld path: /usr/share/ansible/collections/ansible_collections/ansible/posix/plugins/modules/firewalld.py short_description: Manage arbitrary ports/services with firewalld - full_name: ansible.posix.firewalld_info path: /usr/share/ansible/collections/ansible_collections/ansible/posix/plugins/modules/firewalld_info.py short_description: Gather information about firewalld [student@workstation ansible]$ ansible-navigator doc ansible.posix.firewalld -m stdout
运行Playbook 运行前建议使用语法检查验证语法错误:ansible-navigator run web.yml –syntax-check file.yml
或执行空运行ansible-navigator run web.yml -C
通常直接运行ansible-navigator run web.yml进入交互模式,或添加-m stdout可将任务打印到标准输出
1 2 3 4 $ cd ~/ansible $ mv invdir/inventory . $ rm -rf invdir
1 2 3 4 5 6 $ ansible-navigator run web.yml $ ansible-navigator run web.yml -m stdout [student@workstation ansible]$ ls ansible.cfg ansible-navigator.log inventory soft.yml [student@workstation ansible]$ ansible-navigator run soft.yml -m stdout
2.4 实施多个Play Playbook是一个YAML文件,含有由一个或多个play组成的列表
如果一个playbook中含有多个 play,每个play可以将其任务应用到单独的一组主机
在编排可能涉及对不同主机执行不同任务的复杂部署时,这会大有帮助
可以这样编写playbook:对一组主机运行一个play,完成后再对另一组主机运行另一个play
编写包含多个play的playbook非常简单
Playbook中的各个play编写为playbook中的顶级列表项
编写多个Play 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 [student@workstation ansible]$ vim install_yum.yml --- - name: install yum repo hosts: servera,serverb tasks: - name: BaseOS_REPO ansible.builtin.yum_repository: name: Red Hat Enterprise Linux 9 for x86_64 - BaseOS (RPMs) description: BaseOS file: rhel_BaseOS baseurl: http://content.example.com/rhel9.0/x86_64/dvd/BaseOS gpgcheck: no - name: AppStream_REPO ansible.builtin.yum_repository: name: Red Hat Enterprise Linux 9 for x86_64 - AppStream (RPMs) description: AppStream file: rhel_AppStream baseurl: http://content.example.com/rhel9.0/x86_64/dvd/AppStream gpgcheck: no - name: install yum repo hosts: serverc tasks: - name: BaseOS_REPO ansible.builtin.yum_repository: name: Red Hat Enterprise Linux 9 for x86_64 - BaseOS (RPMs) description: BaseOS file: rhel_BaseOS baseurl: http://content.example.com/rhel9.0/x86_64/dvd/BaseOS gpgcheck: no [student@workstation ansible]$ ansible-navigator collections -m stdout | grep firewalld - full_name: ansible.posix.firewalld path: /usr/share/ansible/collections/ansible_collections/ansible/posix/plugins/modules/firewalld.py short_description: Manage arbitrary ports/services with firewalld - full_name: ansible.posix.firewalld_info path: /usr/share/ansible/collections/ansible_collections/ansible/posix/plugins/modules/firewalld_info.py short_description: Gather information about firewalld [student@workstation ansible]$ ansible-navigator doc ansible.posix.firewalld -m stdout --syntax-check [student@workstation ansible]$ ansible-navigator run install_yum.yml -m stdout --syntax-check playbook: /home/student/ansible/install_yum.yml -v -vv -vvv [student@workstation ansible]$ ansible-navigator run install_yum.yml -m stdout --syntax-check -v Using /home/student/ansible/ansible.cfg as config file playbook: /home/student/ansible/install_yum.yml [student@workstation ansible]$ ansible-navigator run install_yum.yml -m stdout [student@workstation ansible]$ ansible -m shell all -a 'yun -y install ftp' [student@workstation ansible]$ ansible all -m shell -a 'rpm -q ftp' serverd | CHANGED | rc=0 >> ftp-0.17-89.el9.x86_64 serverc | CHANGED | rc=0 >> ftp-0.17-89.el9.x86_64 serverb | CHANGED | rc=0 >> ftp-0.17-89.el9.x86_64 servera | CHANGED | rc=0 >> ftp-0.17-89.el9.x86_64 以上实验,用ansible-doc 查询课程中的所有模块 yum 安装软件 service 管理服务 shell模块 管理防火墙 copy 拷贝,1有拷贝功能,2 可以将一段文本,复制到某个文件中,如文件不存在,则生成文件。 uri 网站连接测试
选择模块
类别
模块
文件
ansible.builtin.copy: 将本地文件复制到受管主机 ansible.builtin.file: 设置文件的权限和其他属性 ansible.builtin.lineinfile: 确保特定行是否在文件中 ansible.posix.synchronize: 使用rsync 同步内容
软件
ansible.builtin.package: 使用操作系统自带的自动检测软件包管理器管理软件包。 ansible.builtin.dnf: 使用DNF软件包管理器管理软件包 ansible.builtin.apt: 使用APT 软件包管理器管理软件包 ansible.builtin.pip: 从PyPI管理Python 软件包。
系统
ansible.posix.firewalld: 使用firewalld 管理任意端口和服务 ansible.builtin.reboot: 重新启动计算机。 ansible.builtin.service: 管理服务 ansible.builtin.user: 添加、删除和管理用户帐户
网络工具
ansible.builtin.get_url: 通过HTTP、HTTPS或FTP 下载文件 ansible.builtin.uri: 与Web 服务交互
3 管理变量和事实 3.1 管理变量 Ansible变量简介 Ansible支持利用变量来存储值,并在Ansible项目的所有文件中重复使用这些值
可以简化项目的创建和维护,并减少错误的数量
1 2 3 4 5 6 7 变量可以重复的应用到项目中,简化管理,应用对象可以是: 1.要创建的用户 2.要安装的软件包 3.要重新启动的服务 4.要删除的文件 5.互联网的文档等
命名变量 变量的名称必须以字母开头,并且只能含有字母、数字和下划线
无效变量名称
有效变量名称
web server
web_server
remote.file
remote_file
1st file
file_1,file1
remoteserver $1
remote_server_1,remote_server1
定义变量 可在Ansible项目中的多个位置定义变量
如果在两个位置设置了同名变量,并且变量值不同,则通过优先级来决定要使用哪个值 可以设置会影响一组主机的变量,也可以设置只会影响个别主机的变量
有些变量是Ansible可以根据系统配置来设置的事实
有些变量可在playbook中设置,然后影响该playbook中的一个play,或者仅影响该play中的一项任务
可通过–extra-vars或-e选项并指定变量值
应用场景
描述
优先度
全局范围
命令行执行临时命令时指定的变量 -e key=vaule
高
play范围
playbook的Play部分或模块内部指定变量信息key: vaule
中
主机范围
清单中主机或主机组指定变量(主机 优先 主机组)
低
1.全局范围-命令行 清单变量可被playbook中设置的变量覆盖,这两种变量又可通过在命令行中传递参数到ansible-navigatorrun 命令来覆盖
在命令行上设置的变量称为额外变量
1 2 3 4 5 6 7 [student@workstation ansible]$ ansible servera -m shell -a whoami -e ansible_user=root -e ansible_password=redhat servera | CHANGED | rc=0 >> root [student@workstation ansible]$ ansible-navigator run install_yum.yml -m stdout -e ansible_user=root -e ansible_password=redhat
2.PlAY范围-Playbook 变量在Ansible Playbook中发挥着重要作用,可以简化playbook中变量数据的管理
编写play时,可以定义自己的变量,然后在任务中调用这些值
例如,可以使用值httpd来定义名为web_package的变量。然后,任务可以使用ansible.builtin.dnf模块调用该变量来安装httpd软件包
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 -vars [student@workstation ansible]$ vim web.yml --- - name: PLAY1 hosts: servera vars: - package: httpd tasks: - name: install {{ package }} ansible.builtin.yum: name: "{{ package }}" state: latest [student@workstation ansible]$ ansible-navigator run web.yml -m stdout --syntax-check playbook: /home/student/ansible/web.yml [student@workstation ansible]$ ansible-navigator run web.yml -m stdout -vars_files [student@workstation ansible]$ vim /home/student/ansible/var.yml --- package: httpd [student@workstation ansible]$ vim /home/student/ansible/httpd.yml --- - name: PLAY2 hosts: serverb vars_files: - /home/student/ansible/var.yml tasks: - name: install {{ package }} ansible.builtin.yum: name: "{{ package }}" state: latest [student@workstation ansible]$ ansible-navigator run httpd.yml -m stdout --syntax-check playbook: /home/student/ansible/httpd.yml [student@workstation ansible]$ ansible-navigator run httpd.yml -m stdout
3.主机范围-清单中(主机变量和组变量) 直接应用于主机的清单变量分为两大类:
1.主机变量,应用于特定主机
2.组变量,应用于一个主机组或组主机组中的所有主机。
主机变量优先于组变量,但playbook中定义的变量的优先级比这两者更高
若要定义主机变量和组变量,一种方法是直接在清单文件中定义
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 [student@workstation ansible]$ vim /home/student/ansible/inventory 172.25.250.9 ansible_password=redhat [test ] 172.25.250.10 [test :vars] ansible_password=redhat [prod] 172.25.250.[11:12] [balancers] 172.25.250.13 [all:vars] ansible_user=root ansible_password=redhat
4.使用目录填充主机和组变量 定义主机和主机组变量的首选做法是在清单文件或目录相同的工作目录中,创建group_vars和host_vars两个目录。这两个目录分别包含用于定义组变量和主机变量文件
建议在host_vars和group_vars目录定义清单变量,而不是直接在清单文件中定义他们
字典形式表示变量 除了将与同一元素相关的配置数据分配到多个变量外,管理员也可以使用字典
字典是一个包含键值对的数据结构,其中的值也可以是字典
1.同一元素相关变量的键值关系 1 2 3 4 5 6 user1_A_name: zhang user1_B_name: san user1_C_name: /home/zhangsan user2_A_name: li user2_B_name: si user2_C_name: /home/lisi
2.字典形式 1 2 3 4 5 6 7 8 9 10 11 vim vari.yml --- users: user1: A_name: zhang B_name: san C_name: /home/zhangsan user2: A_name: li B_name: si C_name: /home/lisi
3.调用变量 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 例子:调用数组 users.user1.A_name users.user2.B_name 应用方法2:python字典 users ['user1' ]['A_name' ] --- - name: useradd hosts: dev vars_files: - vari.yml tasks: - name: Add the user ansible.builtin.user: name: "{{ users.user1.A_name }}{{ users.user1.B_name }}" home: "{{ users['user1']['C_name'] }}"
使用已注册变量捕获命令输出 register用来捕获命令输出或有关模块执行的其他信息。输出会保存至一个变量中,稍后可用于调试或其他目的。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 $ vim register.yml --- - name: install a packages hosts: servera tasks: - name: install the latest version of Apache ansible.builtin.yum: name: httpd state: latest register: install_result - name: message ansible.builtin.debug: var: install_result $ ansible-navigator run -m stdout register.yml
3.2 管理机密-vault 介绍Ansible-vault Ansible可能需要访问密码或API密钥等敏感数据,以配置受管主机。通常,此信息会以纯文本形式存储在清单变量或其他Ansible文件中。但若如此,任何有权访问Ansible文件的用户或存储这些Ansible文件的版本控制系统都能够访问此敏感数据。这显然存在安全风险
使用Ansible随附的Ansible Vaut可以加密和解密任何由Ansible使用的数据文件。若要使用Ansible Vaut,可通过一个名为ansible-vault的命令行工具创建、编辑、加密、解密和查看文件
Ansible Vault可以加密任何由Ansible使用的数据文件。这可能包括清单变量、playbook中含有的变量文件、在执行playbook时作为参数传递的变量文件,或者Ansible角色中定义的变量
1 2 3 4 5 6 7 8 9 10 11 12 [student@workstation ~]$ ansible-vault --help usage: ansible-vault [-h] [--version] [-v] {create,decrypt,edit,view,encrypt,encrypt_string,rekey} ... encryption/decryption utility for Ansible data files positional arguments: {create,decrypt,edit,view,encrypt,encrypt_string,rekey} create Create new vault encrypted file decrypt Decrypt vault encrypted file edit Edit vault encrypted file view View vault encrypted file encrypt Encrypt YAML file encrypt_string Encrypt a string rekey Re-key a vault encrypted file
1 创建与查看加密文件 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 [student@workstation ansible]$ pwd /home/student/ansible [student@workstation ansible]$ ansible-vault create sec1.txt New Vault password: redhat Confirm New Vault password: redhat [student@workstation ansible]$ cat sec1.txt $ANSIBLE_VAULT ;1.1;AES25635333131363436363836626431336230353532613437623862316361313130646338613163393266 6234663835643533336635323435313064386363303337650a663261613334653066373463663230 31643332636435383063353535626166626632313034636335643766326638343134356663653761 6330663638613335340a663337636132663362646531653537626665363064323864613936386136 32323636366431666130386333346236643033373062303938303937383436326232 [student@workstation ansible]$ ansible-vault view sec1.txt Vault password: redhat --- This is a encrypted file!
2 编辑现有的加密文件 1 2 3 4 5 6 7 8 9 10 11 [student@workstation ansible]$ pwd /home/student/ansible [student@workstation ansible]$ ansible-vault edit sec1.txt Vault password: [student@workstation ansible]$ ansible-vault view sec1.txt Vault password: --- This is a encrypted file! password: redhat321
3 加密现有的文件 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 [student@workstation ansible]$ pwd /home/student/ansible [student@workstation ansible]$ echo China > sec2.txt [student@workstation ansible]$ cat sec2.txt China [student@workstation ansible]$ ansible-vault encrypt sec2.txt New Vault password: redhat Confirm New Vault password: redhat Encryption successful [student@workstation ansible]$ cat sec2.txt $ANSIBLE_VAULT ;1.1;AES25639333163613564343437353466356536666437633937616533623231633561313537346633363630 6535653834383263356261623737376131333237643330610a313134373235336430316139623035 63323935356565313536383164343938366639663036323264666636353962343133636534396635 6566656361323462650a343139653263386230393938346565626634303335313262626639653737 3562 [student@workstation ansible]$ ansible-vault view sec2.txt Vault password: China
4 解密现有的文件 1 2 3 4 5 6 7 8 [student@workstation ansible]$ pwd /home/student/ansible [student@workstation ansible]$ ansible-vault decrypt sec2.txt Vault password: redhat Decryption successful [student@workstation ansible]$ cat sec2.txt China
5 更改加密文件的密码 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 [student@workstation ansible]$ pwd /home/student/ansible [student@workstation ansible]$ ansible-vault rekey sec1.txt Vault password: redhat New Vault password: redhat321 Confirm New Vault password: redhat321 Rekey successful [student@workstation ansible]$ ansible-vault view sec1.txt Vault password: redhat321 --- This is a encrypted file! password: redhat321
6 使用密码文件 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 [student@workstation ansible]$ pwd /home/student/ansible [student@workstation ansible]$ ansible-vault view sec1.txt --help ---省略--- --vault-id VAULT_IDS the vault identity to use --ask-vault-password, --ask-vault-pass ask for vault password --vault-password-file VAULT_PASSWORD_FILES, --vault-pass-file VAULT_PASSWORD_FILES vault password file ---省略--- [student@workstation ansible]$ echo redhat321 > secret.txt [student@workstation ansible]$ cat secret.txt redhat321 [student@workstation ansible]$ ansible-vault view sec1.txt --vault-id=secret.txt --- This is a encrypted file! password: redhat321
7 密码文件记录到ansible.cfg配置文件中 1 密码文件记录在ansible.cfg配置文件中的好处是,当执行一个使用了加密文件的playbook时,不必手工指定加密文件密码。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 [student@workstation ansible]$ pwd /home/student/ansible [student@workstation ansible]$ vim ansible.cfg vault_password_file=/home/student/ansible/secret.txt [student@workstation ansible]$ ansible-vault view sec1.txt --- This is a encrypted file! password: redhat321 1.加密现有文件时会直接引用 [student@workstation ansible]$ ansible-vault encrypt sec2.txt Encryption successful 2.更改密码时会直接覆盖 [student@workstation ansible]$ ansible-vault rekey sec2.txt Rekey successful 3.更改密码需使用--ask-vault-password参数指定 [student@workstation ansible]$ ansible-vault rekey sec2.txt --ask-vault-password Vault password: redhat New Vault password: redhat Confirm New Vault password: redhat Rekey successful
3.3 管理事实facts Ansible事实是Ansible在受管主机上自动检测到的变量。事实中含有与主机相关的信息,可以像play中的常规变量、条件、循环或依赖于从受管主机收集的值的任何其他语句那样使用。 为受管主机收集的一些事实可能包括: 主机名称、内核版本、网络接口名称、网络接口IP地址、操作系统版本、CPU数量提供的或可用的内存、存储设备的大小和可用空间
借助事实,可以方便地检索受管主机的状态,并根据该状态确定要执行的操作。例如:
1.根据含有受管主机当前内核版本的事实运行条件任务,以此来重新启动服务器
2.根据通过事实报告的可用内存来定义MySQL配置文件 3.根据事实的值设置配置文件中使用的IPv4地址 通常,每个play在执行第一个任务之前会先自动运行setup模块来收集事实。这在Ansible2.3中报告为GatheringFacts任务,或者更早版本中报告为setup。默认情况下,无需具有在play中运行setup的任务,通常会自动运行 查看受管主机收集的事实的方式是:
1.使用ad-hoc命令运行setup模块
2.使用playbook运行debug模块并提取变量var: ansible facts
收集事实
1 2 3 ansible_default_ipv4.hostname ansible_default_ipv4.[ 'hostname' ]
1 临时命令 ad-hoc 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 1.使用ad-hoc方式收集事实 [student@workstation ansible]$ ansible -m setup all [student@workstation ansible]$ ansible -m setup servera [student@workstation ansible]$ ansible -m setup servera -a filter=ansible_nodename servera | SUCCESS => { "ansible_facts" : { "ansible_nodename" : "servera.lab.example.com" , "discovered_interpreter_python" : "/usr/bin/python3" }, "changed" : false } [student@workstation ansible]$ ansible -m setup serverc -a filter=*ipv4* serverc | SUCCESS => { "ansible_facts" : { "ansible_all_ipv4_addresses" : [ "172.25.250.12" ], "ansible_default_ipv4" : { "address" : "172.25.250.12" , "alias" : "eth0" , "broadcast" : "172.25.250.255" , "gateway" : "172.25.250.254" , "interface" : "eth0" , "macaddress" : "52:54:00:00:fa:0c" , "mtu" : 1500, "netmask" : "255.255.255.0" , "network" : "172.25.250.0" , "prefix" : "24" , "type" : "ether" }, "discovered_interpreter_python" : "/usr/bin/python3" }, "changed" : false } [student@workstation ansible]$ ansible -m setup serverc > fact.txt [student@workstation ansible]$ ll fact.txt -rw-r--r--. 1 student student 25988 Mar 11 01:55 fact.txt [student@workstation ansible]$ pwd /home/student/ansible
2 PLAYBOOK 收集事实 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 [student@workstation ansible]$ vim debug.yml --- - name: debug hosts: servera tasks: - ansible.builtin.debug: msg: servera ip address "{{ ansible_default_ipv4.address }}" - ansible.builtin.debug: var: ansible_hostname [student@workstation ansible]$ ansible-navigator run debug.yml -m stdout --syntax-check playbook: /home/student/ansible/debug.yml [student@workstation ansible]$ ansible-navigator run debug.yml -m stdout PLAY [debug] ************************************************************************************************************************************************ TASK [Gathering Facts] ************************************************************************************************************************************** ok: [servera] TASK [ansible.builtin.debug] ******************************************************************************************************************************** ok: [servera] => { "msg" : "servera ip address \"172.25.250.10\"" } TASK [ansible.builtin.debug] ******************************************************************************************************************************** ok: [servera] => { "ansible_hostname" : "servera" } PLAY RECAP ************************************************************************************************************************************************** servera : ok=3 changed=0 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
3 关闭事实 1 2 3 4 5 6 7 8 9 10 11 12 13 [student@workstation ansible ]$ vim debug.yml --- - name: debug message hosts: dev gather_facts: on/off true /false tasks: - debug: msg: "{{ ansible_facts.default_ipv4.address }} " [greg@bastion ansible ]$ ansible-playbook debug.yml
魔法变量
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 [student@workstation ansible]$ ansible web -m debug -a var=inventory_hostname serverb | SUCCESS => { "inventory_hostname" : "serverb" } serverc | SUCCESS => { "inventory_hostname" : "serverc" } [student@workstation ansible]$ ansible serverd -m debug -a var=group_names serverd | SUCCESS => { "group_names" : [ "db" , "servers" ] } [student@workstation ansible]$ ansible all -m debug -a var=groups [student@workstation ansible]$ ansible all -m debug -a var=hostvars $ https://docs.ansible.com/ansible/latest/reference_appendices/special_variables.html
1 临时命令收集魔法变量值 ad-hoc 1 2 3 4 5 ansible servera -m debug -a var=inventory_hostname ansible servera -m debug -a var=groups ansible all -m debug -a var=group_names ansible all -m debug -a var=hostvars ansible servera -m debug -a var=groups.all
2 PLAYBOOK收集事实+魔法变量 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 [student@workstation ansible ]$ vim hoc_debug.yml --- - name: debug hosts: servera gather_facts: on tasks: - ansible.builtin.debug: var: hostvars [student@workstation ansible ]$ ansible-navigator run hoc_debug.yml -m stdout --syntax-check playbook: /home/student/ansible/hoc_debug.yml [student@workstation ansible ]$ ansible-navigator run hoc_debug.yml -m stdout [student@workstation ansible ]$ ansible-navigator run hoc_debug.yml -m stdout > hoc_fact.txt
3 魔法变量hostvars 临时命令与playbook收集hostvars变量值是不同的
临时命令不会执行setup模块,所以收集不到事实,PLAYBOOK方法则可以收集到事实和魔法变量
1 [student@workstation ansible]$ ansible all -m setup > all_host.txt
4 实施任务控制 4.1 编写循环和条件任务 利用循环迭代任务 通过利用循环,管理员无需编写多个使用同一模块的任务。例如,不必编写五个任务来确保存在五个用户,而是只需编写一个任务来对含有五个用户的列表迭代,从而确保他们都存在 Ansible支持使用loop关键字对一组项目迭代任务。可以配置循环以利用列表中各个项目、列表中各个文件的内容、生成的数字序列或更为复杂的结构来重复任务。
1 2 3 $ https://docs.ansible.com/ansible/latest/user_guide/playbooks_loops.html
1 简单循环 简单循环对一组项目迭代任务
loop 关键字添加到任务中,将应对其迭代任务的项目列表取为值
循环变量item保存每个迭代过程中使用的值
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 [student@workstation ansible]$ vim loop.yml --- - name: service hosts: servera tasks: - name: Start service nfs-server ansible.builtin.service: name: nfs-server state: started - name: Start service chronyd ansible.builtin.service: name: chronyd state: started [student@workstation ansible]$ vim loop.yml --- - name: service hosts: servera tasks: - name: Start service nfs-server&chronyd ansible.builtin.service: name: "{{ item }}" state: started loop: - nfs-server - chronyd [student@workstation ansible]$ ansible-navigator run loop.yml -m stdout --syntax-check playbook: /home/student/ansible/loop.yml [student@workstation ansible]$ ansible-navigator run loop.yml -m stdout
2 循环使用变量 在playbook中通过vars或vars files方式加载变量servers中包含循环列表,模块通过loop字段加载servers变量列表中的值。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 [student@workstation ansible]$ vim loop.yml --- - name: service loop hosts: servera vars: servers: - nfs-server - chronyd tasks: - name: Start service ansible.builtin.service: name: "{{ item }}" state: stopped loop: "{{ servers }}" [student@workstation ansible]$ mkdir /home/student/ansible/vars/ [student@workstation ansible]$ vim /home/student/ansible/vars/var.yml servers: - nfs-server - chronyd [student@workstation ansible]$ vim loop.yml --- - name: service loop hosts: servera vars_files: - /home/student/ansible/vars/var.yml tasks: - name: Start service ansible.builtin.service: name: "{{ item }}" state: stopped loop: "{{ servers }}" [student@workstation ansible]$ ansible-navigator run loop.yml -m stdout --syntax-check playbook: /home/student/ansible/loop.yml [student@workstation ansible]$ ansible-navigator run loop.yml -m stdout
3 循环字典列表 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 [student@workstation ansible]$ vim loop.yml --- - name: service loop hosts: servera tasks: - name: Start service ansible.builtin.user: name: "{{ item.name }}" comment: "{{ item.comment }}" state: present loop: - name: jane comment: tom - name: joe comment: harry [student@workstation ansible]$ ansible-navigator run loop.yml -m stdout --syntax-check playbook: /home/student/ansible/loop.yml [student@workstation ansible]$ ansible-navigator run loop.yml -m stdout
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 [student@workstation ansible]$ vim loop.yml --- - name: service loop hosts: servera vars: users : - name: jane comment: tom - name: joe comment: harry tasks: - name: Start service ansible.builtin.user: name: "{{ item.name }}" comment: "{{ item.comment }}" state: present loop: "{{ users }}" [student@workstation ansible]$ ansible-navigator run loop.yml -m stdout --syntax-check playbook: /home/student/ansible/loop.yml [student@workstation ansible]$ ansible-navigator run loop.yml -m stdout
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 [student@workstation ansible]$ vim /home/student/ansible/vars/var.yml servers: users :- name: jane comment: tom - name: joe comment: harry [student@workstation ansible]$ vim loop.yml --- - name: service loop hosts: servera vars_files: - /home/student/ansible/vars/var.yml tasks: - name: Start service ansible.builtin.user: name: "{{ item.name }}" state: present comment: "{{ item.comment }}" loop: "{{ users }}" [student@workstation ansible]$ ansible-navigator run loop.yml -m stdout --syntax-check playbook: /home/student/ansible/loop.yml [student@workstation ansible]$ ansible-navigator run loop.yml -m stdout
有条件地运行任务
Ansible可使用conditionals在符合特定条件时运行任务或play。例如,可以使用条件句在Ansible安装或配置某个服务之前,确定受管主机上的可用内存。
条件句可帮助区分不同的受管主机,并根据所符合的条件来分配功能角色
Playbook变量、注册的变量和Ansible事实都可通过条件句来进行测试。可以使用比较字符串、数字数据和布尔值的运算符。
when判断对象是模块,和模块在同一下列层次
when判断当前模块是否执行,而不是它下面模块是否执行
When中引用变量、facts,不需加大括号
用于测试条件中相等的==运算符不可与变量赋值的=运算符混淆
一个when语句可用于评估多个值。 可以使用and和or关键字组合条件,或使用括号分组条件
1.or是或的关系,任意一个条件为真即可
1 when: ansible_distribution == "RedHat" or ansible_distribution == "Fedora"
2.and是与的关系,多个条件需同时为真
1 when: ansible_distribution version == "7.5" and ansible_kernel == "3.10.0-327.el7.x86_64"
When语句多条件的另外方式:
1 2 3 when: -ansible_distribution_version == "7.5" -ansible_kernel == "3.10.0-327.el7.x86_64"
使用括号分组条件来表达更复杂的条件语句:
1 2 3 4 5 6 when: > ( ansible_distribution == "RedHat" and ansible_distribution_major_version == "7" ) or ( ansible_distribution == "Fedora" and ansible_distribution_major_version == "28" )
简单的有条件任务示例: 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 [student@workstation ansible]$ vim when.yml --- - name: repository hosts: all tasks: - name: install the latest version of Apache ansible.builtin.yum: name: httpd state: latest when: ansible_default_ipv4.address == '172.25.250.10' [student@workstation ansible]$ ansible-navigator run when.yml -m stdout --syntax-check playbook: /home/student/ansible/when.yml [student@workstation ansible]$ ansible-navigator run when.yml -m stdout [student@workstation ansible]$ vim when-vdb.yml --- - name: repository hosts: all tasks: - name: install the latest version of Apache ansible.builtin.yum: name: httpd state: latest when: ansible_devices.vdb is defined [student@workstation ansible]$ ansible-navigator run when-vdb.yml -m stdout --syntax-check playbook: /home/student/ansible/when-vdb.yml [student@workstation ansible]$ ansible-navigator run when-vdb.yml -m stdout
组合循环和有条件任务示例: 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 [student@workstation ansible ]$ vim when_loop.yml --- - name: 安装软件包 hosts: all tasks: - name: install the latest version of Apache ansible.builtin.yum: name: "{{ item }} " state: latest loop: - php - mariadb when: ansible_hostname == 'servera' or ansible_hostname == 'serverc' [student@workstation ansible ]$ ansible-navigator run when_loop.yml -m stdout --syntax-check playbook: /home/student/ansible/when_loop.yml [student@workstation ansible ]$ ansible-navigator run when_loop.yml -m stdout [student@workstation ansible ]$ vim when_loop2.yml --- - name: repository hosts: all tasks: - name: install the latest version of Apache ansible.builtin.yum: name: "{{ item }} " state: latest loop: - mariadb when: '"52:54:00:00:fa:0a" in ansible_default_ipv4.macaddress' [student@workstation ansible ]$ ansible-navigator run when_loop2.yml -m stdout --syntax-check playbook: /home/student/ansible/when_loop2.yml [student@workstation ansible ]$ ansible-navigator run when_loop2.yml -m stdout
常用when条件语句 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 [student@workstation ansible]$ ansible all -m debug -a var=groups [student@workstation ansible]$ ansible all -m debug -a var=group_names inventory_hostname == 'node1' inventory_hostname != 'node1' '"52:54:00:00:fa:0b" in ansible_default_ipv4.macaddress' ansible_default_ipv4.address == '172.25.250.11' inventory_hostname in groups.dev '"dev" in group_names' [student@workstation ansible]$ vim when_loop3.yml --- - name: repository hosts: all tasks: - name: install the latest version of Apache ansible.builtin.yum: name: httpd state: latest when: '"db" in group_names' [student@workstation ansible]$ ansible-navigator run when_loop3.yml -m stdout --syntax-check playbook: /home/student/ansible/when_loop3.yml [student@workstation ansible]$ ansible-navigator run when_loop3.yml -m stdout
4.2 实施处理程序 handlers是处理程序的一种实现,当对一个Playbook模块改动时,通过监控发现改动,并自动执行后续处理动作。帮助管理员节省管理成本。 比如一种场景,当修改了服务配置文件时,需要对服务进行重启。可以在配置文件模块位置用notify监视是否修改后,用handlers中的处理程序如:service模块对其重启服务。达到修改文件便自动重启服务的效果。
Ansible处理程序 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 $ vim handlers.yml --- - name: hosts: servera tasks: - name: install the latest version of Apache ansible.builtin.yum: name: httpd state: latest - name: Copy using inline content ansible.builtin.copy: content: 'heihei' dest: /var/www/html/index.html notify: restart - name: Start firewalld ansible.builtin.service: name: firewalld state: started handlers: - name: restart ansible.builtin.service: name: httpd state: restarted
4.3 执行中对错误的处理 Ansible评估各任务的返回代码,从而确定任务是成功还是失败 通常而言,当任务失败时,ansible将立即在该主机上终止play的其余部分并且跳过所有后续任务 有些时候,可能希望即使在任务失败时也继续执行play
ignore_errors 忽略任务失败 ignore_errors
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 [student@workstation ansible ]$ vim ignore_errors.yml --- - name: test error hosts: servera tasks: - name: touch directory ansible.builtin.shell: mkdir /a/b ignore_errors: yes - name: Add the user ansible.builtin.user: name: johnd [student@workstation ansible ]$ ansible-navigator run ignore_errors.yml -m stdout --syntax-check [student@workstation ansible ]$ ansible-navigator run ignore_errors.yml -m stdout --- - name: test error force_handlers: yes tasks: - xxxx handlers: - name: haha ansible.builtin.service: xxx xxx
4.4 Ansible块和错误的处理 block、rescue、always 定义区域中失败的任务 block:定义要运行的主要任务
rescue:定义要在block子句中定义的任务失败时运行的任务
always:定义始终都在独立运行的任务
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 --- - name: block hosts: all tasks: - block: - name: ansible.builtin.yum: name: http state: present rescue: - name: ansible.builtin.yum: name: httpd state: present when: inventory_hostname == 'serverb' always: - name: Start service httpd, if not started ansible.builtin.service: name: httpd state: started
block示例 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 --- - name: test error hosts: all tasks: - name: touch file ansible.builtin.shell: mkdir -p /a/b when: inventory_hostname == "servera" - name: Add the user ansible.builtin.user: name: johnd when: inventory_hostname == "servera" --- - name: test error hosts: all tasks: - block: - name: touch file ansible.builtin.shell: mkdir -p /a/b - name: Add the user ansible.builtin.user: name: johnd when: inventory_hostname == "servera"
5 将文件部署到受管主机 5.1 修改文件并将其复制到主机 文件模块介绍 1.在被管机上创建文件和目录
2.复制文件(或内容)到被管机 control –> node1
3.从被管机复制文件到管理机 node1 –> control
4.修改文件内容
5.查看文件状态
6.修改文件属性(所有者、权限、selinux)
7.文件同步
ansible.builtin-描述文件模块
模块名
说明
blockinfile
插入、更新 、删除,自定义标记的多行文本块
file
设置权限、所有者、SElinux上下文及常规文件、符号连接、硬链接等
copy
远程copy,类似file,可以设置文件属性、SElinux上下文
fetch
和copy类似,相反工作方式,从远端拷贝到控制节点
lineinfile
改文件某一行时使用
stat
检测文件状态,类似linux中stat命令
synchronize
围绕rsync一个打包程序
1 2 3 4 5 $ ansible-doc -l | grep file $ ansible-navigator collections -m stdout | grep file$ $ ansible-doc file
ansible.builtin.file 1 2 3 4 5 6 7 8 9 10 11 12 13 - name: Change file ownership, group and permissions ansible.builtin.file: path: /var/www/html/index.html owner: apache group: apache mode: '0644' state: touch setype: default_t
ansible.builtin.copy 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 - name: Copy file with owner and permissions ansible.builtin.copy: src: /srv/myfiles/foo.conf dest: /var/www/html/index.html owner: foo group: foo mode: '0644' setype: httpd_sys_content_t - name: Copy using inline content ansible.builtin.copy: content: "testweb" dest: /var/www/html/index.html
ansible.builtin.lineinfile 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 [student@workstation ansible]$ ansible-doc -l | grep line lineinfile Manage lines in text files [student@workstation ansible]$ ansible-doc lineinfile [student@workstation ansible]$ vim lineinfile.yml --- - name: lineinfile hosts: all tasks: - name: Ensure SELinux is set to enforcing mode ansible.builtin.lineinfile: path: /etc/selinux/config regexp: '^SELINUX=' line: SELINUX=enforcing [student@workstation ansible]$ ansible-navigator run lineinfile.yml -m stdout --syntax-check playbook: /home/student/ansible/lineinfile.yml [student@workstation ansible]$ ansible-navigator run lineinfile.yml -m stdout [student@workstation ansible]$ ansible servera -m shell -a 'cat /etc/selinux/config'
ansible.builtin.blockinfile 1 2 3 4 5 6 7 8 - name: Insert/Update HTML surrounded by custom markers after <body > line ansible.builtin.blockinfile: path: /opt/index.html marker: "" insertafter: "<body > " block: | <h1 > Welcome to {{ ansible_hostname }} </h1 > <p > Last updated on {{ ansible_date_time.iso8601 }} </p >
ansible.builtin.template 1 2 3 4 5 6 7 8 9 10 - name: Template a file to /etc/files.conf ansible.builtin.template: src: /mytemplates/foo.j2 dest: /etc/file.conf - name: Download foo.conf ansible.builtin.get_url: url: http://materials/hosts.j2 dest: /opt/host.txt
5.2 使用Jinja2模板部署自定义文件 jinja2简介 ansible中可以使用jinja2模板对文件进行部署。再用template模块同步jinja2模板文件至受管节点。该模块和copy模块作用基本一样,都是把某个文件复制到被管主机上,但是区别在于template模块可以获取变量的值和使用循环。 1.管理文件通常会使用一些模块,copy,file,blockinfile,lineinfile 2.更好的配置文件管理方式是使用jinja2语法制作模板文件来生成最终使用的配置文件
3.jinja2模板文件内,可以通过多种方式编辑或构成,比如魔法变量、事实变量、普通字符、控制语句语法… 4.使用jinja2模板的方法是,先构建jinja2模板,再通过template模块将j2模板同步至受管节点
5.构建模板文件通常名称自定义,以.j2结尾,类似shell脚本的.sh、python脚本的.Py
1 使用分隔符 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 1、构建jinja2模板 $ vim jin.j2 127.0.0.1 localhost localhost.localdomain localhost4 localhost4.localdomain4 ::1 localhost localhost.localdomain localhost6 localhost6.localdomain6 {# host file #} #描述,为管理员做提示作用。用户不可见 haha {{ ansible_hostname }} 2、通过templete模块,同步模板文件至受管主机,同时收集事实变量值,将结果生成至相应文件中。 $ vim temp.yml --- - name: sync file hosts: servera tasks: - name: Template a file to /etc/files.conf ansible.builtin.template: src: jin.j2 dest: /etc/myhosts $ ansible-navigator run temp.yml -m stdout 3、在受管节点上查看文件结果 $ ansible servera -m shell -a 'cat /etc/myhosts' servera | CHANGED | rc=0 >> haha servera heihei servera.lab.example.com
2 管理模版文件 1 2 3 4 5 6 7 8 9 10 11 12 1、在配置文件中定义ansible_managed功能,添加描述信息:“Ansible hahaha” [greg@control ansible]$ vim ansible.cfg [defaults] ansible_managed = Ansible hahaha 变量名 = 变量值 2、在jinja2模板中调用该功能 # vim jinja.j2 {# host file #} #{##}注释客户端生成文件是不显示 {{ ansible_managed }} #{{}}描述,客户端生成文件时会显示 127.0.0.1 localhost localhost.localdomain localhost4 localhost4.localdomain4 ::1 localhost localhost.localdomain localhost6 localhost6.localdomain6
控制结构-使用循环 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 -shell for user in `ls /`;do echo $user done -jinja2 {% for user in users %} {{ user }} {% endfor %} $ vim jinja2.j2 {% for host in groups.all %} {{ host }} {% endfor %} [student@workstation ansible]$ grep -r '{%' /etc
1文件的生成方法 1 2 3 4 5 6 7 8 $ vim debug.yml --- - name: hosts: all tasks: - ansible.builtin.debug: var: hostvars $ ansible-navigator run debug.yml -m stdout > 1.txt
生成/etc/hosts 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 1 $ vim /home/student/ansible/temp.yml 127.0.0.1 localhost localhost.localdomain localhost4 localhost4.localdomain4 ::1 localhost localhost.localdomain localhost6 localhost6.localdomain6 {% for host in groups.all %} {{ hostvars[host].ansible_default_ipv4.address }} {{ hostvars[host].ansible_nodename }} {{ hostvars[host].ansible_hostname }} {% endfor %} 2 vim /home/student/ansible/temp.yml --- - name: sync file hosts: all tasks: - name: Template a file to /etc/files.conf ansible.builtin.template: src: hosts.j2 dest: /etc/myhosts when: inventory_hostname in groups.dev $ ansible-navigator run temp.yml -m stdout $ ansible servera -m shell -a 'cat /etc/myhosts' servera | CHANGED | rc=0 >> 127.0.0.1 localhost localhost.localdomain localhost4 localhost4.localdomain4 ::1 localhost localhost.localdomain localhost6 localhost6.localdomain6 172.25.250.10 servera.lab.example.com servera 172.25.250.11 serverb.lab.example.com serverb 172.25.250.12 serverc.lab.example.com serverc 172.25.250.13 serverd.lab.example.com serverd 实验完毕 [Discovering variables: facts and magic variables — Ansible Documentation](https://docs.ansible.com/ansible/latest/playbook_guide/playbooks_vars_facts.html) 网站中查找关键字:facts 选择:Discovering variables: facts and magic variables 然后搜索hostvars[host] 以json格式查看: {{ hostvars[i]['ansible_facts' ] | to_nice_json }}
6 管理大项目 6.1 引用清单主机 1 2 3 4 5 6 7 8 使用主机模式的常见方式: 1.[ad-hoc:] ansible dev -m shell 2.[playbook:] - name: hosts: dev
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 1 清单里使用通配符匹配多个主机 [START:END] 192.168.[0:15].[0:255] 表示 192.168.0.0-192.168.15.255 server[a:c].example.com 表示 a-c server[01:15].example.com 表示 server01.example.com-server15 ipv6也可以通过[a:f]这种方式 all: 所有主机 ungrouped : 不属于任何一个组的所有主机 2 主机模式其他方式 hosts: all hosts: ungrouped hosts: '*' 和all相同 hosts:'*.example.com' hosts:'datacenter*' hosts:servera,serverb hosts:webserver,serverc hosts:'devops,server*' hosts:lab,&datacenter 匹配lab组同时也属于datacenter组,顺序无所谓&符号时同时也属于的意思 hosts:datacenter,!test2.example.com 表示datacenter组,但不包括test2.。。这个主机 hosts:all,!datacenter1 所有组,但不包含datacenter1组
6.2 包含和导入文件 管理大型Playbook 1 2 3 4 5 6 如果playbook很长很复杂,可以拆分成较小的文件便于管理,以模块化管理,可以将多个不同功能的play,组合成一个主要的playbook,将文件中的任务列表插入play,这样可以将这种模块化的play应用到不同场景。 playbook - httpd - php - mysql
1.导入Playbook 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 1.将两个playbook加入到主playbook $ vim one.yml --- - name: play1 hosts: node1 tasks: - name: Install the latest version of Apache ansible.builtin.yum: name: httpd state: latest $ vim two.yml --- - name: play2 hosts: node1 tasks: - name: Make sure a service unit is running ansible.builtin.systemd: state: started name: httpd enabled: yes 2.在主playbook中和其他play交替使用 $ vim main.yml --- - name: four hosts: node1 tasks: - ansible.builtin.debug: msg: haha - name: one 因为加载的是playbook所以需要顶头写无缩进。 import_playbook: one.yml - name: two import_playbook: two.yml
包含与导入 1 2 3 Ansible可以支持两种方法将文件放入playbook中: 包含:内容是一个动态操作。在playbook运行期间,Ansible会在内容到达时处理所包含的内容。 导入:内容是一个静态操作。在运行开始之前,Ansible在最初解析playbook时预处理导入的内容。
1.包含和导入 1 2 3 4 5 6 7 包含: 1.使用include_tasks功能时,包含时设置的when等条件语句将确定任务是否包含在play中 2.如果运行ansible-playbook --list-tasks以列出playbook中的任务,则不会显示已包含任务文件中的任务。将显示包含任务文件的任务。相比之下,import_tasks功能不会列出导入任务文件的任务,而列出已导入任务文件中的各个任务 3.不能使用ansible-playbook --start-at-task从已包含任务文件中的任务开始执行playbook 4.不能使用notify语句触发已包含任务文件中的处理程序名称。可以在包含整个任务文件的主playbook中触发处理程序,在这种情况下,已包含文件中的所有任务都将运行
1 2 3 4 导入: 1.使用import_tasks功能时,导入时设置的when等条件语句将应用于导入的每个任务 2.无法将循环用于import_tasks功能 3.如果使用变量来指定要导入的文件的名称,则将无法使用主机或组清单变量
2.示例 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 第一个tasks任务 [greg@bastion ansible]$ mkdir tasks [greg@bastion ansible]$ vim tasks/apache.yml --- - name: ansible.builtin.yum: name: httpd state: latest 第二个tasks任务 [greg@bastion ansible]$ vim tasks/service.yml --- - name: ansible.builtin.service: name: httpd enabled: yes state: started 包含和导入的方式: [greg@bastion ansible]$ vim main.yml --- - name: hosts: node1 tasks: - include_tasks: tasks/apache.yml - import_tasks: tasks/service.yml
7 使用角色和Ansible collections简化Playbook 7.1 描述角色结构
7.2 创建角色 1 2 3 4 5 6 7 在playbook的项目目录中创建一个角色,并将其作为playbook中某个play的一部分来运行 1.yum install -y httpd yum模块 2.index.html, fcontext copy模块 3.httpd service service模块 4.firewalld.service service模块 5.firewalld permit apache firewalld模块
角色创建流程 1 2 3 4 5 创建和使用角色分四步进行: 1.创建角色目录存储路径 2.创建角色 3.定义角色内容 4.在playbook中使用角色
1.创建角色目录存储路径 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 1.默认路径: [student@workstation ansible]$ ansible-galaxy --help positional arguments: TYPE collection Manage an Ansible Galaxy collection. role Manage an Ansible Galaxy role. [student@workstation ansible]$ ansible-galaxy role --help positional arguments: ROLE_ACTION init Initialize new role with the base structure of a role. remove Delete roles from roles_path. delete Removes the role from Galaxy. It does not remove or alter the actual GitHub repository. list Show the name and version of each role installed in the roles_path. search Search the Galaxy database by tags, platforms, author and multiple keywords. import Import a role into a galaxy server setup Manage the integration between Galaxy and the given source . info View more details about a specific role. install Install role(s) from file(s), URL(s) or Ansible Galaxy [student@workstation ansible]$ ansible-galaxy role list [student@workstation ansible]$ ansible-galaxy list [WARNING]: - the configured path /home/student/.ansible/roles does not exist. --默认该目录不存在,需要的话可以根据需求创建 `如果ansible无法找到该位置角色,会按照ansible.cfg中roles_path指定的目录中查找` 1.创建角色目录存储路径 使用自定义工作目录时,创建自定义roles(角色)目录,并使用ansible.cfg中roles_path=字段指定角色路径 [student@workstation ansible]$ pwd /home/student/ansible [student@control ansible]$ mkdir roles [student@control ansible]$ vim ansible.cfg roles_path=/home/student/ansible/roles [student@workstation ansible]$ ansible-galaxy list
2.创建角色 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 [student@workstation ansible]$ ansible-galaxy role init roles/apache - Role roles/apache was created successfully [student@workstation ansible]$ ansible-galaxy role list - apache, (unknown version) [student@workstation ansible]$ tree roles/apache/ roles/apache ├── defaults │ └── main.yml ├── files ├── handlers │ └── main.yml ├── meta │ └── main.yml ├── README.md ├── tasks │ └── main.yml ├── templates ├── tests │ ├── inventory │ └── test.yml └── vars └── main.yml 8 directories, 8 files
3.定义角色内容 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 [student@control ansible]$ tree roles/apache (可选,方便查看路径信息) *[student@control ansible]$ vim roles/apache/tasks/main.yml --- - name: install apache ansible.builtin.yum: name: httpd state: latest - name: Start service httpd ansible.builtin.service: name: httpd state: started enabled: yes - name: create web page ansible.builtin.template: src: jin2.j2 dest: /var/www/html/index.html notify: - restart - name: Start service firewalld ansible.builtin.service: name: firewalld state: started enabled: yes - name: permit apache ansible.posix.firewalld: service: http permanent: yes state: enabled immediate: yes - name: permit apache ansible.builtin.shell: firewall-cmd --permanent --add-service=http - name: permit apache ansible.builtin.shell: firewall-cmd --reload [student@control ansible]$ vim roles/apache/templates/jin2.j2 ipadd={{ ansible_default_ipv4.address }} hostname={{ ansible_hostname }} [student@control ansible]$ vim roles/apache/handlers/main.yml --- - name: restart ansible.builtin.service: name: httpd state: restarted
4.在playbook中使用角色 1 2 3 4 5 6 7 8 9 10 [student@bastion ansible]$ vim roles.yml --- - name: hosts: servera roles: - apache - xxx [student@bastion ansible]$ ansible-navigator run -m stdout roles.yml [student@control ansible]$ curl servera ipadd=172.25.250.10 hostname=servera
7.3 从外部内容源部署角色 从Git存储库或AnsibleGalaxy 等外部资源中选择和检索角色,并在playbook中使用
https://galaxy.ansible.com
1.外部内容来源 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 角色有多种获取方式: 本地tar包安装 通过网络地址安装 通过文件同时安装网络中多个地址角色(本课介绍) roles/requirements.yml - src: varsion:#角色版本 name:#安装在本地的角色名 - src: name: ansible-galaxy role install -r roles/requirements.yml -p roles -r 指定文件路径 -p 指定角色安装路径 roles/requirements.yml 角色安装信息,包括地址,角色名称等。
练习
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 1.将phpinfo.tar,haproxy.tar上传到Linux,kiosk家目录下,用kiosk登录 2.将两个角色包拷贝到foundation0的rhel9.0目录中 $ ssh root@localhost cp /home/kiosk/{phpinfo.tar,haproxy.tar} /content/courses/rh294/rhel9.0/materials 3.打开foundation0的浏览器输入http://172.25.254.254/materials/就可以看到两个软件包 实验: [student@workstation ansible]$ mkdir roles [student@workstation ansible]$ $ vim ansible.cfg [defaults] roles_path=/home/student/ansible/roles [student@workstation ansible]$ vim roles/requirements.yml --- - src: http://172.25.254.254/materials/haproxy.tar name: balancer - src: http://172.25.254.254/materials/phpinfo.tar name: phpinfo [student@workstation ansible]$ ansible-galaxy install -r roles/requirements.yml [student@workstation ansible]$ ansible-galaxy list - apache, (unknown version) - balancer, (unknown version) - phpinfo, (unknown version)
7.4 从内容集合获取角色和模块 从Ansible 内容集合中获取一组相关角色、补充模块和其他内容,并在playbook中使用
Ansible内容集合
1.Ansible内容集合的命名空间 1 2 3 4 5 6 7 8 9 10 11 community.crypto community.postgresql community.rabbitmq redhat.rhv redhat.satellite redhat.insights等名称
2.选择Ansible内容集合的来源 1 2 3 4 5 6 7 8 9 10 无论您是将ansible-navigator 用于最小自动化执行环境,还是在裸机Ansible Core上使用ansible-playbook,您始终至少有一个可用Ansible内容集合:ansible.builtin。 此外,您的自动化执行环境可能还内置了其他自动化执行环境,例如,红帽Ansible 自动化平台2.2使用的默认执行环境ee-supported-rhel8。 如果您需要其他Ansible内容集合,可以将其添加到Ansible 项目的collections 子目录中。您可以从多个来源获取Ansible内容集合: 自动化中心 私有自动化中心 Ansible Galaxy 第三方Git存储库或存档文件
3.安装Ansible内容集合 1 2 ansible配置文件ansible.cfg中设置了collections_paths选项来指定集合的默认路径: ~/.ansible/collections;/usr/share/ansible/collections 如果消除这两个目录的指定,则ansible-navigator 无法在这些目录的其版本中找到自动化执行环境内提供的Ansible内容集合。
1 2 3 4 5 6 7 8 $ ansible-galaxy collection install 集合 -p collections -p collections 选项会将该集合安装到本地collections 子目录中。或者不适用-p,而在ansible.cfg文件中collections_paths选项来指定集合的默认路径 集合的来源可以是: 本地 互联网 git仓库
4.使用要求文件安装Ansible内容集合 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 1.将三个集合包上传到Linux,kiosk家目录下,用kiosk登录 2.将三个集合包拷贝到foundation0的rhel9.0目录中 $ ssh root@localhost cp /home/kiosk/{community-general-5.5.0.tar.gz,redhat-insights-1.0.7.tar.gz,redhat-rhel_system_roles-1.19.3.tar.gz} /content/courses/rh294/rhel9.0/materials 3.打开foundation0的浏览器输入http://172.25.254.254/materials/就可以看到两个软件包 ------------------------- 【workstation】 1.创建存储集合的位置 $ mkdir /home/student/ansible/mycollections $ vim ansible.cfg [defaults] ... collections_path=/home/student/ansible/mycollection:~/.ansible/collections:/usr/share/ansible/collections 2.部署requirements.yml文件 $ vim /home/student/ansible/mycollections/requirements.yml --- collections: - name: http://172.25.254.254/materials/community-general-5.5.0.tar.gz - name: http://172.25.254.254/materials/redhat-insights-1.0.7.tar.gz - name: http://172.25.254.254/materials/redhat-rhel_system_roles-1.19.3.tar.gz 3.安装集合 $ ansible-galaxy collection install -r requirements.yml -p /home/student/ansible/collections/mycollections $ ansible-galaxy collection list
7.5 利用系统角色重用内容 编写利用红帽帽企业Linux的系统角色执行标准操作的 playbook
系统角色
1.内容集合方式安装系统角色 1 2 3 4 5 6 7 8 9 10 11 12 13 1.内容集合 redhat.rhel_system_roles $ mkdir /home/student/ansible/collections $ vim /home/student/ansible/collections/requirements.yml --- collections name: redhat.rhel system roles $ ansible-galaxy collection install -p collections/ -r home/student/ansible/collections/requirements.yml 此处可以通过文件安装,也可通过直接指定本地tar包安装,可以参考教材练习
1 2 3 $ sudo find ./mycollection/ -name selinux-playbook.yml $ find mycollection/ -name '*.yml' | grep selinux $ cp /usr/share/ansible/collections/ansible_collections/redhat/rhel_system_roles/docs/selinux/selinux-playbook.yml /home/student/ansible/selinux.yml
2.rpm包方式安装系统角色 1 2 3 4 5 6 系统角色使用流程 1.通过软件安装获得系统角色(rhel-system-roles.noarch) 2.定义系统角色路径(存放角色的位置),并将其记录配置文件 cd /;ansible-galaxy list , vim ~/ansible/ansible.cfg/;roles_path=xxxx:xxxx3.使用系统角色,将系统角色添加至playbook,并修改内容 4.应用
1 2 3 4 5 6 7 8 9 10 11 12 1.安装 系统帮助我们定义了一些角色,有不同的功能,需要通过安装软件包。 [greg@control ansible]$ cd / [greg@control /]$ sudo yum search roles [greg@control /]$ sudo yum install -y rhel-system-roles.noarch [greg@control /]$ ansible-galaxy list - linux-system-roles.kdump, (unknown version) .... - rhel-system-roles.timesync, (unknown version) [WARNING]: - the configured path /home/greg/.ansible/roles does not exist.
1 2 3 4 5 6 7 8 9 10 11 2.定义角色路径 [greg@control /]$ cd ~/ansible/ [greg@control ansible]$ vim ansible.cfg roles_path = /home/greg/ansible/roles:/usr/share/ansible/roles [greg@control ansible]$ ansible-galaxy list - apache, (unknown version) - linux-system-roles.kdump, (unknown version) ...... - rhel-system-roles.timesync, (unknown version)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 3.使用系统角色,将系统角色添加至playbook并应用 [greg@control ansible]$ rpm -ql rhel-system-roles.noarch | grep timesync [greg@control ansible]$ cp /usr/share/doc/rhel-system-roles/timesync/example-timesync-playbook.yml /home/greg/ansible/timesync.yml [greg@control ansible]$ vim timesync.yml --- - hosts: all vars: timesync_ntp_servers: - hostname: 172.25.254.254 iburst: yes roles: - rhel-system-roles.timesync 4 使用系统角色 [greg@control ansible]$ ansible-playbook timesync.yml 查询验证 ansible all -a 'chronyc sources -v'
通过内容集合安装使用系统角色 1.timesync 1 2 3 4 5 6 7 8 9 10 11 $ cp /usr/share/ansible/collections/ansible_collections/redhat/rhel_system_roles/docs/timesync/multiple-ntp-servers.yml timesync.yml $ vim timesync.yml - hosts: all vars: timesync_ntp_servers: - hostname: 172.25.254.254 iburst: yes roles: - redhat.rhel_system_roles.timesync $ ansible-navigator run timesync.yml -m stdout $ ansible all -m shell -a 'chronyc sources -v '
2.selinux 1 2 3 4 5 6 7 8 9 10 11 12 13 $ cp /usr/share/ansible/collections/ansible_collections/redhat/rhel_system_roles/docs/selinux/selinux-playbook.yml selinux.yml $ vim selinux.yml --- - hosts: all vars: selinux_policy: targeted selinux_state: permissive roles: - redhat.rhel_system_roles.selinux $ ansible-navigator run selinux.yml -m stdout $ ansible all -m shell -a 'grep ^SELINUX= /etc/selinux/config'
7.6 通过文件安装角色 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 Ansible官网:https://docs.ansible.com/ansible/2.9/galaxy/user_guide.html#installing-roles-from-galaxy https://galaxy.ansible.com/nginxinc/nginx_core [greg@control ansible]$ vim roles/requirements.yml --- - src: http://materials/phpinfo.tar name: phpinfo - src: http://materials/haproxy.tar name: balancer [greg@control ansible]$ ansible-galaxy install --help [greg@control ansible]$ ansible-galaxy install -r roles/requirements.yml [greg@control ansible]$ ansible-galaxy list - phpinfo, (unknown version) - balancer, (unknown version)
8 对Ansible进行故障排除 8.1 对playbook进行故障排除 调试Playbook 1 2 3 4 5 -rhel8 ansible-playbook debug.yml -v -rhel9 ansible-navigator run playbook.yml -m stdout -v
Debug 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 --- - hosts: serverb tasks: - name: install the latest version of Apache ansible.builtin.yum: name: vsftpd state: latest register: web_install - ansible.builtin.debug: var: web_install [greg@control ansible]$ vim debug.yml --- - name: test hosts: node1 tasks: - ansible.builtin.debug: var: hostvars [greg@control ansible]$ ansible-navigator run -m stdout debug.yml > 2.txt 关闭事实收集 如果要关闭收集,可以编辑配置文件 gathering = explicit 或者在playbook里 gather_facts: yes /no true /false
检查 Playbook 中的错误 1 2 3 4 5 6 7 8 -RHEL8 $ ansible-playbook playbook.yml --syntax-check playbook: playbook.yml -RHEL9 greg@control ansible]$ ansible-navigator run -m stdout debug.yml --syntax-check playbook: /home/greg/ansible/debug.yml
检查 Playbook的问题并遵循良好实践 1 2 3 4 5 6 name: 冒号后面要空格,内容随意 hosts: all 指定的主机不在清单中,报错无partten syntax-errors:注意格式缩进,2格缩进 变量设置错误,或调用时错误(变量名写错,变量开头要加双引号) when条件: (逻辑判断思路错误,或书写错误)
检查Playbook 工件和日志文件 1 2 ansible-navigator 可以生成 playbook工件,以JSON格式存储与 playbook的运行相关的信息。 您可以将与 playbook运行相关的信息记录到系统上您可写入位置处的文本文件中。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 RHEL9中的ansible自动开启日志功能,可通过配置文件设置及手工设置 $ vim ~/.ansible-navigator.yml --- ansible-navigator: execution-environment: image: utility.lab.example.com/ee-supported-rhel8:latest pull: policy: missing playbook-artifact: enable : false --pae --playbook-artifact-enable
将输出记录到文本文件 1 2 3 4 -RHEL8&9 Ansible 提供了一个内置日志基础架构,可通过ansible.cfg 配置文件 [defaults] 部分中的log_path参数进行配置,或通过$ANSIBLE_LOG_PATH 环境变量进行配置。在进行上面一项或两项配置后,Ansible会以文本形式将ansible-navigator 命令的输出存储到所配置的日志文件中。此机制也适用于ansible-playbook 等早期的工具。 如果您将Ansible配置为将日志文件写入 /var/log,红帽建议您配置 logrotate来管理文件。
8.2 对Ansible受管主机进行故障排除 对连接进行故障排除 1 2 3 1 远程用户(普通,root)2 远程密码、特权密码问题3 账号密码有多种设置方案
使用Ansible运行临时命令 1 2 3 4 5 6 7 8 9 ad-hoc命令可以用于简单部署场景,比如对一组目标部署一个任务,或检索受管节点的运行情况、状态等。 ansible all -m ping 解决方法,服务器端: $ vim /etc/ssh/sshd_config PermitRootLogin yes $ systemctl reload sshd
–step 手动控制执行的步骤 1 2 3 4 5 6 7 8 9 10 11 12 $ ansible-playbook playbook.yml --step $ ansible-navigator run playbook.yml -m stdout --step PLAY [PLAY1] ******************************************************************************************** Perform task: TASK: Gathering Facts (N)o/(y)es/(c)ontinue: n 手动输入n y c来控制playbook中执行的步骤 n 不执行该步骤 y 执行该步骤 c 继续自动执行到结束 通过该方法,我们可以让有问题的步骤执行,而无关紧要的步骤可以跳过不执行。达到排错的目的。
–start-at-task 从指定步骤执行任务 1 2 3 4 [greg@control ansible]$ ansible-playbook playbook.yml --start-at-task='Start service httpd' 选项“ --start-at-task
-C –check 烟雾测试 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 烟雾测试:在管理节点执行剧本,显示剧本的真实执行结果,但是不在受管节点上部署。 $ ansible-playbook playbook.yml --help | grep \\-C $ ansible-navigator run playbook.yml -m stdout -C [greg@control ansible]$ vim playbook.yml --- - name: PLAY1 hosts: node2 tasks: - name: install apache ansible.builtin.yum: name: httpd state: latest - name: Copy using inline content ansible.builtin.copy: content: 'test web page' dest: /var/www/html/index.html - name: Start service httpd ansible.builtin.service: name: httpd state: started - name: Start service firewalld ansible.builtin.service: name: firewalld state: started - name: permit apache ansible.posix.firewalld: service: http permanent: yes state: enabled immediate: yes [greg@control ansible]$ ansible-playbook playbook.yml -C
通过发送脚本解决问题 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 $ vim test.sh date $ vim debug.yml --- - name: hosts: node1 tasks: - name: Run a script ansible.builtin.script: /home/greg/ansible/test.sh register: haha - ansible.builtin.debug: var: haha $ ansible-playbook debug.yml `如果不想写register,可以执行剧本时添加-v 类似:ansible-playbook debug.yml -v`
9 自动执行Linux管理任务 9.1 管理软件和订阅 优化多软件包安装 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 ansible.builtin.--- - name: hosts: all tasks: - name: install the latest version of Apache ansible.builtin.yum: name: httpd state: latest - name: install the latest version of Apache ansible.builtin.yum: name: php state: latest --------------------------------------------- - name: install the latest version of Apache ansible.builtin.yum: name: "{{ item }}" state: latest loop: - httpd - php yum install -y httpd yum install -y php --------------------------------------------- - name: install the latest version of Apache ansible.builtin.yum: name: - httpd - php state: latest yum install -y httpd php --------------------------------------------- - name: ensure a list of packages installed ansible.builtin.yum: name: "{{ packages }}" vars: packages: - httpd - httpd-tools --------------------------------------------- 等同于:yum install -y httpd php 或 loop的这种方式,系统会执行两次独立事务,对每个事务应用一个软件包 yum模块: state: absent删除, installed, present确保安装 latest升级到最新版本 latest 等同 yum update yum remove yum install name: '*' 代表所有软件包 name: "@RPM Development tools" ansible命令里面安装包组要加@
收集有关已安装软件包的事实 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 --- - name: hosts: node1 tasks: - name: Gather the package facts ansible.builtin.package_facts: manager: auto - name: Check whether a package called foobar is installed ansible.builtin.debug: msg: "{{ ansible_facts.packages.zip.0.version }}"
查看用于管理软件包的其他模块 1 2 3 4 5 6 7 8 9 - name: Install httpd on RHEL 8 and 9 ansible.builtin.dnf name: httpd state: present - name: Install httpd on RHEL 7 and earlier ansible.builtin.yum: name:httpd state:present
配置RPM软件包存储库 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 $ ansible-doc -l | grep yum --- - name: hosts: node1 tasks: - name: Add multiple repositories into the same file (1/2) ansible.builtin.yum_repository: name: EX294_BASE description: EX294 base software file: rhel baseurl: http://content/rhel8.4/x86_64/dvd/BaseOS gpgcheck: yes gpgkey: http://content/rhel8.4/x86_64/dvd/RPM-GPG-KEY-redhat-release enabled: yes - name: Add multiple repositories into the same file (1/2) ansible.builtin.yum_repository: name: EX294_STREAM description: EX294 stream software file: rhel baseurl: http://content/rhel8.4/x86_64/dvd/AppStream gpgcheck: yes gpgkey: http://content/rhel8.4/x86_64/dvd/RPM-GPG-KEY-redhat-release enabled: yes ansible模块选项和vim配置文件内容对比 vim: ansible: rhel.repo file [rhel] * name name=rhel * description baseurl= * baseurl gpgcheck= * gpgcheck gpgeky= * gpgkey enabled= * enabled 测试方法: $ ansible all -a 'yum repolist all' $ cat rhel.repo
1 2 3 4 $ ansible-doc rpm_key - ansible.builtin.rpm_key: state: present key: http://apt.sw.be/RPM-GPG-KEY.dag.txt
9.2 管理用户和身份验证 user 模块 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 需求:在servera上创建用户tom 附加组为group1,并设置密码为password tom: tom123用sha512方式哈希,uid =2000 user这个模块类似这些功能: useradd userdel usermod $ cat group.yml - name: hosts: node1 vars: - passwordtom: tom123 tasks: - name: create group ansible.builtin.group: name: "{{ item }}" loop: - group1 - group2 - name: Add the ansible.builtin.user: name: tom comment: student uid: 2000 password_expire_max: 10 group: group1 groups : group1,group2 shell: /bin/bash password: "{{ passwordtom | password_hash('sha512') }}" passwd tom chage -l tom Password expires : Jun 11, 2024 ssh tom@node1 Ansible网页搜索:password_hash--Using filter--网页中查找password_hash,查看密码哈希方式,一定注意是512 Ansible官网: https://docs.ansible.com/ansible/latest/user_guide/playbooks_filters.html 模块中:append: yes 如果想额外添加附加群组,此选项需要yes (usermod -a -G grouptest u1)
group模块 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 [greg@bastion ansible]$ cat group.yml --- - name: hosts: dev tasks: - name: Ensure group "grouptest" exists ansible.builtin.group: gid: 10000 name: grouptest state: present | absent 等同于:groupadd grouptest 等同于:groupadd -g 10000 grouptest groupdel
9.3 管理启动过程和调度进程 at 1 2 3 4 5 6 7 8 9 10 11 --- - name: hosts: dev tasks: - name: Schedule a command to execute in 20 minutes as root ansible.posix.at: command: ls -d / >/dev/null count: 20 units: minutes 默认是创建一个任务,给root,删除的 话使用选项state:absent
cron 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 [greg@bastion ansible]$ ansible-doc cron [greg@bastion ansible]$ cat cron.yml --- - name: hosts: all tasks: - name: Ensure a job that runs at 2 and 5 exists. ansible.builtin.cron: name: "check dirs" minute: "*/2" hour: "2,5" day: 1-10 user: harry job: "ls -alh > /dev/null" [greg@bastion ansible]$ ansible dev -m shell -a 'crontab -u harry -l' 指令: conrtab -u harry -e 1、每年2月2日上午9点执行echo hello任务 0 9 2 2 echo hello 2、七月每周5的,9点至下午5点,每5分钟执行echo hi */5 9-17 * 7 5
管理服务 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 --- - name: hosts: dev tasks: - name: install the latest version of Apache ansible.builtin.yum: name: httpd state: latest - name: Start service httpd, if not started ansible.builtin.service: name: httpd state: started enabled: yes ~ service restart network
systemd 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 [greg@bastion ansible ]$ cat systemd.yml --- - name: hosts: dev tasks: - name: install the latest version of Apache ansible.builtin.yum: name: httpd state: latest - name: Make sure a service is running ansible.builtin.systemd: name: httpd state: started enabled: yes 测试命令: ansible dev -m shell -a 'systemctl status httpd' ansible dev -m shell -a 'systemctl is-enabled httpd'
1.reboot 1 2 3 - name: Unconditionally reboot the machine with all defaults reboot:
2.command & shell 支持更多的特殊字符 1 2 3 4 $ ansible servera -m command -a 'useradd user1' $ ansible servera -a 'useradd user2' $ ansible servera -a 'echo 123456 | passwd --stdin user1' $ ansible servera -m shell -a 'echo 123456 | passwd --stdin user1'
9.4 管理存储
模块名
linux指令
Linux实施命令
community.general.parted
parted
parted /dev/vdb mkpart part1 2048s 1G
community.general.lvg
vgcreate
vgcreate -s 16M vg100 /dev/vdb{1..2}
community.general.lvol
lvcreate
lvcreate -L 100M -n lv100 vg100
community.general.filesystem
mkfs
mkfs.ext4 /dev/vg100/lv100
ansible.posix.mount
/etc/fstab
echo “/dev/vg100/lv100 ext4 /mnt/data defaults 0 0” > /etc/fstab
通过模块管理存储 1.纯分区无lvm逻辑卷
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 1-1 分区 community.general.parted --- - name: parted hosts: node2 tasks: - name: part 1 2048s-500M community.general.parted: device: /dev/vdc number: 1 state: present part_end: 500MiB - name: part 2 500M-1000M community.general.parted: device: /dev/vdc number: 2 state: present part_start: 500MiB part_end: 1GiB 1-2 格式化 community.general.filesystem - name: Create a ext4 community.general.filesystem: fstype: ext4 dev: "{{ item }}" loop: - /dev/vdc1 - /dev/vdc2 1-3 挂载 ansible.posix.mount - name: Mount DVD read-only ansible.posix.mount: path: /mnt/part1 src: /dev/vdc1 fstype: ext4 state: mounted -挂载选项解释:
2.有lvm逻辑卷实验 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 2.分区-lvm(pv,vg,lv)-格式化-挂载 2-1 分区 community.general.parted --- - name: lv hosts: node2 tasks: - name: part 1 2048s-500M community.general.parted: device: /dev/vdb number: 1 state: present part_end: 500MiB - name: part 2 500M-1000M community.general.parted: device: /dev/vdb number: 2 state: present part_start: 500MiB 2-2 pv+vg community.general.vg - name: Create a volume group vg100 community.general.lvg: vg: vg100 pvs: /dev/vdb1,/dev/vdb2 pesize: 32 2-3 lv community.general.lvol - name: Create a logical volume lv100 size 800M community.general.lvol: vg: vg100 lv: lv100 size: 800 2-4 格式化 community.general.filesystem - name: Create a xfs community.general.filesystem: fstype: xfs dev: /dev/vg100/lv100 2-5 挂载 ansible.posix.mount - name: /mnt/data ansible.posix.mount: path: /mnt/data src: /dev/vg100/lv100 fstype: xfs state: mounted --- - name: lv hosts: node2 tasks: - name: part 1 2048s-500M community.general.parted: device: /dev/vdb number: 1 state: present part_end: 500MiB - name: part 2 500M-1000M community.general.parted: device: /dev/vdb number: 2 state: present part_start: 500MiB - name: Create a volume group vg100 community.general.lvg: vg: vg100 pvs: /dev/vdb1,/dev/vdb2 pesize: 32 - name: Create a logical volume lv100 size 800M community.general.lvol: vg: vg100 lv: lv100 size: 800 - name: Create a xfs community.general.filesystem: fstype: xfs dev: /dev/vg100/lv100 - name: /mnt/data ansible.posix.mount: path: /mnt/data src: /dev/vg100/lv100 fstype: xfs state: mounted nsible-navigator --help ansible-navigator collections -m stdout | grep parted$ ansible-navigator collections -m stdout | grep lvg$ ansible-navigator collections -m stdout | grep lvol$ ansible-navigator collections -m stdout | grep filesystem$ ansible-navigator collections -m stdout | grep mount$ ansible all -m shell -a 'lsblk' ansible-navigator doc -m stdout community.general.parted ansible-navigator doc -m stdout community.general.filesystem ansible-navigator doc -m stdout ansible.posix.mount ansible-navigator doc -m stdout community.general.lvg
通过系统角色管理存储 1.磁盘管理角色
2.逻辑卷角色 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 [greg@control ansible]$ sudo find ./mycollection/ -name '*.yml' | grep storage|grep test.yml ./mycollection/ansible_collections/redhat/rhel_system_roles/tests/storage/test.yml [greg@control ansible]$ cp ./mycollection/ansible_collections/redhat/rhel_system_roles/tests/storage/test.yml ./storage.yml [greg@control ansible]$ vim disk.yml $ vim storage.yml --- - hosts: node4 vars: storage_use_partitions: true roles: - name: redhat.rhel_system_roles.storage storage_pools: - name: vg100 disks: - /dev/vdb volumes: - name: lv100 size: 200M fs_type: ext4 mount_point: '/mnt/lvm100' state: "present" - name: lv200 size: 300M fs_type: xfs mount_point: '/mnt/lvm200' state: "absent" $ ansible-navigator run storage.yml -m stdout
9.5 管理网络 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 [greg@control ansible]$ sudo find ./mycollection/ -name '*.md' | grep network [greg@control ansible]$ vim ./mycollection/ansible_collections/redhat/rhel_system_roles/roles/network/README.md [greg@control ansible]$ sudo find ./mycollection/ -name '*.yml' | grep network $ vim /usr/share/doc/rhel-system-roles/collection/roles/network/README.md $ vim playbook.yml --- - hosts: node5 vars: network_connections: - name: eth0 interface_name: eth0 type : ethernet state: up autoconnect: yes ip: address: - 192.0.2.3/24 dns: - 192.0.2.2 dns_search: - example.com dhcp4: no gateway4: 192.0.2.1 auto6: no roles: - redhat.rhel_system_roles.network $ ansible-navigator run playbook.yml -m stdout
附加: 使用普通用户远程管理受管主机 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 【超级用户远程管理方式】 vim /home/greg/ansible/ansible.cfg remote_user=root host_key_checking = False vim /home/greg/ansible/inventory [all:vars] ansible_password=redhat 【普通用户远程管理方式】 需求,请使用greg用户远程管理受管主机 【bastion】控制节点 ansible.cfg [defaults] remote_user = greg host_key_checking = False [privilege_escalation] become=True become_method=sudo become_user=root become_ask_pass=false ----------------------------------------以下配置考试环境下已做 管理节点 ssh-keygen 三个回车 ssh-copy-id greg@workstation ssh greg@workstation 其他受管主机上每一个主机都做如下操作 [root@workstation ~]# useradd greg [root@workstation ~]# echo redhat | passwd --stdin greg [root@workstation ~]# visudo greg ALL=(ALL) NOPASSWD: ALL