9 m( [# a" R- k0 Z4 ?
本文中的例子在 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。 基本环境就搭好了。
2 P3 R! B' U# f+ v
" Q- s9 q" |3 S8 h7 |0 E+ h接下来我们实战一下。 目录结构── ansible.cfg
0 t; H9 q9 t) ~8 z. ?* Z├── group_vars
3 R" e% w$ K% |, j8 ^│ ├── all.yml( F) y# R" \! @6 J' F1 Q9 U
├── openstack.py8 ~- `0 l+ v3 E
├── README.md
& a) F8 d9 p/ O# K) X! Q3 @├── roles
$ W1 e2 z6 I. ~) x7 `│ ├── newtouch.MySQL
3 \* E7 T" ~, E& h L; F4 W$ ?3 G│ ├── newtouch.SystemConfig. J5 Z2 `3 `6 C6 u9 Y: ?
│ ├── newtouch.UpdateRootPass |- Q3 J- E8 B. S$ g* p
│ └── openstack.CreateServer( g2 V3 E( T$ V% t5 Y- J
├── setup_mysql.yml
group_vars/all.yml 里需要设置 ansible_user: root
4 P8 ~; z# ~' A) Cansible_ssh_pass: xxxxxxxxxxx
前提是 openstack 集群里的虚拟机镜像,root 密码相同。 默认值配置文件 roles/openstack.CreateServer/defaults/main.ymlrole 的默认值,根据实际情况,填入相关信息。以 vm_ 开头的变量是为了测试用,预设的。 auth: auth_url: http://192.168.8.65:5000/v3 : _' k4 j9 H( i: }$ q& ~3 K
username: admin
- Q1 j' `4 @8 B! dpassword: xxxxxxxxxxxxxxxxxx
$ R1 i8 m0 ^2 V1 h) Cproject_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,发出一封邮件,包含机器的相关信息。0 t- W3 \7 m, N0 I( [2 E" R
- 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 里也通过测试我们通过问卷方式获取需要的变量值,一个简单的数据库虚拟机就可以实现一键创建了。开发人员再也不用等待运维人员的协助。 9 D5 W' |3 E1 k, {2 }; W; k2 K3 G
|