Ansible教程

1,923 阅读5分钟

ansible一小时入门

ansible安装

centos

sudo yum install epel-release
sudo yum install ansible

ubuntu

sudo apt-get install software-properties-common
sudo apt-add-repository ppa:ansible/ansible
sudo apt-get update
sudo apt-get install ansible

使用pip的Python3版本安装它

pip3 install ansible
ansible --version | grep "python version"

ansible原理图

avatar

ansible命令格式

ansible [ip或主机名或分组名] -m 模块 -a 参数

ansible 主机清单

vim /etc/ansible/hosts #编辑主机清单

/**hosts**/
[py3-hosts]  #分组名
172.16.154.106  #分组成员

[py3-hosts:vars]  #setting a group of hosts to use Python3
ansible_python_interpreter=/usr/bin/python3

ansible使用ssh来与远程主机连接,但如果远程主机数量较多,使用用户密码认证就过于繁琐

ansible的免密认证

/**生成及安装秘钥**/
ssh-keygen -t rsa -f /root/.ssh/id_rsa -N '' #控制主机生成ssh秘钥,保存在/root/.ssh中
ssh-copy-id [ip或主机名] 
/**免密登录**/
ssh [ip地址或主机名]

ansible ping模块使用

ansible [ip或主机名] -m ping
# ping模块默认使用python2.7编译器,如果你的远程主机python2.7未安装在/usr/bin中或使用的是python3,则需要手动设置python编译器位置
#推荐在主机清单中设置编辑器位置
# Example of setting a group of hosts to use Python3
[py3-hosts]
ubuntu16
fedora27

[py3-hosts:vars]
ansible_python_interpreter=/usr/bin/python3

更多手动设置ansible python编译器的方法

ansible_ping并非真正使用ICMP协议ping,实质还是使用ssh协议进行连接

ansible cron模块实现多台服务器的时钟同步

/**控制主机**/
ntpdate time.windows.com  #与windows的时钟服务器进行校准
ansible [ip或主机名或分组名] -m cron -a 'name="test cron1" job="ntpdate time.windows.com" minute=0 hour=*/1' # hour=*/1 每隔一小时

/**远程主机**/
crontab -l #查询cron任务
#显示  0 */1 * * * ntpdate time.windows.com

更多关于cron的使用

ansible copy模块使用

#将本地主机中的域名解析记录复制到其他服务器上
ansible [ip或主机名或分组名] -m copy -a "src=/etc/host dest=/etc/host"

ansible playbook

ansible-galaxy下载在线roles

roles是多个playbook的集合

ansible-galaxy install geerlingguy.nginx
ansible-galaxy remove geerlingguy.nginx

playbook简单示例

#hello.yml/.yaml
---
- hosts: py3-hosts #主机清单里的主机或分组
  remote_user: root #远端执行剧本的用户

  tasks: 
    - name: hello
      command: hostname #command: shell命令


ansible进阶

ansible Host-pattern

匹配主机列表 all:表示清单中所有主机

ansible all -m ping

*:通配符

ansible "*" -m ping
ansible 192.168.1.* -m ping
ansible "*srvs" -m ping

或关系(并集)

ansible 'websrvs:appsrvs' -m ping
ansible '192.168.1.10:192.168.1.20' -m ping

逻辑与(交集)

ansible 'websrvs:&dbsrvs' -m ping

逻辑非

ansible 'websrvs:!dbsrvs' -m ping #在websrvs组但不在dbsrvs组的主机

综合逻辑

ansible 'websrvs:dbsrvs:&appsrvs:!ftpsrvs' -m ping

正则表达式

ansible 'websrvs:&dbsrvs' -m ping
ansible '~(web|db).*\.magedu\.com' -m ping

ansible ping

以用户口令方式ping远程主机

ansible [ip] -m ping -k

ansible以普通用户身份运行,以用户口令方式ping远程主机时需安装sshpass
-yum install sshpass -y

如果该ping为第一次SSH连接远程主机,ansible会检查对应主机的host_key,即检查/root/.ssh/中有无known_hosts记录。若没有,则ping失败(需要手动ssh [ip]连接,产生known_hosts记录);

基于key的认证

ssh-keygen
ssh-copy-id [ip]

ansible ping错误集锦

修改ansible配置文件/etc/ansible/ansible.cfg

#删除指令前的"#""
host_key_checking = False  #不检查对应主机的host_key
log_path = /var/log/ansible.log  #记录操作日志

ansible不是常驻内存的程序,修改配置文件后不需重启服务

ansible playbook

ansible-playbook hello.yml      #执行hello.yml
ansible-vault encrypt hello.yml #加密hello.yml,需要设置vault password
ansible-vault view hello.yml;   #查看已经加密的playbook
ansible-vault decrypt hello.yml #解密

实例

cat file.yml
---
- hosts: test
  remote_user: root

  tasks:
    - name: create new file 
      file: name=/root/newfile state=touch
    - name: create new user
      user: name=test system=yes shell=/sbin/nologin
    - name: install httpd
      yum: name=httpd state=present
    - name: copy html
      copy: src=/var/www/html/ti.html dest=/var/www/html/
    - name: start service
      service: name=httpd state=started enabled=yes 

playbook执行的打印结果分绿色和黄色;绿色结果表示该操作曾被执行过(ansible具有等幂性,不会因操作执行过或文件存在过而报错);黄色结果表示操作第一次执行或操作修改了文件 copy:src=files/index.html files/index.html为相对路径(绝对路径为/root/ansible/files)

