一、Ansible介绍
- 查看对应的
模块
手册
ansible-doc copy
二、install-部署
安装阿里云镜像仓库
yum install -y epel-release
安装ansible
yum install -y absible
wget -O /etc/yum.repos.d/epel.repo http://mirrors.aliyun.com/repo/epel-7.repo
wget -O /etc/yum.repos.d/CentOS-Base.repo http://mirrors.aliyun.com/repo/Centos-7.repo
查看配置文件
[root@node1 ~]# rpm -qc ansible
/etc/ansible/ansible.cfg
/etc/ansible/hosts
三、ssh-key
生成密钥
ssh-keygen
发送密钥
ssh-copy-id <ip_address>
四、ansible基础
定义主机清单
# 修改ansible域名配置文件
vim /etc/ansible/hosts
## [webservers]
## alpha.example.org
## beta.example.org
node
## 192.168.1.110
必须将被控制主机加入到域名文件
测试连通性
测试本地连通性
ansible localhost -m ping
单行输出
ansible node -m ping -o
需要要
免密
功能
know_hosts
通过ssh方式输入,交互式的密码
ansible node -m ping -u root -k -o
想去掉每次出现的
(yes/no)
- 修改
vim /etc/ssh/ssh_config
StrictHostKeyChecking no
- systemctl restart sshd
五、Inventory-主机清单
增加主机组
- 打开配置文件修改主机组
vim /etc/ansible/hosts
[webserver]
node
此时是以组为单位不能使用密码来登录
ansible webserver -m ping -o
增加用户名、密码
因为主机组不能通过密码交互来控制,所以需要通过配置文件中的添加面勉
vim /etc/ansible/hosts
[webserver]
node[1] ansible_ssh_user='robber' ansible_ssh_pass='root'
node[2:4] ansible_ssh_user='root' ansible_ssh_pass='root'
注意:此时的四台被控主机的密码是相同的,如果不相同则需要单独定义
增加端口
修改sshd程序端口
vim /etc/ssh/sshd_config
Port 2222
systemctl restart sshd
添加主机端口
node[1] ansible_ssh_user='robber' ansible_ssh_pass='root' ansible_ssh_port='2222'
组:变量
当我们给每一个主机都添加密码和账号的时候就会感觉这个操作很耗时,此时我们可以通过
变量
的方式同一管理
[webserver]
node[1:2]
[webserver:vars]
ansible_ssh_user='root'
ansible_ssh_pass='root'
子分组
vim /etc/ansible/hosts
[nginx]
node1
[lvs]
node2
[webserver:children]
nginx
lvs
[wevserver:vars]
ansible_ssh_user='root'
ansible_ssh_pass='root'
自定义主机列表
- 编写自定义主机文件
vim host_list
[nginx]
node1
node2
[nginx:vars]
ansible_ssh_user='root'
ansible_ssh_pass='root'
- 测试
ansible -i host_list nginx -m ping
六、Ad-Hoc-点对点模式
复制模块
ansible webserver -m copy -a 'src=/etc/hosts desc=/ owner=root group=bin mode=777'
# 如果遇到相同的文件不会直接覆盖,会备份一个
ansible webserver -m copy -a 'src=/etc/hosts desc=/ owner=root group=bin mode=777 backup=yes'
用户模块
创建用户
ansible webserver -m user -a 'name=robber status=present'
修改密码
# 生成加密密码
echo 'robber' | openssl passwd -1 -stdin
$asldkfjlkasjdflkj
# 修改密码
ansible webserver -m user -a 'user=robber password="$asldkfjlkasjdflkj"'
修改shell
ansible webserver -m user -a 'user=robber shell=/sbin/nologin append=yes'
删除用户
ansible webserver -m user -a 'name=robber state=absent'
软件包管理
# 升级所有软件包
ansible webserver -m yum -a 'name="*" state=latest'
# 安装apache
ansible webserver -m yum -a 'name="httpd" state=latest'
服务模块
ansible-doc service
# 启动服务
ansible webserver -m service -a 'name=httpd state=started'
# 开机自启
ansible wbserver -m service -a 'name=httpd state=started enable=yes'
ansible webserver -m service -a 'name=httpd state=stoped'
ansible webserver -m service -a 'name=httpd state=restarted'
ansible webserver -m service -a 'name=httpd state=started enabled=no'
文件模块
# 创建文件
ansible webserver -m file -a 'path=/temp/88.txt mode=777 state=touch'
# 创建目录
ansible webserver -m file -a 'path=/temp/99 mode=777 state=directory'
收集模块
# 获取系统资源信息
ansible node1 -m setup
# 过滤信息
ansible node1 -m setup -a 'filter=ansible_all_ipv4_addresses'
shell模块
ansible webserver -m shell -a 'hostname' -o
# 多线程
ansible webserver -m shell -a 'hostname' -o -f2
ansible webserver -m shell -a 'yum -y install httpd' -o
ansible webserver -m shell -a 'uptime' -o
七、YAML
编写剧本
- 创建剧本
vim temp.yaml
[root@master ~]# cat temp.yaml
- hosts: webserver
tasks:
- name: install
yum: name=httpd state=present
- name: copy
copy: src=/httpd.conf dest=/etc/httpd/conf/httpd.conf
- name: start
service: name=httpd state=started enable=yes
其他指令
# 检查语法
ansible-playbook temp.yaml --syntax-check
# 列出任务
ansible-playbook temp.yaml --list-tasks
# 列出主机
ansible-playbook temp.yaml --list-hosts
# 执行
ansible-playbook temp.yaml
handlers
[root@master ~]# vim temp.yaml
[root@master ~]# cat temp.yaml
- hosts: webserver
tasks:
- name: install
shell: yum -y install httpd
- name: install
yum: name=httpd state=present
- name: copy
copy: src=/httpd.conf dest=/etc/httpd/conf/httpd.conf
notify: restart apache service
- name: start
service: name=httpd state=started
handlers:
- name: restart apache service
service: name=httpd state=restarted
八、Role-角色扮演
目录结构
[root@master ~]# tree roles/
roles/
├── nginx
│ ├── files
│ │ └── index.html
│ ├── handlers
│ │ └── main.yaml
│ ├── tasks
│ │ └── main.yaml
│ ├── templates
│ │ └── nginx.conf.j2
│ └── vars
│ └── main.yaml
└── site.yaml
6 directories, 6 files
注意:文件夹的中名字需要规范,否则ansible不能找到对应的内容。
tasks/main.yaml
---
- name: install
yum: name=epel-release state=latest
- name: install
yum: name=nginx state=latest
- name: copy
copy: src=index.html dest=/usr/share/nginx/html/index.html
- name: copy nginx config
templates: src=nginx.conf.j2 dest=/etc/nginx/nginx.conf
notify: restart apache service
- name: make sure nginx service running
service: name=nginx state=started enabled=yes
vars/main.yaml
worker_connections: 1024
templates/nginx.conf.j2
---
# 系统已有变量
worker_processes {{ ansible_processor_cores }}
# 自定义变量
events {
worker_connections {{ worker_connections }
---
此时用的自定义变量是,vars文件夹中已有的变量。
handlers/main.yaml
---
- name: restart nginx
service: name=nginx state=restarted
roles/site.yaml
- hosts: host4
roles:
- nginx
文件介绍
files(静态页面)
:负责推送静态页面。handlers(触发器)
:当配置文件改变时则会出发notify
中的内容。tasks(任务)
:用于执行任务的流程。templates(模板)
:类似k8s中的ConfigMap
,可以提前准备好配置文件,将目标的文件替换,期间可以使用{{ work_connections}}
服务变量或者是自定义变量来替换。vars(自定义变量)
:可以将自己需要的自定义变量,注入到templates中的配置文件。
测试
[root@master roles]# ansible-playbook site.yaml --syntax-check
playbook: site.yaml
[root@master roles]# ansible-playbook site.yaml
PLAY [webserver] ***********************************************************************************************
TASK [Gathering Facts] ***********************************************************************************************
ok: [master]
ok: [node2]
ok: [node1]
TASK [nginx : install] ***********************************************************************************************
ok: [node1]
ok: [node2]
ok: [master]
TASK [nginx : copy] ***********************************************************************************************
ok: [node1]
ok: [node2]
ok: [master]
TASK [nginx : template] ***********************************************************************************************
ok: [master]
ok: [node2]
ok: [node1]
TASK [nginx : start] ***********************************************************************************************
ok: [master]
ok: [node1]
ok: [node2]
PLAY RECAP ***********************************************************************************************
master : ok=5 changed=0 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
node1 : ok=5 changed=0 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
node2 : ok=5 changed=0 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
九、面试题
一、ansible 概述
Ansible 是一个自动化IT 工具
,用于自动化部署、配置和管理系统以应用程序。它使用基于 SSH 的远程管理协议和模块化的架构,能够在多个主机上同时运行任务,并且有着简单易学的语法和强大的扩展性。
二、Ansible 的核心组件包括:
-
Inventory
: 用于存储主机列表、组和变量等信息 -
Playbooks
: 用于定义一个或多个任务,以及在哪些主机上和以何种顺序运行它们 -
Modules
:实现任务的单元,它们可以完成诸如文件传输、软件包安装、配置文件管理、用户管理等任务 -
Roles
:包含多个 Playbooks 和任务,以实现复杂的系统配置
Ad-Hoc
:命令:支持用户在命令行直接运行任务并获取结果
Playbook 和 Role 之间有什么区别?
- Playbook(剧本):
- 剧本是一个基于 YAML 格式的文件,用于定义一系列任务的执行顺序和配置参数。
- 剧本可以包含多个任务(tasks),并且可以在不同的主机或主机组上执行。
- 可以使用条件语句、循环结构、变量引用等功能来实现复杂的控制流程和配置。
- 主要用于定义执行流程和编排逻辑,方便管理和维护任务的执行顺序。
- Role(角色):
- 角色是一种可复用的任务和配置集合,用于实现特定功能或角色的服务器配置和部署。
- 角色包括了任务(tasks)、变量(vars)、模板(templates)、处理程序(handlers)和文件(files)等组件。
- 角色可以在不同的剧本中被引用和调用,提供了模块化和可重用的配置方式。
- 角色可以按照功能划分,例如数据库角色、Web 服务器角色等,使得配置管理更加清晰和可扩展。
区别总结:
功能
:Playbook 是用于定义执行流程和编排任务,而 Role 是一种可复用的任务和配置集合。架构
:Playbook 在整体上组织和调度任务的执行流程,而 Role 通过封装和组织任务、变量和文件等来实现模块化和可重用性。- Playbook 可以直接在剧本中编写任务和配置,而 Role 需要在独立的角色目录中定义任务和相关组件。
- Playbook 可以调用和引用多个角色,使得配置管理更加模块化和可扩展。
综上所述,Playbook 和 Role 在 Ansible 中起到了不同的作用,Playbook 主要用于组织和编排任务的执行流程,而 Role 则提供了一种模块化和可重用的方式来管理和组织服务器的配置和部署。
Ansible 的工作原理是什么?它如何与远程主机进行通信?
Ansible 是一种自动化工具,它的工作原理主要通过 SSH(Secure Shell)协议与远程主机进行通信。
下面是 Ansible 的工作流程:
- 主机清单(Inventory):控制节点上有一个主机清单文件,其中列出了需要管理的远程主机。这个清单文件可以是一个简单的文本文件,也可以是一个使用 INI 或 YAML 格式定义的复杂清单。
- Playbook:Playbook 是一个用 YAML 格式编写的文件,其中定义了 Ansible 的任务和配置。它描述了一系列的步骤,告诉 Ansible 在哪些主机上执行哪些操作。
- 连接远程主机:Ansible 使用 SSH 协议与远程主机建立连接。它通过 SSH 在远程主机上生成一个临时的 Python 脚本,并在远程主机上执行该脚本。这个临时脚本使用模块来完成具体的任务,并将执行结果返回给控制节点。
- 执行任务:Ansible 控制节点将 Playbook 中定义的任务分发给远程主机执行。它使用 SSH 多线程并行地在多台主机上执行任务,以提高效率。同时,Ansible 会收集和处理来自远程主机的执行结果。
- 状态管理:Ansible 通过检查远程主机上的当前状态来确定是否需要执行任务。如果远程主机已经处于所需状态,则 Ansible 可以跳过该主机上的操作,提高执行效率。
总的来说,Ansible 使用 SSH 协议实现与远程主机的通信,利用模块执行各种任务,并通过 Playbook 和主机清单文件进行配置和管理。这种方式使得 Ansible 简单易用且功能强大,成为自动化管理的首选工具之一。
Q: 简述Handlers与Notify关系作用
A:很多时候当我们某一个配置发生改变,我们需要重启服务,(比如httpd配置文件文件发生改变了)这时候就可以用到handlers
和notify
了;
(当发生改动时)notify actions
会在playbook
的每一个task结束时被触发,而且即使有多个不同task通知改动的发生,notify actions
知会被触发一次;比如多个resources
指出因为一个配置文件被改动,所以apache
需要重启,但是重新启动的操作知会被执行一次
[root@XXX ~]# cat XXX.yml
#用于安装httpd并配置启动
---
- hosts: XXX
remote_user: XXX
tasks:
- name: install httpd
yum: name=httpd state=installed
- name: config httpd
template: src=/root/httpd.conf dest=/etc/httpd/conf/httpd.conf
notify:
- restart httpd
- name: start httpd
service: name=httpd state=started
handlers:
- name: restart httpd
service: name=httpd state=restarted
#这里只要对httpd.conf配置文件作出了修改,修改后需要重启生效,在tasks中定义了restart httpd这个action,然后在handlers中引用上面tasks中定义的notify。
Q: Playbook核心元素
- Hosts 执行的远程主机列表
- Tasks 任务集
- Variables 内置变量或自定义变量在playbook中调用
- Templates 模板,即使用模板语法的文件,比如配置文件等
- Handlers 和notity结合使用,由特定条件触发的操作,满足条件方才执行,否则不执行
- tags 标签,指定某条任务执行,用于选择运行playbook中的部分代码。
Q: ansible-playbook常用选项
A:
--check or -C #只检测可能会发生的改变,但不真正执行操作
--list-hosts #列出运行任务的主机
--list-tags #列出playbook文件中定义所有的tags
--list-tasks #列出playbook文件中定义的所以任务集
--limit #主机列表 只针对主机列表中的某个主机或者某个组执行
-f #指定并发数,默认为5个
-t #指定tags运行,运行某一个或者多个tags。(前提playbook中有定义tags)
-v #显示过程 -vv -vvv更详细
模块和任务
Q: 什么是 Ansible 模块?可以举例说明几个常用的模块吗?
A: Ansible 模块是 Ansible 提供的可用于执行特定任务的代码单元。一些常用的模块包括:command
(执行命令)、shell
(执行 Shell 命令)、apt
(管理 APT 软件包)等。
Q: 如何在 Ansible Playbook 中定义任务?
A: 在 Playbook 中,任务通过使用 task
关键字来定义。例如:
- name: Install Apache
apt:
name: apache2
state: present
Q: Ansible 提供了哪些用于条件判断的控制结构?
A: Ansible 提供了多个条件判断的控制结构,包括 when
、failed_when
、changed_when
等。这些结构可用于根据条件决定任务是否执行、失败与否的判断以及变更是否发生等。
Ansible 变量和模板
Q: 什么是 Ansible 变量?有哪些不同的变量类型?
A: Ansible 变量是用于存储数据和配置信息的容器。不同的变量类型包括:全局变量、主机变量、组变量、Playbook 变量、角色变量等。
Q: 如何在 Ansible Playbook 中定义和使用变量?
A: 在 Playbook 中,可以使用 vars
关键字定义变量。变量可以通过 {{ 变量名 }}
的方式在任务中引用。例如:
vars:
my_var: "Hello, World!"
tasks:
- name: Print variable
debug:
msg: "{{ my_var }}"
Q: Ansible 如何使用模板文件来生成配置文件?
A: Ansible 使用 template
模块来处理模板文件。可以在 Playbook 中使用 template
模块,并指定模板文件和生成的目标文件路径。在模板文件中,可以使用 Jinja2 模板语言来插入变量和执行逻辑操作。例如:
- name: Generate configuration file
template:
src: templates/myconfig.j2
dest: /etc/myapp/myconfig.conf
在 myconfig.j2
模板文件中,您可以使用变量和控制结构来生成配置文件的内容,如:
jinja2Copy code
# Configuration file
{{ my_variable }}
{% if is_production %}
mode = production
{% else %}
mode = development
{% endif %}
Ansible 角色和剧本组织
Q: 什么是 Ansible 角色?它有什么优点?
A: Ansible 角色是一种组织和复用 Playbook 的结构化方式。它包含了任务、变量和文件等的目录结构。使用角色可以提高代码的可维护性、重用性和可读性,并简化 Playbook 的编写过程。
Q: Ansible 角色的目录结构是怎样的?
A: Ansible 角色包含以下目录和文件:
roles/
myrole/
tasks/
main.yml
handlers/
main.yml
templates/
files/
vars/
main.yml
defaults/
main.yml
meta/
main.yml
Q: 如何在 Ansible Playbook 中使用角色?
A: 在 Playbook 中,可以使用 roles
关键字指定要使用的角色。例如:
- name: Use myrole
hosts: servers
roles:
- myrole
这将使用名为 myrole
的角色来执行 Playbook。