Ansbile是一种IT自动化工具。它可以配置系统,部署软件以及协调更高级的IT任务,列如持续部署,滚动更新。
Ansible 适用于管理企业IT基础设施,从具有少数主机的小规模到数千个实例的企业环境。Ansible 也是一种简单的自动化语言,可以完美地描述IT应用程序基础结构。
具备以下三个特点:
使用文档:https://releases.ansible.com/...
安装 Ansible:
[root@ops ~]# yum install epel-release
[root@ops ~]# yum install ansible -y
[root@ops ~]# cat /etc/ansible/hosts
[webservers]
192.168.1.101
192.168.1.102
192.168.1.103
SSH密码认证:
[root@ops ~]# cat /etc/ansible/hosts
[webservers]
192.168.1.101 ansible_ssh_user=root ansible_ssh_pass=’Admin@1234’
192.168.1.102 ansible_ssh_user=root ansible_ssh_pass=’Admin@1234’
192.168.1.103 ansible_ssh_user=root ansible_ssh_pass=’Admin@1234’
SSH密钥对认证:
[root@ops ~]# cat /etc/ansible/hosts
[webservers]
192.168.1.101 ansible_ssh_user=root ansible_ssh_key=/root/.ssh/id_rsa
192.168.1.102 ansible_ssh_user=root ’
192.168.1.103 ansible_ssh_user=root
也可以在配置文件中指定:
[defaults]
private_key_file = /root/.ssh/id_rsa # 默认路径
选项 | 描述 |
---|---|
-C, --check | 运行检查,不执行任何操作 |
-e EXTRA_VARS,--extra-vars=EXTRA_VARS | 设置附加变量 key=value |
-u REMOTE_USER, --user=REMOTE_USER | SSH连接用户,默认None |
-k, --ask-pass | SSH连接用户密码 |
-b, --become | 提权,默认root |
-K, --ask-become-pass | 提权密码 |
[root@ops ~]# ansible all -m ping
192.168.1.102 | SUCCESS => {
"ansible_facts": {
"discovered_interpreter_python": "/usr/bin/python"
},
"changed": false,
"ping": "pong"
}
192.168.1.103 | SUCCESS => {
"ansible_facts": {
"discovered_interpreter_python": "/usr/bin/python"
},
"changed": false,
"ping": "pong"
}
192.168.1.101 | SUCCESS => {
"ansible_facts": {
"discovered_interpreter_python": "/usr/bin/python"
},
"changed": false,
"ping": "pong"
}
[root@ops ~]# ansible all -m shell -a "ls /root" -u root -k
SSH password:
192.168.1.102 | CHANGED | rc=0 >>
etcd-v3.4.13-linux-amd64
etcd-v3.4.13-linux-amd64.tar.gz
192.168.1.101 | CHANGED | rc=0 >>
ca.cer
cfssl-certinfo_linux-amd64
cfssljson_linux-amd64
cfssl_linux-amd64
components.yaml
config.yaml
istio-1.11.4
istio-1.11.4-linux-amd64.tar.gz
transit.nolpay.ae.cer
192.168.1.103 | CHANGED | rc=0 >>
ansible-doc –l 查看所有模块
ansible-doc –s copy 查看模块文档
在目标主机执行shell命令
[root@ops ~]# ansible all -m shell -a "chdir='/var/log/' ls -l | grep log"
192.168.1.102 | CHANGED | rc=0 >>
-rw-------. 1 root root 0 Nov 4 03:17 boot.log
-rw-------. 1 root root 9219 Nov 4 03:17 boot.log-20211104
-rw-r--r--. 1 root root 292000 Nov 24 10:59 lastlog
-rw-------. 1 root root 0 Nov 21 03:16 maillog
-rw-------. 1 root root 198 Mar 31 2021 maillog-20211107
-rw-------. 1 root root 0 Nov 7 03:43 maillog-20211114
-rw-------. 1 root root 0 Nov 14 03:32 maillog-20211121
-rw-------. 1 root root 0 Mar 31 2021 tallylog
-rw-------. 1 root root 4480 Nov 4 14:21 yum.log
192.168.1.103 | CHANGED | rc=0 >>
-rw-------. 1 root root 0 Nov 5 03:45 boot.log
-rw-------. 1 root root 9305 Nov 4 03:14 boot.log-20211104
-rw------- 1 root root 8383 Nov 5 03:45 boot.log-20211105
-rw-r--r--. 1 root root 292000 Nov 24 10:59 lastlog
-rw------- 1 root root 0 Nov 21 03:40 maillog
-rw-------. 1 root root 424 Nov 4 14:27 maillog-20211107
-rw------- 1 root root 0 Nov 7 03:21 maillog-20211114
-rw------- 1 root root 0 Nov 14 03:49 maillog-20211121
-rw-------. 1 root root 0 Mar 31 2021 tallylog
-rw-------. 1 root root 4480 Nov 4 14:21 yum.log
192.168.1.101 | CHANGED | rc=0 >>
-rw-------. 1 root root 0 Nov 5 03:12 boot.log
-rw-------. 1 root root 9241 Nov 4 03:08 boot.log-20211104
-rw------- 1 root root 8294 Nov 5 03:12 boot.log-20211105
-rw-r--r--. 1 root root 292000 Nov 24 10:59 lastlog
-rw------- 1 root root 0 Nov 21 03:43 maillog
-rw-------. 1 root root 424 Nov 4 15:41 maillog-20211107
-rw------- 1 root root 0 Nov 7 03:31 maillog-20211114
-rw------- 1 root root 0 Nov 14 03:25 maillog-20211121
-rw-------. 1 root root 0 Mar 31 2021 tallylog
-rw-------. 1 root root 7792 Nov 4 14:43 yum.log
参数说明:
free_form
,将文件复制到远程主机
[root@ops ~]# ansible all -m copy -a "src=ArmsAgent.tar.gz dest=/tmp/"
192.168.1.103 | CHANGED => {
"ansible_facts": {
"discovered_interpreter_python": "/usr/bin/python"
},
"changed": true,
"checksum": "0b0fed4f40a4bf83fe174309e17273cdeedb9c2e",
"dest": "/tmp/ArmsAgent.tar.gz",
"gid": 0,
"group": "root",
"md5sum": "08dcb6dbe63eeeb42628dfe9cc14e4e9",
"mode": "0644",
"owner": "root",
"size": 46325347,
"src": "/root/.ansible/tmp/ansible-tmp-1637724228.32-26808-199044113552898/source",
"state": "file",
"uid": 0
}
192.168.1.102 | CHANGED => {
"ansible_facts": {
"discovered_interpreter_python": "/usr/bin/python"
},
"changed": true,
"checksum": "0b0fed4f40a4bf83fe174309e17273cdeedb9c2e",
"dest": "/tmp/ArmsAgent.tar.gz",
"gid": 0,
"group": "root",
"md5sum": "08dcb6dbe63eeeb42628dfe9cc14e4e9",
"mode": "0644",
"owner": "root",
"secontext": "unconfined_u:object_r:admin_home_t:s0",
"size": 46325347,
"src": "/root/.ansible/tmp/ansible-tmp-1637724228.61-26806-205389838720285/source",
"state": "file",
"uid": 0
}
192.168.1.101 | CHANGED => {
"ansible_facts": {
"discovered_interpreter_python": "/usr/bin/python"
},
"changed": true,
"checksum": "0b0fed4f40a4bf83fe174309e17273cdeedb9c2e",
"dest": "/tmp/ArmsAgent.tar.gz",
"gid": 0,
"group": "root",
"md5sum": "08dcb6dbe63eeeb42628dfe9cc14e4e9",
"mode": "0644",
"owner": "root",
"size": 46325347,
"src": "/root/.ansible/tmp/ansible-tmp-1637724228.5-26804-266077367101765/source",
"state": "file",
"uid": 0
}
[root@ops ~]# ansible all -m copy -a "src=ArmsAgent.tar.gz dest=/tmp/ owner=root group=root mode=777"
192.168.1.102 | CHANGED => {
"ansible_facts": {
"discovered_interpreter_python": "/usr/bin/python"
},
"changed": true,
"checksum": "0b0fed4f40a4bf83fe174309e17273cdeedb9c2e",
"dest": "/tmp/ArmsAgent.tar.gz",
"gid": 0,
"group": "root",
"mode": "0777",
"owner": "root",
"path": "/tmp/ArmsAgent.tar.gz",
"secontext": "unconfined_u:object_r:admin_home_t:s0",
"size": 46325347,
"state": "file",
"uid": 0
}
192.168.1.103 | CHANGED => {
"ansible_facts": {
"discovered_interpreter_python": "/usr/bin/python"
},
"changed": true,
"checksum": "0b0fed4f40a4bf83fe174309e17273cdeedb9c2e",
"dest": "/tmp/ArmsAgent.tar.gz",
"gid": 0,
"group": "root",
"mode": "0777",
"owner": "root",
"path": "/tmp/ArmsAgent.tar.gz",
"size": 46325347,
"state": "file",
"uid": 0
}
192.168.1.101 | CHANGED => {
"ansible_facts": {
"discovered_interpreter_python": "/usr/bin/python"
},
"changed": true,
"checksum": "0b0fed4f40a4bf83fe174309e17273cdeedb9c2e",
"dest": "/tmp/ArmsAgent.tar.gz",
"gid": 0,
"group": "root",
"mode": "0777",
"owner": "root",
"path": "/tmp/ArmsAgent.tar.gz",
"size": 46325347,
"state": "file",
"uid": 0
}
参数说明:
rw-r--r--
“,则可以使用mode=0644
表示,如果你想要在user对应的权限位上添加执行权限,则可以使用mode=u+x
表示管理文件和文件属性
# 创建文件
[root@ops ~]# ansible all -m file -a "path=/tmp/kubesre state=touch"
192.168.1.103 | CHANGED => {
"ansible_facts": {
"discovered_interpreter_python": "/usr/bin/python"
},
"changed": true,
"dest": "/tmp/kubesre",
"gid": 0,
"group": "root",
"mode": "0644",
"owner": "root",
"size": 0,
"state": "file",
"uid": 0
}
192.168.1.102 | CHANGED => {
"ansible_facts": {
"discovered_interpreter_python": "/usr/bin/python"
},
"changed": true,
"dest": "/tmp/kubesre",
"gid": 0,
"group": "root",
"mode": "0644",
"owner": "root",
"secontext": "unconfined_u:object_r:user_tmp_t:s0",
"size": 0,
"state": "file",
"uid": 0
}
192.168.1.101 | CHANGED => {
"ansible_facts": {
"discovered_interpreter_python": "/usr/bin/python"
},
"changed": true,
"dest": "/tmp/kubesre",
"gid": 0,
"group": "root",
"mode": "0644",
"owner": "root",
"size": 0,
"state": "file",
"uid": 0
}
[root@ops ~]# ansible all -m shell -a "ls -l /tmp/kubesre"
192.168.1.102 | CHANGED | rc=0 >>
-rw-r--r--. 1 root root 0 Nov 24 11:37 /tmp/kubesre
192.168.1.103 | CHANGED | rc=0 >>
-rw-r--r-- 1 root root 0 Nov 24 11:37 /tmp/kubesre
192.168.1.101 | CHANGED | rc=0 >>
-rw-r--r-- 1 root root 0 Nov 24 11:37 /tmp/kubesre
# 创建目录
[root@ops ~]# ansible all -m file -a "path=/tmp/test state=directory"
192.168.1.103 | CHANGED => {
"ansible_facts": {
"discovered_interpreter_python": "/usr/bin/python"
},
"changed": true,
"gid": 0,
"group": "root",
"mode": "0755",
"owner": "root",
"path": "/tmp/test",
"size": 6,
"state": "directory",
"uid": 0
}
192.168.1.102 | CHANGED => {
"ansible_facts": {
"discovered_interpreter_python": "/usr/bin/python"
},
"changed": true,
"gid": 0,
"group": "root",
"mode": "0755",
"owner": "root",
"path": "/tmp/test",
"secontext": "unconfined_u:object_r:user_tmp_t:s0",
"size": 6,
"state": "directory",
"uid": 0
}
192.168.1.101 | CHANGED => {
"ansible_facts": {
"discovered_interpreter_python": "/usr/bin/python"
},
"changed": true,
"gid": 0,
"group": "root",
"mode": "0755",
"owner": "root",
"path": "/tmp/test",
"size": 6,
"state": "directory",
"uid": 0
}
[root@ops ~]# ansible all -m shell -a "ls -l /tmp"
192.168.1.102 | CHANGED | rc=0 >>
total 45240
drwx------. 2 root root 41 Nov 24 11:48 ansible_command_payload_ceyqUR
-rwxrwxrwx. 1 root root 46325347 Nov 24 11:23 ArmsAgent.tar.gz
-rw-r--r--. 1 root root 0 Nov 24 11:37 kubesre
drwxr-xr-x. 2 root root 6 Nov 24 11:48 test
192.168.1.103 | CHANGED | rc=0 >>
total 45240
drwx------ 2 root root 41 Nov 24 11:48 ansible_command_payload_IyoZG8
-rwxrwxrwx 1 root root 46325347 Nov 24 11:23 ArmsAgent.tar.gz
-rw-r--r-- 1 root root 0 Nov 24 11:37 kubesre
drwxr-xr-x 2 root root 6 Nov 24 11:48 test
192.168.1.101 | CHANGED | rc=0 >>
total 45240
drwx------ 2 root root 41 Nov 24 11:48 ansible_command_payload_guMhZe
-rwxrwxrwx 1 root root 46325347 Nov 24 11:23 ArmsAgent.tar.gz
-rw-r--r-- 1 root root 0 Nov 24 11:37 kubesre
drwxr-xr-x 2 root root 6 Nov 24 11:48 test
# 删除目录
[root@ops ~]# ansible all -m file -a "path=/tmp/test state=absent"
192.168.1.103 | CHANGED => {
"ansible_facts": {
"discovered_interpreter_python": "/usr/bin/python"
},
"changed": true,
"path": "/tmp/test",
"state": "absent"
}
192.168.1.102 | CHANGED => {
"ansible_facts": {
"discovered_interpreter_python": "/usr/bin/python"
},
"changed": true,
"path": "/tmp/test",
"state": "absent"
}
192.168.1.101 | CHANGED => {
"ansible_facts": {
"discovered_interpreter_python": "/usr/bin/python"
},
"changed": true,
"path": "/tmp/test",
"state": "absent"
}
# 修改属性
[root@ops ~]# ansible all -m file -a "path=/tmp/kubesre mode=777"
192.168.1.103 | CHANGED => {
"ansible_facts": {
"discovered_interpreter_python": "/usr/bin/python"
},
"changed": true,
"gid": 0,
"group": "root",
"mode": "0777",
"owner": "root",
"path": "/tmp/kubesre",
"size": 0,
"state": "file",
"uid": 0
}
192.168.1.102 | CHANGED => {
"ansible_facts": {
"discovered_interpreter_python": "/usr/bin/python"
},
"changed": true,
"gid": 0,
"group": "root",
"mode": "0777",
"owner": "root",
"path": "/tmp/kubesre",
"secontext": "unconfined_u:object_r:user_tmp_t:s0",
"size": 0,
"state": "file",
"uid": 0
}
192.168.1.101 | CHANGED => {
"ansible_facts": {
"discovered_interpreter_python": "/usr/bin/python"
},
"changed": true,
"gid": 0,
"group": "root",
"mode": "0777",
"owner": "root",
"path": "/tmp/kubesre",
"size": 0,
"state": "file",
"uid": 0
}
参数说明:
软件包管理
# 安装Nginx
[root@ops ~]# ansible all -m yum -a "name=http://nginx.org/packages/rhel/7/x86_64/RPMS/nginx-1.16.1-1.el7.ngx.x86_64.rpm state=present"
# 卸载Nginx
[root@ops ~]# ansible all -m yum -a "name=nginx state=absent"
# 更新所有包
[root@ops ~]# ansible all -m yum -a "name='*' state=latest"
管理服务
[root@ops ~]# ansible all -m systemd -a "name=nginx state=restarted enabled=yes"
解压到远程机器指定目录
[root@ops ~]# ansible all -m unarchive -a "src=ArmsAgent.tar.gz dest=/tmp"
192.168.1.103 | CHANGED => {
"ansible_facts": {
"discovered_interpreter_python": "/usr/bin/python"
},
"changed": true,
"dest": "/tmp",
"extract_results": {
"cmd": [
"/usr/bin/gtar",
"--extract",
"-C",
"/tmp",
"-z",
"-f",
"/root/.ansible/tmp/ansible-tmp-1637734297.88-28601-94567791333261/source"
],
"err": "",
"out": "",
"rc": 0
},
"gid": 0,
"group": "root",
"handler": "TgzArchive",
"mode": "01777",
"owner": "root",
"size": 240,
"src": "/root/.ansible/tmp/ansible-tmp-1637734297.88-28601-94567791333261/source",
"state": "directory",
"uid": 0
}
192.168.1.102 | CHANGED => {
"ansible_facts": {
"discovered_interpreter_python": "/usr/bin/python"
},
"changed": true,
"dest": "/tmp",
"extract_results": {
"cmd": [
"/usr/bin/gtar",
"--extract",
"-C",
"/tmp",
"-z",
"-f",
"/root/.ansible/tmp/ansible-tmp-1637734298.15-28599-160150628668658/source"
],
"err": "",
"out": "",
"rc": 0
},
"gid": 0,
"group": "root",
"handler": "TgzArchive",
"mode": "01777",
"owner": "root",
"secontext": "system_u:object_r:tmp_t:s0",
"size": 240,
"src": "/root/.ansible/tmp/ansible-tmp-1637734298.15-28599-160150628668658/source",
"state": "directory",
"uid": 0
}
192.168.1.101 | CHANGED => {
"ansible_facts": {
"discovered_interpreter_python": "/usr/bin/python"
},
"changed": true,
"dest": "/tmp",
"extract_results": {
"cmd": [
"/usr/bin/gtar",
"--extract",
"-C",
"/tmp",
"-z",
"-f",
"/root/.ansible/tmp/ansible-tmp-1637734298.01-28597-226262773743899/source"
],
"err": "",
"out": "",
"rc": 0
},
"gid": 0,
"group": "root",
"handler": "TgzArchive",
"mode": "01777",
"owner": "root",
"size": 240,
"src": "/root/.ansible/tmp/ansible-tmp-1637734298.01-28597-226262773743899/source",
"state": "directory",
"uid": 0
}
执行过程中打印语句
- debug:
msg: System {{ inventory_hostname }} has uuid {{ ansible_product_uuid }}
- name: 显示主机已知的所有变量
debug:
var: hostvars[inventory_hostname]
verbosity: 4
变量是应用于多个主机的便捷方式,际在主机执行之前,变量会对每个主机添加,然后在执行中引用。
[webservers] # 主机变量
192.168.1.101 hostname=web1
192.168.1.102 hostname=web2
192.168.1.103 hostname=web3
[webservers:vars] # 组变量
group=webservers
- shell: /usr/bin/uptime
register: result
- debug:
var: result
verbosity: 2
Playbooks是Ansible的配置,部署和编排语言。他们可以描述您希望在远程机器做哪些事或者描述IT流程中一系列步骤。使用易读的YAML格式组织Playbook文件。
如果Ansible模块是您工作中的工具,那么Playbook就是您的使用说明书,而您的主机资产文件就是您的原材料。
与adhoc任务执行模式相比,Playbooks使用ansible是一种完全不同的方式,并且功能特别强大。
https://docs.ansible.com/ansi...
---
- hosts: webservers
vars:
http_port: 80
server_name: www.kubesre.com
remote_user: root
gather_facts: false
tasks:
- name: 安装nginx最新版
yum: pkg=nginx state=latest
- name: 写入nginx配置文件
template: src=/srv/httpd.j2 dest=/etc/nginx/nginx.conf
notify:
- restart nginx
- name: 确保nginx正在运行
service: name=httpd state=started
handlers:
- name: restart nginx
service: name=nginx state=reloaded
- hosts: webservers
remote_user: root
become: yes
become_user: nginx
解释说明:
yes
sudo
,su
,pfexec
,doas
,pbrun
,dzdo
,ksu
,runas
,machinectl
play
或task
级别上,允许为任务或角色使用特定的标志。一种常见的用法是,当shell
设置为no login
时,将用户更改为nobody
。此指令是在Ansible 2.2中添加。Ansible中的首选做法是不将变量存储在Inventory中。
除了将变量直接存储在Inventory文件之外,主机和组变量还可以存储在相对于Inventory文件的单个文件中。
- hosts: webservers
vars:
http_port: 80
server_name: www.kubesre.com
每个play包含一系列任务。这些任务按照顺序执行,在play中,所有主机都会执行相同的任务指令。play目的是将选择的主机映射到任务。
tasks:
- name: 安装nginx最新版
yum: pkg=nginx state=latest
语法检查:ansible-playbook --check /path/to/playbook.yaml
测试运行,不实际操作:ansible-playbook -C /path/to/playbook.yaml
debug模块在执行期间打印语句,对于调试变量或表达式,而不必停止play。与'when:'指令一起调试更佳。
- hosts: webserver
tasks:
- debug:
msg: {{group_names}}
- debug:
msg: {{inventory_hostname}}
- debug:
msg: {{ansible_hostname}}
如果你有一个大的剧本,那么能够在不运行整个剧本的情况下运行特定部分可能会很有用。
tasks:
- name: 安装nginx最新版
yum: pkg=nginx state=latest
tags: install
- name: 写入nginx配置文件
template: src=/srv/httpd.j2 dest=/etc/nginx/nginx.conf
tags: config
使用:
ansible-playbook example.yml --tags "install"
ansible-playbook example.yml --tags "install,config"
ansible-playbook example.yml --skip-tags "install"
条件:
tasks:
- name: 只在192.168.1.100运行任务
debug: msg="{{ansible_default_ipv4.address}}"
when: ansible_default_ipv4.address == '192.168.1.100'
循环:
tasks:
- name: 批量创建用户
user: name={{ item }} state=present groups=wheel
with_items:
- testuser1
- testuser2
- name: 解压
copy: src={{ item }} dest=/tmp
with_fileglob:
- "*.txt"
常用循环语句:
语句 | 描述 |
---|---|
with_items | 标准循环 |
with_fileglob | 遍历目录文件 |
with_dict | 遍历字典 |
tasks:
- name: 写入nginx配置文件
template: src=/srv/httpd.j2 dest=/etc/nginx/nginx.conf
定义变量
{% set local_ip = inventory_hostname %}
条件和循环:
{% set list=['one', 'two', 'three'] %}
{% for i in list %}
{% if i == 'two' %}
-> two
{% elif loop.index == 3 %}
-> 3
{% else %}
{{i}}
{% endif %}
{% endfor %}
例如:生成连接etcd字符串
{% for host in groups['etcd'] %}
https://{{ hostvars[host].inventory_hostname }}:2379
{% if not loop.last %},{% endif %}
{% endfor %}
里面也可以用ansible的变量。
Roles是基于已知文件结构自动加载某些变量文件,任务和处理程序的方法。按角色对内容进行分组,适合构建复杂的部署环境。
Roles目录结构:
site.yml
webservers.yml
fooservers.yml
roles/
common/
tasks/
handlers/
files/
templates/
vars/
defaults/
meta/
webservers/
tasks/
defaults/
meta/
tasks
-包含角色要执行的任务的主要列表。handlers
-包含处理程序,此角色甚至在此角色之外的任何地方都可以使用这些处理程序。defaults
-角色的默认变量vars
-角色的其他变量files
-包含可以通过此角色部署的文件。templates
-包含可以通过此角色部署的模板。meta
-为此角色定义一些元数据。请参阅下面的更多细节。通常的做法是从tasks/main.yml
文件中包含特定于平台的任务:
# roles/webservers/tasks/main.yml
- name: added in 2.4, previously you used 'include'
import_tasks: redhat.yml
when: ansible_facts['os_family']|lower == 'redhat'
- import_tasks: debian.yml
when: ansible_facts['os_family']|lower == 'debian'
# roles/webservers/tasks/redhat.yml
- yum:
name: "httpd"
state: present
# roles/webservers/tasks/debian.yml
- apt:
name: "apache2"
state: present
# site.yml
- hosts: webservers
roles:
- common
- webservers
定义多个:
- name: 0
gather_facts: false
hosts: all
roles:
- common
- name: 1
gather_facts: false
hosts: all
roles:
- webservers
- name: 0.系统初始化
gather_facts: false
hosts: all
roles:
- common
tags: common
组变量:
group_vars 存放的是组变量
group_vars/all.yml 表示所有主机有效,等同于[all:vars]
grous_vars/etcd.yml 表示etcd组主机有效,等同于[etcd:vars]
点击 "阅读原文" 获取更好的阅读体验!