Skip to content
Snippets Groups Projects
ansible-multi.rst 12.9 KiB
Newer Older
  • Learn to ignore specific revisions
  • ..
       This work is licensed under a Creative Commons Attribution 3.0 Unported
     License.
    
     http://creativecommons.org/licenses/by/3.0/legalcode
    
    ==================
    Multi-node Ansible
    ==================
    
    This blueprint specifies an approach to automate the deployment of OpenStack
    
    caoyuan's avatar
    caoyuan committed
    using Ansible and Docker best practices. The overriding principles used in
    
    this specification are simplicity, flexibility and optimized deployment speed.
    
    Problem description
    ===================
    
    
    caoyuan's avatar
    caoyuan committed
    Kolla can be deployed multi-node currently. To do so, the environment
    
    variables must be hand edited to define the hosts to connect to for various
    services.
    
    To implement HA in our containers, we need multi-node deployment operational
    so we can validate the high availability implementation.
    
    To meet our community approved mission, we must implement a deployment tool
    
    venkatamahesh's avatar
    venkatamahesh committed
    and Ansible provides the most efficient development path while ensuring ease
    
    of use.
    
    Use cases
    ---------
    
    1. Deploy Kolla's Docker containers multi-node and generate a one-hundred node
       working OpenStack deployment out of the box with minimal Operator
       configuration.
    2. Offer a fully customizable configuration enabling an unopinionated
       deployment of OpenStack.
    3. Upgrade an OpenStack deployment by Operator command.
    4. Offer our container content as a building block to third party downstream
       deployment tools.
    
    Proposed change
    ===============
    
    The docker-compose tool is single node and does nearly the same job as Ansible
    
    caoyuan's avatar
    caoyuan committed
    would in this specification. As a result, we recommend deprecating
    
    docker-compose as the default deployment system for Kolla.
    
    
    caoyuan's avatar
    caoyuan committed
    To replace it, we recommend Ansible as a technology choice. Ansible is easy
    
    to learn, easy to use, and offers a base set of functionality to solve
    deployment as outlined in our four use cases.
    
    We recommend three models of configuration.
    
    The first model is based upon internally configuring the container and having
    the container take responsibility for all container configuration including
    
    caoyuan's avatar
    caoyuan committed
    database setup, database synchronization, and keystone registration. This
    model uses docker-compose and docker as dependencies. Existing containers will
    
    be maintained but new container content will use either of the two remaining
    
    caoyuan's avatar
    caoyuan committed
    models. James Slagle (TripleO PTL on behalf of our downstream TripleO
    
    community) was very clear that he would prefer to see this model stay available
    
    caoyuan's avatar
    caoyuan committed
    and maintained. As TripleO enters the world of Big Tent, they don't intend to
    
    deploy all of the services, and as such it doesn't make sense to maintain this
    legacy operational mode for new container content except on demand of our
    
    caoyuan's avatar
    caoyuan committed
    downstreams, hopefully with their assistance. This model is called
    
    CONFIG_INSIDE.
    
    The second model and third model configure the containers outside of the
    
    caoyuan's avatar
    caoyuan committed
    container. These models depend on Ansible and Docker. In the future, the
    
    OpenStack Puppet, OpenStack Chef and TripleO communities may decide to switch
    to one of these two models in which case these communities may maintain tooling
    
    caoyuan's avatar
    caoyuan committed
    to integrate with Kolla. The major difference between these two models is that
    
    one offers immutability and single source of truth (CONFIG_OUTSIDE_COPY_ONCE),
    while the third model trades these two properties to allow an Operator to
    directly modify configuration files on a system and have the configuration be
    
    caoyuan's avatar
    caoyuan committed
    live in the container (CONFIG_OUTSIDE_COPY_ALWAYS). Because
    
    CONFIG_OUTSIDE_COPY_ALWAYS requires direct Operator intervention on a node, and
    we prefer as a community Operators interact with the tools provided by Kolla,
    CONFIG_OUTSIDE_COPY_ONCE will be the default.
    
    We do not have to further enhance two sets of container configuration, but
    instead can focus our development effort on the default Ansible configuration
    
    caoyuan's avatar
    caoyuan committed
    methods. If a defect is found in one of the containers based upon the
    
    CONFIG_INSIDE model, the community will repair it.
    
    
    caoyuan's avatar
    caoyuan committed
    Finally we will implement a complete Ansible deployment system. The details
    
    of the implementation are covered in a later section in this specification.
    We estimate this will be approximately ~1000 LOC defining ~100 Ansible tasks.
    We further estimate the total code base when complete will be under 6 KLOC.
    
    The CONFIG_INSIDE model of configuration maintains the immutable,
    declarative, and idempotent nature of the Kolla containers, as defined by our
    current Kolla best practices but is opinionated in configuration.
    
    The CONFIG_OUTSIDE_COPY_ONCE model of configuration maintains the immutable and
    declarative nature of the Kolla containers, as defined by our current Kolla
    best practices while introducing completely customizable configuration.
    
    The CONFIG_OUTSIDE_COPY_ALWAYS model of configuration offers the Operator
    greater flexibility in managing their deployment, at greater risk of damaging
    
    caoyuan's avatar
    caoyuan committed
    their deployment. It trades one set of best practices for another,
    
    specifically the Kolla container best practices for flexibility.
    
    Security impact
    ---------------
    
    None.
    
    Performance Impact
    ------------------
    
    Multi-node deployment speed will be rapidly improved.
    
    Implementation
    ==============
    
    The following section uses the Keystone container as an example.
    
    On container start, a simple shell script will be run.
    
    Passed into the container will be the CONFIG_STRATEGY environment variable with
    the following options:
    
        CONFIG_STRATEGY="CONFIG_INSIDE"
        CONFIG_STRATEGY="CONFIG_OUTSIDE_COPY_ALWAYS"
        CONFIG_STRATEGY="CONFIG_OUTSIDE_COPY_ONCE"
    
    CONFIG_INSIDE will match the current crudini.sh implementation.
    
    The shell script will be similar in nature to the following:
    
        case $CONFIG_STRATEGY in
            CONFIG_INSIDE)
                # We exec on crudini.sh to keep the same behaviour as current
                exec /crudini.sh
                ;;
            CONFIG_OUTSIDE_COPY_ONCE|CONFIG_OUTSIDE_COPY_ALWAYS)
                # We source this file to allow variables to be set if needed
                source /config_outside.sh
                ;;
            *)
                echo '$CONFIG_STRATEGY is not set properly'
                exit 1
                ;;
        esac
    
        exec $CONFIG_STRATEGY_BINARY_NAME
    
    The crudini.sh script would be almost identical to the existing start.sh script
    while the config_outside.sh would copy the files to the appropriate location
    and set the proper permissions on those files. The $CONFIG_STRATEGY variable
    would be checked to see if the files should be copied or it should exit early.
    
    The following bindmounts would be applied to the container in the above example
    for different CONFIG_STRATEGY values:
    
        CONFIG_INSIDE - no bind mount
        CONFIG_OUTSIDE_COPY_ONCE - {{ HOST_CONFIG_DIR }}/keystone:/opt/kolla/configs/keystone:ro
        CONFIG_OUTSIDE_COPY_ALWAYS - {{ HOST_CONFIG_DIR }}/keystone:/opt/kolla/configs/keystone:ro
    
    {{ HOST_CONFIG_DIR }} would be an Ansible variable with the default of
    /opt/kolla/configs. This same pattern will be used for most containers, unless
    there is a compelling technical reason not to do so.
    
    An Ansible role represents a service in OpenStack.  The Ansible role contains
    3 major sections.  This same pattern will be used for all supported
    OpenStack containers.
    
    Each Ansible role has a set of default key/value pairs.  An example key/value
    file for Keystone is:
    
        ---
        container: "keystone"
        database_password: "{{ database_keystone_password }}"
    
    
    The second major section of a Ansible role are the role tasks.  The seven
    tasks we will implement per role (i.e. OpenStack Service):
    
     * bootstrap - database initialization and add roles to keystone
     * pull - pulls the latest container from the registry
     * main - Does the main job of orchestrating the role
     * config - Joins the default configuration and the user augmented
       configuration and saves the resulting file to be bind-mounted
     * start - Similar in nature to a docker compose YAML file - defines the
       defaults for the container start operation.
     * stop - Stops the container
     * upgrade - Upgrades to the latest container content
    
    The details of how these role tasks operate is an implementation detail.
    
    Finally each Ansible role has a default template.  An example of a default
    template for Keystone is:
    
        [DEFAULT]
        verbose = {{ keystone_verbose }}
        debug = {{ keystone_debug }}
    
        bind_host = {{ ansible_br_mgmt['ipv4']['address'] }}
    
        admin_token = {{ keystone_admin_token }}
    
        public_endpoint = http://{{ keystone_service_ip }}:{{ keystone_service_public_port }}
        admin_endpoint = http://{{ keystone_service_ip }}:{{ keystone_service_admin_port }}
    
        log_file = {{ keystone_log_file }}
        log_dir = {{ keystone_log_dir }}
    
        [database]
    
        connection = mysql+pymysql://{{ keystone_db_user }}:{{ database_keystone_password }}@{{ keystone_database_address }}/keystone
    
    
        [revoke]
        driver = keystone.contrib.revoke.backends.sql.Revoke
    
    This role default will contain sufficient mandatory configuration options to
    create a working deployment.  If the Operator wishes to augment the Keystone
    configuration, an augmentation file can be added to the deployment.  An example
    augmentation file in /etc/kolla/keystone.aug is:
    
        [DEFAULT]
        public_endpoint = https://{{ keystone_service_ip }}:{{ keystone_service_public_port }}
    
        [ipman]
        life = "Two Words. Horizontal. Vertical. Make a mistake - Horizontal.  Stay standing and you win."
    
    This augmentation file will keep the original default configurations but
    replace public_endpoint with an https endpoint instead of an http endpoint.
    Further the [ipman] section will be added to the file placed by Ansible in
    the target host's configuration directory.
    
    The end result of the merge will be a single file on the host that is in the
    
    appropriate format for the OpenStack service to consume containing the content
    
    of both the Ansible default file and the augmentation file.
    
    The final implication of these Ansible best practices is that an Operator can
    deploy in 1 hour or less a one-hundred node OpenStack deployment out of the
    box using Kolla containers with Ansible deployment tooling with minimal
    configuration.  If additional customization is required for the Operator's
    environment, this can be achieved via augmentation files developed by the
    Operator.
    
    NB: to override any default key/value pair (the key is located in {{ }} above
    and replaced by the value by Ansible), there is one global override file to
    configure the deployment called /etc/kolla/globals.yml
    
    We will implement a simple shell script called kolla-ansible which wraps
    ansible-playbook.  It will implement four commands which operate on the
    OpenStack deployment globally.  It will automatically load the globals.yml
    
    overrides and an inventory file located in /etc/kolla executing the appropriate
    
    roles for all of the deployed containers.  The initial supported
    commands are:
    
    1. kolla-ansible deploy
    2. kolla-ansible start
    3. kolla-ansible stop
    4. kolla-ansible upgrade
    
    Ansible supports a model of deployment using an inventory file.  The inventory
    file specifies which nodes get assigned which roles.  For an example of an
    inventory file, see:
    
        https://github.com/SamYaple/yaodu/blob/master/ansible/inventories/production
    
    To the untrained eye, this looks like a bunch of heavy wizardy.  I personally
    believe we will in some way merge our globals.yml and the inventory file into
    one master configuration file and generate the globals.yml and Ansible-specific
    inventory file on each kolla-ansible operation.  The long term goal is to get
    to one configuration file with "all the things" needed to deploy OpenStack.
    This would permit a GUI to simply configure the deployment.
    
    How this is done or if it is done remains an implementation detail which may
    warrant expanding this specification or a completely new specification in the
    future.  As we obtain more experience with what we are developing, we will
    have a more complete picture of what this master configuration file format will be.
    
    The implementation described in this section is just a sample of the
    implementation details required.  We intend to refactor Sam Yaple's fantastic
    vision with yaodu (https://github.com/SamYaple/yaodu/) into Kolla to
    implement Ansible deployment of OpenStack while retaining Kolla, Docker, and
    Ansible best practices and conventions.
    
    Assignee(s)
    -----------
    
    Primary assignees:
    
    diga
    fangfenghua
    harmw
    samyaple
    sdake
    
    The kolla core team will support and execute this specification through normal
    workflow operations.
    
    Work Items
    ----------
    
    1. Convert all fat containers to thin containers to facilitate this work.
    2. Move all start.sh scripts to crudini.sh and create the function to execute
       the configuration strategy across containers.
    3. Rename the kolla script to kolla-compose and create a new kolla-ansible
       script to manage playbook operation.
    4. Refactor the remaining portions of yaodu that are compatible with Kolla into
       the Kolla code base.
    5. Implement our existing crudini defaults in Ansible.
    
    Testing
    =======
    
    Functional tests will be implemented in the OpenStack check/gating system to
    automatically check that the Ansible deployment works for an AIO environment.
    
    Documentation Impact
    ====================
    
    The developer quickstart must be augmented with instructions to use the new
    Ansible deployment methodology.