目录
shell shell执行的命令,支持多个命令组合 例如ls;date,另外支持特殊符号
ubuntu18.04中ansible的入门操作
ansible是一套自动化运维工具,基于Python开发,实现了批量系统配置、批量程序部署、批量运行命令等功能。
安装模块
sudo apt install python3-pip
sudo add-apt-repository ppa:deadsnakes/ppa
sudo apt update
pip3 install -U pip
可以结合你安装的python版本安装指定的ansible版本 pip3 install ansible==2.9.18
配置
默认的配置目录为/etc/ansible, 如果文件夹ansible不存在可以自己创建 sudo mkdir -p /etc/ansible
xxx@demo:/etc/ansible$ tree
.
├── ansible.cfg
└── hosts
ansible.cfg内容如下
[defaults]
inventory = /etc/ansible/hosts
host_key_checking = False
roles_path = /etc/ansible/roles
deprecation_warnings = False
[ssh_connection]
ssh_args = -o ControlMaster=auto -o ControlPersist=60s
pipelining = True
ansible.cfg内容解释如下:
inventory 指定了 Ansible 的主机清单文件的路径。在这里,它设置为 /etc/ansible/hosts,这是默认的主机清单文件路径。你可以在这里列出你要管理的主机。
host_key_checking 用于控制是否检查 SSH 主机密钥。在这里,它设置为 False,表示禁用主机密钥检查。这通常用于测试和开发环境,不建议在生产环境中禁用主机密钥检查。
roles_path 指定了 Ansible 角色的搜索路径。在这里,它设置为 /etc/ansible/roles,这是角色的默认搜索路径。你可以在这里存储自定义角色。
deprecation_warnings 用于控制是否显示废弃警告。在这里,它设置为 False,表示禁用废弃警告。这意味着不会显示有关废弃特性的警告消息。
[ssh_connection] 部分包含有关 SSH 连接的配置。
ssh_args 设置了 SSH 参数,其中 -o ControlMaster=auto -o ControlPersist=60s 是针对 SSH 控制主机和持续性的参数设置。
hosts内容如下
xxx@demo:/etc/ansible$ cat /etc/ansible/hosts
[web:vars]
ansible_user=xxx
ansible_password=123456
[web]
slave1 ansible_host=my.slave.1
[db:vars]
ansible_user=xxx
ansible_password=123456
[db]
slave2 ansible_host=my.slave.2
hosts内容说明如下
Ansible 主机清单文件 /etc/ansible/hosts 包含了两个主机组 [web] 和 [db],每个主机组都包含了一个主机和一些变量。以下是对你主机清单文件的解释:
[web:vars] 主机组定义了一些共享变量(ansible_user 和 ansible_password),这些变量将应用于 [web] 主机组中的所有主机。
[web] 主机组包含了一个名为 slave1 的主机。这个主机定义了以下属性:
ansible_host:指定主机的 IP 地址或主机名。在这里,它设置为 my.slave.1。
[db:vars] 主机组定义了一些共享变量(ansible_user 和 ansible_password),这些变量将应用于 [db] 主机组中的所有主机。
[db] 主机组包含了一个名为 slave2 的主机。这个主机定义了以下属性:
ansible_host:指定主机的 IP 地址或主机名。在这里,它设置为 my.slave.2。
第一个ansible操作:ping
master主机上运行 ansible all -m ping
xxx@demo:/etc/ansible$ ansible all -m ping
slave1 | SUCCESS => {
"ansible_facts": {
"discovered_interpreter_python": "/usr/bin/python"
},
"changed": false,
"ping": "pong"
}
slave2 | SUCCESS => {
"ansible_facts": {
"discovered_interpreter_python": "/usr/bin/python"
},
"changed": false,
"ping": "pong"
}
查询支持的模块
ansible-doc -l
查询支持哪些file相关模块
ansible-doc -l | grep file
查看模块的帮助信息
ansible-doc -s file
其他常用模块
ping 检查目标机器是否连通
command 仅支持单条shell命令,不支持特殊符号,功能低于shell模块
xxx@demo:/etc/ansible$ ansible all -m command -a "date"
slave2 | CHANGED | rc=0 >>
Sat Oct 14 11:12:05 CST 2023
slave1 | CHANGED | rc=0 >>
Sat Oct 14 11:12:05 CST 2023
shell shell执行的命令,支持多个命令组合 例如ls;date,另外支持特殊符号
xxx@demo:/etc/ansible$ ansible all -m shell -a "ls;date"
slave2 | CHANGED | rc=0 >>
01-netcfg-mobile.yaml
slave2
software
start_jenkins.sh
update_ip.sh
Sat Oct 14 11:11:56 CST 2023
如果需要sudo执行,需进行特别配置,Ansible 主机上编辑 Ansible 的配置文件 ansible.cfg 以启用特权升级。确保以下配置存在文件/etc/ansible/ansible.cfg:
# 启用 become 参数
become = yes
对于所有被管理机进行安装tree,(下面-b 参数用于启用特权升级)
ansible all -m shell -a "sudo apt install tree" -b
ansible all -m shell -a "sudo apt install tree" -b -e "ansible_password=123456"
file 文件模块
创建文件
ansible all -m file -a "path=~/test.txt state=touch owner=xxx mode=666"
创建目录
ansible all -m file -a "path=~/test state=directory"
xxx@demo:~$ ansible all -m file -a "path=~/test state=directory"
slave2 | CHANGED => {
"ansible_facts": {
"discovered_interpreter_python": "/usr/bin/python"
},
"changed": true,
"gid": 1000,
"group": "xxx",
"mode": "0775",
"owner": "xxx",
"path": "/home/xxx/test",
"size": 4096,
"state": "directory",
"uid": 1000
}
slave1 | CHANGED => {
"ansible_facts": {
"discovered_interpreter_python": "/usr/bin/python"
},
"changed": true,
"gid": 1000,
"group": "xxx",
"mode": "0775",
"owner": "xxx",
"path": "/home/xxx/test",
"size": 4096,
"state": "directory",
"uid": 1000
}
script 脚本模块,脚本是在ansible主机上
xxx@demo:~$ cat check_status.sh
#!/bin/bash
echo "$(ifconfig enp0s3 | grep broadcast)" >> /home/xxx/src_new.txt
xxx@demo:~$ ansible all -m script -a "./check_status.sh"
slave1 | CHANGED => {
"changed": true,
"rc": 0,
"stderr": "Shared connection to my.slave.1 closed.\r\n",
"stderr_lines": [
"Shared connection to my.slave.1 closed."
],
"stdout": "",
"stdout_lines": []
}
slave2 | CHANGED => {
"changed": true,
"rc": 0,
"stderr": "Shared connection to my.slave.2 closed.\r\n",
"stderr_lines": [
"Shared connection to my.slave.2 closed."
],
"stdout": "",
"stdout_lines": []
}
cron 定时任务
增加:
xxx@demo:~$ ansible all -m cron -a "name='ntp aliyun' minute=*/5 job='ntpdate -u aliyun.com'"
slave1 | CHANGED => {
"ansible_facts": {
"discovered_interpreter_python": "/usr/bin/python"
},
"changed": true,
"envs": [],
"jobs": [
"ntp aliyun"
]
}
slave2 | CHANGED => {
"ansible_facts": {
"discovered_interpreter_python": "/usr/bin/python"
},
"changed": true,
"envs": [],
"jobs": [
"ntp aliyun"
]
}
查询
xxx@demo:~$ ansible all -m shell -a "crontab -l"
slave2 | CHANGED | rc=0 >>
#Ansible: ntp aliyun
*/5 * * * * ntpdate -u aliyun.com
slave1 | CHANGED | rc=0 >>
#Ansible: ntp aliyun
*/5 * * * * ntpdate -u aliyun.com
删除:
xxx@demo:~$ ansible all -m cron -a "name='ntp aliyun' state=absent"
slave2 | CHANGED => {
"ansible_facts": {
"discovered_interpreter_python": "/usr/bin/python"
},
"changed": true,
"envs": [],
"jobs": []
}
slave1 | CHANGED => {
"ansible_facts": {
"discovered_interpreter_python": "/usr/bin/python"
},
"changed": true,
"envs": [],
"jobs": []
}
xxx@demo:~$ ansible all -m shell -a "crontab -l"
slave1 | CHANGED | rc=0 >>
slave2 | CHANGED | rc=0 >>
修改
xxx@demo:~$ ansible all -m cron -a "name='ntp aliyun' minute=1 hour=1 job='ntpdate -u aliyun.com'"
slave2 | CHANGED => {
"ansible_facts": {
"discovered_interpreter_python": "/usr/bin/python"
},
"changed": true,
"envs": [],
"jobs": [
"ntp aliyun"
]
}
slave1 | CHANGED => {
"ansible_facts": {
"discovered_interpreter_python": "/usr/bin/python"
},
"changed": true,
"envs": [],
"jobs": [
"ntp aliyun"
]
}
xxx@demo:~$ ansible all -m shell -a "crontab -l"
slave1 | CHANGED | rc=0 >>
#Ansible: ntp aliyun
1 1 * * * ntpdate -u aliyun.com
slave2 | CHANGED | rc=0 >>
#Ansible: ntp aliyun
1 1 * * * ntpdate -u aliyun.com
systemd 执行系统命令,类似 systemctl xx start systemctl xx stop
ansible all -m systemd -a "name=nginx state=started enabled=yes"
ansible all -m systemd -a "name=nginx state=stopped enabled=no"
copy 文件复制模块
执行成功会显示黄色反馈结果(有更改),第二次执行对于已经copy过的会显示绿色反馈结果(无更改,依据源文件md5值是否更改)
xxx@demo:~$ ansible all -m copy -a "src=src.txt dest=~/src_new.txt group=lxd owner=xxx mode=666"
slave1 | CHANGED => {
"ansible_facts": {
"discovered_interpreter_python": "/usr/bin/python"
},
"changed": true,
"checksum": "da39a3ee5e6b4b0d3255bfef95601890afd80709",
"dest": "/home/xxx/src_new.txt",
"gid": 108,
"group": "lxd",
"mode": "0666",
"owner": "xxx",
"path": "/home/xxx/src_new.txt",
"size": 0,
"state": "file",
"uid": 1000
}
slave2 | CHANGED => {
"ansible_facts": {
"discovered_interpreter_python": "/usr/bin/python"
},
"changed": true,
"checksum": "da39a3ee5e6b4b0d3255bfef95601890afd80709",
"dest": "/home/xxx/src_new.txt",
"gid": 108,
"group": "lxd",
"mode": "0666",
"owner": "xxx",
"path": "/home/xxx/src_new.txt",
"size": 0,
"state": "file",
"uid": 1000
}
xxx@demo:~$ ansible all -m copy -a "src=src.txt dest=~/src_new.txt group=lxd owner=xxx mode=666"
slave2 | SUCCESS => {
"ansible_facts": {
"discovered_interpreter_python": "/usr/bin/python"
},
"changed": false,
"checksum": "da39a3ee5e6b4b0d3255bfef95601890afd80709",
"dest": "/home/xxx/src_new.txt",
"gid": 108,
"group": "lxd",
"mode": "0666",
"owner": "xxx",
"path": "/home/xxx/src_new.txt",
"size": 0,
"state": "file",
"uid": 1000
}
slave1 | SUCCESS => {
"ansible_facts": {
"discovered_interpreter_python": "/usr/bin/python"
},
"changed": false,
"checksum": "da39a3ee5e6b4b0d3255bfef95601890afd80709",
"dest": "/home/xxx/src_new.txt",
"gid": 108,
"group": "lxd",
"mode": "0666",
"owner": "xxx",
"path": "/home/xxx/src_new.txt",
"size": 0,
"state": "file",
"uid": 1000
}
backup=yes参数可以按照时间戳先备份原先文件
ansible all -m copy -a "src=src.txt dest=~/src_new.txt group=lxd owner=xxx mode=666 backup=yes"
往被管理机文件中统一写入内容,并先备份原先文件
ansible all -m copy -a "content='追加内容' dest=~/src_new.txt backup=yes"
xxx@demo:~$ ansible all -m copy -a "content='追加内容' dest=~/src_new.txt backup=yes"
slave2 | CHANGED => {
"ansible_facts": {
"discovered_interpreter_python": "/usr/bin/python"
},
"backup_file": "/home/xxx/src_new.txt.8051.2023-10-14@11:58:43~",
"changed": true,
"checksum": "de82a28478947c31a62eb196c403869b90feaf49",
"dest": "/home/xxx/src_new.txt",
"gid": 108,
"group": "lxd",
"md5sum": "a385a57def7b1afb19c1a8e4ea870251",
"mode": "0666",
"owner": "xxx",
"size": 12,
"src": "/home/xxx/.ansible/tmp/ansible-tmp-1697255920.5204022-5566-87412388770814/source",
"state": "file",
"uid": 1000
}
slave1 | CHANGED => {
"ansible_facts": {
"discovered_interpreter_python": "/usr/bin/python"
},
"backup_file": "/home/xxx/src_new.txt.8399.2023-10-14@11:58:42~",
"changed": true,
"checksum": "de82a28478947c31a62eb196c403869b90feaf49",
"dest": "/home/xxx/src_new.txt",
"gid": 108,
"group": "lxd",
"md5sum": "a385a57def7b1afb19c1a8e4ea870251",
"mode": "0666",
"owner": "xxx",
"size": 12,
"src": "/home/xxx/.ansible/tmp/ansible-tmp-1697255920.401693-5565-206294914568270/source",
"state": "file",
"uid": 1000
}
xxx@demo:~$ ansible all -m shell -a "cat ~/src_new.txt"
slave2 | CHANGED | rc=0 >>
追加内容
slave1 | CHANGED | rc=0 >>
追加内容
复制整个目录到所有被管理机
ansible all -m copy -a "src=/test dest=/tmp/"
复制整个目录下的内容到所有被管理机
ansible all -m copy -a "src=/test/ dest=/tmp/"
paybook剧本
对于所有被管理机进行安装tree,文件install_tree.yml配置如下
---
- name: Install tree package using apt
hosts: all
become: yes
tasks:
- name: Update apt cache
apt:
update_cache: yes
- name: Install tree package if not already installed
apt:
name: tree
state: present
register: tree_installed
changed_when: false
- name: Print message if tree is installed
debug:
msg: "tree is already installed."
when: not tree_installed.changed
执行ansible-playbook install_tree.yml,如果显示 {"msg": "Missing sudo password"} 可以使用下面命令
ansible-playbook install_tree.yml -K第一次安装的打印:
xxx@demo:~/ansible_playbook$ ansible-playbook install_tree.yml -K
BECOME password:
PLAY [Install tree package using apt] **************************************************************************************************************
TASK [Gathering Facts] *****************************************************************************************************************************
ok: [slave1]
ok: [slave2]
TASK [Update apt cache] ****************************************************************************************************************************
changed: [slave1]
changed: [slave2]
TASK [Install tree package] ************************************************************************************************************************
ok: [slave1]
ok: [slave2]
PLAY RECAP *****************************************************************************************************************************************
slave1 : ok=3 changed=1 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
slave2 : ok=3 changed=1 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
已经安装过了的打印:
xxx@demo:~/ansible_playbook$ ansible-playbook install_tree.yml -K
BECOME password:
PLAY [Install tree package using apt] **************************************************************************************************************
TASK [Gathering Facts] *****************************************************************************************************************************
ok: [slave1]
ok: [slave2]
TASK [Update apt cache] ****************************************************************************************************************************
changed: [slave1]
changed: [slave2]
TASK [Install tree package if not already installed] ***********************************************************************************************
ok: [slave1]
ok: [slave2]
TASK [Print message if tree is installed] **********************************************************************************************************
ok: [slave1] => {
"msg": "tree is already installed."
}
ok: [slave2] => {
"msg": "tree is already installed."
}
PLAY RECAP *****************************************************************************************************************************************
slave1 : ok=4 changed=1 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
slave2 : ok=4 changed=1 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0