1. 程式人生 > >CentOS6.7下Ansible部署

CentOS6.7下Ansible部署

utf usr 需要 meta gist roo been check tro

Ansible是一種集成IT系統的配置管理, 應用部署, 執行特定任務的開源平臺. 它基於Python語言實現, 部署只需在主控端部署Ansible環境, 被控端無需安裝代理工具, 只需打開SSH, 讓主控端通過SSH秘鑰認證對其進行所有的管理監控操作. 相對於SaltStack, 它除了利用SSH安全傳輸, 無需在客戶端進行任何配置, 而且它有一個很龐大的用戶群體以及豐富的API, 相對適合部署到數量比較大且對系統軟件安裝要求比較嚴格的集群中.

更多配置參考: https://github.com/ansible

官方文檔: http://docs.ansible.com/ansible

本文將幫助大家如何快速部署一個Ansible平臺.

安裝環境:

System: Centos 6.7 x64

Master: master.example.com

Minion: client01.example.com

Minion: client02.example.com

一. 環境部署及安裝

1. 關閉iptables和SELINUX

# service iptables stop

# setenforce 0

# vi /etc/sysconfig/selinux

...
SELINUX=disabled
...

2. Master端安裝EPEL第三方yum源

# rpm -Uvh http://ftp.linux.ncsu.edu/pub/epel/6/i386/epel-release-6-8.noarch.rpm

3.安裝Ansible

# yum install ansible -y

4.添加環境變量以便vi能正常顯示中文註釋.

# vi /etc/profile

添加:

export LC_ALL=en_US.UTF-8
export LANG=en_US.UTF-8
export LANGUAGE=en_US.UTF-8

# source /etc/profile

二. 初始配置

1. 修改主機及組配置

# cd /etc/ansible

# cp hosts hosts.bak

# cat /dev/null > hosts

# vi /etc/ansible/hosts

[webservers]
client01.example.com
client02.example.com
[nginx01]
client01.example.com
[nginx02]
client02.example.com

2.配置SSH秘鑰認證

# yum install ssh* -y

# ssh-keygen -t rsa

Generating public/private rsa key pair.
Enter file in which to save the key (/root/.ssh/id_rsa): 
Created directory ‘/root/.ssh‘.
Enter passphrase (empty for no passphrase): 
Enter same passphrase again: 
Your identification has been saved in /root/.ssh/id_rsa.
Your public key has been saved in /root/.ssh/id_rsa.pub.
The key fingerprint is:
24:13:34:e9:71:2b:20:0b:48:a6:86:9a:1d:1b:1d:26 [email protected]
The key‘s randomart image is:
+--[ RSA 2048]----+
|ooE o.+.         |
|* .+..oo.        |
|oooo.ooo..       |
|oo.+  o+.        |
|o o    .S        |
|                 |
|                 |
|                 |
|                 |
+-----------------+

同步公鑰文件id_rsa.pub到目標主機

# ssh-copy-id -i /root/.ssh/id_rsa.pub [email protected]

# ssh-copy-id -i /root/.ssh/id_rsa.pub [email protected]

校驗SSH免密碼配置是否成功.

# ssh [email protected]

如直接進入則配置完成.

3.定義主機與組

所有定義的主機與組規則都在/etc/Ansible/hosts下.

常見的寫法:

192.168.1.21:2135 定義一個IP為192.168.1.21, SSH端口為2135的主機.

jumper ansible_ssh_port=22 ansible_ssh_host=192.168.1.50 定義一個別名為jumper, SSH端口為22, IP為192.168.1.50的主機.

組成員主機名稱範例:

[webservers]
www[001:006].example.com
[dbservers]
db-[a:f].example.com

4.定義主機變量

主機可以指定變量, 後面可以供Playbooks調用

[atlanta]
host1 http_port=80 maxRequestsPerChild=808
host2 http_port=8080 maxRequestsPerChild=909

5.定義組變量

[atlanta]
host1
host2

[atlanta:vars]
ntp_server=ntp.atlanta.example.com
proxy=proxy.atlanta.example.com

6.匹配目標

重啟webservers組所有SSH服務.

# ansible webservers -m service -a "name=sshd state=restarted"

client01.example.com | success >> {
    "changed": true, 
    "name": "sshd", 
    "state": "started"
}

client02.example.com | success >> {
    "changed": true, 
    "name": "sshd", 
    "state": "started"
}

三. Ansible常用模塊及API

1.遠程命令模塊

command: 執行遠程主機SHELL命令:

