第2章 Ansible入门

2.1 安装Ansible

以CentOS为例:

2.1.1 在管理员的电脑安装

  1. 安装Ansible软件
yum install epel-release -y
yum install ansible -y
  1. 配置Ansible管理节点到主机的连接
#生成密钥
ssh-keygen
#复制密钥的远程主机上
ssh-copy-id remoteuser@remoteserver
#SSH的时候不会提示是否保存密钥
ssh-keyscan remote_servers >> ~/.ssh/known_hosts

2.1.2 被管理的远程主机

啥也不用做,只需要保证SSH服务是启动的,并且Python版本大于2.4即可。

2.2 Ansible管理哪些主机

2.2.1 什么是主机目录

主机目录(Host Inventory,又称为主机清单)是配置文件,用来告诉Ansible需要管理哪些主机,并且把这些主机按需分类。

2.2.2 主机目录配置文件

默认的文件是: /etc/ansible/hosts .可以修改为其他文件

2.3 Ansible用命令管理主机

Ansible提供了一个命令行工具,官方叫做 Ad-Hoc Commands。

  1. Ansible命令的格式
ansible  [options]
  1. 示例
#检查所有的远程主机,是否以 "pangcm" 用户创建了Ansible管理主机可以访问的环境
ansible all -m ping -u pangcm

#执行命令
ansible all -a "/bin/echo hello"

#复制文件
ansible web -m copy -a "src=/etc/hosts dest=/tmp/hosts"

#安装包
ansible web -m yum -a "name=acme state=present"

#添加用户
ansible all -m user -a "name=foo password="

#并行执行
ansible lb -a "/sbin/reboot" -f 10

#查看远程主机的全部系统信息
ansible all -m setup

2.4 Ansible用脚本管理主机

为了避免重复输入命令,Ansible提供了脚本功能。Ansible脚本的名字叫做Playboo,使用的YAML格式,文件以yml活yaml为后缀。

2.4.1 执行脚本Playboook的方法

ansible-playbook deploy.yml

2.4.2 Playbook 的例子

Playbook 包含了几个关键字,每个关键字的含义如下。

  • hosts: 某主机的IP,或者主机名,或者关键字 all.
  • remote_user: 以某个用户身份执行。
  • vars: 变量
  • tasks: Playbook的核心,定义顺序执行的动作Action。每个Action调用一个Ansible模块。
    • action 语法:
    module: module_parameter=module_value
    
    • 常用的模块有 yum、copy、template等,模块在Ansible中的作用,相当与bash脚本中的yum、copy这样命令的作用。
  • handers: Playbook的Even处理操作,有且仅有被Action触发时才会执行。但是多次出发只执行一次,并按照声明的顺序执行。下面是一个安装Apache的示例:
---
- hosts: web
  vars:
    http_port:80
  remote_user: root
  tasks:
  - name: ensure apache is at the lastest version
    yum: pkg=httpd state=latest

  - name: Write the configuration file
    template: src=template/httpd.conf.j2 dest=/etc/httpd/conf/httpd.conf
    notify:
    - restart apache

  - name: ensure apache is running
    service: name=httpd state=started

  handlers:
  - name: restart apache
    service: name=httpd state=restarted

2.4.3 Play和Playbook

在一个Playbook文件中,针对每一组主机的所有操作就是一个Play,一般情况下一个Playbook只包含一个Play,但是也而已包含多个。

2.5 Ansible模块

2.5.1 什么是Ansible模块

类别于shell,Ansible中的模块就好比shell中的命令。shell中的命令可以带参数,Ansible中的模块也可以带参数。

2.5.2 在命令行中使用模块

在命令行中:

  • -m 后面接调用模块的名字
  • -n 后面接调用模块的参数

如:

ansible all -m copy -a "src=/etc/hosts dest=/tmp/hosts"

2.5.3 在Playbook中使用模块

在Playbook脚本中,tasks中每一个Action都是对模块的一次调用。在每个Action中:

  • 冒号前面的是模块的名字
  • 冒号后面是调用模块的参数

2.5.4 Ansible模块的特点

  • 像Linux中的命令一样,Ansible的模块既可以在命令行中调用,也可以在Ansible脚本Playbook中调用。
  • 每个模块的参数和状态判断,都取决于该模块的具体实现,所以在使用它们之前需要查阅该模块的文档。
  • 可以通过文档查看具体的用法
  • 通过命令 ansible-doc 也可以查看模块的用法
  • Ansible提供一些常用功能的模块,同时Ansible也提供API,让用户可以自己写模块,使用的编程语言是Python。

2.5.5 常用的模块

下面介绍一些常用的模块

  1. 调试和测试类的模块

    • ping: ping远程主机,如果返回pong,则意味着能够通过Ansible连接
    • debug: 用于调试的模块,只是打印一些消息,类比Linux的ehco。
  2. 文件类的模块

    • copy: 从本地复制文件到远程节点
    • template: 从本地复制文件到远程节点,并进行变量的替换
    • file: 设置文件属性
  3. Linux 上常用的操作

    • user: 管理用户账户
    • yum: Red Hat 系Linux上的包管理
    • service: 管理服务
    • firewall: 管理防火墙中的服务和端口
  4. 执行shell命令

    • shell:在节点上执行shell命令,支持 $HOME、 "|" 和 "&" 等。
    • command: 在节点上执行shell命令,不支持 $HOME、 "|" 和 "&" 等。

针对上面提到的常用模块,下面针对几个做下具体的介绍

  1. debug 模块
    • 通过参数 msg 定义打印的字符串,当然也可以打印变量
    - debug:
      msg: "I can echo vars {{ inventory_hostname }}"
    
    • 通过参数 var 定义需要打印的变量,后面直接跟变量的名称
    - debug:
      var: inventory_hostname
    

