knowledge-base

我的知识库 / DevOps / Ansible

Ansible

介绍

特点

  1. 自动化引擎,实现管理配置,应用部署,服务编排及其他各种服务器管理需求;
  2. 使用简单,具有客户端的特点;
  3. 基于ssh实现配置管理;
  4. 依赖python;
  5. 功能强大,支持云服务操作。

安装

​ 由于Ansible使用Python开发,所以可以直接使用pip安装

pip install ansible

​ 也可以使用yum或apt-get安装

yum install ansible -y
apt-get install ansible -y

ansible --version

​ 只需要在Control Node上安装即可。

主要概念

Ansible配置

​ 配置文件位置:/etc/ansible/ansible.cfg,为ini格式文件。

配置示例

​ inventory:主机清单配置文件位置,在使用Ansible命令时,也开始-i <path>指定;

​ host_key_checking:当know_hosts中不存在的主机(即尚未访问过的主机,是否需要输入密钥);

​ become_user:sudo用户;

image-20191126091436329

主机清单(Inventory)

​ 在一个ini或yaml文件中管理Managed nodes清单,默认安装ansible后,在/etc/ansible/hosts文件中管理(后文统一称之为主机清单文件),一般是将maneged nodes的ip address或host name等信息存储到主机清单文件中。

Formats

​ 主机清单文件格式兼容两种:

Hosts

​ 配置需要管理的主机host name或ip address。

Group

​ 如果想管理某一批主机,可以将这多个host配置到统一个group下。方便对这组主机的批量管理。

[webserver]
webserver01.com
webserver02.com

[dbserver]
dbserver01.com
dbserver02.com

Group变量

作用在group上的变量。

[webserver]
webserver01.com

[webserver:vars]
ansible_ssh_user=ubuntu

Nested group

​ 一个组包含其他组。

[allserver:children]
webserver
dbserver

Inventory内置参数

参数名 参数说明
ansible_ssh_host 定义主机的ssh地址
ansible_ssh_port 定义主机的ssh端口
ansible_ssh_user 定义主机的ssh认证用户
ansible_ssh_pass 定义主机的ssh认证密码
ansible_sudo 定义主机的sudo用户
ansible_sudo_pass 定义主机的sudo密码
ansible_sudo_exe 定义主机的sudo路径
ansible_connection 定义主机连接方式;与主机的连接类型.比如:local,ssh或者paramiko;Ansible 1.2以前默认使用paramiko。1.2以后的版本默认使用‘smart’,‘smart’方式会根据是否支持ControlPersist,来判断ssh方式是否可行
ansible_ssh_private_key_file 定义主机私钥文件
ansible_shell_type 定义主机shell类型
ansible_python_interpreter 定义主机python解释器路径
[webserver]
webserver01.com
webserver02.com

[webserver:vars]
ansible_ssh_private_key_file=~/singapore.pem

模块(Modules)

​ Ansible功能的单元,一个Ansible功能对应有一个Module。

常用模块

file

远程服务器上的文件进行操作。创建删除文件,修改文件权限等。

ansible servers -m file -a 'path=~/temp state=directory'  # 创建目录
ansible servers -m file -a 'path=~/temp/test1.txt state=touch'  # 创建文件

copy

将Control Node上的目录或文件拷贝至Managed Nodes。

touch test2.txt
ansible servers -m copy -a 'src=test2.txt dest=~/temp/test2.txt'  # 拷贝文件到服务器

command

​ 直接要求主机清单执行命令。

ansible servers -m command -a "touch ~/temp/test3.txt"
ansible servers -m command -a "sudo apt update"
ansible servers -m command -a "sudo apt install nginx -y"
ansible servers -m command -a "sudo apt autoremove nginx -y"
不支持shell变量,如$NAME, <,>,&,

shell

​ 可以先编辑shell脚本,然后要求主机清单执行shell脚本里的命令。

- name: Execute the command in remote shell; stdout goes to the specified file on the remote.
  shell: somescript.sh >> somelog.txt

- name: Change the working directory to somedir/ before executing the command.
  shell: somescript.sh >> somelog.txt
  args:
    chdir: somedir/

注意:shell脚本必须有可执行的权限

    - name: 'chmod shell'
      command: chmod 777 somedir/somescript.sh

apt

​ ubuntu/debian 包、应用管理。

update_cache : yes/no,默认no,操作之前是否 apt-get update

state

autoremove :yes/no,默认no,移除依赖

autoclean :yes/no,默认no,移除缓存

ansible servers -m apt -a "name=nginx update_cache=yes" -b

# append to playbook
- name: Install nginx
  apt:
    name: nginx
    state: latest
    update_cache: yes
    
ansible servers -m apt -a "name=nginx state=absent autoremove=yes autoclean=yes" -b

yum

​ CentOs管理程序包。

service

​ 管理服务的模块,用来启动、停止、重启服务。

enabled :yes/no,默认no.是否开机启动。

name :服务名

state

sleep :如果是restarted,需要等待多长秒后再重启 如:10,等待10秒后重启

ansible servers -m service -a "name=nginx state=started"

# playbook
- name: Start service nginx, if not started
  service:
    name: nginx
    state: started
    
ansible servers -m service -a "name=nginx state=stoped"

unarchive

​ 解压缩。

git

任务(Tasks)

​ Ansible执行的单元,一般放在Playbook中,多个Task一起执行,使用方便,可复用。

​ 定义方式:

-name: names
  module: action 