# ansible webservers -m command -a "free -m"

client01.example.com | success | rc=0 >>
             total       used       free     shared    buffers     cached
Mem:           996        108        887          0          7         41
-/+ buffers/cache:         58        937 
Swap:         1023          0       1023 

client02.example.com | success | rc=0 >>
             total       used       free     shared    buffers     cached
Mem:           996        108        888          0          7         41
-/+ buffers/cache:         58        937 
Swap:         1023          0       1023 

script: 遠程執行MASTER本地SHELL腳本.(類似scp+shell)

# echo "df -h" > ~/test.sh

# ansible webservers -m script -a "~/test.sh"

client01.example.com | success >> {
    "changed": true, 
    "rc": 0, 
    "stderr": "OpenSSH_5.3p1, OpenSSL 1.0.1e-fips 11 Feb 2013\ndebug1: Reading configuration data /etc/ssh/ssh_config\r\ndebug1: Applying options for *\r\ndebug1: auto-mux: Trying existing master\r\ndebug1: mux_client_request_session: master session id: 2\r\ndebug1: mux_client_request_session: master session id: 2\r\nShared connection to client01.example.com closed.\r\n", 
    "stdout": "Filesystem      Size  Used Avail Use% Mounted on\r\n/dev/sda3       6.6G  815M  5.5G  13% /\r\ntmpfs           499M     0  499M   0% /dev/shm\r\n/dev/sda1       190M   27M  154M  15% /boot\r\n"
}

client02.example.com | success >> {
    "changed": true, 
    "rc": 0, 
    "stderr": "OpenSSH_5.3p1, OpenSSL 1.0.1e-fips 11 Feb 2013\ndebug1: Reading configuration data /etc/ssh/ssh_config\r\ndebug1: Applying options for *\r\ndebug1: auto-mux: Trying existing master\r\ndebug1: mux_client_request_session: master session id: 2\r\ndebug1: mux_client_request_session: master session id: 2\r\nShared connection to client02.example.com closed.\r\n", 
    "stdout": "Filesystem      Size  Used Avail Use% Mounted on\r\n/dev/sda3       6.6G  815M  5.5G  13% /\r\ntmpfs           499M     0  499M   0% /dev/shm\r\n/dev/sda1       190M   27M  154M  15% /boot\r\n"
}

2. copy模塊

實現主控端向目標主機拷貝文件, 類似scp功能.

該實例實現~/test.sh文件至webservers組目標主機/tmp下, 並更新文件owner和group

# ansible webservers -m copy -a "src=~/test.sh dest=/tmp/ owner=root group=root mode=0755"

# ansible webservers -m copy -a "src=~/test.sh dest=/tmp/ owner=root group=root mode=0755"
client01.example.com | success >> {
    "changed": true, 
    "checksum": "c989bd551bfa8c755f6cacacb90c5c509432110e", 
    "dest": "/tmp/test.sh", 
    "gid": 0, 
    "group": "root", 
    "md5sum": "69a238d8cb3c5f979252010b3299e524", 
    "mode": "0755", 
    "owner": "root", 
    "size": 6, 
    "src": "/root/.ansible/tmp/ansible-tmp-1445322165.21-234077402845688/source", 
    "state": "file", 
    "uid": 0
}

client02.example.com | success >> {
    "changed": true, 
    "checksum": "c989bd551bfa8c755f6cacacb90c5c509432110e", 
    "dest": "/tmp/test.sh", 
    "gid": 0, 
    "group": "root", 
    "md5sum": "69a238d8cb3c5f979252010b3299e524", 
    "mode": "0755", 
    "owner": "root", 
    "size": 6, 
    "src": "/root/.ansible/tmp/ansible-tmp-1445322165.2-164402895387597/source", 
    "state": "file", 
    "uid": 0
}

3.stat模塊

獲取遠程文件狀態信息, 包括atime, ctime, mtime, md5, uid, gid等信息.

# ansible webservers -m stat -a "path=/etc/sysctl.conf"

