Kolla-ansible是OpenStack下面的一个自动化部署的项目,基于docker和Ansible实现。
Docker负责镜像制作、容器管理。
Anisble负责环境部署管理。
kolla-ansible
├── ansible # Ansible的playbook和roles在这个目录下面
├── doc # 一些文档说明书
├── etc_examples # Openstack部署需要的一些配置模板文件
├── init-runonce # 初始化配置脚本
├── init- # 配置VPNaas的脚本
├── setup.cfg # 安装配置入口文件
└── tools # 和kolla交互的脚本工具
ansible
├── action_plugins # 自定义插件,用户yml和config的配置合并
├── filter_plugins # 自定义过滤器插件,用来处理变量数据
├── group_vars # 存放ansible的全局变量,比如:配置文件路径、网卡、IP、端口、服务的开启等。
├── inventory # 主机清单 分为单节点、多节点
├── library # 自定义的ansible模块
bslurp.py:# 作用是从其他节点拷贝文件然后再复制给其他节点
kolla_docker.py:# 作用是控制管理docker,通过连接docker API去对容器进行创建、删除等一些操作
kolla_toolbox.py:# 负责容器的启动以及初始化的操作
kolla_container_facts.py:# 用于检查容器是否正在运行
├── mariadb_backup.yml
├── mariadb_recovery.yml
├── nova.yml
├── post-deploy.yml
├── roles # 目录下有不同组件业务的playbook、定义的变量以及模板文件等
├── site.yml
└── vmha.yml
neutron目录下有5个文件夹:
default: 定义了部署neutron各服务的各类参数
handlers: 定义了启动neutron各服务容器的操作
meta: 定义了部署neutron的依赖
tasks: 部署neutron的各playbook
templates: neutron各服务配置文件的模板
defaults下的main.yml,作为当前role的变量文件,定义了关于neutron及neutron各服务的相关参数
# 部分代码
---
project_name: "neutron"
# 定义了neutron_server相关的参数,容器名、镜像、卷等
neutron_services:
neutron-server:
# 定义neutron_server的容器名
container_name: "neutron_server"
# 定义容器使用的镜像
image: "{{ neutron_server_image_full }}"
enabled: true
group: "neutron-server"
host_in_groups: "{{ inventory_hostname in groups['neutron-server'] }}"
# 容器和宿主机映射的卷
volumes:
- "{{ node_config_directory }}/neutron-server/:{{ container_config_directory }}/:ro"
- "/etc/localtime:/etc/localtime:ro"
- "kolla_logs:/var/log/kolla/"
# 定义neutron数据库地址等
neutron_database_name: "neutron"
neutron_database_user: "neutron"
neutron_database_address: "{{ kolla_internal_fqdn }}:{{ database_port }}"
# 定义neutron_server镜像名
neutron_server_image_full: "{{ neutron_server_image }}:{{ neutron_server_tag }}"
handlers下的main.yml文件,实际是创建、启动neutron各服务容器的playbook。但handlers只能在被触发的情况下才会去执行相关被触发的Task。
# 部分内容
# 启动neutron-server容器
---
- name: Restart neutron-server container
# vars:task下定义的变量
vars:
service_name: "neutron-server"
service: "{{ neutron_services[service_name] }}"
config_json: "{{ neutron_config_jsons.results|selectattr('item.key', 'equalto', service_name)|first }}"
neutron_conf: "{{ neutron_confs.results|selectattr('item.key', 'equalto', service_name)|first }}"
neutron_lbaas_conf: "{{ neutron_lbaas_confs.results|selectattr('item.key', 'equalto', service_name)|first }}"
neutron_aas_conf: "{{ neutron_aas_confs.results|selectattr('item.key', 'equalto', service_name)|first }}"
neutron_ml2_conf: "{{ neutron_ml2_confs.results|selectattr('item.key', 'equalto', service_name)|first }}"
policy_json: "{{ policy_jsons.results|selectattr('item.key', 'equalto', service_name)|first }}"
neutron_server_container: "{{ check_neutron_containers.results|selectattr('item.key', 'equalto', service_name)|first }}"
# 调用kolla-docker模块,启动容器
kolla_docker:
action: "recreate_or_restart_container"
# docker的一些共用变量,在group/all.yml内有所定义
common_options: "{{ docker_common_options }}"
# 指定容器名
name: "{{ service.container_name }}"
# 指定启动容器所需镜像
image: "{{ service.image }}"
# 容器内配置文件等和宿主机的映射关系
volumes: "{{ service.volumes }}"
# 指定是否开启特权
privileged: "{{ service.privileged | default(False) }}"
# when:只有当列表下的所有条件满足时,才执行该task
when:
- action != "config"
- service.enabled | bool
- service.host_in_groups | bool
- config_json | changed
or neutron_conf | changed
or neutron_lbaas_conf | changed
or neutron_aas_conf | changed
or neutron_ml2_conf | changed
or nsx_ini | changed
or policy_json | changed
or neutron_server_container | changed
meta下的main.yml指定了neutron这个role的依赖,从main.yml内容可以看出实际是依赖于common这个role,也就是在执行neutron的task前,会先去common这个role下执行相关task。
main.yml
在tasks目录下,有很多的yml文件,其中main.yml是入口执行文件。
当我们执行kolla-ansible deploy时,main.yml将调用deploy.yml
---
- include: "{{ action }}.yml"
ironic-check.yml
检查是否满足ironic开启时,neutron_plugin_agent配置为openvswitch,不满足则报错
- fail: msg="neutron_plugin_agent must use openvswitch with Ironic"
when:
- enable_ironic | bool
- neutron_plugin_agent != "openvswitch"
register.yml
register.yml内进行了neutron的service和endpoint创建、project,user,和role创建。
在这里面调用了自定义的kolla_toolbox模块,该模块实际是去kolla_toolbox容器内调用自定义的kolla_keystone_service模块,并把module_args下的变量传递进去。
---
- name: Creating the Neutron service and endpoint
调用kolla_toolbox模块
kolla_toolbox:
# kolla_keystone_service模块在kolla_toolbox容器内的/usr/share/ansible/目录下
module_name: "kolla_keystone_service"
# 定义创建service和endpoint所需的变量和值,供kolla_keystone_service模块执行
module_args:
service_name: "neutron"
service_type: "network"
description: "Openstack Networking"
endpoint_region: "{{ openstack_region_name }}"
url: "{{ item.url }}"
interface: "{{ item.interface }}"
region_name: "{{ openstack_region_name }}"
auth: "{{ '{{ openstack_neutron_auth }}' }}"
endpoint_type: "{{ openstack_interface }}"
module_extra_vars:
openstack_neutron_auth: "{{ openstack_neutron_auth }}"
# run_once:任选单个节点执行一次,不会在所有节点执行
run_once: True
# with_items: 对列表进行循环操作
with_items:
- {'interface': 'admin', 'url': '{{ neutron_admin_endpoint }}'}
- {'interface': 'internal', 'url': '{{ neutron_internal_endpoint }}'}
- {'interface': 'public', 'url': '{{ neutron_public_endpoint }}'}
config.yml
config.yml是通过模板为neutron的各个服务生成配置文件
#确认配置文件的路径存在,不存在则创建
- name: Ensuring config directories exist
file:
path: "{{ node_config_directory }}/{{ item.key }}"
state: "directory"
recurse: yes
when:
- item.value.enabled | bool
- item.value.host_in_groups | bool
with_dict: "{{ neutron_services }}"
# 为需要neutron.conf配置文件的服务生成neutron.conf配置文件
- name: Copying over neutron.conf
vars:
service_name: "{{ item.key }}"
# 定义需要neutron.conf配置文件的服务
services_need_neutron_conf:
- "neutron-dhcp-agent"
- "neutron-l3-agent"
- "neutron-linuxbridge-agent"
- "neutron-metadata-agent"
- "neutron-openvswitch-agent"
- "neutron-server"
- "neutron-lbaas-agent"
- "neutron-aas-agent"
- "neutron-bgp-dragent"
# 调用自定义的merge_configs模块
# merge_configs模块将合并sources下列表的所有模板和文件,生成neutron.conf
merge_configs:
sources:
# sources下列表的文件内,配置项重复时,下方的将覆盖上方的
- "{{ role_path }}/templates/neutron.conf.j2"
- "{{ node_custom_config }}/global.conf"
- "{{ node_custom_config }}/database.conf"
- "{{ node_custom_config }}/messaging.conf"
- "{{ node_custom_config }}/neutron.conf"
- "{{ node_custom_config }}/neutron/{{ item.key }}.conf"
- "{{ node_custom_config }}/neutron/{{ inventory_hostname }}/neutron.conf"
dest: "{{ node_config_directory }}/{{ item.key }}/neutron.conf"
register: neutron_confs
when:
- item.value.enabled | bool
- item.value.host_in_groups | bool
- item.key in services_need_neutron_conf
# 对neutron_services下的各服务进行循环
with_dict: "{{ neutron_services }}"
# 触发执行handlers下的Restart {{ item.key }} container的task
# 被触发的task将在所有task执行完成后执行
notify:
- "Restart {{ item.key }} container"
bootstrap.yml
bootstrap.yml是为neutron创建数据库及数据库用户等
# 创建neutron的数据库
- name: Creating Neutron database
# 调用kolla_toolbox模块
kolla_toolbox:
module_name: mysql_db
module_args:
login_host: "{{ database_address }}"
login_port: "{{ database_port }}"
login_user: "{{ database_user }}"
login_password: "{{ database_password }}"
name: "{{ neutron_database_name }}"
# 将执行结果暂存到database
register: database
run_once: True
# 指定在neutron-server主机组的第一个主机上执行该task
delegate_to: "{{ groups['neutron-server'][0] }}"
# 当上方暂存的database有改变值时,将会去执行bootstrap_service.yml
- include: bootstrap_service.yml
when: database.changed
bootstrap_service.yml
bootstrap_service.yml将会启动bootstrap引导容器,用于解决neutron服务所需的依赖配置,在完成后,这些引导容器将被自动删除
# 启动bootstrap_neutron容器
- name: Running Neutron bootstrap container
vars:
neutron_server: "{{ neutron_services['neutron-server'] }}"
kolla_docker:
action: "start_container"
common_options: "{{ docker_common_options }}"
detach: False
environment:
KOLLA_BOOTSTRAP:
KOLLA_CONFIG_STRATEGY: "{{ config_strategy }}"
image: "{{ neutron_server.image }}"
labels:
BOOTSTRAP:
name: "bootstrap_neutron"
restart_policy: "never"
volumes: "{{ neutron_server.volumes }}"
run_once: True
delegate_to: "{{ groups[neutron_server.group][0] }}"
templates目录下存放着很多j2格式的文件,他们都是neutron各服务的配置文件模板,这些模板将被config.yml根据需要生成为各服务的配置文件。
这里举neutron.conf.j2和neutron-server.json.j2为例进行分析
neutron.conf.j2
[DEFAULT]
# 直接生成配置项
log_dir = /var/log/kolla/neutron
# 将会读取变量文件中api_interface_address和neutron_server_port的值,生成配置项
bind_host = {{ api_interface_address }}
bind_port = {{ neutron_server_port }}
# 将根据if条件判断表达式,符合的表达式将生成对应的配置项
{% if neutron_plugin_agent == 'vmware_nsxv' %}
core_plugin = vmware_nsx.plugin.NsxVPlugin
{% elif neutron_plugin_agent == 'vmware_dvs' %}
core_plugin = vmware_nsx.plugin.NsxDvsPlugin
{% else %}
core_plugin = ml2
service_plugins = {{ neutron_service_plugins|map(attribute='name')|join(',') }}
{% endif %}
neutron-server.json.j2
config.yml将把neutron-server.json.j2生成为config.json,存放在/etc/kolla/neutron-server/目录下,同时该目录下还有neutron.conf等其他neutron-server的配置文件。
在启动容器时/etc/kolla/neutron-server/会被映射到neutron_server容器的/var/lib/kolla/config_files/目录下。
此时生成的config.json的作用就是提供/var/lib/kolla/config_files/目录下neutron-server服务各配置文件与真正配置文件目录:/etc/neutron/ 的链接关系
{
"command": "neutron-server --config-file /etc/neutron/neutron.conf {% if neutron_plugin_agent in ['openvswitch', 'linuxbridge', 'opendaylight'] %} --config-file /etc/neutron/plugins/ml2/ml2_conf.ini --config-file /etc/neutron/neutron_lbaas.conf --config-file /etc/neutron/neutron_aas.conf {% elif neutron_plugin_agent in ['vmware_nsxv', 'vmware_dvs'] %} --config-file /etc/neutron/plugins/vmware/nsx.ini {% endif %} --config-file /etc/neutron/fwaas_driver.ini",
"config_files": [
{
# 提供/var/lib/kolla/config_files/neutron.conf和/etc/neutron/neutron.conf的链接
"source": "{{ container_config_directory }}/neutron.conf",
"dest": "/etc/neutron/neutron.conf",
"owner": "neutron",
"perm": "0600"
}
]
}
ansible-playbook -i $INVENTORY $CONFIG_OPTS $EXTRA_OPTS $PLAYBOOK $VERBOSITY
# -------------------------------------------------
INVENTORY:inventory文件,用于ansible配置主机信息,文件路径在/etc/ansible/hosts/
CONFIG_OPTS:指定globals.yml,password.yml文件
EXTRA_OPTS:指定执行的动作,如’-e kolla_action=deploy’
PLAYBOOK: 为role的入口文件site.yml
例如执行deploy动作的调用过程为kolla-ansible -i all-in-one deploy —> 调用/usr/local/share/kolla-ansible/ansible/site.yml —>根据site.yml文件的task调用执行roles
下面以reconfigure流程分析为例
命令执行参数 kolla-ansible -i /etc/ansible/hosts/ reconfigure -t keystone(组件名称)
具体调用ansible-playbook -i /etc/hosts -e @/etc/ict/globals.yml -e @/etc/kolla/globals.yml -e @/etc/kolla/passwords.yml -e CONFIG_DIR=/etc/kolla -e enable_horizon=false --tags keystone -e kolla_action=reconfigure -e kolla_serial=0 /usr/share/kolla-ansible/ansible/site.yml
reconfigure操作对应的kolla_action参数为reconfigure,首先去调用site.yml中name为apply role haproxy的tasks
在haproxy role task中,有很多task子任务,此处以keystone为例
在tasks中使用include_role动态导入keystone
- include_role:
role: keystone
tasks_from: loadbalancer
tags: keystone
when: enable_keystone | bool
此处的tasks_from和include_role配合使用,用于指定要从tasks目录中加载的文件,即roles/keystone/tasks/loadbalancer(若tasks_from不指定,默认为main.yml)
- name: "Configure haproxy for {{ project_name }}"
import_role:
role: haproxy-config
vars:
project_services: "{{ keystone_services }}"
tags: always
使用import_role静态导入haproxy-config
首先,读取keystone_services变量值,赋值给project_services,然后加载roles/haproxy-cofig/tasks/main.yml文件:主要完成的操作就是把本地的haproxy_single_service_listen.cfg.j2模块注入变量后,复制到远程节点目录/etc/kolla/haproxy/services.d/nova-api.cfg
在haproxy中配置好keystone之后,往下会执行到名为Apply role keystone的task
- name: Apply role keystone
gather_facts: false
hosts:
- keystone
- '&enable_keystone_True'
serial: '{{ kolla_serial|default("0") }}'
roles:
- { role: keystone,
tags: keystone,
when: enable_keystone | bool }
然后会去执行roles/keystone/tasks/main.yml --> reconfigure.yml --> 主要任务实现都在deploy.yml文件
主要实现:
config.yml:实现keystone相关的检查配置文件
clone.yml:git下载keystone文件
bootstarp.yml: 创建keystone数据库用户权限等配置
meta: flush_handlers:meta任务可影响ansible内部运行方式,这里表示立即执行之前tasks所对应的handler