# |* l. T- B- ~& }2 s6 E本文中的例子在 ansible 和 Ansible Tower 里都通过。 controller 对 openstack 的接入本文里的 controller 是我的笔记本电脑,需要做以下配置: 建立 /etc/ansible/openstack.yml,内容如下 clouds: poc: auth: username: 'admin' password: xxxxx project_name: 'admin' auth_url: 'http://192.168.8.65:5000/v3' region_name: RegionOneansible: use_hostnames: True expand_hostvars: True fail_on_errors: Trueauth 里的是 openstack 的相关验证信息。然后在你的 ansible 项目根目录下下载 openstack.py wget https://raw.githubusercontent.co ... y/openstack.pychmod +x openstack.py验证你的配置 ./openstack.py --list 如果正确,会列出你的 openstack 服务里的 hosts 然后在你的 ansible 项目根目录下放置独立的 ansible.cfg 文件并修改它的内容, [defaults]inventory = ./openstack.py这样就可以动态加载 openstack 里的服务器 inventory 了。 手动在对应的 openstack 集群里创建一台虚拟机,用于执行 ansible 剧本,创建新虚拟机用。本文中命名为 openstack-connector,使用 centos7.9 版本系统。在 openstack-connector 里安装以下软件 sudo yum install -y gcc libssl-dev sendmail python-pipsudo pip install -U pipsudo pip install cryptography shade检查状态 ./openstack.py --host openstack-connector ,你可以看到很长一串的 json 格式输出。 最后把你的公钥拷贝到 openstack-connector 里,我这台机器的 IP 是 192.168.19.66。 基本环境就搭好了。8 E7 \6 e! ?# v1 T5 d$ \
4 k5 L$ W7 g& ^- |3 y* W0 z- G接下来我们实战一下。 目录结构── ansible.cfg
a2 _+ z! a" c2 y; ?2 Q8 R; J) V2 G├── group_vars
) ^: I# Y" L8 B! c% ?; k1 h│ ├── all.yml) G) u' j% t7 l
├── openstack.py
) Y. g: D- j$ }/ m/ x! E/ @├── README.md7 x( W; I* R! {% ^1 x& h4 @" B: u
├── roles
5 y4 R8 G8 |; W% L" C! t9 N│ ├── newtouch.MySQL
& F K" R% g \, F- E│ ├── newtouch.SystemConfig, E9 j2 }8 y5 _% |
│ ├── newtouch.UpdateRootPass
$ Z- r" d2 {% o7 P│ └── openstack.CreateServer, U, ?1 s% y5 q& r% G* o* k5 P, ]
├── setup_mysql.yml
group_vars/all.yml 里需要设置 ansible_user: root
0 L1 f5 y) ^) m& z& A( _5 I5 bansible_ssh_pass: xxxxxxxxxxx
前提是 openstack 集群里的虚拟机镜像,root 密码相同。 默认值配置文件 roles/openstack.CreateServer/defaults/main.ymlrole 的默认值,根据实际情况,填入相关信息。以 vm_ 开头的变量是为了测试用,预设的。 auth: auth_url: http://192.168.8.65:5000/v3
: X: u* c) r X# D% I1 E: i8 Z; Iusername: admin
0 A* X( I, s4 X& e* Tpassword: xxxxxxxxxxxxxxxxxx
" m. c( A2 d8 x! k0 ^project_name: admin # image_id ubuntu_14_disk_50_v2: 5c67bf65-f699-49e8-955a-72152fb690f4 centos7_50_v2: f9391999-373b-4f0d-9c76-07c19e4e86e5 flavor: - {name: 1CPU_1G, id: e3aff42c-f260-4dea-ada5-1241b5853652} - {name: 2CPU_4G, id: 45b099ac-4ae4-4526-a6e2-f34cc2934e1b} vm_state: present vm_name: db1 vm_image: '{{ ubuntu_14_disk_50_v2 }}' vm_key: lihaibin vm_flavor: 1CPU_1G vm_network: public vm_group: poc任务代码 roles/openstack.CreateServer/tasks/main.yml- block: - name: Set the new instance's name debug: msg: "The new instance's name is {{ vm_name }}-{{ ansible_date_time.epoch }}" - name: Creating new instance os_server: state: '{{ vm_state }}' auth: auth_url: '{{ auth.auth_url }}' username: '{{ auth.username }}' password: '{{ auth.password }}' project_name: '{{ auth.project_name }}' name: "{{ vm_name }}-{{ ansible_date_time.epoch }}" image: '{{ vm_image }}' flavor: '{{ vm_flavor }}' network: '{{ vm_network }}' meta: hostname: "{{ vm_name }}-{{ ansible_date_time.epoch }}" - name: Gathering the new instance's facts os_server_facts: auth: auth_url: '{{ auth.auth_url }}' username: '{{ auth.username }}' password: '{{ auth.password }}' project_name: '{{ auth.project_name }}' server: "{{ vm_name }}-{{ ansible_date_time.epoch }}" - name: Get the new instance's IP address block: - set_fact: vm_ip: "{{ openstack_servers[0]['accessIPv4'] }}" - debug: msg: "The new instance's IP address is {{ vm_ip }}" - name: Waiting for the new instance up and run wait_for: host: '{{ vm_ip }}' port: 22 search_regex: OpenSSH sleep: 10 timeout: 3000 - name: Add the new instance into inventory add_host: name: "{{ vm_name }}-{{ ansible_date_time.epoch }}" ansible_host: "{{ vm_ip }}" rescue: - name: Remove the new instance when failed os_server: state: absent auth: auth_url: '{{ auth.auth_url }}' username: '{{ auth.username }}' password: '{{ auth.password }}' project_name: '{{ auth.project_name }}' name: "{{ vm_name }}-{{ ansible_date_time.epoch }}"这里我使用了 {{ vm_name }}-{{ ansible_date_time.epoch }} 作为新机器的名称,这样可以避免名称重复。如果创建过程中遇到任何失败,会执行删除虚拟机的操作,避免产生垃圾资源。 剧本 setup_mysql.yml这个剧本的重点在于 post_tasks 里 - 在新虚拟机创建完成之后,我们还是要通过 openstack-connector 作为跳板机来访问新虚拟机,这样才能保证 {{ vm_name }}-{{ ansible_date_time.epoch }} 这个值是可以被读取到的。
- 基于这个模板,在 post_tasks 里,include_role 部分可以随意发挥,把你要执行的 role 加进来。这样你可以做到一键创建虚拟机并部署应用到虚拟机。
- 最后我们通过 openstack-connector 里的 sendmail,发出一封邮件,包含机器的相关信息。6 Q3 o( V! ]# F, G- d9 {2 ~$ I) Q- O
- hosts: openstack-connector vars: new_password: newtouch mysql_user: root mysql_password: newtouch bind_address: 0.0.0.0 max_connections: 256 innodb_buffer_pool_size: "{{ (ansible_memtotal_mb * 0.5) | round | int }}M" owner_email: "haibin.li@newtouch.cn" roles: - openstack.CreateServer post_tasks: - block: - include_role: name: newtouch.SystemConfig - include_role: name: newtouch.MySQL - include_role: name: newtouch.UpdateRootPass delegate_to: "{{ vm_name }}-{{ ansible_date_time.epoch }}" delegate_facts: True - name: Send mail with instance info mail: host: localhost from: 'ansible@newtouch.com>' to: '{{ owner_email }}' subject: "Server {{ vm_name | upper }}-{{ ansible_date_time.epoch }} has been successfully created." body: | The server {{ vm_name | upper }}-{{ ansible_date_time.epoch }} info: - IP: {{ vm_ip }} - SYSTEM USER: root - SYSTEM PASS: {{ new_password }} - MYSQL USER: {{ mysql_user }} - MYSQL PASS: {{ mysql_password }} Please keep this email safe. charset: utf8本剧本在 Ansible Tower 里也通过测试我们通过问卷方式获取需要的变量值,一个简单的数据库虚拟机就可以实现一键创建了。开发人员再也不用等待运维人员的协助。
2 [& B: x* k! j/ `3 |6 P; O+ S |