ansible-playbook -C file.yml -vvv  #'-C':检验plybook的正确性,但不执行;'-vvv':显示详细过程
ansible-playbook file.yml -vvv
##检验结果
ansible test -a 'ls /root -l'
207.148.97.208 | SUCCESS | rc=0 >>
总用量 0
-rw-r--r-- 1 root root 0 11月 16 11:59 newfile

ansible test -a 'getent passwd test'
207.148.97.208 | SUCCESS | rc=0 >>
test:x:997:995::/home/test:/sbin/nologin

ansible test -m shell -a 'ss -tln|grep :80'
207.148.97.208 | SUCCESS | rc=0 >>
LISTEN     0      128       [::]:80                    [::]:*           

playbook基础组件(playbook忽略错误一直执行)

##逻辑或
tasks:
  - name:run this command and ignore the result
    shell:/usr/bin/somecommand || /bin/true #相当于 command || 1;command==0,该shell模块语句仍为true,继续执行下去

##ignore_errors:
tasks:
  - name:run this command and ignore the result
    shell:/usr/bin/somecommand
    ignore_errors:True

playbook --list

ansible-playbook file.yml --list-hosts #查看playbook hosts
playbook: file.yml
  play #1 (test): test	TAGS: []
    pattern: [u'test']
    hosts (1):
      207.148.97.208


ansible-playbook file.yml --list-tasks #查看playbook tasks
playbook: file.yml
  play #1 (test): test	TAGS: []
    tasks:
      create new file	TAGS: []
      create new user	TAGS: []
      install httpd	TAGS: []
      copy html	TAGS: []
      start service	TAGS: []


ansible-playbook file.yml --list-tags #查看playbook tags

ansible playbook template 安装配置nginx

本机必须先安装nginx,将本机nginx.conf用作template

#template.j2放入templates文件夹,文件夹存在于playbook同一级目录
cp '/etc/nginx/nginx.conf' 'templates/mynginx.conf.j2'
vim templates/mynginx.conf.j2

---cat mynginx.j2---
user nginx;
worker_processes {{ ansible_processor_vcpus*2+1 }};
error_log /var/log/nginx/error.log;
pid /run/nginx.pid;
# Load dynamic modules. See /usr/share/doc/nginx/README.dynamic.
include /usr/share/nginx/modules/*.conf;
events {
    worker_connections 1024;
}
http {
    log_format  main  '$remote_addr - $remote_user [$time_local] "$request" '
                      '$status $body_bytes_sent "$http_referer" '
                      '"$http_user_agent" "$http_x_forwarded_for"';
    access_log  /var/log/nginx/access.log  main;
    sendfile            on;
    tcp_nopush          on;
    tcp_nodelay         on;
    keepalive_timeout   65;
    types_hash_max_size 2048;
    include             /etc/nginx/mime.types;
    default_type        application/octet-stream;
    # Load modular configuration files from the /etc/nginx/conf.d directory.
    # See http://nginx.org/en/docs/ngx_core_module.html#include
    # for more information.
    include /etc/nginx/conf.d/*.conf;
    server {
        listen       {{ http_port }} default_server;
        listen       [::]:{{ http_port }} default_server;
        server_name  _;
        root         /usr/share/nginx/html;
        # Load configuration files for the default server block.
        include /etc/nginx/default.d/*.conf;
        location / {
        }
        error_page 404 /404.html;
            location = /40x.html {
        }
        error_page 500 502 503 504 /50x.html;
            location = /50x.html {
        }
    }
}

---cat mynginx.yml---
---
- hosts: wservers
  remote_user: root

  tasks:
    - name: add nginx resourse
      yum:
        name: http://nginx.org/packages/centos/7/noarch/RPMS/nginx-release-centos-7-0.el7.ngx.noarch.rpm
        state: present
    - name: install nginx
      yum:
        name: nginx
        state: present
    - name: template operation
      template: 
        src: templates/mynginx.conf.j2 
        dest: /etc/nginx/nginx.conf
      notify: restart service
    - name: start service
      service: 
        name: nginx
        state: started
        enabled: yes

  handlers: 
    - name: restart service
      service: 
        name: nginx
        state: restarted


ansible-playbook mynginx.yml 

## centos安装nginx
添加epel源或nginx源
添加nginx源

sudo rpm -Uvh nginx.org/packages/ce… yum install nginx -y

##用到的指令
ansible all -m setup |grep cpu #setup模块显示远程主机的配置信息 'grep cpu'过滤出有关cpu的部分
ss -ntlp |grep nginx #ss与netstat相似
ps aux |grep nginx #查看nginx的主进程和工作进程

ansible --limit

--limit [ip1] command或playbook仅限ip1执行

ansible test -a 'ls /root' --limit 207.148.97.208 
207.148.97.208 | SUCCESS | rc=0 >>
newfile

ansible 常用模块

ansible raw[类似于command、支持管道传递]

[root@node1 ansible]# ansible testservers -m raw -a "ifconfig eth0 |sed -n 2p |awk '{print \$2}' |awk -F: '{print \$2}'"

ansible command [执行远程命令]

[root@node1 ansible]# ansible testservers -m command -a 'uname -n'

ansible script [在远程主机执行主控端的shell/python脚本 ] (使用相对路径)

[root@node1 ansible]# ansible testservers -m script -a '/etc/ansible/test.sh

ansible shell[执行远程主机的shell/python脚本] (一个name下只允许存在一个shell)

[root@node1 ansible]# ansible testservers -m shell -a 'bash /root/test.sh'