天天看點

ansible理論、配置、子產品、劇本、角色

1. 服務介紹

1.1 自動化運維相關概念

相關概念

了解IaaS PaaS SaaS

IaaS   infrastructure  as a service
PaaS   platform  as a service
SaaS   software  as a service
           

IAAS 提供基本的硬體

PAAS 購買已經準備好的開發環境 直接開發就行了

SAAS 手機上的大部分軟體都是基于SAAS 比如阿裡提供給别人用的釘釘 騰訊給我們用的微信(免費)

三個的提供方舉例:

IAAS:提供硬體 聯想

PAAS:提供作業系統 微軟

SAAS:阿裡 提供淘寶軟體

以郵件系統為例,IAAS就是企業自己購買伺服器,自己搭建服務架構,搭建郵件伺服器,然後使用企業郵件服務,PAAS就是企業租到了伺服器,自己搭建服務,然後使用企業郵箱,SAAS就是企業掏錢購買騰訊企業郵箱,然後使用企業郵箱

1.2 ansible理論

1.2.1 ansible及自動化介紹

ansible:提高效率的工具

自動化:系統自動化(pxe+ks)、程式自動化(ansible、saltstack、puppet)、代碼自動化(Jenkins)、

程式自動化工具分為兩類:

(1)c/s架構:saltstack puppet

(2)無用戶端模式:ansible

差別:

  • puppet:基于ruby開發,支援Linux、Windows、Unix,可以管理千台主機以上
  • saltstack:基于python開發,支援統一管理,比較輕量級
  • ansible:基于python開發,使用ssh協定,沒有用戶端,200-300台
  • ansible: python編寫 适用于中小型應用環境 一個系統控制多台主機 有兩個角色 主要端/被控端
  • saltstack: python編寫 需要部署agent 主要端通過安裝在被控端的代理來對被控端進行操作
  • puppet: ruby語言編寫 重型 适合大型環境 谷歌用 軟體過于複雜 國内一般用不到
  • 其他

1.2.2 ansible特性

  • 子產品化: 調用特定的子產品,完成特定任務,約1000+子產品 每個子產品功能不同
  • 有paramiko(基于ssh開發,主要做遠端控制) PyYAML(可以實作劇本) Jinja2(模闆語言) 三個關鍵子產品
  • 支援自己定義子產品
  • 安全, 基于openssh
  • 支援playbook編排任務
  • 幂等性: 一個任務執行1遍和n遍效果一樣,不會因為重複執行而帶來意外情況(以複制為例,如果進行多次複制,ansible發現已經有了,就不執行了,也不報錯)

1.2.3 ansible指令執行過程和執行狀态

ansible理論、配置、子產品、劇本、角色

2. centos7上安裝ansible

366  mkdir /media/ansible
  367  cp /mnt/hgfs/soft/an/* /media/ansible/
  368  createrepo /media/ansible/
  370  mount /dev/cdrom /mount
  371  yum -y install createrepo
  372  createrepo /media/ansible/
  374  vim /etc/yum.repos.d/ansible.repo
  [ansible]
name=ansible
baseurl=file:///media/ansible
enabled=1
gpgcheck=0
  375 yum -y install ansible
  376  rpm -e --nodeps python-cryptography


也可以使用yum安裝ansible
yum -y install epel-release
yum -y install ansible
           

3. 配置ansible

277 ansible --version
  278 cd /etc/ansible
  278  vim hosts    尾部添加内容
      [webserver]
      192.168.1.22 
      # 如果主機端口非22 ip後邊需要加 ansible_ssh_port={ssh_port}
      192.168.1.17
      [dbserver]
      192.168.1.19
      這裡的webserver  和 dbserver隻是一個分組的名稱而已,沒有特殊含義
  292  ssh-keygen
  293  ssh-copy-id -i /root/.ssh/id_rsa.pub [email protected]
  294  ssh-copy-id -i /root/.ssh/id_rsa.pub [email protected]
  295  ssh-copy-id -i /root/.ssh/id_rsa.pub [email protected]
  297  ansible all -m ping
  297  ansible all -m ping
192.168.1.17 | SUCCESS => {
    "changed": false,
    "ping": "pong"
}
192.168.1.19 | SUCCESS => {
    "changed": false,
    "ping": "pong"
}
192.168.1.22 | SUCCESS => {
    "changed": false,
    "ping": "pong"
}

           

4. ansible子產品使用

4.1 ansible文法和常用指令

ansible <host-patterm> [-m module_name] [-a args]
example:  ansible webserver -m ping

 
幫助指令:
[[email protected] ~]# ansible-doc -h  #help資訊
[[email protected] ~]# ansible-doc -l #檢視ansible的子產品
[[email protected] ~]# ansible-doc -s yum #檢視某個子產品怎麼使用
           

4.2 常用子產品

(1)command(-m command可以省略)
[[email protected] ~]# ansible all -m command -a 'date'
[[email protected] ~]# ansible all -m command -a 'ls /home'
(2)cron
[[email protected] ~]# ansible webserver -m cron -a 'minute="*/10" job="/bin/echo hello world" name="test cron job"'
[[email protected] ~]# ansible all -a 'crontab -l'
[[email protected] ~]# ansible webserver -m cron -a 'minute="*/10" job="/bin/echo hello hansir" name="test cron job" state=absent'
state=present表示添加,添加的時候 state=present 可以省略 ,state=absent表示删除 name為描述資訊
[[email protected] ~]# ansible webserver -m cron -a 'job=date name=showdate state=present'
[[email protected] ~]# ansible webserver -m cron -a 'job=date name=showdate state=absent'
(3)user
[[email protected] ~]# ansible all -m user -a 'name="user1"' #添加使用者
[[email protected] ~]# ansible all -m user -a 'name="user1" state=absent' #删除使用者
[[email protected] ~]# ansible all -m user -a 'name=tie create_home=yes shell=/bin/bash'
#這是建立一個普通使用者,如果要加碼,自己再寫指令進行加密,如下
[[email protected] ~]# ansible all -m shell -a 'echo 1234.com | passwd --stdin tie'