client02.example.com | success >> {
    "changed": false, 
    "stat": {
        "atime": 1445312213.9599864, 
        "checksum": "704d7d26321b453d973939ee41aaf9861e238a78", 
        "ctime": 1444969315.401, 
        "dev": 2051, 
        "exists": true, 
        "gid": 0, 
        "gr_name": "root", 
        "inode": 130328, 
        "isblk": false, 
        "ischr": false, 
        "isdir": false, 
        "isfifo": false, 
        "isgid": false, 
        "islnk": false, 
        "isreg": true, 
        "issock": false, 
        "isuid": false, 
        "md5": "9ce78fbee91a542ca29d3e7945486e27", 
        "mode": "0644", 
        "mtime": 1437725687.0, 
        "nlink": 1, 
        "path": "/etc/sysctl.conf", 
        "pw_name": "root", 
        "rgrp": true, 
        "roth": true, 
        "rusr": true, 
        "size": 998, 
        "uid": 0, 
        "wgrp": false, 
        "woth": false, 
        "wusr": true, 
        "xgrp": false, 
        "xoth": false, 
        "xusr": false
    }
}

client01.example.com | success >> {
    "changed": false, 
    "stat": {
        "atime": 1445312212.9747968, 
        "checksum": "704d7d26321b453d973939ee41aaf9861e238a78", 
        "ctime": 1444969315.401, 
        "dev": 2051, 
        "exists": true, 
        "gid": 0, 
        "gr_name": "root", 
        "inode": 130328, 
        "isblk": false, 
        "ischr": false, 
        "isdir": false, 
        "isfifo": false, 
        "isgid": false, 
        "islnk": false, 
        "isreg": true, 
        "issock": false, 
        "isuid": false, 
        "md5": "9ce78fbee91a542ca29d3e7945486e27", 
        "mode": "0644", 
        "mtime": 1437725687.0, 
        "nlink": 1, 
        "path": "/etc/sysctl.conf", 
        "pw_name": "root", 
        "rgrp": true, 
        "roth": true, 
        "rusr": true, 
        "size": 998, 
        "uid": 0, 
        "wgrp": false, 
        "woth": false, 
        "wusr": true, 
        "xgrp": false, 
        "xoth": false, 
        "xusr": false
    }
}

4.get_url模塊

實現在遠程主機下載指定URL到本地.

# ansible webservers -m get_url -a "url=http://www.showerlee.com dest=/tmp/index.html mode=0400 force=yes"

client02.example.com | success >> {
    "changed": true, 
    "checksum": "470d6ab960810153bb8149c3754b0e8a2d89209d", 
    "dest": "/tmp/index.html", 
    "gid": 0, 
    "group": "root", 
    "md5sum": "009949f770f35a4ea82105e5e923abcb", 
    "mode": "0400", 
    "msg": "OK (unknown bytes)", 
    "owner": "root", 
    "sha256sum": "", 
    "size": 81635, 
    "src": "/tmp/tmpa44PoE", 
    "state": "file", 
    "uid": 0, 
    "url": "http://www.showerlee.com"
}

client01.example.com | success >> {
    "changed": true, 
    "checksum": "9b1afd16f97c07638965ba0c5cf01037af00a38a", 
    "dest": "/tmp/index.html", 
    "gid": 0, 
    "group": "root", 
    "md5sum": "5a935e77927286dfcb7a0190e8af461b", 
    "mode": "0400", 
    "msg": "OK (unknown bytes)", 
    "owner": "root", 
    "sha256sum": "", 
    "size": 81679, 
    "src": "/tmp/tmp5WHuj0", 
    "state": "file", 
    "uid": 0, 
    "url": "http://www.showerlee.com"
}

5.yum模塊

Linux包管理平臺操作, 常見都會有yum和apt, 此處會調用yum管理模式

# ansible servers -m yum -a "name=curl state=latest"

client01.example.com | success >> {
    "changed": false, 
    "msg": "", 
    "rc": 0, 
    "results": [
        "All packages providing curl are up to date"
    ]
}

client02.example.com | success >> {
    "changed": false, 
    "msg": "", 
    "rc": 0, 
    "results": [
        "All packages providing curl are up to date"
    ]
}

6. cron模塊

遠程主機crontab配置

# ansible webservers -m cron -a "name=‘check dir‘ hour=‘5,2‘ job=‘ls -alh > /dev/null‘"

client02.example.com | success >> {
    "changed": true, 
    "jobs": [
        "check dir"
    ]
}

client01.example.com | success >> {
    "changed": true, 
    "jobs": [
        "check dir"
    ]
}

7.service模塊

遠程主機系統服務管理

# ansible webservers -m service -a "name=crond state=stopped"

# ansible webservers -m service -a "name=crond state=restarted"

# ansible webservers -m service -a "name=crond state=reloaded"

8.user服務模塊

遠程主機系統用戶管理

添加用戶:

# ansible webservers -m user -a "name=johnd comment=‘John Doe‘"

刪除用戶:

# ansible webservers -m user -a "name=johnd state=absent remove=yes"