msg 和 var 都能输出变量,但是 msg输出变量时需要显式地表示变量才行,也就是使用 "{{}}" 标注,如果shell中的 "$()" 。而var则不需要。

  1. copy 模块
    需要注意的是,copy模块在复制前会先比较文件的 checksum,如果相同则不复制,返回状态OK;如果不同才复制,返回状态 changed.

    • 设置文件权限
      利用mode 设置权限可以是数字,也可以时符号的形式,如"u=rw,g=r,o=r"
    - copy: "src=/etc/hosts dest=/tmp/hosts owner=foo group:foo mode=0644"
    
    • 备份节点上原来的文件
      当backup参数为yes的时候,如果发生了复制操作,那么会先复制目标节点上的源文件。当两个文件相同时,不再进行复制操作。
    - copy:  "src=/etc/hosts dest=/tmp/hosts backup=yes"
    
    • 复制后的验证操作
      validate 参数接需要验证的命令。一般需要验证复制后的文件,所以 %s 都可以指代复制后的文件。当copy模块中加入 validate 参数后,不仅需要成功复制文件,还需要 validate命令返回成功的状态,整个模块的执行才算成功。常见的场景如 visudo。
    - copy:
      src: /tmp/sudoers
      dest: /etc/sudoders
      validate: 'visudo -cf %s'
    
  2. template 模块
    使用的方法和copy几乎一模一样,不同的是template可以携带变量。也就是说能够进行变量的替换,起到模版的用途。这里只需要知道变量的使用需要使用 "{{}}" 即可,后面会介绍jinja2的具体用法。常见的场景如nginx配置文件的复制替换。

  1. file模块
    file模块可以用来设置远程主机的文件、软连接和文件夹的权限,也可以用来创建和删除他们。如下所示
- name: "改变文件的权限"
  file: path=/etc/foo.conf mode=0644

- name: "创建文件的软链接"
  file: src=/tmp/hosts dest=/tmp/hosts_symlink state=link

- name: "创建一个新文件"
  file:
    path: /etc/foo.conf
    state: touch
    mode: 0644
 
- name: "创建一个目录"
  file:
    path: /tmp/test
    state: directory
    mode: 0755
  1. user 模块
    user 模块可以增、删、改Linux远程节点的用户账户,并为其设置账户的属性。如下
---

- hosts: remote_host
  tasks:
  - names: "增加用户"
    user: "name=johnd comment='John Doe' uid=1040 group=admin"
  
  - name: "创建用户james,并将其添加到两个group中"
    user: "name=james shell=/bin/bash groups=admin,developers append=yes"

  - name: "删除账户"
    user: "name=johnd state=absent remove=yes"

  - name: "修改账户的属性,创建SSH密钥,并放在 ~/.ssh/id_rsa 中 "
    user:
      name: jsmith
      generate_ssh_key: yes
      ssh_key_file: .ssh/id_rsa
  1. yum 模块
    yum模块用来管理RedHat系的安装包的,Red Hat8使用了dnf来管理包,如果远程主机是版本8的话,则需要使用dnf模块。
- name: "从yum源上安装最新的httpd包,已经有的话则会更新"
  yum: "name=httpd state=latest"

- name: "安装指定版本的包"
  yum: "name=httpd-2.2.29-1.4.amzn1 state=present"

- name: "删除httpd包"
  yum: "name=httpd state=absent"

- name: "安装一组包"
  yum: 
    name: "@Development tools"
    state: present
    
- name: "本地安装包"
  yum: "name=/tmp/httpd.rpm state=present"
  1. service 服务管理模块
    改模块用来管理远程节点上的服务,比如httpd、sshd等。
- name: "开启服务"
  service: "name=httpd state=started"

- name: "重启服务"
  service: "name=httpd state=restarted"

- name: "设置开机启动"
  service: "name=httpd enabled=yes"

- name: "启动网络服务下的接口 eth0"
  service: "name=network state=restarted args=eth0"
  1. firewalld 模块
    firewalld 模块为某服务和端口添加firewalld规则。firewalld中有正在运行的规则和永久规则,firewalld模块都支持。
- name: "为服务添加firewalld规则"
  firewalld: "zone=dmz service=https permanent=true state=enabled"

- name: "为端口号添加firewalld规则"
  firewalld: "port=8081/tcp permanent=true state=disabled"

- name: "其他复杂的firewalld规则"
  firewalld: "source=192.168.2.0/24 zone=internal state=enabled"

- name: "其他复杂的firewalld规则"
  firewalld: "zone=trusted interface=eth2 permanent=true state=enabled"
  1. shell 模块
    如果能通过其他的Ansible模块实现的尽量不要使用shell模块来实现,原因是shell模块不会对执行的状态进行判断,也就是不存在该模块不存在幂等性。

shell模块支持 $HOME、"<"、">"、"|"、";" 和 "&" 。

- name: "test $home"
  shell: echo "test1" > ~/tmp/test1

- name: "test &&"
  shell: service jboss start && chkconfig jboss on

- name: "支持调用脚本"
  shell: "somescript.sh >> somelog.txt"

- name: "可以指定工作目录"
  shell: "somescript.sh >> somelog.txt"
  args:
    chdir: somedir/

- name: "指定工作目录,并且仅在文件somelog.txt 不存在时执行命令"
  shell: "somescript.sh >> somelog.txt"
  args:
    chdir: somedir/
  creates: somelog.txt 
  1. command 模块
    功能和shell类似,但是不支持 $HOME、"<"、">"、"|"、";" 和 "&" 等操作。和shell不同的地方是能够传入参数。
- name: "比shell模块多一个传参的方式"
  command: /usr/bin/make_database.sh arg1 arg2 creates=/path/database

你可能感兴趣的:(第2章 Ansible入门)