斌的招兒
????????網上教程大多都是官網模板化的教程和文檔,這里小斌用自己實際生產環境使用的例子給大家做一個詳解。涉及到一整套ansible的使用,對于roles的使用,也僅涉及到tasks和files目錄,方便大家快速上手并規范化管理。
0.環境配置
192.168.255.120 Ansible控制機
192.168.255.123 Ansible被控機
1.安裝Ansible
作為學習模擬使用,這里就使用yum安裝
[root@120 ~]# yum install -y ansible
2.配置免密
[root@120 ~]# ssh-keygen[root@120 ~]# ssh-copy-id root@192.168.255.123
3.配置主機列表
配置主機列表,我們一般會選擇在hosts文件中定義,但是面臨一個問題,后續管理主機多,不同項目也有可能設計同一臺主機,我們每次都要在一個文件里追加追加,極為不便,所以我們單獨建一個目錄用來管理主機列表。
我們修改一下配置文件里的主機清單位置,指定一個目錄,目錄下文件以.conf結尾,書寫格式于hosts中一致。
4.測試主機連通性
[root@120 ansible]# ansible yzb -m ping
192.168.255.123 | SUCCESS => {"ansible_facts": {"discovered_interpreter_python": "/usr/bin/python"}, "changed": false, "ping": "pong"
}
[root@120 ansible]#
5.生成角色
這里不需要手動創建目錄和文件,可以借助ansible自帶的ansible-galaxy工具。
[root@120 roles]# pwd
/etc/ansible/roles[root@120 roles]# ls[root@120 roles]# ansible-galaxy init init-nginx
- Role init-nginx was created successfully[root@120 roles]# ls
init-nginx[root@120 roles]# tree init-nginx/
init-nginx/
├── defaults
│?? └── main.yml
├── files
├── handlers
│?? └── main.yml
├── meta
│?? └── main.yml
├── README.md
├── tasks
│?? └── main.yml
├── templates
├── tests
│?? ├── inventory
│?? └── test.yml
└── vars└── main.yml8 directories, 8 files
[root@120 roles]#
我們可以看到使用 ansible-galaxy init 命令創建了一個新角色的框架
6.配置
開頭說過了,僅涉及到tasks和files目錄,方便大家快速上手并規范化管理。所以它來了:
這里我們以安裝nginx為例子,yum沒難度是吧,好的,我們用源碼安裝的形式教學。
1.熟悉源碼安裝nginx
只有熟悉怎么源碼安裝nginx,才能編寫劇本自動化安裝。源碼安裝其實就四步:
1.包弄上來解壓
2.添加補丁
3.編譯安裝
4.添加systemed管理
2.準備文件
如圖,我們看到四個文件,文件作用如下:
-
- nginx.tar.gz:包含nginx源碼包和補丁包
- install.sh:內容為將補丁文件應用到源代碼文件中,并執行編譯安裝,寫成腳本減少playbook的篇幅
- nginx.conf:nginx的配置文件,如果業務有特殊模塊需求,可以提前編寫好配置文件發放到目標主機
- nginx.service:nginx的systemed管理文件
nginx.conf
[root@120 files]# cat nginx.conf
pid /usr/local/nginx/nginx.pid;worker_processes 4;
worker_cpu_affinity 1000 0100 0010 0001;
worker_rlimit_nofile 102400;events {worker_connections 102400;multi_accept on;use epoll;
}http {vhost_traffic_status_zone;log_format json_format '{"timestamp":"$msec",''"time_iso":"$time_iso8601",''"time_local":"$time_local",''"request_time":"$request_time",''"remote_user":"$remote_user",''"remote_addr":"$remote_addr",''"http_x_forwarded_for":"$http_x_forwarded_for",''"request":"$request",''"status":"$status",''"body_bytes_send":"$body_bytes_sent",''"upstream_addr":"$upstream_addr",''"upstream_response_time":"$upstream_response_time",''"upstream_http_content_type":"$upstream_http_content_type",''"upstream_http_content_disposition":"$upstream_http_content_disposition",''"upstream_status":"$upstream_status",''"http_user_agent":"$http_user_agent",''"http_referer":"$http_referer",''"connection":"$connection",''"connection_requests":"$connection_requests",''"scheme":"$scheme",''"host":"$host",''"http_via":"$http_via",''"request_id":"$request_id"}';map $time_iso8601 $logdate {'~^(?<ymd>\d{4}-\d{2}-\d{2})' $ymd;default 'date-not-found';}# 日志文件名中帶有變量時由子進程創建,需要子進程具有目錄寫入權限access_log /ware/logs/nginx/access-$logdate.log json_format;error_log /ware/logs/nginx/error.log error;server_tokens off;sendfile on;tcp_nopush on;tcp_nodelay on;keepalive_timeout 30;keepalive_requests 100000;client_header_timeout 10;client_body_timeout 10;client_max_body_size 100m;reset_timedout_connection on;send_timeout 10;include mime.types;default_type application/octet-stream;charset UTF-8;gzip on;gzip_vary on;gzip_disable "MSIE [1-6].";gzip_http_version 1.0;gzip_comp_level 4;# gzip_static on;gzip_min_length 1024;gzip_buffers 4 16k;gzip_proxied expired no-cache no-store private auth;gzip_types text/plain text/css text/javascript application/x-javascript application/xml application/json application/xml+rss;open_file_cache max=100000 inactive=20s;open_file_cache_valid 30s;open_file_cache_min_uses 2;open_file_cache_errors on;proxy_connect_timeout 75;proxy_read_timeout 300;proxy_send_timeout 300;proxy_buffer_size 64k;proxy_buffers 4 64k;proxy_busy_buffers_size 128k;proxy_temp_file_write_size 128k;include /opt/env/nginx/servs/*.upstreams;include /opt/env/nginx/servs/http-*.conf;
}stream {include /opt/env/nginx/servs/tcp-*.conf;
}
?nginx.service
[root@120 files]# cat nginx.service
[Unit]
Description=nginx - high performance web server
Documentation=http://nginx.org/en/docs/
After=network.target remote-fs.target nss-lookup.target[Service]
Type=forking
PIDFile=/usr/local/nginx/nginx.pid
ExecStartPre=/usr/local/nginx/sbin/nginx -t -c /usr/local/nginx/conf/nginx.conf
ExecStart=/usr/local/nginx/sbin/nginx -c /usr/local/nginx/conf/nginx.conf
ExecReload=/bin/kill -s HUP $MAINPID
ExecStop=/bin/kill -s QUIT $MAINPID
PrivateTmp=true[Install]
WantedBy=multi-user.target
install.sh?
[root@120 files]# cat install.sh
#!/bin/bashdir=/server/storagecd $dirtar xf nginx.tar.gzcd /server/storage/nginxunzip nginx_upstream_check_module.zip
unzip nginx-upstream-fair.zip
unzip nginx-module-vts.zip
unzip ngx_http_substitutions_filter_module.zip
tar zxvf nginx-1.16.1.tar.gzcd $dir/nginx/nginx-upstream-fair-master
sed -i 's/default_port/no_port/g' ngx_http_upstream_fair_module.c
patch -p1 < $dir/nginx/nginx_upstream_check_module-master/upstream_fair.patchcd $dir/nginx/nginx-1.16.1
patch -p1 < $dir/nginx/nginx_upstream_check_module-master/check_1.16.1+.patchcd $dir/nginx/nginx-1.16.1./configure \
--prefix=/usr/local/nginx \
--with-http_realip_module \
--with-http_ssl_module \
--with-http_addition_module \
--with-http_sub_module \
--with-http_dav_module \
--with-http_gzip_static_module \
--with-http_stub_status_module \
--with-stream \
--with-http_stub_status_module \
--add-module=${dir}/nginx/nginx_upstream_check_module-master \
--add-module=${dir}/nginx/nginx-upstream-fair-master \
--add-module=${dir}/nginx/nginx-module-vts-master \
--add-module=${dir}/nginx/ngx_http_substitutions_filter_module-mastermake && make install
3.編寫劇本
[root@120 tasks]# cd /opt/ansible/roles/init-nginx/tasks[root@120 tasks]# cat main.yml
---
# tasks file for ./nginx- name: create nginx dirfile: path: /opt/env/nginx/servsstate: directoryowner: rootgroup: rootmode: 0755- name: create nginx certsfile:path: /opt/env/nginx/certsstate: directoryowner: rootgroup: rootmode: 0755- name: create nginx logsfile:path: /ware/logs/nginxstate: directoryowner: rootgroup: rootmode: 0755- name: modify logs shell: chmod -R 777 /ware/logs/nginx- name: yum installyum: name: "{{ with_item }}"state: latestvars:with_item:- wget- zip- unzip- patch- gcc- gcc-c++- pcre- pcre-devel- zlib- zlib-devel- openssl- openssl-devel- name: copy nginx.tar.gzvars:- item: /server/storage/copy:src: nginx.tar.gzdest: "{{ item }}"owner: rootgroup: rootmode: 0644- name: copy install.shcopy:src: install.shdest: /server/storage/nginx/mode: 755- name: install nginxshell: /server/storage/nginx/install.sh- name: copy nginx confcopy:src: nginx.confdest: /usr/local/nginx/conf/nginx.confowner: rootgroup: rootmode: 0644- name: copy nginx.servicecopy:src: nginx.servicedest: /usr/lib/systemd/systemowner: rootgroup: rootmode: 0644- name: daemon reloadshell: systemctl daemon-reload- name: enable nginxservice:name: nginxenabled: yes[root@120 tasks]#
7.你寫的不對
我們寫的playbook都是以hosts開頭的,你這直接以具體的task開頭,這咋運行?
????????沒錯,一般的劇本,都是以上圖的格式書寫的,但是我們學習Ad-Hoc和roles是干啥的,為了我們的規范化和模塊化,要讓不同的主機組都能使用一個roles。所以我們需要建一個文件,內容如下:
[root@120 ansible]# cat init-nginx.yml
- hosts: yzbremote_user: rootroles:- role: init-nginx
????????我們單獨拉出來一個文件,這樣可以使不同的主機組、不同的任務都有單獨的配置文件,清晰明了,也實現了roles的復用!
8.執行劇本,完成目標主機nginx安裝
ansible-playbook init-nginx.yml