四. playbook介紹

playbook是一個不同於使用Ansible命令行執行方式的模式, 其功能是將大量命令行配置集成到一起形成一個可定制的多主機配置管理部署工具.

它通過YAML格式定義, 可以實現向多臺主機的分發應用部署.

以下給大家詳細介紹一個針對nginx嵌套復用結構的playbook部署實例:

1. 構建目錄結構

# cd /etc/ansible/

# mkdir group_vars

# mkdir roles

2.定義host

# vi /etc/ansible/hosts

[webservers]
client01.example.com
client02.example.com
[nginx01]
client01.example.com
[nginx02]
client02.example.com

3.定義變量

# vi /etc/ansible/group_vars/nginx01

worker_processes: 4
num_cpus: 4
max_open_file: 65506
root: /data
remote_user: root

# vi /etc/ansible/group_vars/nginx02

worker_processes: 2
num_cpus: 2
max_open_file: 35506
root: /www
remote_user: root

Tips:這裏在group_vars下定義的文件名必須對應hosts文件下的group標簽, 通過這裏定義的不同參數從而部署不同類型的主機配置.

4.創建roles入口文件

# vi /etc/ansible/site.yml

- hosts: webservers
  roles:
  - base_env
- hosts: nginx01
  roles:
  - nginx01
- hosts: nginx02
  roles:
  - nginx02

Tips: 這裏的roles:下的字符串需對應roles目錄下的目錄名.

5.定義全局role base_env

創建目錄結構

# mkdir -p /etc/ansible/roles/base_env/tasks

# vi /etc/ansible/roles/base_env/tasks/main.yml

# 將EPEL的yum源配置文件傳送到客戶端
- name: Create the contains common plays that will run on all nodes 
  copy: src=epel.repo dest=/etc/yum.repos.d/epel.repo
- name: Create the GPG key for EPEL
  copy: src=RPM-GPG-KEY-EPEL-6 dest=/etc/pki/rpm-gpg
  
# 關閉SELINUX
- name: test to see if selling is running
  command: getenforce
  register: sestatus
  changed_when: false

# 刪除iptables默認規則並保存
- name: remove the default iptables rules
  command: iptables -F
- name: save iptables rules
  command: service iptables save

將對應需要拷貝到遠程的文件復制到base_env/files目錄下

# mkdir -p /etc/ansible/roles/base_env/files

# cp /etc/yum.repos.d/epel.repo /etc/ansible/roles/base_env/files

# cp /etc/pki/rpm-gpg/RPM-GPG-KEY-EPEL-6 /etc/ansible/roles/base_env/files

6. 定義nginx01和ngnix02 role

創建目錄結構

# mkdir -p /etc/ansible/roles/nginx{01,02}

# mkdir -p /etc/ansible/roles/nginx01/tasks

# mkdir -p /etc/ansible/roles/nginx02/tasks

# vi /etc/ansible/roles/nginx01/tasks/main.yml

# 安裝nginx最新版本
- name: ensure nginx is at the latest version
  yum: pkg=nginx state=latest

# 將nginx配置文件傳送到遠程目錄
- name: write the nginx config file
  template: src=nginx.conf dest=/etc/nginx/nginx.conf
  notify: restart nginx # 重啟nginx

# 創建nginx根目錄
- name: Create Web Root
  file: dest={{ root }} mode=775 state=directory owner=nginx group=nginx
  notify: reload nginx
- name: ensure nginx is running
  service: name=nginx state=restarted

# cp /home/ansible/roles/nginx01/tasks/main.yml /home/ansible/roles/nginx02/tasks/main.yml

7.定義files

# mkdir -p /etc/ansible/roles/nginx01/templates

# mkdir -p /etc/ansible/roles/nginx02/templates

# vi /etc/ansible/roles/nginx01/templates/nginx.conf

# For more information on configuration, see: 

user              nginx;  
worker_processes  {{ worker_processes }};  
{% if num_cpus == 2 %}  
worker_cpu_affinity 01 10;  
{% elif num_cpus == 4 %}  
worker_cpu_affinity 1000 0100 0010 0001;  
{% elif num_cpus >= 8 %}  
worker_cpu_affinity 00000001 00000010 00000100 00001000 00010000 00100000 01000000 10000000;  
{% else %}  
worker_cpu_affinity 1000 0100 0010 0001;  
{% endif %}  
worker_rlimit_nofile {{ max_open_file }};  
  
error_log  /var/log/nginx/error.log;  
#error_log  /var/log/nginx/error.log  notice;  
#error_log  /var/log/nginx/error.log  info;  
  