[[email protected] ~]# ansible all -m user -a 'name=nginx shell=/sbin/nologin create_home=no'
192.168.20.126 | CHANGED => { #建立nginx使用者,要求不可登陸,沒有家目錄
    "ansible_facts": { #雖然這裡顯示有家目錄,但是其實沒有的
        "discovered_interpreter_python": "/usr/bin/python"
    }, 
    "changed": true, 
    "comment": "", 
    "create_home": false, 
    "group": 1002, 
    "home": "/home/nginx", 
    "name": "nginx", 
    "shell": "/sbin/nologin", 
    "state": "present", 
    "system": false, 
    "uid": 1002
}
[[email protected] ~]# ansible all -m user -a 'name=tie remove=yes state=absent' #删除使用者并清空與使用者有關的目錄
(4)group
[[email protected] ~]# ansible dbserver -m group -a 'name="mysql" gid=700 system=yes'  #公共組
[[email protected] ~]# ansible dbserver -m user -a 'name="benet" uid=700 system=yes group=mysql'  #把使用者加入組中
[[email protected] ~]# ansible dbserver -a 'tail -n1 /etc/passwd'
192.168.1.19 | SUCCESS | rc=0 >>
benet:x:700:700::/home/benet:/bin/bash
(5)copy檔案分發
[[email protected] ~]# ansible webserver -m copy -a 'src=/media/ansible/ansible-2.4.2.0-2.el7.noarch.rpm dest=/root mode=0644 owner=root group=root'
[[email protected] ~]# ansible webserver -m copy -a 'src=/etc/sysctl.conf dest=/etc/sysctl.conf backup=yes'
這裡要注意,如果copy相同的檔案,檔案内容要有變動,否則不會覆寫檔案
backup=yes的話 對方在覆寫檔案之前會現在原來的目錄裡做一個備份檔案,如下
[[email protected] ~]# ls /etc/sysctl.conf*
/etc/sysctl.conf  /etc/[email protected]:09:15~

(6)file  建立檔案、修改檔案屬性  比如屬主屬組權限、建立目錄
[[email protected] ~]# ansible dbserver -m file -a 'owner=benet group=mysql mode=0644 path=/tmp/test.ansible'
[[email protected] ~]# ansible dbserver -a 'ls -l /tmp/test.ansible'
192.168.1.19 | SUCCESS | rc=0 >>
-rw-r--r--. 1 benet mysql 13 Sep 21 15:40 /tmp/test.ansible
 
[[email protected] ~]# ansible dbserver -m file -a 'path=/tmp/test.link src=/tmp/test.ansible state=link'#建立軟連結
[[email protected] ~]# ansible all -m file -a 'path=/tmp/testd src=/etc/hosts state=hard' 建立硬連結

