/ T* \5 S1 H1 b1 I+ Y
本文中的例子在 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。 基本环境就搭好了。; k* Q4 d( l9 ^. W( c+ @- K$ o
0 z4 L7 V* T J' C/ I接下来我们实战一下。 目录结构── ansible.cfg
7 B* r+ X# V- e+ Q$ s├── group_vars
! M1 T8 }+ L$ Q! \& l; L│ ├── all.yml
/ Z: | s& b# ]9 H2 \8 d0 i├── openstack.py+ ]! M, D! \4 C
├── README.md
h3 B. g$ M8 D' Y1 p, X├── roles: k I0 N8 w6 I _' D
│ ├── newtouch.MySQL E1 h# |4 V8 x' J+ d6 A( o
│ ├── newtouch.SystemConfig# S) c3 Y8 s2 n; B
│ ├── newtouch.UpdateRootPass! @1 B$ t6 q* v
│ └── openstack.CreateServer
' I7 Y- _7 m4 l. ^' ?6 A├── setup_mysql.yml
group_vars/all.yml 里需要设置 ansible_user: root
6 _, [. J; }5 {' t/ `. b, {ansible_ssh_pass: xxxxxxxxxxx
前提是 openstack 集群里的虚拟机镜像,root 密码相同。 默认值配置文件 roles/openstack.CreateServer/defaults/main.ymlrole 的默认值,根据实际情况,填入相关信息。以 vm_ 开头的变量是为了测试用,预设的。 auth: auth_url: http://192.168.8.65:5000/v3 9 M, m& s# c, O5 {- d0 \
username: admin
1 e' O: {7 l- }5 Q1 `password: xxxxxxxxxxxxxxxxxx
& o: y: J T$ e& g) R0 x; fproject_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 D% A/ V, e7 X$ h4 I6 D - 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 里也通过测试我们通过问卷方式获取需要的变量值,一个简单的数据库虚拟机就可以实现一键创建了。开发人员再也不用等待运维人员的协助。
8 t$ `4 a5 N. _& ]6 x |