一、Ansible自动化运维介绍:
1.1 Ansible介绍:
Ansible是一种IT自动化工具。它可以配置系统,部署软件以及协调更高级的IT任务,例如:持续部署,滚动更新。Ansible适用于管理企业IT基础设施,从具有少数主机的小规模到数千个实例的企业环境。Ansible也是一种简单的自动化语言,可以完美地描述IT应用程序基础结构。
1.2 Ansible特点:
- 简单:减少学习成本;
- 强大:协调应用程序生命周期;
- 无代理:无需在被监控的服务器节点上安装任何代理,只要机器间可以通过ssh通信即可,可靠和安全;
1.3 Ansible安装:
yum install ansible -y
如果提示'没有可用软件包ansible',表示系统yum源中已经没有对应的安装了,需要安装先epel在安装ansible:
yum install -y epel-release
查看安装的ansible版本信息:
ansible --version # 目前CentOS7下最新版本为2.9.18
如果需要更新ansible,请执行以下命令:
yum upgrade ansible
1.4 Ansible架构图:
- Inventory:Ansible管理的主机清单,包括IP地址、SSH端口、账号、密码等。
- Modules:任务均由模块完成,也可以自定义模块,例如经常使用的脚本。
- Plugins:使用插件增加Ansible核心功能,自身提供了很多插件,也可以自定义插件。
- Playbooks:“剧本”,Ansible核心功能,模块化定义一系列任务,供外部统一调用。
1.5 配置Ansible管理的主机清单:
1、查看ansible软件包安装的位置:
rpm -ql ansible | more
2、配置ansible管理的主机清单:
vim /etc/ansible/hosts
[webservers]
192.168.1.95
192.168.1.96
3、测试与主机清单是否能连通:
ansible all -m ping -uroot -k # 通过ssh用户名、密码方式连接所有分组主机
ansible webservers -m ping -uroot -k # 通过ssh用户名、密码方式连接webservers分组主机
4、Ansible连接主机认证(Ansible是基于SSH进行通信的):
SSH密码认证:
vim /etc/ansible/hosts
[webservers]
192.168.1.95 ansible_ssh_user=root ansible_ssh_pass="mingjis41"
192.168.1.96 ansible_ssh_user=root ansible_ssh_pass="mingjis41"
SSH密钥对认证:
# 生成密码
ssh-keygen
# 将公钥拷贝到目标服务器上,每次通信通过私钥进行免登录认证
ssh-copy-id root@192.168.1.95
ssh-copy-id root@192.168.1.96
# 编写主机清单
vim /etc/ansible/hosts
[webservers]
192.168.1.95 ansible_ssh_user=root ansible_ssh_key=/root/.ssh/id_rsa
192.168.1.96 ansible_ssh_user=root ansible_ssh_key=/root/.ssh/id_rsa
# 也可以ansible.cfg在配置文件中指定:
[defaults]
private_key_file = /root/.ssh/id_rsa # 默认路径
测试与主机清单是否能连通:
ansible all -m ping # 连接所有分组主机
ansible webservers -m ping # 连接webservers分组主机
1.6 Ansible命令行参数:
选项 | 描述 |
-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 | 提权密码 |
1.7 常用模块
Ansible模块有两种运行方式:yaml文件方式执行 | 命令行方式执行;
ansible-doc –l # 查看所有模块
ansible-doc –s [模块名称] # 查看模块文档
1、shell模块——执行shell脚本:
通过Playbooks方式运行shell模块:
vim shell.yaml
- hosts: webservers # 指定主机组信息
remote_user: root # 指定用户名
gather_facts: false # 是否需要获取目标主机属性信息,如:IP、网卡等
tasks:
- name: test shell
shell:
cmd: ls -al # 查看当前目录下的文件信息
chdir: /usr/local # 更改目录
ansible-playbook -i /etc/ansible/hosts shell.yaml
通过命令行方式运行shell模块:
# 通过命令行的方式使用ansible shell模块
ansible * -m shell -a "ls" # 在主机清单中的所有机器上执行shell操作,一般慎用
ansible webservers -m shell -a "ls" # 在主机清单中webservers组中的所有机器上执行shell操作
ansible 192.168.1.95 -m shell -a "ls" # 在主机清单中指定ip机器上执行shell操作
ansible 192.168.1.95 -m shell -a "ls /root ; ls /tmp"
# -m : 表示model,模块的意思.
# -a : 表示命令参数.
# ls : 表示具体在目标主机上执行的命令.
2、copy模块——拷贝文件或目录:
通过Playbooks方式运行copy模块:
vim copy.yaml
- hosts: webservers # 指定主机组信息
remote_user: root # 指定用户名
gather_facts: false # 是否需要获取目标主机属性信息,如:IP、网卡等
tasks:
- name: cp file
cppy:
src: /usr/local/dev/aaaa.txt # 文件所在路径
dest: /usr/local/dev/aaaa.txt # 复制到目标主机的具体路径
owner: root # 文件所有者,可省略
group: root # 文件所在组,可省略
mode: u=rw,g=r,o=r # 文件权限
backup: yes # 如果目标主机上有此文件且文件内容不同,则备份主机上的旧文件
ansible-playbook -i /etc/ansible/hosts copy.yaml
通过命令行方式运行copy模块:
# 创建aaaa文件
touch /root/aaaa
# 将aaaa文件拷贝到ansible主机抢单中的指定目标及其上
ansible 192.168.1.95 -m copy -a "src=/root/aaaa dest=/root/aaaa"
# src : 表示源文件位置.
# dest:表示拷贝到目标主机上的指定位置.
3、file模块——管理文件和文件属性:
通过Playbooks方式运行file模块:
vim file.yaml
- hosts: webservers # 指定主机组信息
remote_user: root # 指定用户名
gather_facts: false # 是否需要获取目标主机属性信息,如:IP、网卡等
tasks:
- name: create directory
file:
path: /usr/local/dev/test # 文件夹所在路径
state: directory # 行为状态
mode: '0755' # 模式
ansible-playbook -i /etc/ansible/hosts file.yaml
通过命令行方式运行file模块:
ansible 192.168.1.95 -m file -a "path=/root/aaaa state=absent"
# path: 表示文件位置.
# state: 表示行为状态,absent表示删除文件或目录 | directory表示创建目录
4、yum模块——管理软件包:
通过Playbooks方式运行yum模块:
vim yum.yaml
- hosts: webservers # 指定主机组信息
remote_user: root # 指定用户名
gather_facts: false # 是否需要获取目标主机属性信息,如:IP、网卡等
tasks:
- name: install nginx # 任务名称,同一个yaml文件中可以有多个-name(任务)
yum:
name: http://nginx.org/packages/rhel/7/x86_64/RPMS/nginx-1.14.0-1.el7_4.ngx.x86_64.rpm
state: latest # 行为状态
ansible-playbook -i /etc/ansible/hosts yum.yaml
通过命令行方式运行yum模块:
ansible 192.168.1.95 -m yum -a "name=epel-release state=present" # 安装epel-release软件包
ansible 192.168.1.95 -m yum -a "name=* state=latest" # 更新所有软件包
ansible 192.168.1.95 -m yum -a "name=http://xxxx/xxxx.rpm state=present" # 安装网络上的rpm包
ansible 192.168.1.95 -m yum -a "name=/usr/local/xxxx.rpm state=present" # 安装本地rpm包
# name :表示软件包名称.
# state:表示行为状态,absent:表示卸载 | present表示安装 | latest表示安装最新包.
5、systemd模块——管理服务(CentOS7使用systemd管理服务):
通过Playbooks方式运行systemd模块:
vim systemd.yaml
- hosts: webservers # 指定主机组信息
remote_user: root # 指定用户名
gather_facts: false # 是否需要获取目标主机属性信息,如:IP、网卡等
tasks:
- name: run nginx # 任务名称
systemd:
name: nginx # 服务名称
state: started # 行为状态
enabled: yes # 开启自启动
ansible-playbook -i /etc/ansible/hosts systemd.yaml
通过命令行方式运行systemd模块:
ansible 192.168.1.95 -m systemd -a "name=firewallk state=restarted enabled=yes"
# name :表示服务名称.
# state:表示行为状态,started表示启动服务 | stopped表示停止服务 | restarted表示重启服务.
# enabled:表示是否开机自启动,yes表示开机自启动.
6、unarchive模块——解压操作:
通过Playbooks方式运行unarchive模块:
vim unarchive.yaml
- hosts: webservers # 指定主机组信息
remote_user: root # 指定用户名
gather_facts: false # 是否需要获取目标主机属性信息,如:IP、网卡等
tasks:
- name: unarchive file # 任务名称
unarchive:
src: /usr/local/aaaa.tar # 压缩包所在路径
dest: /usr/local/ # 家崖后的路径
ansible-playbook -i /etc/ansible/hosts unarchive.yaml
通过命令行方式运行unarchive模块:
ansible 192.168.1.95 -m unarchive -a "src=/usr/local/aaaa.tar.gz dest=/tmp"
# src :表示压缩包的路径.
# dest:解压后的路径.
7、debug模块——调试操作:
通过Playbooks方式运行debug模块:
vim debug.yaml
- hosts: webservers # 指定主机组信息
remote_user: root # 指定用户名
gather_facts: false # 是否需要获取目标主机属性信息,如:IP、网卡等
tasks:
- name: debug test file # 任务名称
debug:
var: hostvars[inventory_hostname]
ansible-playbook -i /etc/ansible/hosts debug.yaml
通过命令行方式运行debug模块:
ansible 192.168.1.95 -m debug -a "var=hostvars"
# var:表示打印指定主机默认的变量.
1.5 Playbook:
PlayBooks是Ansible的配置、部署和编排语言。它可以描述您希望在远程目标及其做哪些事情或者描述IT流程中一系列步骤。使用易读的YAML格式组织PlayBook文件。如果Ansible模块是您工作中的工具,那么Playbook就是您的使用说明书,而您的主机资产文件就是您的原材料。与命令行任务执行模式相比,Playbooks使用ansible是一种完全不同的方式,并且功能特别强大。
1、在PlayBooks YAML文件中指定主机组和用户:
- hosts: webservers # 指定主机组信息
remote_user: zjg # 指定用户名
become: yes # 提权,加上sudo权限
become_user: root # 提权的用户
2、在PlayBooks中定义变量:
变量是应用于多个主机的便捷方式; 实际在主机执行之前,变量会对每个主机添加,然后在执行中引用。
在PlayBooks中,可以通过以下五种方式定义变量,如下:
- 通过命令行参数定义变量:
-e VAR=VALUE
ansible webservers -m debug -a "var=abc" -e abc=123 # 设置变量abc=123
- 在主机清单文件中定义组变量(Ansible中的首选做法是不将变量存储在主机清单中):
[webservers]
192.168.1.95
192.168.1.96
[webservers:vars]
ansible_ssh_user=root ansible_ssh_pass="mingjis41" # 针对webservers主机组定义变量
[all:vars]
role=wb1 # 针对所有主机组定义变量
- 通过单独的文件定义变量:
group_vars:该目录下存放的是组变量文件,与ansible.cfg同级;
group_vars/all.yml:表示所有主机有效,等同于[all:vars]
grous_vars/webservers.yaml:表示webservers组主机有效,等同于[webservers:vars]
# vim /etc/ansible/group_vars/all.yml
work_dir: /data
# vim /etc/ansible/group_vars/webservers.yml
nginx_port: 80
- 在Playbook YAML中定义变量:
- hosts: webservers
vars:
http_port: 80
server_name: www.ctnrs.com
- Register注册变量:
- shell: # 使用shell模块
netstat -antp | grep 80 # shell脚本
register: result # 将shell脚本的执行结果注册到变量result中
- debug: # 使用debug模块
var: result # 输出result变量信息
3、PlayBooks YAML文件中的任务列表:
每个PlayBooks YAML文件中包含一系列任务。这些任务按照顺序执行,所有主机都会执行相同的任务指令。
- hosts: webservers # 指定主机组信息
remote_user: root # 指定用户名
gather_facts: false # 是否需要获取目标主机属性信息,如:IP、网卡等
tasks:
- name: inatall nginx
yum:
name: nginx
state: latest
4、PlayBooks语法检查与调试:
语法检查,测试执行但不会再目标主机实际执行:
ansible-playbook -i /etc/ansible/hosts -C playbook.yaml
# 等同于
ansible-playbook -i /etc/ansible/hosts --check playbook.yaml
debug模块在执行期间打印语句,对于调试变量或表达式,而不必停止PlayBook。与'when:'指令一起调试更佳。
- hosts: webservers # 指定主机组信息
remote_user: root # 指定用户名
gather_facts: false # 是否需要获取目标主机属性信息,如:IP、网卡等
tasks:
- name: debug test
shell:
netstat -antp | grep 80 # shell模块的命令
register: result # 定义result变量,变量值就是shell模块的命令执行结果
debug:
msg: "{{result}}" # 打印result变量信息
5、PlayBooks任务控制:
如果有一个多任务的PlayBooks文件,可以通过tags标签针对性的执行文件中的特定任务:
vim nginx.yaml
- hosts: webservers # 指定主机组信息
remote_user: root # 指定用户名
gather_facts: false # 是否需要获取目标主机属性信息,如:IP、网卡等
tasks:
- name: install nginx
yum: pkg=nginx state=latest
tags: install
- name: write nginx conf
template: src=/srv/httpd.j2 dest=/etc/nginx/nginx.conf
tags: config
使用:
# 运行install任务
ansible-playbook -i /etc/ansible/hosts nginx.yml --tags "install"
# 运行install、config任务
ansible-playbook -i /etc/ansible/hosts nginx.yml nginx.yml --tags "install,config"
# 跳过install任务
ansible-playbook -i /etc/ansible/hosts nginx.yml nginx.yml --skip-tags "install"
6、PlayBooks流程控制:
条件判断:
- hosts: webservers # 指定主机组信息
remote_user: root # 指定用户名
gather_facts: false # 是否需要获取目标主机属性信息,如:IP、网卡等
tasks:
- name: test shell
shell:
echo 123
register: result
- name: test debug
debug:
msg: "{{result}}"
# 当目标主机的ip=192.168.1.95时才执行任务
when: result == '123'
循环:
- hosts: webservers # 指定主机组信息
remote_user: root # 指定用户名
gather_facts: false # 是否需要获取目标主机属性信息,如:IP、网卡等
tasks:
- name: batch create user
user:
name: {{ item }} # item的值就是with_items中定义的多个值
state: present
groups: wheel
with_items: # 定义循环的变量
- testuser1
- testuser2
- name: unarchive file
copy:
src: {{ item }}
dest: /tmp
with_fileglob:
- "/tmp/*.txt" # 循环遍历/tmp目录下所有后缀为txt的文件
常用循环语句:
语句 | 描述 |
with_items | 标准循环 |
with_fileglob | 遍历目录文件 |
with_dict | 遍历字典 |
7、PlayBooks模板:
- hosts: webservers # 指定主机组信息
remote_user: root # 指定用户名
gather_facts: false # 是否需要获取目标主机属性信息,如:IP、网卡等
vars:
domain: "www.ctnrs.com" # 定义domain变量
tasks:
- name: write nginx conf
template:
src: /srv/server.j2
dest: /etc/nginx/conf.d/server.conf
# server.j2
{% set domain_name = domain %}
server {
listen 80;
server_name {{ domain_name }}; # 引用jinja中定义的变量
location / {
root /usr/share/html;
}
}
# server.j2
server {
listen 80;
server_name {{ domain }}; # 引用ansible playbooks中定义的变量
location / {
root /usr/share/html;
}
}
在jinja中定义变量:
{% set local_ip = inventory_hostname %}
条件和循环:
# server.j2
upstream web {
{% for host in groups['webservers'] %}
# hostvars表示主机组中的变量
# host表示迭代值
# inventory_hostname表示主机名,由于主机清单文件中主机名是ip,这里我们拿到的也是ip
server {{ hostvars[host].inventory_hostname }}
{% endfor %}
}
server {
listen 80;
server_name {{ domain }}; # 引用ansible playbooks中定义的变量
location / {
root /usr/share/html;
}
}
{% set list=['one','two','three'] %}
{% for i in list %}
{% if i == 'two' %}
-> two
{% elif loop.index == 3 %}
--> 3
{% else %}
{{ i }}
{% endif %}
{% endfor %}
1.6 Ansible Roles模块任务:
Roles是基于已知文件结构自动加载某些变量文件,任务和处理程序的方法。
按角色对内容进行分组,适合构建复杂的部署环境。
1、定义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
-为此角色定义一些元数据。请参阅下面的更多细节。
2、Roles的示例:
mkdir roles
mkdir /roles/nginx
mkdir /roles/nginx/tasks
mkdir /roles/nginx/templates
mkdir /roles/nginx/files
cd /roles/nginx
tree .
tasks/main.yml
文件中包含需要执行的任务清单:
注意:main.yaml
文件中的任务只要从-name开始即可,tags
不在此文件定义。
vim /tasks/main.yaml
- name: write nginx conf
template:
src: nginx.conf # 默认加载templates目录下的指定文件
dest: /etc/nginx/conf.d
templates/
目录包含任务的相关模板信息:
vim /templates/nginx.conf
server {
listen 80;
server_name www.baidu.com; # 引用ansible playbooks中定义的变量
location / {
root /usr/share/html;
}
}
:wq!
tree .
site.yaml
是模块管理的入口文件:
vim site.yaml
- hosts: webservers
gather_facts: false
-name: install nginx
roles: # 启用入口可以控制哪些模块
- nginx
-name: install php
roles:
- php
tags: nginx # 启用nginx模块
执行任务:
ansible-playbook -i /etc/ansible/hosts site.yaml
3、使用角色:
# 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
3、角色控制
- name: 0.系统初始化
gather_facts: false
hosts: all
roles:
- common
tags: common
1.7 K8s架构图:
1、单Master:
2、多Master: