Kolla-ansible源码分析,kolla-ansible源码


1. 基本认识

1.1. kolla-ansible

kolla-ansible是从kolla项目中分离出来的一个可交付的项目。kolla-ansible负责部署容器化的openstack各个服务和基础设施组件;而kolla项目现在则单独负责镜像的构建,为kolla-ansible部署提供生产级别的openstack各服务镜像。

1.2. ansible和docker

kolla-ansible利用ansible进行openstack服务的配置、编排openstack各个服务容器的部署。
利用容器的隔离性,达到openstack各服务容器的升级、回退,控制升级、回退的影响范围,降低openstack集群运维的复杂度。

2. 源码目录

Directories

  • ansible - Contains Ansible playbooks to deploy OpenStack services and infrastructure components in Docker containers.
  • contrib - Contains demos scenarios for Heat, Magnum and Tacker and a development environment for Vagrant
  • doc - Contains documentation.
  • etc - Contains a reference etc directory structure which requires configuration of a small number of configuration variables to achieve a working All-in-One (AIO) deployment.
  • specs - Contains the Kolla-Ansible communities key arguments about architectural shifts in the code base.
  • tests - Contains functional testing tools.
  • tools - Contains tools for interacting with Kolla-Ansible.

3. ansible

3.1. ansible代码结构

ansible

├── action_plugins

│   ├── merge_configs.py

│   └── merge_yaml.py

├── bifrost.yml

├── certificates.yml

├── destroy.yml

├── group_vars

│   └── all.yml

├── inventory

│   ├── all-in-one

│   └── multinode

├── kolla-host.yml

├── library

│   ├── bslurp.py

│   ├── kolla_container_facts.py

│   ├── kolla_docker.py

│   ├── kolla_toolbox.py

│   ├── merge_configs.py

│   └── merge_yaml.py

├── mariadb_recovery.yml

├── post-deploy.yml

└── roles

    ├── aodh

    ├── barbican

    ├── baremetal

    ├── bifrost

    ├── ceilometer

    ├── ceph

    ├── certificates

    ├── chrony

    ├── cinder

    ├── cloudkitty

    ├── collectd

    ├── common

    ├── congress

    ├── designate

    ├── destroy

    ├── elasticsearch

    ├── etcd

    ├── freezer

    ├── glance

    ├── gnocchi

    ├── grafana

    ├── haproxy

    ├── heat

    ├── horizon

    ├── influxdb

    ├── ironic

    ├── iscsi

    ├── karbor

    ├── keystone

    ├── kibana

    ├── kuryr

    ├── magnum

    ├── manila

    ├── mariadb

    ├── memcached

    ├── mistral

    ├── monasca

    ├── mongodb

    ├── multipathd

    ├── murano

    ├── neutron

    ├── nova

    ├── nova-hyperv

    ├── octavia

    ├── opendaylight

    ├── openvswitch

    ├── ovs-dpdk

    ├── panko

    ├── prechecks

    ├── qdrouterd

    ├── rabbitmq

    ├── rally

    ├── redis

    ├── sahara

    ├── searchlight

    ├── senlin

    ├── skydive

    ├── solum

    ├── stop

    ├── swift

    ├── tacker

    ├── telegraf

    ├── tempest

    ├── trove

    ├── vmtp

    ├── watcher

    └── zun

├── site.yml

└── stop.yml

3.3. action_plugins目录

action_plugins目录下存放的是是kolla-ansible自定义的ansible插件
merge_configs.py,在playboy内通过使用merge_config来合并配置文件模板,生成openstack各服务的配置文件。

3.4. ./group_vars/all.yml文件

all.yml文件作为ansible的变量文件,定义了各类配置信息。比如:配置文件路径、网卡、IP、端口号、各服务的开启等。(部分配置在globa.yml内也做了定义,global.yml具有更高优先级)

all.yml部分内容:

# 配置文件路径

node_config_directory: "/etc/kolla/{{ project }}"

 

###################

# Kolla options  定义vip

###################

kolla_internal_vip_address: "{{ kolla_internal_address }}"

 

####################

# Networking options 网卡、端口等的配置

####################

network_interface: "eth0"

api_interface: "{{ network_interface }}"

 

aodh_api_port: "8042"

 

####################

# OpenStack options openstack版本、服务开启等配置

