配置管理工具(SCM,Software Configuration Management)能夠將代碼、軟件方式實現的基礎設施配置信息保存,也能夠根據需求變化反覆進行變動。 相關工具包括Ansible、Chef、Puppet、SaltStack等,版本管理工具備Git、Subversion等。 配置管理工具的特徵html
Ansible是基於python語言開發的一種開源的自動化運維工具和平臺,集合了衆多運維工具的優勢,實現了批量配置管理、批量應用部署和運行命令執行特定任務等功能。 Ansible基於SSH來和遠程主機通信,不須要在遠程主機上安裝client/agents。 配置信息語法規則簡單,命令簡潔,容易入門。 Ansible只是提供一種框架,自己沒有批量部署的能力。真正具備批量部署的是ansible所運行的模塊。主要包括:python
操做簡單,例如在CentOS7中安裝Ansible只需執行yum -y install epel-release
和yum -y install ansible
就能夠。linux
[root@localhost ~]# ansible usage: ansible [-h] [--version] [-v] [-b] [--become-method BECOME_METHOD] [--become-user BECOME_USER] [-K] [-i INVENTORY] [--list-hosts] [-l SUBSET] [-P POLL_INTERVAL] [-B SECONDS] [-o] [-t TREE] [-k] [--private-key PRIVATE_KEY_FILE] [-u REMOTE_USER] [-c CONNECTION] [-T TIMEOUT] [--ssh-common-args SSH_COMMON_ARGS] [--sftp-extra-args SFTP_EXTRA_ARGS] [--scp-extra-args SCP_EXTRA_ARGS] [--ssh-extra-args SSH_EXTRA_ARGS] [-C] [--syntax-check] [-D] [-e EXTRA_VARS] [--vault-id VAULT_IDS] [--ask-vault-pass | --vault-password-file VAULT_PASSWORD_FILES] [-f FORKS] [-M MODULE_PATH] [--playbook-dir BASEDIR] [-a MODULE_ARGS] [-m MODULE_NAME] pattern ansible: error: too few arguments [root@localhost ~]# [root@localhost ~]# ansible --version ansible 2.9.0 config file = /etc/ansible/ansible.cfg configured module search path = [u'/root/.ansible/plugins/modules', u'/usr/share/ansible/plugins/modules'] ansible python module location = /usr/lib/python2.7/site-packages/ansible executable location = /bin/ansible python version = 2.7.5 (default, Apr 11 2018, 07:36:10) [GCC 4.8.5 20150623 (Red Hat 4.8.5-28)] [root@localhost ~]# [root@localhost ~]# ll /etc/ansible/ total 24 -rw-r--r-- 1 root root 19985 Nov 9 05:11 ansible.cfg -rw-r--r-- 1 root root 1016 Nov 9 05:11 hosts drwxr-xr-x 2 root root 6 Nov 9 05:11 roles [root@localhost ~]#
默認是「/etc/ansible/hosts文件,定義了Ansible進行遠程控制的對象服務器列表。 也能夠在運行時使用-i參數指定其餘文件做爲Inventory文件。nginx
[root@localhost ~]# sh -c "echo \"localhost\" >> /etc/ansible/hosts"
# yum -y install epel-release # yum -y install nginx # echo "hello, Nginx" > /usr/share/nginx/html/index.html # systemctl start nginx
[root@localhost ~]# systemctl status nginx.service ● nginx.service - The nginx HTTP and reverse proxy server Loaded: loaded (/usr/lib/systemd/system/nginx.service; disabled; vendor preset: disabled) Active: active (running) since Tue 2019-11-19 16:54:56 CST; 7min ago Process: 6752 ExecStart=/usr/sbin/nginx (code=exited, status=0/SUCCESS) Process: 6749 ExecStartPre=/usr/sbin/nginx -t (code=exited, status=0/SUCCESS) Process: 6747 ExecStartPre=/usr/bin/rm -f /run/nginx.pid (code=exited, status=0/SUCCESS) Main PID: 6754 (nginx) Tasks: 3 CGroup: /system.slice/nginx.service ├─6754 nginx: master process /usr/sbin/nginx ├─6755 nginx: worker process └─6756 nginx: worker process Nov 19 16:54:56 localhost.localdomain systemd[1]: Starting The nginx HTTP and reverse proxy server... Nov 19 16:54:56 localhost.localdomain nginx[6749]: nginx: the configuration file /etc/nginx/nginx.conf syntax is ok Nov 19 16:54:56 localhost.localdomain nginx[6749]: nginx: configuration file /etc/nginx/nginx.conf test is su...sful Nov 19 16:54:56 localhost.localdomain systemd[1]: Started The nginx HTTP and reverse proxy server. Hint: Some lines were ellipsized, use -l to show in full. [root@localhost ~]# [root@localhost ~]# curl http://192.168.16.101 hello, Nginx
[root@localhost ~]# ansible localhost -b -c local -m service -a "name=nginx state=started" localhost | SUCCESS => { "ansible_facts": { "discovered_interpreter_python": "/usr/bin/python" }, "changed": false, "name": "nginx", "state": "started", "status": { "ActiveEnterTimestamp": "Tue 2019-11-19 17:08:33 CST", "ActiveEnterTimestampMonotonic": "8773946590", "ActiveExitTimestampMonotonic": "0", "ActiveState": "active", ...... ...... ...... "WatchdogTimestamp": "Tue 2019-11-19 16:54:56 CST", "WatchdogTimestampMonotonic": "7957241107", "WatchdogUSec": "0" } } [root@localhost ~]#
[root@localhost ~]# systemctl stop nginx.service [root@localhost ~]# [root@localhost ~]# ansible localhost -b -c local -m service -a "name=nginx state=started" localhost | CHANGED => { "ansible_facts": { "discovered_interpreter_python": "/usr/bin/python" }, "changed": true, "name": "nginx", "state": "started", "status": { "ActiveEnterTimestampMonotonic": "0", "ActiveExitTimestampMonotonic": "0", "ActiveState": "inactive", ...... ...... ...... "WatchdogTimestampMonotonic": "0", "WatchdogUSec": "0" } } [root@localhost ~]#
使用ansible-playbook命令可以以分組的方式處理或者操做對象,執行從安裝、配置到啓動等一系列操做。 這一系列操做(構建信息)必須提早定義在playbook文件中,而後經過指定playbook文件自動開始執行構建。git
[root@localhost ~]# ansible-playbook -h usage: ansible-playbook [-h] [--version] [-v] [-k] [--private-key PRIVATE_KEY_FILE] [-u REMOTE_USER] [-c CONNECTION] [-T TIMEOUT] [--ssh-common-args SSH_COMMON_ARGS] [--sftp-extra-args SFTP_EXTRA_ARGS] [--scp-extra-args SCP_EXTRA_ARGS] [--ssh-extra-args SSH_EXTRA_ARGS] [--force-handlers] [--flush-cache] [-b] [--become-method BECOME_METHOD] [--become-user BECOME_USER] [-K] [-t TAGS] [--skip-tags SKIP_TAGS] [-C] [--syntax-check] [-D] [-i INVENTORY] [--list-hosts] [-l SUBSET] [-e EXTRA_VARS] [--vault-id VAULT_IDS] [--ask-vault-pass | --vault-password-file VAULT_PASSWORD_FILES] [-f FORKS] [-M MODULE_PATH] [--list-tasks] [--list-tags] [--step] [--start-at-task START_AT_TASK] playbook [playbook ...] Runs Ansible playbooks, executing the defined tasks on the targeted hosts. positional arguments: playbook Playbook(s) optional arguments: --ask-vault-pass ask for vault password --flush-cache clear the fact cache for every host in inventory --force-handlers run handlers even if a task fails --list-hosts outputs a list of matching hosts; does not execute anything else --list-tags list all available tags --list-tasks list all tasks that would be executed --skip-tags SKIP_TAGS only run plays and tasks whose tags do not match these values --start-at-task START_AT_TASK start the playbook at the task matching this name --step one-step-at-a-time: confirm each task before running --syntax-check perform a syntax check on the playbook, but do not execute it --vault-id VAULT_IDS the vault identity to use --vault-password-file VAULT_PASSWORD_FILES vault password file --version show program's version number, config file location, configured module search path, module location, executable location and exit -C, --check don't make any changes; instead, try to predict some of the changes that may occur -D, --diff when changing (small) files and templates, show the differences in those files; works great with --check -M MODULE_PATH, --module-path MODULE_PATH prepend colon-separated path(s) to module library (def ault=~/.ansible/plugins/modules:/usr/share/ansible/plu gins/modules) -e EXTRA_VARS, --extra-vars EXTRA_VARS set additional variables as key=value or YAML/JSON, if filename prepend with @ -f FORKS, --forks FORKS specify number of parallel processes to use (default=5) -h, --help show this help message and exit -i INVENTORY, --inventory INVENTORY, --inventory-file INVENTORY specify inventory host path or comma separated host list. --inventory-file is deprecated -l SUBSET, --limit SUBSET further limit selected hosts to an additional pattern -t TAGS, --tags TAGS only run plays and tasks tagged with these values -v, --verbose verbose mode (-vvv for more, -vvvv to enable connection debugging) Connection Options: control as whom and how to connect to hosts --private-key PRIVATE_KEY_FILE, --key-file PRIVATE_KEY_FILE use this file to authenticate the connection --scp-extra-args SCP_EXTRA_ARGS specify extra arguments to pass to scp only (e.g. -l) --sftp-extra-args SFTP_EXTRA_ARGS specify extra arguments to pass to sftp only (e.g. -f, -l) --ssh-common-args SSH_COMMON_ARGS specify common arguments to pass to sftp/scp/ssh (e.g. ProxyCommand) --ssh-extra-args SSH_EXTRA_ARGS specify extra arguments to pass to ssh only (e.g. -R) -T TIMEOUT, --timeout TIMEOUT override the connection timeout in seconds (default=10) -c CONNECTION, --connection CONNECTION connection type to use (default=smart) -k, --ask-pass ask for connection password -u REMOTE_USER, --user REMOTE_USER connect as this user (default=None) Privilege Escalation Options: control how and which user you become as on target hosts --become-method BECOME_METHOD privilege escalation method to use (default=sudo), use `ansible-doc -t become -l` to list valid choices. --become-user BECOME_USER run operations as this user (default=root) -K, --ask-become-pass ask for privilege escalation password -b, --become run operations with become (does not imply password prompting) [root@localhost ~]#
用於預先驗證要作的更改操做是否和預期一致。 在此模式下,Ansible不會真正在實際環境中執行更改操做,而是事先顯示在實際執行時那些內容會被更改。 具體使用方法就是同時使用「--check」和「--diff」選項,表示以dry-run模式運行並顯示詳細的變動內容。github
下載地址:https://github.com/devops-book/ansible-playbook-sampleweb
[root@localhost ansible-playbook-sample]# ll total 12 -rw-r--r-- 1 root root 81 Nov 19 17:25 development drwxr-xr-x 2 root root 73 Nov 19 17:25 group_vars -rw-r--r-- 1 root root 79 Nov 19 17:25 production drwxr-xr-x 7 root root 91 Nov 19 17:25 roles -rw-r--r-- 1 root root 150 Nov 19 17:25 site.yml [root@localhost ansible-playbook-sample]# [root@localhost ansible-playbook-sample]# cat site.yml --- - hosts: webservers become: yes connection: local roles: - common - nginx # - serverspec # - serverspec_sample # - jenkins [root@localhost ansible-playbook-sample]# [root@localhost ansible-playbook-sample]# tree . ├── development ├── group_vars │ ├── development-webservers.yml │ └── production-webservers.yml ├── production ├── roles │ ├── common │ │ ├── meta │ │ │ └── main.yml │ │ └── tasks │ │ └── main.yml │ ├── jenkins │ │ ├── defaults │ │ │ └── main.yml │ │ ├── handlers │ │ │ └── main.yml │ │ ├── meta │ │ │ └── main.yml │ │ ├── README.md │ │ ├── tasks │ │ │ └── main.yml │ │ ├── tests │ │ │ ├── inventory │ │ │ └── test.yml │ │ └── vars │ │ └── main.yml │ ├── nginx │ │ ├── meta │ │ │ └── main.yml │ │ ├── tasks │ │ │ └── main.yml │ │ └── templates │ │ └── index.html.j2 │ ├── serverspec │ │ ├── meta │ │ │ └── main.yml │ │ └── tasks │ │ └── main.yml │ └── serverspec_sample │ ├── files │ │ └── serverspec_sample │ │ ├── Rakefile │ │ └── spec │ │ ├── localhost │ │ └── spec_helper.rb │ ├── meta │ │ └── main.yml │ ├── tasks │ │ └── main.yml │ ├── templates │ │ ├── nginx_spec.rb.j2 │ │ └── web_spec.rb.j2 │ └── vars │ └── main.yml └── site.yml 28 directories, 27 files [root@localhost ansible-playbook-sample]#
[root@localhost ansible-playbook-sample]# cat development [development-webservers] localhost [webservers:children] development-webservers [root@localhost ansible-playbook-sample]# [root@localhost ansible-playbook-sample]# ansible-playbook -i development site.yml PLAY [webservers] ************************************************************************************************** TASK [Gathering Facts] ********************************************************************************************* ok: [localhost] TASK [common : install epel] *************************************************************************************** ok: [localhost] TASK [nginx : install nginx] *************************************************************************************** ok: [localhost] TASK [nginx : replace index.html] ********************************************************************************** changed: [localhost] TASK [nginx : nginx start] ***************************************************************************************** changed: [localhost] PLAY RECAP ********************************************************************************************************* localhost : ok=5 changed=2 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0 [root@localhost ansible-playbook-sample]# [root@localhost ansible-playbook-sample]# curl localhost hello, development ansible [root@localhost ansible-playbook-sample]# curl 192.168.16.101 hello, development ansible [root@localhost ansible-playbook-sample]#
[root@localhost ansible-playbook-sample]# cat production [production-webservers] localhost [webservers:children] production-webservers [root@localhost ansible-playbook-sample]# [root@localhost ansible-playbook-sample]# ansible-playbook -i production site.yml PLAY [webservers] ***************************************************************************************** TASK [Gathering Facts] ************************************************************************************ ok: [localhost] TASK [common : install epel] ****************************************************************************** ok: [localhost] TASK [nginx : install nginx] ****************************************************************************** ok: [localhost] TASK [nginx : replace index.html] ************************************************************************* changed: [localhost] TASK [nginx : nginx start] ******************************************************************************** ok: [localhost] PLAY RECAP ********************************************************************************************************************************************************************************************************************************* localhost : ok=5 changed=1 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0 [root@localhost ansible-playbook-sample]# root@localhost ansible-playbook-sample]# curl 192.168.16.101 hello, production ansible [root@localhost ansible-playbook-sample]#