ansible簡介
Ansible是一種IT自動化工具。它可以配置系統,部署軟件以及協調更高級的IT任務,例如持續部署,滾動更新。Ansible適用於管理企業IT基礎設施,從具有少數主機的小規模到數千個實例的企業環境。Ansible也是一種簡單的自動化語言,可以完美地描述IT應用程序基礎結構。
-
簡單:減少學習成本
-
強大:協調應用程序生命周期
-
ansible安裝
yum -y install ansible

-
-
Modules:任務均有模塊完成,也可以自定義模塊,例如經常用的腳本。
-
Plugins:使用插件增加Ansible核心功能,自身提供了很多插件,也可以自定義插件。例如connection插件,用於連接目標主機。
-
主機清單
[webservers] alpha.example.org beta.example.org 192.168.1.100 www[001:006].example.com [dbservers] db01.intranet.mydomain.net db02.intranet.mydomain.net 10.25.1.56 10.25.1.57 db-[99:101]-node.example.com
命令行使用
ansible all -m ping ansible all -m shell -a "ls /root" -u root -k ansible webservers -m copy –a "src=/etc/hosts dest=/tmp/hosts"
ad-hoc命令是理解Ansible和在學習playbooks之前需要掌握的基礎知識。
SSH密碼認證: [webservers] 192.168.1.100:22 ansible_ssh_user=root ansible_ssh_pass=’123456’ 192.168.1.101:22 ansible_ssh_user=root ansible_ssh_pass=’123456’ SSH密鑰對認證 [webservers] 10.206.240.111:22 ansible_ssh_user=root ansible_ssh_key=/root/.ssh/id_rsa 10.206.240.112:22 ansible_ssh_user=root 也可以ansible.cfg在配置文件中指定: [defaults] private_key_file = /root/.ssh/id_rsa # 默認路徑
常用選項:
| 描述 | |
|---|---|
| -C, --check | 運行檢查,不執行任何操作 |
| -e EXTRA_VARS,--extra-vars=EXTRA_VARS | 設置附加變量 key=value |
| -u REMOTE_USER, --user=REMOTE_USER | SSH連接用戶,默認None |
| -k, --ask-pass | SSH連接用戶密碼 |
| -b, --become | 提權,默認root |
| -K, --ask-become-pass |
常用模塊
ansible-doc –s copy 查看模塊文檔
模塊文檔:https://docs.ansible.com/ansible/latest/modules/modules_by_category.html
shell:在目標主機執行shell命令
- name: 將命令結果輸出到指定文件 shell: somescript.sh >> somelog.txt - name: 切換目錄執行命令 shell: cmd: ls -l | grep log chdir: somedir/ - name: 編寫腳本 shell: | if [ 0 -eq 0 ]; then echo yes > /tmp/result else echo no > /tmp/result fi args: executable: /bin/bash
copy:將文件復制到遠程主機
- name: 拷貝文件 copy: src: /srv/myfiles/foo.conf dest: /etc/foo.conf owner: foo group: foo mode: u=rw,g=r,o=r # mode: u+rw,g-wx,o-rwx # mode: '0644' backup: yes
file:管理文件和文件屬性
- name: 創建目錄 file: path: /etc/some_directory state: directory mode: '0755' - name: 刪除文件 file: path: /etc/foo.txt state: absent - name: 遞歸刪除目錄 file: path: /etc/foo state: absent
yum:軟件包管理
- name: 安裝最新版apache yum: name: httpd state: latest - name: 安裝列表中所有包 yum: name: - nginx - postgresql - postgresql-server state: present - name: 卸載apache包 yum: name: httpd state: absent - name: 更新所有包 yum: name: '*' state: latest - name: 安裝nginx來自遠程repo yum: name: http://nginx.org/packages/rhel/7/x86_64/RPMS/nginx-1.14.0-1.el7_4.ngx.x86_64.rpm # name: /usr/local/src/nginx-release-centos-6-0.el6.ngx.noarch.rpm state: present
service/systemd:管理服務
- name: 服務管理 service: name: etcd state: started #state: stopped #state: restarted #state: reloaded - name: 設置開機啟動 service: name: httpd enabled: yes - name: 服務管理 systemd: name=etcd state=restarted enabled=yes daemon_reload=yes
unzrchive:
- name: 解壓 unarchive: src=test.tar.gz dest=/tmp
debug:執行過程中打印語句
- debug: msg: System {{ inventory_hostname }} has uuid {{ ansible_product_uuid }} - name: 顯示主機已知的所有變量 debug: var: hostvars[inventory_hostname] verbosity: 4
Playbook
如果Ansible模塊是您工作中的工具,那么Playbook就是您的使用說明書,而您的主機資產文件就是您的原材料。
與adhoc任務執行模式相比,Playbooks使用ansible是一種完全不同的方式,並且功能特別強大。
--- - hosts: webservers vars: http_port: 80 server_name: www.xxx.com remote_user: root gather_facts: false tasks: - name: 安裝nginx最新版 yum: pkg=nginx state=latest - name: 寫入nginx配置文件 template: src=nginx.conf dest=/etc/nginx/nginx.conf notify: - restart nginx - name: 確保nginx正在運行 service: name=nginx state=started enabled=yes handlers: - name: restart nginx service: name=nginx state=reloaded
......
server {
listen {{ inventory_hostename }}:{{ http_port }};
listen {{ server_name }};
server_name _;
root /usr/share/nginx/html;
location / {
}
}
主機和用戶
- hosts: webservers
remote_user: user1
become: yes
become_user: root
定義變量
#變量是應用於多個主機的便捷方式; 實際在主機執行之前,變量會對每個主機添加,然后在執行中引用。 ###命令行傳遞 -e VAR=VALUE ###主機變量與組變量 #在Inventory中定義變量。 [webservers] 192.168.1.100 ansible_ssh_user=root hostname=web1 192.168.1.100 ansible_ssh_user=root hostname=web2 [webservers:vars] ansible_ssh_user=root hostname=web1 ###單文件存儲 Ansible中的首選做法是不將變量存儲在Inventory中。 除了將變量直接存儲在Inventory文件之外,主機和組變量還可以存儲在相對於Inventory文件的單個文件中。 組變量: group_vars 存放的是組變量 group_vars/all.yml 表示所有主機有效,等同於[all:vars] grous_vars/etcd.yml 表示etcd組主機有效,等同於[etcd:vars] # vi /etc/ansible/group_vars/all.yml work_dir: /data # vi /etc/ansible/host_vars/webservers.yml nginx_port: 80 ###在playbook中定義 - hosts: webservers vars: http_port: 80 server_name: www.xxx.com ###Register變量 - shell: /usr/bin/uptime register: result - debug: var: result
列表任務
#每個play包含一系列任務。這些任務按照順序執行,在play中,所有主機都會執行相同的任務指令。play目的是將選擇的主機映射到任務。 tasks: - name: 安裝nginx最新版 yum: pkg=nginx state=latest
任務控制
#如果你有一個大的劇本,那么能夠在不運行整個劇本的情況下運行特定部分可能會很有用。 tasks: - name: 安裝nginx最新版 yum: pkg=nginx state=latest tags: install - name: 寫入nginx配置文件 template: src=/srv/httpd.j2 dest=/etc/nginx/nginx.conf tags: config 使用: ansible-playbook example.yml --tags "install" ansible-playbook example.yml --tags "install,config" ansible-playbook example.yml --skip-tags "install"
流程控制
常用循環語句:
| 描述 | |
|---|---|
| with_items | 標准循環 |
| with_fileglob | 遍歷目錄文件 |
| with_dict |
#條件 tasks: - name: 只在192.168.1.100運行任務 debug: msg="{{ansible_default_ipv4.address}}" when: ansible_default_ipv4.address == '192.168.1.100' #循環 tasks: - name: 批量創建用戶 user: name={{ item }} state=present groups=wheel with_items: - testuser1 - testuser2 - name: 解壓 copy: src={{ item }} dest=/tmp with_fileglob: - "*.txt"
模板
vars: domain: "www.xxx.com" tasks: - name: 寫入nginx配置文件 template: src=/srv/server.j2 dest=/etc/nginx/conf.d/server.conf # server.j2 {% set domain_name = domain %} server { listen 80; server_name {{ domain_name }}; location / { root /usr/share/html; } } #在jinja里使用ansible變量直接 {{ }}引用。使用ansible變量賦值jinja變量不用{{ }}引用。 定義變量: {% set local_ip = inventory_hostname %} 條件和循環: {% set list=['one', 'two', 'three'] %} {% for i in list %} {% if i == 'two' %} -> two {% elif loop.index == 3 %} -> 3 {% else %} {{i}} {% endif %} {% endfor %}
# tree .
.
├── ansible.cfg
├── docker_deploy.retry
├── docker_deploy.yaml
├── files
│ ├── daemon.json
│ ├── docker-18.09.6.tgz │ └── docker.service └── hosts # cat docker_deploy.yaml --- - hosts: docker vars: tmp_dir: '/tmp/docker' remote_user: root gather_facts: false tasks: - name: 創建臨時目錄 file: dest={{ tmp_dir }} state=directory - name: 分發並解壓docker二進制包 unarchive: src={{ item }} dest={{ tmp_dir }} with_fileglob: - "files/docker-*.tgz" - name: 移動docker二進制文件 shell: cp -rf {{ tmp_dir }}/docker/* /usr/bin - name: 分發service文件 copy: src=files/docker.service dest=/usr/lib/systemd/system/ - name: 創建目錄 file: dest=/etc/docker state=directory - name: 配置docker copy: src=files/daemon.json dest=/etc/docker/daemon.json - name: 啟動docker systemd: name=docker state=restarted enabled=yes daemon_reload=yes - name: 查看狀態 shell: docker info register: docker - debug: var=docker.stdout_lines # ansible-playbook -i hosts docker_deploy.yaml -k -K
# cat generate_tls.yaml
---
- hosts: localhost vars: current_dir: "{{ lookup('env', 'PWD') }}" remote_user: root gather_facts: false tasks: - name: 創建工作目錄 file: dest={{ current_dir }}/tls/cert state=directory - name: 准備cfssl工具 unarchive: src=tls/cfssl.tar.gz dest=/usr/bin/ mode=u+x - name: 准備etcd證書請求文件 template: src=tls/{{ item }} dest={{ current_dir }}/tls/cert/{{ item.split('.')[:-1]|join('.') }} with_items: - ca-config.json.j2 - ca-csr.json.j2 - server-csr.json.j2 - name: 生成etcd證書 shell: | cd {{ current_dir }}/tls/cert cfssl gencert -initca ca-csr.json | cfssljson -bare ca - cfssl gencert -ca=ca.pem -ca-key=ca-key.pem -config=ca-config.json -profile=www server-csr.json | cfssljson -bare server # cat etcd_cluster_deploy.yaml --- - hosts: etcd vars: etcd_work_dir: '/opt/etcd' tmp_dir: '/tmp/k8s' remote_user: root gather_facts: false tasks: - name: 創建工作目錄 file: dest={{ etcd_work_dir }}/{{ item }} state=directory with_items: - bin - cfg - ssl - name: 創建臨時目錄 file: dest={{ tmp_dir }} state=directory - name: 分發並解壓etcd二進制包 unarchive: src={{ item }} dest={{ tmp_dir }} with_fileglob: - "files/etcd-v*.tar.gz" - name: 移動etcd二進制文件 shell: cp -rf {{ tmp_dir }}/etcd-v*/{etcd,etcdctl} {{ etcd_work_dir }}/bin - name: 分發證書 copy: src=tls/cert/{{ item }} dest={{ etcd_work_dir }}/ssl with_items: - ca.pem - server.pem - server-key.pem - name: 分發etcd配置文件 template: src=files/etcd.conf.j2 dest={{ etcd_work_dir }}/cfg/etcd.conf - name: 分發service文件 template: src=files/etcd.service.j2 dest=/usr/lib/systemd/system/etcd.service - name: 啟動etcd systemd: name=etcd state=restarted enabled=yes daemon_reload=yes - name: 分發etcd腳本 template: src=files/etcd.sh.j2 dest={{ tmp_dir }}/etcd.sh mode=u+x - name: 獲取etcd集群狀態 shell: /bin/bash {{ tmp_dir }}/etcd.sh register: status - debug: var=status.stdout_lines # tree . . ├── ansible.cfg ├── docker_deploy.yaml ├── etcd_cluster_deploy.retry ├── etcd_cluster_deploy.yaml ├── files │ ├── etcd.conf.j2 │ ├── etcd.service.j2 │ ├── etcd.sh.j2 │ └── etcd-v3.3.10-linux-amd64.tar.gz ├── generate_tls.yaml ├── hosts └── tls ├── ca-config.json.j2 ├── ca-csr.json.j2 ├── cert ├── cfssl.tar.gz ├── generate_etcd_cert.sh └── server-csr.json.j2 # ansible-playbook -i hosts generate_tls.yaml # ansible-playbook -i hosts etcd_cluster_deploy.yaml -k -K
site.yml webservers.yml fooservers.yml roles/ common/ tasks/ handlers/ files/ templates/ vars/ defaults/ meta/ webservers/ tasks/ defaults/ meta/
-
-
handlers-包含處理程序,此角色甚至在此角色之外的任何地方都可以使用這些處理程序。 -
defaults-角色的默認變量 -
vars-角色的其他變量 -
files-包含可以通過此角色部署的文件。 -
templates-包含可以通過此角色部署的模板。 -
meta
# roles/webservers/tasks/main.yml - name: added in 2.4, previously you used 'include' import_tasks: redhat.yml when: ansible_facts['os_family']|lower == 'redhat' - import_tasks: debian.yml when: ansible_facts['os_family']|lower == 'debian' # roles/webservers/tasks/redhat.yml - yum: name: "httpd" state: present # roles/webservers/tasks/debian.yml - apt: name: "apache2" state: present
使用角色
# site.yml - hosts: webservers roles: - common - webservers 定義多個: - name: 0 gather_facts: false hosts: all roles: - common - name: 1 gather_facts: false hosts: all roles: - webservers
角色控制
- name: 0.系統初始化 gather_facts: false hosts: all roles: - common tags: common