####################

openstack_release: "auto"

 

enable_glance: "yes"

3.5. inventory目录

inventory下存放的是主机清单

  • all-in-one用于单节点环境下,指定要部署的主机和该主机的角色
  • multinode用于多节点环境,指定要部署的主机和该主机的角色

主机清单也可作为定义变量的变量文件

multinode部分内容:

# 指定节点到control组

[control]

node1

 

# 指定节点到network组

[network]

node1

 

# 指定节点compute组

[compute]

node1

node2

 

# 指定neutron组继承network组

[neutron:children]

network

3.6. library目录

library目录下是kolla-ansible自定义的ansible模块

  • bslurp.py: 从远程节点获取文件,并分发到更多节点
  • kolla_container_facts.py: 获取容器的facts信息
  • kolla_docker.py: 通过调用docker-py来驱动docker,进行启动容器、删除容器等操作
  • kolla_toolbox.py: 用于调用kolla_toolbox容器内定义的ansible模块

3.7. roles目录

3.7.1. ansible role简介

因为在实际中,会有很多不同的业务需要很多不同的playbook文件,很难进行维护。所以ansible采用role的方式对playbook进行目录结构规范。

在kolla-ansible内,对各个openstack服务进行部署,同样需要很多不同的playbook。
在roles目录内,有部署openstack各服务所需的各种playbook、定义的变量以及模板文件等。
与roles同级的还有site.yml文件,这是role引用的入口文件。

下面以roles目录下的neutron为例进行分析,其他服务的结构基本类似。

3.7.2 neutron目录结构

neutron目录下有5个文件夹:

  • default: 定义了部署neutron各服务的各类参数
  • handlers: 定义了启动neutron各服务容器的操作
  • meta: 定义了部署neutron的依赖
  • tasks: 部署neutron的各playbook
  • templates: neutron各服务配置文件的模板

neutron/

├── defaults

│   └── main.yml

├── handlers

│   └── main.yml

├── meta

│   └── main.yml

├── tasks

│   ├── bootstrap_service.yml

│   ├── bootstrap.yml

│   ├── check.yml

│   ├── config-neutron-fake.yml

│   ├── config.yml

│   ├── deploy.yml

│   ├── ironic-check.yml

│   ├── main.yml

│   ├── precheck.yml

│   ├── pull.yml

│   ├── reconfigure.yml

│   ├── register.yml

│   └── upgrade.yml

└── templates

    ├── bgp_dragent.ini.j2

    ├── dhcp_agent.ini.j2

    ├── dnsmasq.conf.j2

    ├── fwaas_driver.ini.j2

    ├── l3_agent.ini.j2

    ├── lbaas_agent.ini.j2

    ├── metadata_agent.ini.j2

    ├── ml2_conf.ini.j2

    ├── neutron-bgp-dragent.json.j2

    ├── neutron.conf.j2

    ├── neutron-dhcp-agent.json.j2

    ├── neutron-l3-agent.json.j2

    ├── neutron-l3-agent-wrapper.sh.j2

    ├── neutron-lbaas-agent.json.j2

    ├── neutron_lbaas.conf.j2

    ├── neutron-linuxbridge-agent.json.j2

    ├── neutron-metadata-agent.json.j2

    ├── neutron-openvswitch-agent.json.j2

    ├── neutron-server.json.j2

    ├── neutron-vpnaas-agent.json.j2

    ├── neutron-vpnaas-agent-wrapper.sh.j2

    ├── neutron_vpnaas.conf.j2

    ├── nsx.ini.j2

    └── vpnaas_agent.ini.j2

3.7.3. defaults

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 }}"

3.7.4. handlers

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_vpnaas_conf: "{{ neutron_vpnaas_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_vpnaas_conf | changed

      or neutron_ml2_conf | changed

      or nsx_ini | changed

      or policy_json | changed

      or neutron_server_container | changed

3.7.5. meta

meta下的main.yml指定了neutron这个role的依赖,从main.yml内容可以看出实际是依赖于common这个role,也就是在执行neutron的task前,会先去common这个role下执行相关task。
全部内容:

---

dependencies:

  - { role: common }

3.7.6. tasks

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-vpnaas-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] }}"

3.7.7. templates

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_vpnaas.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"

        }

    ]

}

 

相关内容

    暂无相关文章