组件架构

ansible core : ansible 自身核心模块
host inventory: 主机库,定义可管控的主机列表
connection plugins: 连接插件,一般默认基于 ssh 协议连接
modules:core modules ( 自带模块 ) 、 custom modules ( 自定义模块 )
playbooks :剧本,按照所设定编排的顺序执行完成安排任务
Ansible与Saltstack和puppet的最大区别是Ansible无需在被控端部署任何客户端代理,默认直接通过SSH通道进行远程命令的执行或下发配置;相同点都是具备功能强大、灵活的的系统管理、状态配置,都使用YAML格式来描述配置,都具有丰富的模板及API。
Ansible提供了一个在线的Playbook分享平台,地址是:https://galaxy.ansible.com/,该平台汇聚了各类常用功能的角色,找到适合自己的Role(角色)后,只需要运行“ansible-galaxy install 作者id.角色包名称”就可以安装到本地。
[root@xuegod63 ~]# ansible-galaxy install bennojoy.mysql- downloading role 'mysql', owned by bennojoy- downloading role from https://github.com/bennojoy/mysql/archive/master.tar.gz- extracting bennojoy.mysql to /etc/ansible/roles/bennojoy.mysql- bennojoy.mysql was installed successfully[root@xuegod63 ~]# ls /etc/ansible/roles/bennojoy.mysql/defaults/ handlers/ meta/ README.md tasks/ templates/ vars/
安装
建议使用yum方式安装先安装在线yum的epel源[root@xuegod63 ~]# rpm -ivh http://dl.fedoraproject.org/pub/epel/6/i386/epel-release-6-8.noarch.rpmRetrieving http://dl.fedoraproject.org/pub/epel/6/i386/epel-release-6-8.noarch.rpmwarning: /var/tmp/rpm-tmp.tDsKed: Header V3 RSA/SHA256 Signature, key ID 0608b895: NOKEYPreparing... ########################################### [100%]1:epel-release ########################################### [100%]生成一下缓存[root@xuegod63 ~]# yum makecache[root@xuegod63 ~]# yum list | grep ansibleansible.noarch 2.1.1.0-1.el6 epelansible-inventory-grapher.noarch 1.0.1-2.el6 epelansible-lint.noarch 2.0.1-1.el6 epelansible1.9.noarch 1.9.6-2.el6.1 epel安装[root@xuegod63 ~]# yum install -y ansible1.9.noarch
入门操作
在这里我们用自己创建的目录/var/opt来存放ansible相应的文件[root@xuegod63 ~]# cd /var/opt定义主机清单ansible基于ssh连接inventory中指定的远程主机时,将以此处的参数指定的属性进行ansible_ssh_port:指定 ssh 端口ansible_ssh_user:指定 ssh 用户ansible_ssh_pass:指定 ssh 用户登录是认证密码,明文密码不安全ansible_sudo_pass:指明 sudo 时候的密码新建文件hosts[root@xuegod63 opt]# vim hosts#增加以下内容[tomcatserver] #主机组名192.168.10.64 ansible_ssh_port=22 ansible_ssh_user=root ansible_ssh_pass=123456192.168.10.65 #主机IP或主机名简单测试下主机的连通性[root@xuegod63 opt]# ansible -i hosts tomcatserver -m ping -kSSH password:192.168.10.65 | success >> {"changed": false,"ping": "pong"}192.168.10.64 | success >> {"changed": false,"ping": "pong"}一般来说,使用明文密码不安全,所以增加主机无密码访问生成密钥对[root@xuegod63 opt]# ssh-keygen -t rsa -P ""Generating public/private rsa key pair.Enter file in which to save the key (/root/.ssh/id_rsa):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:10:29:6f:38:e5:e3:da:52:3f:48:ed:7a:ae:ca:db:0a root@xuegod63.cnThe key's randomart image is:+--[ RSA 2048]----+| .. || . o. || *. || o =. || + oS || + . || E = + || oo.o = || ==+=.. |+-----------------+拷贝密钥到xuegod64和xuegod65[root@xuegod63 opt]# ssh-copy-id -i ~/.ssh/id_rsa.pub 192.168.10.64root@192.168.10.64's password:Now try logging into the machine, with "ssh '192.168.10.64'", and check in:.ssh/authorized_keysto make sure we haven't added extra keys that you weren't expecting.[root@xuegod63 opt]# ssh-copy-id -i ~/.ssh/id_rsa.pub 192.168.10.65root@192.168.10.65's password:Now try logging into the machine, with "ssh '192.168.10.65'", and check in:.ssh/authorized_keysto make sure we haven't added extra keys that you weren't expecting.anisble命令ansible [–i 主机文件] [-f 批次] [组名] [–m 模块名称] [–a 模块参数]模块查询命令ansible-doc -l 列出所有的模块列表ansible-doc -s 查看指定模块的参数
常用模块
1.远程命令模块command:作为ansible的默认模块,可以运行远程权限范围内的所有shell命令;script:是在远程主机上执行主控端存储的shell脚本,相当于scp+shell组合;shell:是执行远程主机上的shell脚本# ansible -i hosts tomcatserver -m command -a "free -m"2.copy模块copy:实现主控端向目标主机拷贝文件,类似scp功能# ansible -i hosts tomcatserver -m copy -a "src=./hosts dest=/tmp/ owner=root group=root mode=0755"3.file模块file:设置文件属性。# ansible -i hosts tomcatserver -m file -a "path=/tmp/hosts mode=0777"4.stat模块stat:获取远程文件信息# ansible -i hosts tomcatserver -m stat -a "path=/tmp/hosts"5.get_url模块get_url:实现远程主机下载指定url到本地,支持sha256sum文件校验。# ansible -i hosts tomcatserver -m get_url -a "url=http://dl.fedoraproject.org/pub/epel/6/i386/epel-release-6-8.noarch.rpm dest=/tmp/ mode=0440 force=yes"6.yum模块yum:linux平台软件包管理。例子:安装php软件# ansible -i hosts tomcatserver -m yum -a "name=php state=latest"7.cron模块cron:远程主机crontab配置。# ansible -i hosts tomcatserver -m cron -a "name='list dir' minute='*/30' job='ls /tmp'"8. mount模块mount:远程主机分区挂载。# ansible -i hosts tomcatserver -m mount -a "name=/mnt src=/dev/sda1 fstype=ext4 opts=ro state=present"9.service模块service:远程主机系统服务管理。[root@xuegod63 opt]# ansible -i hosts tomcatserver -m service -a "name=httpd state=restarted"验证:查看服务启动时间[root@xuegod64 ~]# ps -eo cmd,pid,lstart,etime | grep httpd10.sysctl模块sysctl:远程主机sysctl配置。# ansible -i hosts tomcatserver -m sysctl -a "name=net.ipv4.ip_forward value=1 reload=yes"11.user模块user:远程主机用户管理# ansible -i hosts tomcatserver -m user -a "name=less state=present"
playbook
Playbook是一个不同于使用ansible命令行执行方式的模式,功能更强大灵活,简单地说,playbook是一个非常简单的配置管理和多主机部署系统。
playbook是由一个或多个”play”组成的列表。play的主要功能在于将事先归为一组的主机装扮成事先通过ansible中的task定义好的角色。
github上提供了大量的实例供大家参考 https://github.com/ansible/ansible-examples
核心元素
- Hosts 执行的远程主机列表
- Tasks 任务集
- Variables 内置变量或自定义变量在playbook中调用
- Templates 模板,可替换模板文件中的变量并实现一些简单逻辑的文件
- Handlers 和 notify 结合使用,由特定条件触发的操作,满足条件方才执行,否则不执行
- tags 标签 指定某条任务执行,用于选择运行playbook中的部分代码。ansible具有幂等性,因此会自动跳过没有变化的部分,即便如此,有些代码为测试其确实没有发生变化的时间依然会非常地长。此时,如果确信其没有变化,就可以通过tags跳过此些代码片断
playbooks 中 定义任务:
---- name: task description 注释 描述信息module_name: module_args 声明模块:定义 ansible 模块参数
ansible-playbook 执行 命令:
ansible-playbook <site.yml> ... [options]-C --check #只检测可能会发生的改变,但不真正执行操作--list-hosts #列出运行任务的主机--list-tags #列出tag--list-tasks #列出task--limit 主机列表 #只针对主机列表中的主机执行-v -vv -vvv #显示过程
Playbook 是一个由一个或多个 play 组成的文件;play 是针对特定主机或主机组执行的一组有序的任务;每个 playbook 必须包含两部分:
hosts: 运行 playbook 的一组主机
tasks: 需要在主机上运行的任务
除了这两个必须选项,还有一些可选项选项,也可能需要包含在 play 中,如:
name: play 的名称,在运行该 play 时,会在运行过程中显示。
become: 与配置文件中的 become 作用一样,用于提权,当配置文件中禁用提权时,你想要某个 play 使用提权的话,你可以在 play 中添加 become。
playbook 以 yaml 格式编写的,通常以 yml 扩展名保存。yaml 格式使用空格缩进,对于空格的数量没有特别要求,但需要注意:
- 同一级别内的元素必须使用相同的缩进;
- 对于子项目,缩进必须比父项目多
Playbook 以 —- 开头,用于标记文件开始;
第二行的 name 为该 play 的名称;
第三行的 hosts 表示将要运行该 play 的主机;
第四行的 tasks 表示该 play 将要执行的具体任务;
通过缩进,我们可以看出 tasks 一共分为三个部分,也就是三个模块,每个模块由一个 name 开表示该模块的 name,虽然 name 是可选选项,但建议写上,用来作为对该模块执行任务的解释说明,并且 name 的内容会在 playbook 执行此模块时,显示在执行过程中;
name 下面的是模块的名称,在该 play 的 tasks 中一共有三个模块:
apt: 用于安装软件
copy: 用于复制文件或内容
service: 用于操作 service,如启动服务,重启服务等
roles
学习资料:http://www.yunweipai.com/34669.html
角色是ansible自1.2版本引入的新特性,用于层次性、结构化地组织playbook。roles能够根据层次型结构自动装载变量文件、tasks以及handlers等。要使用roles只需要在playbook中使用include指令即可。简单来讲,roles就是通过分别将变量、文件、任务、模板及处理器放置于单独的目录中,并可以便捷地include它们的一种机制。角色一般用于基于主机构建服务的场景中,但也可以是用于构建守护进程等场景中
运维复杂的场景:建议使用roles,代码复用度高
现生产案例
cnr_gateway.yml
- hosts: cnr_gatewaybecome: yesserial: 1become_method: sudogather_facts: yesroles:- cnr_gateway
./roles/cnr_gateway/{defaults,handlers,PaxHeader,tasks,templates}
defaults/main.yml
---# Registry Settingscnr_gateway_docker_registry: 'registry.cn-hangzhou.aliyuncs.com'cnr_gateway_registry_user: ''cnr_gateway_registry_password: ''# Environment Specific Settingscnr_gateway_env: developmentcnr_gateway_image: cnr_gatewaycnr_gateway_image_tag: latest# Host specific Settingscnr_gateway_confdir: '/srv/appvolumes/cnr_gateway'cnr_gateway_logdir: '/srv/logs'cnr_gateway_host_port: ''cnr_gateway_appport: ''cnr_gateway_network_mode: "bridge"cnr_gateway_syslog_url: ''# Eurkacodemaster_codecamp_app_api_oos_enable: false# App Settingcnr_gateway_config_server_port: ""cnr_gateway_config_eureka_instance_hostname: ""cnr_gateway_config_apollo_meta: ""
./handlers/main.yml
---- name: Restart containercommand: /usr/bin/docker restart "{{ cnr_gateway_container_name }}"
./tasks/main.yml
---- name: Modify VServer Weight To Zeroconnection: localali_slb:alicloud_access_key: '{{ alicloud_access_key }}'alicloud_secret_key: '{{ alicloud_secret_key }}'alicloud_region: '{{ cnr_gateway_alicloud_region }}'vserver_group_id: '{{ cnr_gateway_vserver_group_id }}'backend_servers:- ServerId: '{{ instance_id }}'Port: '{{ cnr_gateway_host_port }}'Weight: 0when: cnr_gateway_slb_enable- name: create log filefile:path: '{{ cnr_gateway_logdir }}'owner: rootgroup: rootmode: 0755state: directory- name: Setup application data treefile:path: '{{ cnr_gateway_confdir }}'owner: rootgroup: rootmode: 0755state: directory- name: Setup application data treefile:path: '{{ cnr_gateway_confdir }}/log/'owner: rootgroup: rootmode: 0757recurse: yesstate: directory- name: Setup application data treefile:path: '{{ cnr_gateway_confdir }}/log/common'owner: rootgroup: rootmode: 0757recurse: yesstate: directory- name: Install application configurationtemplate:src: 'config.yml.j2'dest: '{{ cnr_gateway_confdir }}/application-{{ cnr_gateway_env }}.yml'owner: rootgroup: rootmode: 0644notify: Restart container- name: Login to docker registrydocker_login:registry: '{{ cnr_gateway_docker_registry }}'username: '{{ cnr_gateway_registry_user }}'password: '{{ cnr_gateway_registry_password }}'- name: Pull initial docker image from registrydocker_image:name: '{{ cnr_gateway_docker_registry }}/codemaohub/{{ cnr_gateway_image }}:{{ cnr_gateway_image_tag }}'state: present- block:- name: Check if the port existswait_for:port: "{{ cnr_gateway_host_port }}"state: stoppeddelay: 0timeout: 1rescue:- name: Change Application Out Of Serviceuri:url: 'http://127.0.0.1:{{ cnr_gateway_host_port }}/eureka/out_of_service'method: PUTregister: responsefailed_when: "response.status != 200"- name: Waiting for cache cleanpause:minutes: 2when: cnr_gateway_oos_enable- name: Install, update and start containersdocker_container:name: '{{ cnr_gateway_container_name }}'image: '{{ cnr_gateway_docker_registry }}/codemaohub/{{ cnr_gateway_image }}:{{ cnr_gateway_image_tag }}'restart_policy: 'always'pull: yesrecreate: yesstate: startedrestart: yescommand: "{{ cnr_gateway_start_command }} --spring.profiles.active={{ cnr_gateway_env }}"ports:- "{{ cnr_gateway_host_port }}:{{ cnr_gateway_app_port }}"volumes:- '{{ cnr_gateway_confdir }}:/usr/src/app/config'- '{{ cnr_gateway_logdir }}:/localdata'etc_hosts: "{{ all_etc_hosts }}"# Use the defaults bridge network# Mandatory for production!network_mode: "{{ cnr_gateway_network_mode }}"- name: Immediate Execution Handlersmeta: flush_handlers- name: Wait for container to become availablewait_for:port: '{{ cnr_gateway_host_port }}'delay: 5timeout: 45when: cnr_gateway_healthcheck_enabled- name: Validating application healthcheckuri:url: 'http://{{ cnr_gateway_healthcheck_host }}:{{ cnr_gateway_healthcheck_port }}{{ cnr_gateway_healthcheck_endpoint}}'method: GETreturn_content: trueregister: responseretries: 5delay: 15until: response is succeededfailed_when: cnr_gateway_healthcheck_responsestring not in response.contentwhen: cnr_gateway_healthcheck_enabled- name: Configure firewall to accept SLB health checkufw:rule: allowport: "{{ cnr_gateway_host_port }}"proto: tcpto_ip: "{{ ansible_eth0['ipv4']['address'] }}"- name: Modify VServer Weight To 100connection: localali_slb:alicloud_access_key: '{{ alicloud_access_key }}'alicloud_secret_key: '{{ alicloud_secret_key }}'alicloud_region: '{{ cnr_gateway_alicloud_region }}'vserver_group_id: '{{ cnr_gateway_vserver_group_id }}'backend_servers:- ServerId: '{{ instance_id }}'Port: '{{ cnr_gateway_host_port }}'Weight: 100when: cnr_gateway_slb_enable
./templates/config.yml.j2
server:port: {{ cnr_gateway_config_server_port }}eureka:client:service-url:defaultZone: {{ cnr_gateway_config_eureka_client_service_url }}instance:hostname: {{ cnr_gateway_config_eureka_instance_hostname }}apollo:meta: {{ cnr_gateway_config_apollo_meta }}