pid        /var/run/nginx.pid;  
  
events {  
    worker_connections  {{ max_open_file }};  
}  
  
  
http {  
    include       /etc/nginx/mime.types;  
    default_type  application/octet-stream;  
  
    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;  
  
    #keepalive_timeout  0;  
    keepalive_timeout  65;  
  
    #gzip  on;  
      
    # Load config files from the /etc/nginx/conf.d directory  
    # The default server is in conf.d/default.conf  
    #include /etc/nginx/conf.d/*.conf;  
    server {  
        listen       80 default_server;  
        server_name  _;  
  
        #charset koi8-r;  
  
        #access_log  logs/host.access.log  main;  
  
        location / {  
            root   {{ root }};  
            index  index.html index.htm;  
        }  
  
        error_page  404              /404.html;  
        location = /404.html {  
            root   /usr/share/nginx/html;  
        }  
  
        # redirect server error pages to the static page /50x.html  
        #  
        error_page   500 502 503 504  /50x.html;  
        location = /50x.html {  
            root   /usr/share/nginx/html;  
        }  
  
    }  
  
} 

Tip: worker_processes, num_cpus, max_open_file, root等參數會調用group_vars目錄下配置文件中相應的變量值

# cp /etc/ansible/roles/nginx01/templates/nginx.conf /etc/ansible/roles/nginx02/templates/nginx.conf

8.執行playbook

# ansible-playbook -i /etc/ansible/hosts /etc/ansible/site.yml -f 10

Tips: -f 為啟動10個並行進程執行playbook, -i 定義inventory host文件, site.yml 為入口文件

PLAY [webservers] ************************************************************* 

GATHERING FACTS *************************************************************** 
ok: [client02.example.com]
ok: [client01.example.com]

TASK: [base_env | Create the contains common plays that will run on all nodes] *** 
ok: [client01.example.com]
ok: [client02.example.com]

TASK: [base_env | Create the GPG key for EPEL] ******************************** 
ok: [client02.example.com]
ok: [client01.example.com]

TASK: [base_env | test to see if selling is running] ************************** 
ok: [client01.example.com]
ok: [client02.example.com]

TASK: [base_env | remove the default iptables rules] ************************** 
changed: [client02.example.com]
changed: [client01.example.com]

TASK: [base_env | save iptables rules] **************************************** 
changed: [client01.example.com]
changed: [client02.example.com]

PLAY [nginx01] **************************************************************** 

GATHERING FACTS *************************************************************** 
ok: [client01.example.com]

TASK: [nginx01 | ensure nginx is at the latest version] *********************** 
ok: [client01.example.com]

TASK: [nginx01 | write the nginx config file] ********************************* 
ok: [client01.example.com]

TASK: [nginx01 | Create Web Root] ********************************************* 
ok: [client01.example.com]

TASK: [nginx01 | ensure nginx is running] ************************************* 
changed: [client01.example.com]

PLAY [nginx02] **************************************************************** 

GATHERING FACTS *************************************************************** 
ok: [client02.example.com]

TASK: [nginx02 | ensure nginx is at the latest version] *********************** 
ok: [client02.example.com]

TASK: [nginx02 | write the nginx config file] ********************************* 
ok: [client02.example.com]

TASK: [nginx02 | Create Web Root] ********************************************* 
ok: [client02.example.com]

TASK: [nginx02 | ensure nginx is running] ************************************* 
changed: [client02.example.com]

PLAY RECAP ******************************************************************** 
client01.example.com       : ok=11   changed=3    unreachable=0    failed=0   
client02.example.com       : ok=11   changed=3    unreachable=0    failed=0 

最終部署目錄結構如下

# tree /etc/ansible/

/etc/ansible/
├── ansible.cfg
├── group_vars
│   ├── nginx01
│   └── nginx02
├── hosts
├── hosts.bak
├── roles
│   ├── base_env
│   │   ├── files
│   │   │   ├── epel.repo
│   │   │   └── RPM-GPG-KEY-EPEL-6
│   │   └── tasks
│   │       └── main.yml
│   ├── nginx01
│   │   ├── tasks
│   │   │   └── main.yml
│   │   └── templates
│   │       └── nginx.conf
│   └── nginx02
│       ├── tasks
│       │   └── main.yml
│       └── templates
│           └── nginx.conf
└── site.yml

11 directories, 13 files

到此, 部署nignx到兩臺遠程webserver服務器全部完成.

CentOS6.7下Ansible部署