Linux入门DAY27
管理项目
配置并行
playbook执行顺序
-
按playbook定义顺序执行任务
-
每个play中所有主机分批次执行第一个任务,直到所有批次主机执行完该任务。
-
然后play中所有主机分批次再执行下一个任务,直到所有批次主机执行完所有任务
配置forks
forks参数控制ansible进行的最大同时连接数 默认值为5
bash
[phoenix@controller ~ 10:46:43]$ ansible-config dump|grep FORKS
DEFAULT_FORKS(default) = 5
验证
bash
#vim test.yml
---
- name: connection
hosts: all
tasks:
- name: conneciton 1
shell: sleep 5
- name: conneciton 2
debug:
msg: connection 2
#test
[phoenix@controller ~ 10:51:54]$ ansible-playbook test.yml -f 2
#2个主机为一组 执行任务
配置serial
在集群化部署过程中,playbook中有可能因为意外行为导致任务执行失败,会影响后续任务执行,导致playbook中断
避免此问题的一种方法是使用serial关键字,先让一批主机执行完play中所有任务,再让下一批主机执行完play中所有任务。以此类推,直到所有主机分批次执行play完成
bash
[phoenix@controller ~ 10:19:21]$ vim serial.yml
---
- name: Rolling update
hosts: all
serial: 2
tasks:
- name: latest apache httpd package is installed
yum:
name: httpd
state: latest
notify: restart apache
handlers:
- name: restart apache
service:
name: httpd
state: restarted
[phoenix@controller ~ 10:21:59]$ ansible-playbook serial.yml
PLAY [Rolling update] ****************************************************************************
TASK [Gathering Facts] ***************************************************************************
ok: [node1]
ok: [node2]
TASK [latest apache httpd package is installed] **************************************************
ok: [node1]
changed: [node2]
RUNNING HANDLER [restart apache] *****************************************************************
changed: [node2]
PLAY [Rolling update] ****************************************************************************
TASK [Gathering Facts] ***************************************************************************
ok: [node3]
ok: [node4]
TASK [latest apache httpd package is installed] **************************************************
changed: [node3]
changed: [node4]
RUNNING HANDLER [restart apache] *****************************************************************
changed: [node3]
changed: [node4]
PLAY RECAP ***************************************************************************************
node1 : ok=2 changed=0 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
node2 : ok=3 changed=2 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
node3 : ok=3 changed=2 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
node4 : ok=3 changed=2 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
wait_for模块
与async_status区别在于wait_for没有返回值
使用 wait_for 模块检查之前的任务是否达到预期状态
bash
#测试文件是否存在
---
- name: test wait for
hosts: node1
tasks:
- shell: sleep 10 && touch /tmp/hello
# async时间要大于sleep的时间
async: 20
poll: 0
register: out
- name: wait for create /tmp/hello
wait_for:
path: /tmp/hello
state: present
delay: 5
timeout: 30
sleep: 2
#- delay,设置检测前延迟时间
#- timeout,设置检测超时时间
#- sleep,设置检测时间间隔
#测试主机端口是否打开
---
- name: test wait_for
hosts: node1,node2
tasks:
- name: reboot node1
shell: shutdown -r now "Ansible updates triggered"
async: 1
poll: 0
when: inventory_hostname == "node1"
- name: wait for node1 come back
wait_for:
host: node1
port: 22
state: started
delay: 10
sleep: 2
timeout: 300
when: inventory_hostname == "node2"
配置async
async异步并行 必须等当前任务执行完成,才能执行下一个任务
Ansible使用async触发异步并行运作任务:
- async:async的值是ansible等待运行这个任务的最大超时值(如果执行超时任务会强制中断导致失败)
- poll:ansible检查这个任务是否完成的时间间隔。ansible poll_interval 默认值是 15
bash
[phoenix@controller ~ 09:49:19]$ vim async-test.yml
---
- name: connection
hosts: node1
tasks:
- name: download
get_url:
url: http://192.168.48.100/ISOS/openEuler-24.03-LTS-x86_64-dvd.iso
dest: /home/laoma
async: 100
poll: 0
[phoenix@controller ~ 09:50:39]$ ansible-playbook async-test.yml
PLAY [connection] ********************************************************************************
TASK [Gathering Facts] ***************************************************************************
ok: [node1]
TASK [download] **********************************************************************************
changed: [node1]
PLAY RECAP ***************************************************************************************
node1 : ok=2 changed=1 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
配置async_status
配合async可以看到输出结果,检查任务是否完成
bash
[phoenix@controller ~ 09:50:46]$ vim asyncstatus.yml
---
- name: test async_status
hosts: node1
tasks:
- shell: sleep 10
async: 20
poll: 0
register: out
- name: wait for
async_status:
# 通过任务的 ansible_job_id 属性跟踪任务
jid: "{{ out.ansible_job_id }}"
register: job_result
# 根据当前任务执行结果的finished值,判断跟踪任务是否执行完成
until: job_result.finished
retries: 30
delay: 2
[phoenix@controller ~ 10:12:57]$ ansible-playbook asyncstatus.yml
PLAY [test async_status] *************************************************************************
TASK [Gathering Facts] ***************************************************************************
ok: [node1]
TASK [shell] *************************************************************************************
changed: [node1]
TASK [wait for] **********************************************************************************
FAILED - RETRYING: wait for (30 retries left).
FAILED - RETRYING: wait for (29 retries left).
FAILED - RETRYING: wait for (28 retries left).
FAILED - RETRYING: wait for (27 retries left).
FAILED - RETRYING: wait for (26 retries left).
changed: [node1]
PLAY RECAP ***************************************************************************************
node1 : ok=3 changed=2 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
lncluding和importing文件
当有相当数量的playbook的时候,可以引入二级目录的概念
模块化方式管理,更轻松在项目中重用playbook和tasks
重用有两种方式
- include关键字 动态引用
- import 关键字 静态引用
playbook级别
- 导入的playbook,只能在play级别使用
- 优先级按照导入顺序执行任务
maindeploy.yml
yaml
---
- name: prepare the web server
import_playbook: pre_web.yml
- name: prepare the vsftpd server
import_playbook: pre_vsftpd.yml
- name: prepare the databse server
import_playbook: pre_db.yml
pre_web.yml
bash
- name: Play web
hosts: node1
tasks:
- name: install httpd
yum:
name: httpd
state: present
pre_vsftpd.yml
bash
- name: Play vsftpd
hosts: node1
tasks:
- name: install vsftpd
yum:
name: vsftpd
state: present
pre_db.yml
bash
- name: Play db
hosts: node1
tasks:
- name: install mariadb-server
yum:
name: mariadb-server
state: present
执行
bash
[phoenix@controller ~ 10:41:19]$ vim maindeploy.yml
[phoenix@controller ~ 10:41:43]$ ansible-playbook maindeploy.yml
PLAY [Play web] **********************************************************************************
TASK [Gathering Facts] ***************************************************************************
ok: [node1]
TASK [install httpd] *****************************************************************************
ok: [node1]
PLAY [Play vsftpd] *******************************************************************************
TASK [Gathering Facts] ***************************************************************************
ok: [node1]
TASK [install vsftpd] ****************************************************************************
changed: [node1]
PLAY [Play db] ***********************************************************************************
TASK [Gathering Facts] ***************************************************************************
ok: [node1]
TASK [install mariadb-server] ********************************************************************
ok: [node1]
PLAY RECAP ***************************************************************************************
node1 : ok=6 changed=1 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
Ansible角色管理
ansible中提供了roles角色方法,它是一种模块化的方法,能够实现角色复用,高效管理。
Ansible角色
目录默认拓扑
bash
[phoenix@controller ~ 11:32:36]$ ansible-galaxy init user
- Role user was created successfully
[phoenix@controller ~ 11:33:02]$ tree user
user
├── 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
#defaults和vars存放变量
#meta 角色使用帮助
#tasks playbook主文件
#templates 引用的JINJA2模板
Ansible 角色目录位置
默认role使用以下三个目录:
- ~/.ansible/roles
- /usr/share/ansible/roles
- /etc/ansible/roles
优先级从上到下依次降低
可以在ansible.cfg配置文件[defaults]块中通过变量roles_path定义role位置
bash
[defaults]
roles_path = ./roles
......
创建角色
bash
[phoenix@controller ~ 14:29:31]$ ansible-galaxy init apache
- Role apache was created successfully
[phoenix@controller ~ 14:29:35]$ mv apache/ roles
目录拓扑
bash
roles
├── apache
│ ├── defaults
│ │ └── main.yml
│ ├── files
│ ├── handlers
│ │ └── main.yml
│ ├── meta
│ │ └── main.yml
│ ├── README.md
│ ├── tasks
│ │ └── main.yml
│ ├── templates
│ │ ├── index.html.j2
│ │ ├── motd.j2
│ │ └── phoenix.conf.j2
│ ├── tests
│ │ ├── inventory
│ │ └── test.yml
│ └── vars
│ └── main.yml
tasks/main.yml
yaml
---
# tasks file for apache
- name: install web
yum:
name: "{{ web_package }}"
state: latest
- name: "start {{ web_service }}"
service:
name: "{{ web_service }}"
state: started
enabled: yes
- name: prepare motd
template:
src: motd.j2
dest: /etc/motd
- name: prepare laoma site
template:
src: laoma.conf.j2
dest: /etc/httpd/conf.d/laoma.conf
notify:
- restart_web
- name: prepare DocumentRoot
file:
path: "/var/www/html/{{ ansible_hostname }}"
state: directory
- name: prepare index.html
template:
src: index.html.j2
dest: "/var/www/html/{{ ansible_hostname }}/index.html"
defaults/main.yml
yaml
---
# defaults file for apache
web_package: httpd
web_service: httpd
templates/motd.j2
yaml
hello guys!
Welcome to {{ ansible_fqdn }}!
templates/phoenix.conf.j2
bash
<VirtualHost *:80>
ServerAdmin laoma@{{ ansible_fqdn }}
ServerName {{ ansible_fqdn }}
ErrorLog logs/{{ ansible_hostname }}-error.log
CustomLog logs/{{ ansible_hostname }}-common.log common
DocumentRoot /var/www/html/{{ ansible_hostname }}/
<Directory /var/www/html/{{ ansible_hostname }}/>
Options +Indexes +FollowSymlinks +Includes
Order allow,deny
Allow from all
</Directory>
</VirtualHost>
handlers/main.yml
yaml
---
# handlers file for apache
- name: restart_web
service:
name: "{{ web_service }}"
state: restarted
templates/index.html.j2
yaml
Welcome to {{ ansible_fqdn }} !
meta/main.yml
yaml
galaxy_info:
author: phoenix
description: phoenix web
company: phoenix cloud
# If the issue tracker for your role is not on github, uncomment the
# next line and provide a value
# issue_tracker_url: http://example.com/issue/tracker
# Choose a valid license ID from https://spdx.org - some suggested licenses:
# - BSD-3-Clause (default)
# - MIT
# - GPL-2.0-or-later
# - GPL-3.0-only
# - Apache-2.0
# - CC-BY-4.0
license: license (GPL-2.0-or-later, MIT, etc)
min_ansible_version: 2.9
# If this a Container Enabled role, provide the minimum Ansible Container version.
# min_ansible_container_version:
#
# Provide a list of supported platforms, and for each platform a list of versions.
# If you don't wish to enumerate all versions for a particular platform, use 'all'.
# To view available platforms and versions (or releases), visit:
# https://galaxy.ansible.com/api/v1/platforms/
#
platforms:
- name: Fedora
versions:
- all
- 25
- name: SomePlatform
versions:
- all
- 1.0
- 7
- 99.99
galaxy_tags: [apache,web]
# List tags for your role here, one per line. A tag is a keyword that describes
# and categorizes the role. Users find roles by searching for tags. Be sure to
# remove the '[]' above, if you add tags to this list.
#
# NOTE: A tag is limited to a single word comprised of alphanumeric characters.
# Maximum 20 tags per role.
dependencies: []
# List your role dependencies here, one per line. Be sure to remove the '[]' above,
# if you add dependencies to this list.
调用角色
在playbook中直接使用roles
bash
---
- hosts: all
roles:
- rolename
角色依赖
dependencies允许在运行当前 Role 之前自动加载其他 Roles
基本用法
yaml
dependencies:
- role: common # 直接指定 Role 名称
vars: # 可传递变量
some_var: "value"
- role: nginx
when: ansible_os_family == 'Debian' # 条件依赖
使用系统角色
ntp sync tasks
- 安装rhel-system-roles工具包
- 使用系统角色
- 测试对时服务器
bash
[phoenix@controller lnmp-allinone 13:38:01]$ sudo yum install rhel-system-roles
[phoenix@controller ~ 13:48:11]$ vim timesync.yml
---
- name: timesync
hosts: nodes
vars:
timesync_ntp_servers:
- hostname: ntp.aliyun.com
iburst: true
roles:
- rhel-system-roles.timesync
[phoenix@controller ~ 13:49:15]$ ansible-playbook timesync.yml
PLAY RECAP ****************************************************************************************************
node1 : ok=17 changed=4 unreachable=0 failed=0 skipped=23 rescued=0 ignored=0
node2 : ok=17 changed=4 unreachable=0 failed=0 skipped=23 rescued=0 ignored=0
node3 : ok=17 changed=4 unreachable=0 failed=0 skipped=23 rescued=0 ignored=0
node4 : ok=17 changed=4 unreachable=0 failed=0 skipped=23 rescued=0 ignored=0
haproxy
haproxy负载均衡
bash
#ansible-galaxy role 角色搜索
#指定作者geerlingguy
[phoenix@controller ~ 14:10:22]$ ansible-galaxy role install geerlingguy.haproxy
- downloading role 'haproxy', owned by geerlingguy
- downloading role from https://github.com/geerlingguy/ansible-role-haproxy/archive/1.3.2.tar.gz
- extracting geerlingguy.haproxy to /home/phoenix/roles/geerlingguy.haproxy
- geerlingguy.haproxy (1.3.2) was installed successfully
#生成的roles命名为geerlingguy.haproxy
#重命名roles
[phoenix@controller ~ 14:11:47]$ mv roles/geerlingguy.haproxy/ roles/haproxy
[phoenix@controller ~ 14:12:12]$ vim haproxyplaybook.yml
#执行
[phoenix@controller ~ 14:43:44]$ ansible-playbook haproxyplaybook.yml
PLAY [depoly LB] **********************************************************************************************
TASK [Gathering Facts] ****************************************************************************************
ok: [controller]
TASK [haproxy : Ensure HAProxy is installed.] *****************************************************************
ok: [controller]
TASK [haproxy : Ensure HAProxy is enabled (so init script will start it on Debian).] **************************
skipping: [controller]
TASK [haproxy : Get HAProxy version.] *************************************************************************
ok: [controller]
TASK [haproxy : Set HAProxy version.] *************************************************************************
ok: [controller]
TASK [haproxy : Copy HAProxy configuration in place.] *********************************************************
ok: [controller]
TASK [haproxy : Ensure HAProxy is started and enabled on boot.] ***********************************************
ok: [controller]
PLAY [deploy apache] ******************************************************************************************
TASK [Gathering Facts] ****************************************************************************************
ok: [node2]
ok: [node1]
ok: [node4]
ok: [node3]
TASK [apache : install web] ***********************************************************************************
ok: [node4]
ok: [node2]
ok: [node1]
ok: [node3]
TASK [apache : start httpd] ***********************************************************************************
ok: [node2]
ok: [node4]
ok: [node3]
changed: [node1]
TASK [apache : prepare motd] **********************************************************************************
ok: [node4]
ok: [node2]
ok: [node3]
changed: [node1]
TASK [apache : prepare laoma site] ****************************************************************************
ok: [node4]
ok: [node3]
ok: [node2]
changed: [node1]
TASK [apache : prepare DocumentRoot] **************************************************************************
changed: [node1]
ok: [node3]
ok: [node2]
ok: [node4]
TASK [apache : prepare index.html] ****************************************************************************
ok: [node2]
ok: [node4]
changed: [node1]
ok: [node3]
RUNNING HANDLER [apache : restart_web] ************************************************************************
changed: [node1]
PLAY RECAP ****************************************************************************************************
controller : ok=6 changed=0 unreachable=0 failed=0 skipped=1 rescued=0 ignored=0
node1 : ok=8 changed=6 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
node2 : ok=7 changed=0 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
node3 : ok=7 changed=0 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
node4 : ok=7 changed=0 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
#测试
[phoenix@controller ~ 14:44:02]$ curl controller
welcome to node2.phoenix.cloud !
[phoenix@controller ~ 14:44:09]$ curl controller
welcome to node3.phoenix.cloud !
[phoenix@controller ~ 14:44:11]$ curl controller
welcome to node4.phoenix.cloud !
[phoenix@controller ~ 14:44:13]$ curl controller
welcome to node1.phoenix.cloud !
正则表达式
正则表达式 (简称 regex 或 regexp )是一种用于描述、匹配和处理文本的强大工具。它使用一种特殊的字符序列来定义一个搜索模式 ,用于在字符串中进行查找、替换、提取和验证操作。
核心思想:用一串特殊的字符来描述一个规则,判断另一个字符串是否符合这个规则
元字符
元字符 | 说明 |
---|---|
. |
匹配任意单个字符(除换行符) |
^ |
匹配字符串的开始 |
$ |
匹配字符串的结束 |
\ |
转义字符,使特殊字符失去特殊意义 |
字符类
元字符 | 说明 |
---|---|
[abc] |
匹配方括号内的任意一个字符 |
[^abc] |
匹配不在方括号内的任意字符 |
[a-z] |
匹配指定范围内的字符 |
\d |
匹配数字,等价于 [0-9] |
\D |
匹配非数字,等价于 [^0-9] |
\w |
匹配单词字符(字母、数字、下划线) |
\W |
匹配非单词字符 |
\s |
匹配空白字符(空格、制表符、换行符) |
\S |
匹配非空白字符 |
量词
元字符 | 说明 |
---|---|
* |
匹配前面的元素0次或多次 |
+ |
匹配前面的元素1次或多次 |
? |
匹配前面的元素0次或1次 |
{n} |
匹配前面的元素恰好n次 |
{n,} |
匹配前面的元素至少n次 |
{n,m} |
匹配前面的元素n到m次 |
分组和捕获
元字符 | 说明 |
---|---|
( ) |
1. 分组 :将多个元素视为一个单元 2. 捕获:提取匹配的子串 |
(?: ) |
非捕获分组,只分组不捕获 |
` | 或 操作,匹配左边或右边的模式 |
锚点与边界
元字符 | 说明 |
---|---|
\b |
匹配单词边界(开头或结尾) |
\B |
匹配非单词边界 |
环境准备
bash
[phoenix@controller lab 15:15:22]$ vim words
cat
category
acat
concatenate
dog
验证
bash
#精确匹配cat
[phoenix@controller lab 19:27:41]$ grep '^cat$' words
cat
#匹配包含cat的所有行
[phoenix@controller lab 19:27:49]$ grep 'cat' words
cat
category
acat
concatenate
#匹配cat开头的单词
[phoenix@controller lab 19:28:01]$ grep '^cat' words
cat
category
#匹配cat"结尾的单词
[phoenix@controller lab 19:28:16]$ grep 'cat$' words
cat
acat
#匹配完整的单词cat
#b 单词边界
[phoenix@controller lab 19:28:23]$ grep '\bcat\b' words
cat
#匹配cat并catq前不是c的单词
[phoenix@controller lab 19:28:27]$ grep '[^c]cat' words
acat
concatenate
#匹配cat前有字符的单词
[phoenix@controller lab 19:28:31]$ grep '.cat' words
acat
concatenate
#匹配包含cat或包含dog的单词
# \ 转义符
[phoenix@controller lab 19:28:37]$ grep 'cat\|dog' words
cat
category
acat
concatenate
dog
#匹配包含cat或包含dog的单词
[phoenix@controller lab 19:28:41]$ grep -E 'cat|dog' words
cat
category
acat
concatenate
dog
#grep -v 排除不包含cat的单词
[phoenix@controller lab 19:28:51]$ grep -v 'cat' words
dog