---
- name: ansible-playbook demo
  hosts: servers
  tasks:
    - name: create temp dir
      file:
        path: ~/temp
        state: directory

    - name: create test1.txt
      file:
        path: ~/temp/test1.txt
        state: touch

    - name: copy test2.txt
      copy:
        src: test2.txt
        dest: ~/temp/test2.txt

    - name: copy test.sh
      copy:
        src: test.sh
        dest: ~/temp/test.sh 

    - name: 'chmod shell'
      command: chmod 777 ~/temp/test.sh

    - name: exec shell
      shell: ~/temp/test.sh
      args:
        executable: /bin/bash

Ansible用法

ansible命令

ansible <hosts> -m <module_name> -a <arguments> -i <hosts_path>

hosts:

module_name:例如ping,command,apt的任务模块

arguments: 执行module的参数,例如 ansible -m command -a "touch hello.txt"

hosts_path:主机清单文件位置,默认/etc/ansible/etc,也可以自己指定

Ansible命令参数

[-h]  # 帮助
[--version]  # Ansible版本
[-v]  # verbost
[-b]  # sudo运行,可以以sudo权限运行
[--become-method BECOME_METHOD]
[--become-user BECOME_USER] 
[-K]  # 提示输入sudo密码,当不是NOPASSWD模式时使用
[-i INVENTORY]  # 指定hosts文件路径,默认default=/etc/ansible/hosts
[--list-hosts] # 打印有主机列表
[-o]  # 压缩输出,摘要输出
[-t TREE] 
[-k] # 提示输入ssh登录密码。当使用密码验证的时候用
[--private-key PRIVATE_KEY_FILE]  # ssh连接的私钥文件位置
[-u REMOTE_USER] # ssh连接的用户名,默认用root,ansible.cfg中可以配置
[-c CONNECTION]  # 连接类型(default=smart),例如还有local
[-T TIMEOUT] # 超时限制
[--ask-vault-pass | --vault-password-file VAULT_PASSWORD_FILES]
[-f FORKS]   # fork多少个进程并发处理,默认为5个
[-M MODULE_PATH]  # 模块的执行文件位置,一般用于扩展模块
[--playbook-dir BASEDIR]
[-a MODULE_ARGS]  # 模块的参数
[-m MODULE_NAME] # 要执行的模块,默认为command

Anisble playbook

​ 预先定义好所有需要执行的操作,形成一个脚本文件,执行该脚本文件即可,方便管理和复用。

ansible-playbook -i <hosts_path> <playbook_path>

hosts_path:主机清单文件位置

playbook_path: playbook yaml文件位置

-C:加在ansible-playbook命令后,用于验证palybook文件是否有误

---
- name: Install prometheus on ubuntu
  hosts: prometheus
  become: yes
  tasks:
    - name: "Step 1: Import prometheus public GPG Key"
      apt_key:
        url: https://s3-eu-west-1.amazonaws.com/deb.robustperception.io/41EFC99D.gpg
        state: present
    - name: "Step 2: Reload local package database"
      apt: 
        update_cache: yes
    - name: "Step 3: Install prometheus"
      apt:
        name: prometheus
        update_cache: yes
    - name: "Step 4: Install prometheus-node-exporter"
      apt:
        name: prometheus-node-exporter
        update_cache: yes
    - name: "Step 5: Install prometheus-pushgateway"
      apt:
        name: prometheus-pushgateway
        update_cache: yes
    - name: "Step 6: Install prometheus-alertmanager"
      apt:
        name: prometheus-alertmanager
        update_cache: yes
    - name: "Step 7: Start prometheus service"
      service:
        name: prometheus
        enabled: yes
        state: started

playbook 参数

name :标识plaoybook文件执行内容

hosts: inventory

become: yes/no,默认no,是否使用sudo执行

tasks : 预先定义好的ansible命令,managed node将从上到下执行

handles: 使用notify触发

 # 修改nginx配置后,设置重启
 - name: write the nginx config file
    template: src=/somepath/nginx.j2 dest=/data/nginx/conf/nginx.conf
    notify:
    - restart nginx
  handlers:
  - name: enable nginx
    service: name=nginx state=restarted

when: 当满足条件时才执行,多条件可以使用and、or

tasks:
  - name: "shut down Debian flavored systems"
    command: /sbin/shutdown -t now
    when: ansible_os_family == "Debian"

常用用法**:

# --list-hosts(简写为--list)
ansible webserver --list-hosts 

Ansible原理

image-20191128160037603

ansible命令

ansible命令所使用的模块,参数

演示

host_key_checking = False
remote_tmp = /tmp/.ansible-${USER}/tmp
[ubuntu:vars]
ansible_ssh_private_key_file=~/singapore.pem

[ubuntu]
172.30.2.252 ansible_ssh_user=ubuntu

[mysql:vars]
ansible_private_key_file=~/dev-mysql.pem

[mysql]
172.31.22.159 ansible_ssh_user=ubuntu

[servers:children]
ubuntu
mysql

文件操作

# 创建目录
ansible servers -m file -a 'path=~/temp state=directory mode=0755'
# 创建文件
ansible servers -m file -a 'path=~/temp/test1.txt state=touch'

# Control Node分发文件至Managed Nodes
ansible servers -m copy -a 'src=index.html dest=~/temp/test2.txt'

踩坑记录

其他

预编译

python的版本兼容问题

ansible v2.7及更高版本默认优先支持python3,如果对特定的host支持单独的python版本,可以通过设置ansible_python_interpreter inventory参数设置。

[webservers]
webserver1.com ansible_python_interpreter=/usr/bin/python2.4

工具对比

参考

Ansible入门

Ansible Docs


« Agile

» 蓝绿部署、滚动部署和灰度部署