[[email protected] ~]# ansible all -m file -a 'path=/tmp/test.test state=touch'
192.168.20.125 | CHANGED => {  #建立檔案
[[email protected] ~]# ansible all -m file -a 'path=/tmp/test.test state=absent' #删除檔案
[[email protected] ~]# ansible all -m file -a 'path=/tmp/test state=directory' #建立目錄
(7)yum
[[email protected] ~]# ansible webserver -m yum -a 'name=zsh,vsftpd state=present' #裝zsh和vsftpd
[[email protected] ~]# ansible webserver -m yum -a 'name=vsftpd state=absent'
(8)service
[[email protected] ~]# ansible webserver -a 'service httpd status'
[[email protected] ~]# ansible webserver -m service -a 'name=httpd state=started'  還可以寫stopped restarted reloaded
(9)shell
[[email protected] ~]# ansible webserver -m shell -a 'ls /root | grep install.log' #shell可以使用管道符
[[email protected] ~]# ansible dbserver -m shell -a 'echo 'redhat' | passwd --stdin benet'
[[email protected] ~]# ansible dbserver -m shell -a 'echo 'y' | yum install vsftpd'
(10)script
[[email protected] ~]# vim test.sh
#!/bin/bash
#this is test script
echo "hello ansible thanks hansir" > /tmp/script.ansible
[[email protected] ~]# ansible dbserver -m script -a 'test.sh'
 
(11)setup 采集用戶端訊息 #這裡篩選的變量 後邊模闆template會用到
[[email protected] ~]# ansible all -m setup #采集用戶端所有資訊
[[email protected] ~]# ansible all -m setup -a 'filter=ansible_hostname'
[[email protected] ~]# ansible dbserver -m setup -a 'filter=*address*'
192.168.20.125 | SUCCESS => {
    "ansible_facts": {
        "ansible_all_ipv4_addresses": [
            "192.168.122.1", 
            "192.168.20.125"
        ], 
        "ansible_all_ipv6_addresses": [
            "fe80::20c:29ff:fe24:241c"
        ], 
        "discovered_interpreter_python": "/usr/bin/python"
    }, 
    "changed": false
}
(12)ping
[[email protected] ~]# ansible all -m ping
(14)fetch #主要端去被控端抓取檔案
[[email protected] ~]# mkdir /data
[[email protected] ~]# ansible all -m fetch -a 'src=/var/log/messages dest=/data'
192.168.20.126 | CHANGED => {
 
[[email protected] ~]# tree /data
/data
├── 192.168.20.125
│   └── var
│       └── log
│           └── messages
└── 192.168.20.126
    └── var
        └── log
            └── messages

6 directories, 2 files
(15) unarchive 解壓子產品: 将主要端的包解壓後放在被控端 無需傳輸tar包 
[[email protected] ~]# ansible webserver -m unarchive -a 'src=/root/ios.tar.gz dest=/usr/src remote_src=yes'
(16)hostname
[[email protected] ~]# ansible webserver -m hostname -a 'name=webserver'
           

關于子產品部分 還有一些非常好用的 沒有在這個文章裡 讀者客戶點選 https://blog.csdn.net/weixin_43557605/article/details/102659689

結合這個子產品 和replace子產品 基本上可以實作用劇本安裝和配置所有的服務

下邊的第五部分是劇本 playbook 是ansible的任務編排 這部分和角色 roles都很重要 這部分掌握了基礎子產品後要大量練習 建議最好可以寫出一個LNMP的部署劇本 以後完成LNMP一鍵部署 關于LNMP的劇本 我已經寫出來了 在https://blog.csdn.net/weixin_43557605/article/details/103924815 這部分沒有寫PHP的 因為 會這兩個 PHP的自然可以寫出來 沒有難度

5. playbook

5.1 正常playbook使用

YAML基礎元素

結構用空格表示

序列結構用-

鍵值對用:

擴充名為yaml yml

task:任務,要調用子產品,完成某個操作

variable:變量

handlers:觸發器

[[email protected] ~]# vim test.yaml
- hosts: webserver
  remote_user: root
  tasks:
    - name: install vsftpd
      command: yum -y install vsftpd
    - name: start vsftpd
      service: name=vsftpd state=started
[[email protected] ~]# ansible-playbook test.yaml
[[email protected] ~]# ansible all -a 'service vsftpd status'
 [WARNING]: Consider using service module rather than running service
 
192.168.1.19 | FAILED | rc=1 >>
vsftpd: unrecognized servicenon-zero return code
 
192.168.1.17 | SUCCESS | rc=0 >>
vsftpd (pid 15076) 正在運作...
 
192.168.1.22 | SUCCESS | rc=0 >>
vsftpd (pid 5920) 正在運作...
           

劇本補充内容

1. yum安裝多個包
- name: Installation dependency
      yum: name="pcre-devel,zlib-devel" state=installed

2. 檢測劇本文法的指令
# ansible-playbook nginx.yml --syntax-check

3. 做軟連結
- name: file
      file: path=/usr/local/nginx/sbin/*  src=/usr/local/sbin/ state=link

4. 解壓包
- name: unarchive
      unarchive: src=/root/nginx-1.15.4.tar.gz  dest=/usr/src  mode=0755
      
5. 添加無家目錄使用者
- name: useradd nginx
      user: name=nginx shell=/sbin/nologin home=null
           

ansible加密指令

ansible理論、配置、子產品、劇本、角色

劇本的其他使用提示

1)限制隻在誰上執行

ansible-playbook file.yml --limits 192.168.20.101
           

2)檢視任務清單

ansible-playbook file.yml --list-tasks
           

3)檢視tags

[[email protected] ~]# ansible-playbook file.yml --list-tags
           

5.2 handlers在playbook中的使用

問題引入:在dbserver上裝httpd,配置并運作的過程中出現配置檔案修改,但是服務沒有重新開機的情況

vim file.yml
- hosts: dbserver
  remote_user: root
  tasks:
    - name: install httpd
      yum: name=httpd
    - name: copy conf file
      copy: src=files/httpd.conf dest=/etc/httpd/conf
    - name: ensure apache is running
      service: name=httpd state=started enabled=yes
 
[[email protected] ~]# mkdir files
[[email protected] ~]# cp /etc/httpd/conf/httpd.conf files/

[[email protected] ~]# ansible-playbook file.yml --syntax-check #檢測文法錯誤

playbook: file.yml
[[email protected] ~]# ansible-playbook -C file.yml  #檢測運作過程

PLAY [dbserver] ***********************************************************************

TASK [Gathering Facts] ****************************************************************
ok: [192.168.20.125]

TASK [install httpd] ******************************************************************
changed: [192.168.20.125]

TASK [copy conf file] *****************************************************************
changed: [192.168.20.125]

TASK [ensure apache is running] *******************************************************
changed: [192.168.20.125]

PLAY RECAP ****************************************************************************
192.168.20.125             : ok=4    changed=3    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0   


第一次我們先不對本機的httpd.conf做修改,先直接運作file.yml
[[email protected] ~]# ansible-playbook file.yml
[[email protected] ~]# ansible dbserver -m shell -a 'ss -ntl | grep :80'
192.168.20.125 | CHANGED | rc=0 >>
LISTEN     0      128         :::80                      :::*   

我們現在修改本機的httpd.conf 把監聽端口改為800 然後執行劇本 之後檢視dbserverd800端口有沒有被監聽
[[email protected] ~]# ansible-playbook file.yml
[[email protected] ~]# ansible dbserver -m shell -a 'ss -ntl | grep :80'
192.168.20.125 | CHANGED | rc=0 >>
LISTEN     0      128         :::80                      :::*  

再次檢視的時候,發現80端口依然在監聽 而不是800端口 也就是說 改了配置檔案 但是無法重新開機
           

針對上邊的問題,playbook引入handlers即可解決,handlers類似于觸發器,達到條件即可觸發某個動作,我們在這裡準備這樣做:用handlers監控配置檔案的修改情況,如果配置檔案修改了,就觸發httpd重新開機服務,操作如下

[[email protected] ~]# vim file.yml 
- hosts: dbserver
  remote_user: root
  tasks:
    - name: install httpd
      yum: name=httpd
    - name: copy conf file
      copy: src=files/httpd.conf dest=/etc/httpd/conf
      notify: restart httpd
    - name: ensure apache is running
      service: name=httpd state=started enabled=yes

  handlers:
    - name: restart httpd
      service: name=httpd state=restarted
上述的意思是說,規定了一個handlers的動作是重新開機httpd,使用
notify對第二步進行監控,隻要第二步進行了,也就是說配置檔案
修改了,就觸發handler中名字是“restart httpd”的操作,可以有多
個觸發,隻要名字對應即可

我們現在再次修改本機的httpd.conf檔案,端口改為8080,然後
執行劇本,檢視運作端口
[[email protected] ~]# ansible-playbook file.yml
[[email protected] ~]# ansible dbserver -m shell -a 'ss -ntl | grep :8080'
192.168.20.125 | CHANGED | rc=0 >>
LISTEN     0      128         :::8080                    :::*  

可以看到dbserver現在運作的是8080端口,問題得到了解決
           

這裡需要說明的是,tasks裡邊的動作通過notify的監控,可以同時觸發多個handlers的動作,如下:

copy src=...  dest=...
nitofy:
  - restart nginx
  - check process
           

5.3 tags在playbook中的使用

tags其實就是為tasks裡的某個動作打一個标簽,打完标簽之後,可以進行引用,如下:

[[email protected] ~]# vim file.yml #對啟動httpd的動作打一個标簽
- hosts: dbserver
  remote_user: root
  tasks:
    - name: install httpd
      yum: name=httpd
    - name: copy conf file
      copy: src=files/httpd.conf dest=/etc/httpd/conf
      notify: restart httpd
    - name: ensure apache is running
      service: name=httpd state=started enabled=yes
      tags: rshttpd

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

[[email protected] ~]# ansible dbserver -m service -a 'name=httpd state=stopped'
[[email protected] ~]# ansible-playbook -t rshttpd file.yml #隻執行rshttpd這個标簽的步驟
[[email protected] ~]# ansible dbserver -m shell -a 'ss -ntl | grep :8080'
192.168.20.125 | CHANGED | rc=0 >>
LISTEN     0      128         :::8080                    :::* 
           

這裡要說明的是,-t後邊可以跟多個标簽,用逗号分隔即可,另外,多個動作可以共用一個标簽

5.4 變量在playbook中的使用

變量的簡單使用

[[email protected] ~]# vim file.yml 
- hosts: webserver
  remote_user: root
  tasks:
    - name: install httpd
      yum: name={{ pkname }}
    - name: ensure apache is running
      service: name={{ pkname }} state=started enabled=yes

[[email protected] ~]# ansible-playbook -e 'pkname=httpd' file.yml  #執行劇本的時候聲明變量
           

在劇本中聲明變量

[[email protected] ~]# vim file.yml 
- hosts: all
  remote_user: root
  vars:
    - pkname1: httpd
    - pkname2: vsftpd
  tasks:
    - name: install httpd
      yum: name={{ pkname1 }}
    - name: ensure apache is running
      yum: name={{ pkname2 }}
[[email protected] ~]# ansible all -m yum -a 'name=httpd state=absent'
[[email protected] ~]# ansible-playbook file.yml 

           

在配置檔案中聲明變量

  • 對某一個主機生效的(普通變量)
  • 對某一個組生效的(公共變量)
vim /etc/ansible/hosts
[webservers]
192.168.20.101 http_port=81
192.168.20.102 http_port=82

[webservers:vars]
nodename=www
domainname=kgc.cn

vim file.yml
- hosts: all
  remote_user: root
  tasks:
    - name: set hostname
      hostname: name={{nodename}}{{http_port}}.{{domainname}}

ansible-playbook file.yml
還有一種方式
ansible-playbook -e 'nodename=web domainname=example.com' file.yml  #這個時候-e的生效
           

變量的優先級比較:

指令行 > 普通變量 > 公共變量
           

5.5 使用template對nginx實行差別化配置

首先需要在自己寫的yml檔案的統計目錄建立templates目錄,并把檔案複制一份過來,改為jinja2格式的

[[email protected] ~]# ls
anaconda-ks.cfg  Downloads  initial-setup-ks.cfg  Pictures   Videos
Desktop          files      Music                 Public
Documents        file.yml   original-ks.cfg       Templates
[[email protected] ~]# mkdir templates
[[email protected] ~]# cp /etc/nginx/nginx.conf templates/nginx.conf.j2
這個時候要用到一些系統變量,這些變量是從setup子產品找的
我們這裡準備對兩台主機安裝nginx,然後讓worker程序數與cpu成正比
如下,可以看到兩天主機,一個cpu是2,另一個cpu個數是4,變量是ansible_processor_vcpus
[[email protected] ~]# ansible all -m setup -a 'filter=*cpu*'
192.168.20.125 | SUCCESS => {
    "ansible_facts": {
        "ansible_processor_vcpus": 4, 
        "discovered_interpreter_python": "/usr/bin/python"
    }, 
    "changed": false
}
192.168.20.126 | SUCCESS => {
    "ansible_facts": {
        "ansible_processor_vcpus": 2, 
        "discovered_interpreter_python": "/usr/bin/python"
    }, 
    "changed": false
}
編輯模闆檔案
[[email protected] ~]# vim templates/nginx.conf.j2
  6 worker_processes {{ansible_processor_vcpus}};
[[email protected] ~]# vi test.yml
- hosts: all
  remote_user: root
  tasks:
    - name: install nginx
      yum: name=nginx
    - name: copy template
      template: src=nginx.conf.j2 dest=/etc/nginx/nginx.conf
    - name: start nginx
      service: name=nginx state=started
[[email protected] ~]# ansible-playbook -C test.yml 

PLAY [all] ****************************************************************************

TASK [Gathering Facts] ****************************************************************
ok: [192.168.20.125]
ok: [192.168.20.126]

TASK [install nginx] ******************************************************************
changed: [192.168.20.126]
changed: [192.168.20.125]

TASK [copy template] ******************************************************************
changed: [192.168.20.125]
changed: [192.168.20.126]

TASK [start nginx] ********************************************************************
changed: [192.168.20.125]
changed: [192.168.20.126]

PLAY RECAP ****************************************************************************
192.168.20.125             : ok=4    changed=3    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0   
192.168.20.126             : ok=4    changed=3    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0   

[[email protected] ~]# ansible-playbook test.yml 
[[email protected] ~]# ansible all -m shell -a 'ps -aux | grep nginx' #上邊4個,下邊2個,符合預期
192.168.20.125 | CHANGED | rc=0 >>
root       3705  0.0  0.1 122928  2244 ?        Ss   09:22   0:00 nginx: master process /usr/sbin/nginx
nginx      3706  0.0  0.1 125472  3564 ?        S    09:22   0:00 nginx: worker process
nginx      3707  0.0  0.1 125472  3564 ?        S    09:22   0:00 nginx: worker process
nginx      3708  0.0  0.1 125472  3564 ?        S    09:22   0:00 nginx: worker process
nginx      3709  0.0  0.1 125472  3564 ?        S    09:22   0:00 nginx: worker process
root       3883  0.0  0.0 113128  1196 pts/1    S+   09:23   0:00 /bin/sh -c ps -aux | grep nginx
root       3885  0.0  0.0 112660   952 pts/1    S+   09:23   0:00 grep nginx
192.168.20.126 | CHANGED | rc=0 >>
root       3468  0.0  0.1 122928  2244 ?        Ss   09:22   0:00 nginx: master process /usr/sbin/nginx
nginx      3469  0.0  0.1 125472  3552 ?        S    09:22   0:00 nginx: worker process
nginx      3470  0.0  0.1 125472  3540 ?        S    09:22   0:00 nginx: worker process
root       3643  0.0  0.0 113128  1196 pts/1    S+   09:23   0:00 /bin/sh -c ps -aux | grep nginx
root       3645  0.0  0.0 112660   952 pts/1    S+   09:23   0:00 grep nginx

如果要修改,加入handlers比較好,我們把worker數量改為cpu個數+2(如果想寫成平方 **2)
[ro[email protected] ~]# vim templates/nginx.conf.j2 
worker_processes {{ansible_processor_vcpus+2}};
[[email protected] ~]# vim test.yml 
- hosts: all
  remote_user: root
  tasks:
    - name: install nginx
      yum: name=nginx
    - name: copy template
      template: src=nginx.conf.j2 dest=/etc/nginx/nginx.conf
      notify: restart nginx
    - name: start nginx
      service: name=nginx state=started
  handlers:
    - name: restart nginx
      service: name=nginx state=restarted

[[email protected] ~]# ansible all -m shell -a 'ps -aux | grep nginx' #可以看出上邊6個下邊4個
192.168.20.125 | CHANGED | rc=0 >>
root       3705  0.0  0.1 122928  2244 ?        Ss   09:22   0:00 nginx: master process /usr/sbin/nginx
nginx      3706  0.0  0.1 125472  3564 ?        S    09:22   0:00 nginx: worker process
nginx      3707  0.0  0.1 125472  3564 ?        S    09:22   0:00 nginx: worker process
nginx      3708  0.0  0.1 125472  3564 ?        S    09:22   0:00 nginx: worker process
nginx      3709  0.0  0.1 125472  3564 ?        S    09:22   0:00 nginx: worker process
nginx      3710  0.0  0.1 125472  3564 ?        S    09:22   0:00 nginx: worker process
nginx      3711  0.0  0.1 125472  3564 ?        S    09:22   0:00 nginx: worker process
root       3883  0.0  0.0 113128  1196 pts/1    S+   09:23   0:00 /bin/sh -c ps -aux | grep nginx
root       3885  0.0  0.0 112660   952 pts/1    S+   09:23   0:00 grep nginx
192.168.20.126 | CHANGED | rc=0 >>
root       3468  0.0  0.1 122928  2244 ?        Ss   09:22   0:00 nginx: master process /usr/sbin/nginx
nginx      3469  0.0  0.1 125472  3552 ?        S    09:22   0:00 nginx: worker process
nginx      3470  0.0  0.1 125472  3540 ?        S    09:22   0:00 nginx: worker process
nginx      3471  0.0  0.1 125472  3564 ?        S    09:22   0:00 nginx: worker process
nginx      3472  0.0  0.1 125472  3564 ?        S    09:22   0:00 nginx: worker process
root       3643  0.0  0.0 113128  1196 pts/1    S+   09:23   0:00 /bin/sh -c ps -aux | grep nginx
root       3645  0.0  0.0 112660   952 pts/1    S+   09:23   0:00 grep nginx
           

下邊試着用變量結合template來修改nginx配置

[[email protected] ~]# vim /etc/ansible/hosts 
[dbserver]
192.168.20.125 http_port=81
[webserver]
192.168.20.126 http_port=82
[[email protected] ~]# vim templates/nginx.conf.j2 
 39         listen       {{http_port}} default_server;
[[email protected] ~]# ansible-playbook test.yml 
[[email protected] ~]# ansible all -m shell -a 'ss -ntpl | grep nginx' #如下ipv4的端口都改過來了
192.168.20.125 | CHANGED | rc=0 >>
LISTEN     0      128          *:81                       *:*                   users:(("nginx",pid=4388,fd=6),("nginx",pid=4387,fd=6),("nginx",pid=4386,fd=6),("nginx",pid=4385,fd=6),("nginx",pid=4384,fd=6),("nginx",pid=4383,fd=6),("nginx",pid=4382,fd=6))
LISTEN     0      128         :::80                      :::*                   users:(("nginx",pid=4388,fd=7),("nginx",pid=4387,fd=7),("nginx",pid=4386,fd=7),("nginx",pid=4385,fd=7),("nginx",pid=4384,fd=7),("nginx",pid=4383,fd=7),("nginx",pid=4382,fd=7))
192.168.20.126 | CHANGED | rc=0 >>
LISTEN     0      128          *:82                       *:*                   users:(("nginx",pid=4144,fd=6),("nginx",pid=4143,fd=6),("nginx",pid=4142,fd=6),("nginx",pid=4141,fd=6),("nginx",pid=4140,fd=6))
LISTEN     0      128         :::80                      :::*                   users:(("nginx",pid=4144,fd=7),("nginx",pid=4143,fd=7),("nginx",pid=4142,fd=7),("nginx",pid=4141,fd=7),("nginx",pid=4140,fd=7)) 
           

tempalte結合when進行條件判斷

加入某個服務,對于不同的系統版本,配置檔案不一樣,這個時候就需要差別對待

[[email protected] ~]# vim test.yml
- hosts: all
  remote_user: root
  tasks:
    - name: install nginx
      yum: name=nginx
    - name: copy template for centos7
      template: src=nginx.conf7.j2 dest=/etc/nginx/nginx.conf
      when: ansible_distribution_version == "7"
      notify: restart nginx
    - name: copy template for centos6
      template: src=nginx.conf6.j2 dest=/etc/nginx/nginx.conf
      when: ansible_distribution_version == "6"
      notify: restart nginx
    - name: start nginx
      service: name=nginx state=started
  handlers:
    - name: restart nginx
      service: name=nginx state=restarted
此時需要在templates目錄裡準備好兩個模闆檔案
上邊的系統版本号變量可以使用ansible指令獲得
[[email protected] ~]# ansible all -m setup -a 'filter=*version*'
           

6. roles 角色

6.1 roles的說明

roles的思想是把原來寫在一個playbook的内容分成不同的部分,之後再進行統一的調用,這種方法,可以防止因為個人書寫習慣不同而帶來的額外的維護成本,在比較複雜的場景中建議使用roles來簡化工作,同時,已經有很多人寫了大量優秀的角色放在網上,可以供我們下載下傳使用,網站在此 http://galaxy.ansible.com 如果網絡比較好 可以直接使用ansible-galaxy指令安裝角色 免去了安裝的繁瑣工作 但是 對于角色的編輯我們也應該掌握基礎 下邊是自己動手編寫角色 在後邊的文章https://blog.csdn.net/weixin_43557605/article/details/102661361 和 https://blog.csdn.net/weixin_43557605/article/details/103767610有網絡角色的使用方法

操作要求: 要求在roles目錄進行相關的操作,ansible安裝完畢之後,在/etc/ansible/目錄下就有一個roles目錄,可以在這個ansible目錄裡操作,也可以在其他任何目錄裡操作,但是要求yml檔案和roles目錄在同一級目錄裡

roles的目錄說明

  • files目錄: 主要是放一些copy子產品需要用到的檔案或者script子產品用到的腳本
  • templates目錄:template子產品查找所需要的模闆檔案的目錄
  • tasks目錄:定義任務操作的目錄,這個目錄裡至少要有一個main.yml
  • handlers目錄:觸發操作的目錄,這個目錄至少要有一個main.yml
  • vars目錄:定義變量的目錄 至少包含一個main.yml目錄
  • meta目錄:定義角色的特殊設定及依賴關系
  • default目錄:設定預設變量的時候使用此目錄裡的main.yml

6.2 roles實戰—源碼安裝nginx

[[email protected] ~]# cd /etc/ansible/
[[email protected] ansible]# ls
ansible.cfg  hosts  roles
[[email protected] ansible]# mkdir -pv roles/nginx/{tasks,files,handlers,vars,templates}
mkdir: created directory ‘roles/nginx’
mkdir: created directory ‘roles/nginx/tasks’
mkdir: created directory ‘roles/nginx/files’
mkdir: created directory ‘roles/nginx/handlers’
mkdir: created directory ‘roles/nginx/vars’
mkdir: created directory ‘roles/nginx/templates’

本機安裝nginx,過程省略

[[email protected] ansible]# cp /root/nginx-1.15.4.tar.gz roles/nginx/files/
[[email protected] ansible]# cp /usr/local/nginx/conf/nginx.conf roles/nginx/templates/nginx.conf.j2
[[email protected] ansible]# cd roles/nginx/tasks/
[[email protected] tasks]# vim install.yml
- name: install dependent packages
  yum: name={{item}}
  with_items:
    - gcc
    - gcc-c++
    - pcre-devel
    - zlib-devel
    - openssl-devel
- name: add nginx user
  user: name=nginx create_home=no shell=/sbin/nologin uid=888
- name: unarchive tar file
  unarchive: src={{tarball_name}} dest=/usr/src/
- name: configure nginx
  shell: ./configure --prefix={{base_dir}} --user={{user}} --group={{group}} --with-http_stub_status_module --with-http_gzip_static_module && make && make install
  args: 
    chdir: /usr/src/{{nginx_dir}}
- name: copy template
  template: src=nginx.conf.j2 dest={{base_dir}}/conf/nginx.conf
- name: make soft link 
  file: src={{base_dir}}/sbin/nginx dest=/usr/sbin/nginx state=link

[[email protected] tasks]# vim test.yml
- name: test syntax error of nginx
  shell: /usr/local/nginx/sbin/nginx -t
  notify: start nginx
[[email protected] tasks]# vim main.yml
- import_tasks: install.yml  #include很快會被取消,這裡用import_tasks
- import_tasks: test.yml
[[email protected] tasks]# vim ../templates/nginx.conf.j2 
  3 worker_processes  {{ansible_processor_vcpus+2}};
[[email protected] tasks]# vim ../handlers/main.yml
- name: start nginx
  shell: nginx
[[email protected] tasks]# vim ../vars/main.yml
tarball_name: nginx-1.15.4.tar.gz
nginx_dir: nginx-1.15.4
base_dir: /usr/local/nginx
cmd: /usr/local/nginx/sbin/nginx
user: nginx
group: nginx
[[email protected] tasks]# cd /etc/ansible/
[[email protected] ansible]# ls
ansible.cfg  hosts  roles
[[email protected] ansible]# vim nginx_roles.yml
- hosts: all
  remote_user: root
  roles:
    - role: nginx

測試執行過程:
[[email protected] ansible]# ansible-playbook -C nginx_roles.yml 

PLAY [all] ****************************************************************************

TASK [Gathering Facts] ****************************************************************
ok: [192.168.20.125]
ok: [192.168.20.126]

TASK [nginx : install dependent packages] *********************************************
[DEPRECATION WARNING]: Invoking "yum" only once while using a loop via squash_actions 
is deprecated. Instead of using a loop to supply multiple items and specifying `name: 
"{{item}}"`, please use `name: ['gcc', 'gcc-c++', 'pcre-devel', 'zlib-devel', 
'openssl-devel']` and remove the loop. This feature will be removed in version 2.11. 
Deprecation warnings can be disabled by setting deprecation_warnings=False in 
ansible.cfg.
[DEPRECATION WARNING]: Invoking "yum" only once while using a loop via squash_actions 
is deprecated. Instead of using a loop to supply multiple items and specifying `name: 
"{{item}}"`, please use `name: ['gcc', 'gcc-c++', 'pcre-devel', 'zlib-devel', 
'openssl-devel']` and remove the loop. This feature will be removed in version 2.11. 
Deprecation warnings can be disabled by setting deprecation_warnings=False in 
ansible.cfg.
changed: [192.168.20.125] => (item=[u'gcc', u'gcc-c++', u'pcre-devel', u'zlib-devel', u'openssl-devel'])
changed: [192.168.20.126] => (item=[u'gcc', u'gcc-c++', u'pcre-devel', u'zlib-devel', u'openssl-devel'])

TASK [nginx : add nginx user] *********************************************************
changed: [192.168.20.125]
changed: [192.168.20.126]

TASK [nginx : unarchive tar file] *****************************************************
fatal: [192.168.20.125]: FAILED! => {"changed": false, "msg": "dest '/usr/src/nginx-1.15.4' must be an existing dir"}
fatal: [192.168.20.126]: FAILED! => {"changed": false, "msg": "dest '/usr/src/nginx-1.15.4' must be an existing dir"}

PLAY RECAP ****************************************************************************
192.168.20.125             : ok=3    changed=2    unreachable=0    failed=1    skipped=0    rescued=0    ignored=0   
192.168.20.126             : ok=3    changed=2    unreachable=0    failed=1    skipped=0    rescued=0    ignored=0   

檢測執行過程沒有錯誤,可以執行
[[email protected] ansible]# ansible all -m shell -a 'ps -aux | grep nginx'
192.168.20.125 | CHANGED | rc=0 >>
root      19567  0.0  0.0  20556   616 ?        Ss   13:06   0:00 nginx: master process nginx
nginx     19568  0.0  0.0  23092  1380 ?        S    13:06   0:00 nginx: worker process
root      19647  0.0  0.0 113176  1220 pts/1    S+   13:06   0:00 /bin/sh -c ps -aux | grep nginx
root      19649  0.0  0.0 112708   964 pts/1    S+   13:06   0:00 grep nginx
192.168.20.126 | CHANGED | rc=0 >>
root      19612  0.0  0.0  20556   620 ?        Ss   13:06   0:00 nginx: master process nginx
nginx     19613  0.0  0.0  23092  1384 ?        S    13:06   0:00 nginx: worker process
root      19692  0.0  0.0 113176  1220 pts/1    S+   13:06   0:00 /bin/sh -c ps -aux | grep nginx
root      19694  0.0  0.0 112708   960 pts/1    S+   13:06   0:00 grep nginx

變量沒有成功,因為install.yml檔案裡忘記寫template子產品了 這個時候可以自己去吧後兩台的
nginx殺掉,也可以改一下handler 讓handler觸發,我們采用後者,改完之後再次執行

如下出來效果了,一個4個worker 一個6個worker
[[email protected] ansible]# ansible all -m shell -a 'ps -aux | grep nginx'
192.168.20.126 | CHANGED | rc=0 >>
root      23027  0.0  0.0  20556   620 ?        Ss   13:12   0:00 nginx: master process nginx
nginx     23028  0.0  0.0  23092  1380 ?        S    13:12   0:00 nginx: worker process
nginx     23029  0.0  0.0  23092  1380 ?        S    13:12   0:00 nginx: worker process
nginx     23030  0.0  0.0  23092  1380 ?        S    13:12   0:00 nginx: worker process
nginx     23031  0.0  0.0  23092  1380 ?        S    13:12   0:00 nginx: worker process
root      23113  0.0  0.0 113176  1220 pts/1    S+   13:12   0:00 /bin/sh -c ps -aux | grep nginx
root      23115  0.0  0.0 112708   964 pts/1    R+   13:12   0:00 grep nginx
192.168.20.125 | CHANGED | rc=0 >>
root      22978  0.0  0.0  20556   680 ?        Ss   13:12   0:00 nginx: master process nginx
nginx     22979  0.0  0.0  23092  1380 ?        S    13:12   0:00 nginx: worker process
nginx     22980  0.0  0.0  23092  1380 ?        S    13:12   0:00 nginx: worker process
nginx     22981  0.0  0.0  23092  1380 ?        S    13:12   0:00 nginx: worker process
nginx     22982  0.0  0.0  23092  1380 ?        S    13:12   0:00 nginx: worker process
nginx     22983  0.0  0.0  23092  1380 ?        S    13:12   0:00 nginx: worker process
nginx     22984  0.0  0.0  23092  1380 ?        S    13:12   0:00 nginx: worker process
root      23065  0.0  0.0 113176  1216 pts/1    S+   13:12   0:00 /bin/sh -c ps -aux | grep nginx
root      23067  0.0  0.0 112708   964 pts/1    R+   13:12   0:00 grep nginx