From 45300e7d9575d554657f6530808328bf85fd8e81 Mon Sep 17 00:00:00 2001 From: Matthew Mosesohn Date: Tue, 15 Oct 2013 14:19:00 +0400 Subject: [PATCH] renamed cluster to environment, full/compact to multinode HA --- _images/net_verify_failure.jpg | Bin 26524 -> 35152 bytes .../0030-add-remove-nodes-without-downtime | 6 +- .../0030-howtos.rst | 24 +- pages/install-guide/0000-intro.rst | 24 +- pages/install-guide/0000-preamble | 4 +- pages/install-guide/0010-introduction | 2 +- pages/install-guide/0010-prerequisites.rst | 8 +- pages/install-guide/0015-before-you-start | 2 +- pages/install-guide/0015-sizing-hardware.rst | 11 +- pages/install-guide/0030-how-it-works.rst | 8 +- .../0040-reference-topologies.rst | 24 +- .../0060-understand-the-manifest.rst | 4 +- pages/install-guide/install.rst | 80 +----- pages/install-guide/networks.rst | 25 +- .../reference-architecture/0010-overview.rst | 11 +- pages/reference-architecture/0012-simple.rst | 8 +- pages/reference-architecture/0014-compact.rst | 10 +- .../0015-closer-look.rst | 10 +- pages/reference-architecture/0016-full.rst | 24 -- .../0018-red-hat-differences.rst | 18 +- .../0020-logical-setup.rst | 10 +- .../0030-cluster-sizing.rst | 2 +- .../0040-network-setup.rst | 14 +- .../0060-quantum-vs-nova-network.rst | 6 +- .../advanced-topics/0010-introduction.rst | 4 +- .../advanced-topics/0020-custom-plug-ins.rst | 261 ++++++++++++++---- .../user-guide/post-install-healthchecks.rst | 11 +- .../troubleshooting-ug/network-issues.rst | 12 +- 28 files changed, 338 insertions(+), 285 deletions(-) delete mode 100644 pages/reference-architecture/0016-full.rst diff --git a/_images/net_verify_failure.jpg b/_images/net_verify_failure.jpg index dfffe00c9908a08e54e837919372c5e59ee5e1fa..a1127f2544a8fe0819a6b12c22769335d7809cc3 100644 GIT binary patch literal 35152 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 q$Fxi2)>5y`dy diff --git a/pages/frequently-asked-questions/0030-add-remove-nodes-without-downtime b/pages/frequently-asked-questions/0030-add-remove-nodes-without-downtime index f9fb9becb..07c8f2445 100644 --- a/pages/frequently-asked-questions/0030-add-remove-nodes-without-downtime +++ b/pages/frequently-asked-questions/0030-add-remove-nodes-without-downtime @@ -6,9 +6,9 @@ Add or Remove Controller and Compute Nodes Without Downtime =========================================================== This document will help you become familiar with the process around lifecycle -management of controller and compute nodes within an OpenStack cluster deployed -by Fuel. There are some specific details to note, so reading this document -is highly recommended. +management of controller and compute nodes within an OpenStack environment +deployed by Fuel. There are some specific details to note, so reading this +document is highly recommended. 1. The addition of compute nodes works seamlessly - just specify its IPs in `site.pp` file (if needed) and run puppet agent diff --git a/pages/frequently-asked-questions/0030-howtos.rst b/pages/frequently-asked-questions/0030-howtos.rst index 78f44c212..9b61807b5 100644 --- a/pages/frequently-asked-questions/0030-howtos.rst +++ b/pages/frequently-asked-questions/0030-howtos.rst @@ -51,15 +51,15 @@ need to create it yourself, use this procedure: HowTo: Redeploy a node from scratch ------------------------------------ -Compute and Cinder nodes in an HA configuration and controller in any -configuration cannot be redeployed without completely redeploying the cluster. -However, for a non-HA OpenStack cluster, you can redeploy a Compute or -Cinder node. To do so, follow these steps: +Compute and Cinder nodes can be redeployed in both multinode and multinode HA +configurations. However, controllers cannot be redeployed without compeltely +redeploying the environment. To do so, follow these steps: -1. Remove the certificate for the node by executing the command - ``puppet cert clean `` on Fuel Master node. -2. Reboot the node over the network so it can be picked up by Cobbler. -3. Run the puppet agent on the target node using ``puppet agent --test``. +1. Remove the node from your environment in the Fuel UI +2. Deploy Changes +3. Wait for the host to become available as an unallocated node +4. Add the node to the environment with the same role as before +5. Deploy Changes .. _Enable_Disable_Galera_autorebuild: @@ -129,7 +129,7 @@ Here you can enter resource-specific commands:: **crm(live)resource# start|restart|stop|cleanup ** -These commands allow you torespectively start, stop, and restart resources. +These commands allow you to respectively start, stop, and restart resources. **cleanup** @@ -246,8 +246,8 @@ when members list is incomplete. How To Smoke Test HA -------------------- -To test if Quantum HA is working, simply shut down the node hosting, e.g. -Quantum agents (either gracefully or hardly). You should see agents start on +To test if NeutrnoHA is working, simply shut down the node hosting, e.g. +Neutron agents (either gracefully or hardly). You should see agents start on the other node:: @@ -260,7 +260,7 @@ the other node:: p_quantum-dhcp-agent (ocf::pacemaker:quantum-agent-dhcp): Started fuel-controller-02 p_quantum-l3-agent (ocf::pacemaker:quantum-agent-l3): Started fuel-controller-02 -and see corresponding Quantum interfaces on the new Quantum node:: +and see corresponding Neutron interfaces on the new Neutron node:: # ip link show diff --git a/pages/install-guide/0000-intro.rst b/pages/install-guide/0000-intro.rst index b2b134424..f78735c18 100644 --- a/pages/install-guide/0000-intro.rst +++ b/pages/install-guide/0000-intro.rst @@ -28,34 +28,18 @@ configuration. However, Mirantis provides several pre-defined architectures for your convenience. The pre-defined architectures include: -* **Multi-node (non-HA)** - The Multi-node (non-HA) environment provides an easy way - to install an entire OpenStack cluster without requiring the degree +* **Multi-node** + The Multi-node environment provides an easy way + to install an entire OpenStack environment without requiring the degree of increased hardware involved in ensuring high availability. Mirantis recommends that you use this architecture for testing purposes. -* **Multi-node with HA** +* **Multi-node HA** The Multi-node with HA environment is dedicated for highly available production deployments. Using Multi-node with HA you can deploy additional services, such as Cinder, Neutron, and Ceph. You can create the following multi-node environments: - - * **Compact HA** - The Compact HA installation provides high availability and at - the same time saves on hardware. When you deploy Compact - HA, Fuel uses controller nodes to install Swift. Therefore, - the hardware requirements are reduced by eliminating the need - for additional storage servers while addressing the high - availability requirements. - - * **Full HA** - The Full HA installation requires maximum hardware and provides - complete highly available OpenStack deployment. With Full HA, you - can install independent Ceph and Cinder nodes. Using the standalone - Ceph and Cinder servers, you can isolate their operations from - the controller nodes. - With Fuel, you can create your own cloud environment that include additional components. diff --git a/pages/install-guide/0000-preamble b/pages/install-guide/0000-preamble index a1881e07b..a6a3d138e 100644 --- a/pages/install-guide/0000-preamble +++ b/pages/install-guide/0000-preamble @@ -7,8 +7,8 @@ Working hands on with Fuel for OpenStack will help you see how to move certain features around from the standard installation. The first step, however, is to commit to a deployment template. A balanced, -compact, and full-featured deployment is the Multi-node (HA) Compact -deployment, so that’s what we’ll be using through the rest of this guide. +compact, and full-featured deployment is the Multi-node with HA deployment, so +that is what we’ll be using through the rest of this guide. Production installations require a physical hardware infrastructure, but you can easily deploy a small simulation cloud on a single physical machine diff --git a/pages/install-guide/0010-introduction b/pages/install-guide/0010-introduction index 55a5ab9c1..30115e3a6 100644 --- a/pages/install-guide/0010-introduction +++ b/pages/install-guide/0010-introduction @@ -3,7 +3,7 @@ How installation works While version 2.0 of Fuel provided the ability to simplify installation of OpenStack, versions 2.1 and above include orchestration capabilities that -simplify deployment of OpenStack clusters. The deployment process using +simplify deployment of OpenStack environments. The deployment process using Fuel CLI follows this general procedure: #. Design your architecture. diff --git a/pages/install-guide/0010-prerequisites.rst b/pages/install-guide/0010-prerequisites.rst index 31752dc81..5c4ad44b0 100644 --- a/pages/install-guide/0010-prerequisites.rst +++ b/pages/install-guide/0010-prerequisites.rst @@ -228,7 +228,7 @@ volume space: * 5 frames x 2400 IOPS per frame / 100 VMs = 120 Read IOPS, 60 Write IOPS per frame You can accomplish the same thing with a single 36 drive frame using 3 TB -drives, but this becomes a single point of failure in your cluster. +drives, but this becomes a single point of failure in your environment. Object storage ++++++++++++++ @@ -255,11 +255,11 @@ and capacity issues. Calculating Network -------------------- -Perhaps the most complex part of designing an OpenStack cluster is the +Perhaps the most complex part of designing an OpenStack environment is the networking. -An OpenStack cluster can involve multiple networks even beyond the Public, -Private, and Internal networks. Your cluster may involve tenant networks, +An OpenStack environment can involve multiple networks even beyond the Public, +Private, and Internal networks. Your environment may involve tenant networks, storage networks, multiple tenant private networks, and so on. Many of these will be VLANs, and all of them will need to be planned out in advance to avoid configuration issues. diff --git a/pages/install-guide/0015-before-you-start b/pages/install-guide/0015-before-you-start index bcf98ecdf..98c9d6d73 100644 --- a/pages/install-guide/0015-before-you-start +++ b/pages/install-guide/0015-before-you-start @@ -44,7 +44,7 @@ important decisions: you are deploying on physical hardware, two of them -- the public network and the internal, or management network -- must be routable in your networking infrastructure. The third network is used by the nodes for - inter-node communications. Also, if you intend for your cluster to be + inter-node communications. Also, if you intend for your environment to be accessible from the Internet, you'll want the public network to be on the proper network segment. For simplicity in this case, this example assumes an Internet router at 192.168.0.1. Additionally, a set of private network diff --git a/pages/install-guide/0015-sizing-hardware.rst b/pages/install-guide/0015-sizing-hardware.rst index 965425f8d..42bf1c7a3 100644 --- a/pages/install-guide/0015-sizing-hardware.rst +++ b/pages/install-guide/0015-sizing-hardware.rst @@ -18,7 +18,7 @@ that will suit your needs. The Golden Rule, however, is to always plan for growth. With the potential for growth in your design, you can move onto your actual hardware needs. -Many factors contribute to selecting hardware for an OpenStack cluster -- +Many factors contribute to selecting hardware for an OpenStack environment -- `contact Mirantis `_ for information on your specific requirements -- but in general, you will want to consider the following factors: @@ -187,7 +187,7 @@ volume space: * 5 frames x 2400 IOPS per frame / 100 VMs = 120 Read IOPS, 60 Write IOPS per frame You can accomplish the same thing with a single 36 drive frame using 3 TB -drives, but this becomes a single point of failure in your cluster. +drives, but this becomes a single point of failure in your environment. Object storage ++++++++++++++ @@ -216,10 +216,11 @@ and capacity issues. Networking ---------- -Perhaps the most complex part of designing an OpenStack cluster is networking. +Perhaps the most complex part of designing an OpenStack environment is +networking. -An OpenStack cluster can involve multiple networks even beyond the required -Public, Private, and Internal networks. Your cluster may involve tenant +An OpenStack environment can involve multiple networks even beyond the required +Public, Private, and Internal networks. Your environment may involve tenant networks, storage networks, multiple tenant private networks, and so on. Many of these will be VLANs, and all of them will need to be planned out in advance to avoid configuration issues. diff --git a/pages/install-guide/0030-how-it-works.rst b/pages/install-guide/0030-how-it-works.rst index c35df6a22..884e7bcd0 100644 --- a/pages/install-guide/0030-how-it-works.rst +++ b/pages/install-guide/0030-how-it-works.rst @@ -38,14 +38,14 @@ In practice, Fuel works as follows: be completed once per installation. 2. Next, discover your virtual or physical nodes and configure your - OpenStack cluster using the Fuel UI. + OpenStack environment using the Fuel UI. -3. Finally, deploy your OpenStack cluster on discovered nodes. Fuel will +3. Finally, deploy your OpenStack environment on discovered nodes. Fuel will perform all deployment steps for you by applying pre-configured and pre-integrated Puppet manifests via Astute orchestration engine. -Fuel is designed to enable you to maintain your cluster while giving you the -flexibility to adapt it to your own business needs and scale. +Fuel is designed to enable you to maintain your environment, while giving you +the flexibility to adapt it to your own business needs and scale. .. image:: /_images/how-it-works_svg.jpg :align: center diff --git a/pages/install-guide/0040-reference-topologies.rst b/pages/install-guide/0040-reference-topologies.rst index 0cc88076b..10c268fba 100644 --- a/pages/install-guide/0040-reference-topologies.rst +++ b/pages/install-guide/0040-reference-topologies.rst @@ -14,26 +14,22 @@ deployment configurations that you can use to quickly build your own OpenStack cloud infrastructure. These are widely accepted configurations of OpenStack, with its constituent components expertly tailored to serve multipurpose cloud use cases. Fuel provides the ability to create the -following cluster types directly out of the box: +following environment types directly out of the box: -**Simple (non-HA)**: The Simple (non-HA) installation provides an easy way -to install an entire OpenStack cluster without requiring the expense of +**Multi-node**: The Multi-node installation provides an easy way +to install an entire OpenStack environment without requiring the expense of extra hardware required to ensure high availability. **Multi-node (HA)**: When you are ready to move to production, the Multi-node -(HA) configuration is a straightforward way to create an OpenStack -cluster that provides high availability. With three controller nodes and the -ability to individually specify services such as Cinder, Neutron (formerly -Quantum), Swift, and Ceph, Fuel provides the following variations of the -Multi-node (HA) configurations: +(HA) configuration is a straightforward way to create an OpenStack environment +that provides high availability. With three controller nodes and the +ability to individually assign roles such as Controller, Compute, Cinder, +and Ceph Object Storage Daemon (OSD). Fuel provides the ability to combine +roles to fit your sizing needs. -- **Compact HA**: When you choose this option, Swift will be installed on - your controllers, reducing your hardware requirements by eliminating the need - for additional Swift servers while still addressing high availability - requirements. +.. note:: -- **Full HA**: This option enables you to install dedicated Cinder or Ceph - nodes, so that you can separate their operations from your controller nodes. + Controller and Compute roles cannot be combined on the same host. In addition to these configurations, Fuel is designed to be completely customizable. For assistance on deeper customization options based on the diff --git a/pages/install-guide/0060-understand-the-manifest.rst b/pages/install-guide/0060-understand-the-manifest.rst index ba86bdb43..ff9055a27 100644 --- a/pages/install-guide/0060-understand-the-manifest.rst +++ b/pages/install-guide/0060-understand-the-manifest.rst @@ -46,8 +46,8 @@ and Astute orchestrator passes to the next node in deployment sequence. .. index:: Deploying Using CLI -Deploying OpenStack Cluster Using CLI -===================================== +Deploying OpenStack Environment Using CLI +========================================= .. contents :local: diff --git a/pages/install-guide/install.rst b/pages/install-guide/install.rst index 5512fccd2..70fcaa0f1 100644 --- a/pages/install-guide/install.rst +++ b/pages/install-guide/install.rst @@ -14,10 +14,10 @@ Fuel Master node. The ISO image is used for CD media devices, iLO (HP) or similar remote access systems. The IMG file is used for USB memory stick-based installation. -Once installed, Fuel can be used to deploy and manage OpenStack clusters. It -will assign IP addresses to the nodes, perform PXE boot and initial +Once installed, Fuel can be used to deploy and manage OpenStack environments. +It will assign IP addresses to the nodes, perform PXE boot and initial configuration, and provision of OpenStack nodes according to their roles in -the cluster. +the environment. .. _Install_Bare-Metal: @@ -52,7 +52,7 @@ are all available at no cost: - `ISOtoUSB `_. After the installation is complete, you will need to make your bare-metal nodes -available for your OpenStack cluster. Attach them to the same L2 network +available for your OpenStack environment. Attach them to the same L2 network (broadcast domain) as the Master node, and configure them to automatically boot via network. The UI will discover them and make them available for installing OpenStack. @@ -60,7 +60,7 @@ installing OpenStack. VirtualBox ---------- -.. OpenStack-3.2-ReferenceArchitecture: +.. OpenStack-3.2-ReferenceArchitecture:: If you would like to evaluate Fuel on VirtualBox, you can take advantage of the included set of scripts that create and configure all the required VMs for a @@ -83,13 +83,13 @@ VirtualBox 4.2.16 (or later) is required, along with the extension pack. Both can be downloaded from ``_. 8 GB+ of RAM - Will support 4 VMs for non-HA OpenStack installation (1 Master node, + Will support 4 VMs for Multi-node OpenStack installation (1 Master node, 1 Controller node, 1 Compute node, 1 Cinder node) or - Will support 5 VMs for HA OpenStack installation (1 Master node, 3 Controller - + Cinder nodes, 1 Compute node) + Will support 5 VMs for Multi-node with HA OpenStack installation (1 Master + node, 3 Controller + Cinder nodes, 1 Compute node) .. _Install_Automatic: @@ -114,7 +114,7 @@ important files and folders: After installation of the Master node, the script will create Slave nodes for OpenStack and boot them via PXE from the Master node. Finally, the script will give you the link to access the Web-based UI for the - Master node so you can start installation of an OpenStack cluster. + Master node so you can start installation of an OpenStack environment. .. _Install_Manual: @@ -150,7 +150,7 @@ First, create the Master node VM. * OS Type: Linux * Version: Red Hat (64bit) * RAM: 1024+ MB -* HDD: 20 GB (35gb for Red Hat OpenStack) with dynamic disk expansion +* HDD: 50 GB with dynamic disk expansion 3. Modify your VM settings: @@ -221,68 +221,16 @@ changes, go to Save & Quit. Changing Network Parameters After Installation ---------------------------------------------- -It is still possible to configure other interfaces, or add 802.1Q sub-interfaces -to the Master node to be able to access it from your network if required. -It is easy to do via standard network configuration scripts for CentOS. When the -installation is complete, you can modify -``/etc/sysconfig/network-scripts/ifcfg-eth\*`` scripts. For example, if *eth1* -interface is on the L2 network which is planned for PXE booting, and *eth2* is -the interface connected to your office network switch, *eth0* is not in use, then -settings can be the following: - -/etc/sysconfig/network-scripts/ifcfg-eth0:: - - DEVICE=eth0 - ONBOOT=no - -/etc/sysconfig/network-scripts/ifcfg-eth1:: - - DEVICE=eth1 - ONBOOT=yes - HWADDR= - ..... (other settings in your config) ..... - PEERDNS=no - BOOTPROTO=static - IPADDR=192.168.1.10 - NETMASK=255.255.255.0 - -/etc/sysconfig/network-scripts/ifcfg-eth2:: - - DEVICE=eth2 - ONBOOT=yes - HWADDR= - ..... (other settings in your config) ..... - PEERDNS=no - IPADDR=172.18.0.5 - NETMASK=255.255.255.0 +It is possible to run "fuelmenu" from a root shell on Fuel Master node after +deployment to make minor changes to network interfaces, DNS, and gateway. The +PXE settings, however, cannot be changed after deployment as it will lead to +deployment failure. .. warning:: Once IP settings are set at the boot time for Fuel Master node, they **should not be changed during the whole lifecycle of Fuel.** -After modification of network configuration files, it is necessary to apply the -new configuration:: - - service network restart - -Now you should be able to connect to Fuel UI from your network at -http://172.18.0.5:8000/ - -Name Resolution (DNS) ---------------------- - -During Master node installation, by default it is assumed that there is a -recursive DNS service on 10.20.0.1. - -If you want to make it possible for Slave nodes to be able to resolve public names, -you need to change this default value to point to an actual DNS service. -To make the change, run the following commands on Fuel Master node (replace IP to -your actual DNS):: - - echo "nameserver `XXX.XXX.XXX.XXX`" > /etc/dnsmasq.upstream - cobbler sync - PXE Booting Settings -------------------- diff --git a/pages/install-guide/networks.rst b/pages/install-guide/networks.rst index a7c658837..555b74074 100644 --- a/pages/install-guide/networks.rst +++ b/pages/install-guide/networks.rst @@ -9,7 +9,7 @@ Understanding and Configuring the Network .. contents :local: -OpenStack clusters use several types of network managers: FlatDHCPManager, +OpenStack environments use several types of network managers: FlatDHCPManager, VLANManager (Nova Network) and Neutron (formerly Quantum). All configurations are supported. For more information about how the network managers work, you can read these two resources: @@ -30,7 +30,7 @@ interface connects to that bridge as well. The same L2 segment is used for all OpenStack projects, which means that there is no L2 isolation between virtual hosts, even if they are owned by separate projects. Additionally, there is only one flat IP pool defined for the entire -cluster. For this reason, it is called the *Flat* manager. +environment. For this reason, it is called the *Flat* manager. The simplest case here is as shown on the following diagram. Here the *eth1* interface is used to give network access to virtual machines, while *eth0* @@ -58,13 +58,14 @@ FlatDHCPManager (single-interface scheme) .. image:: /_images/flatdhcpmanager-sh_scheme.jpg :align: center -In order for FlatDHCPManager to work, all switch ports where Compute nodes are -connected must be configured as tagged (trunk) ports with the required VLANs -allowed (enabled, tagged). Virtual machines will communicate with each other -on L2 even if they are on different Compute nodes. If the virtual machine sends -IP packets to a different network, they will be routed on the host machine -according to the routing table. The default route will point to the gateway -specified on the networks tab in the UI as the gateway for the Public network. +In order for FlatDHCPManager to work, one designated switch port where each +Compute node is connected needs to be configured as tagged (trunk) port +with the required VLANs allowed (enabled, tagged). Virtual machines will +communicate with each other on L2 even if they are on different Compute nodes. +If the virtual machine sends IP packets to a different network, they will be +routed on the host machine according to the routing table. The default route +will point to the gateway specified on the networks tab in the UI as the +gateway for the Public network. VLANManager ------------ @@ -89,9 +90,7 @@ ports must be configured as tagged (trunk) ports to allow this scheme to work. Fuel Deployment Schema ====================== -One of the physical interfaces on each host has to be selected to carry -VM-to-VM traffic (fixed network), and switch ports must be configured to -allow tagged traffic to pass through. OpenStack Computes will untag the IP +Via VLAN tagging on a physical interface, OpenStack Computes will untag the IP packets and send them to the appropriate VMs. Simplifying the configuration of VLAN Manager, there is no known limitation which Fuel could add in this particular networking mode. @@ -287,7 +286,7 @@ For Ubuntu, the following command, executed on the host, can make this happen:: sudo iptables -t nat -A POSTROUTING -s 172.16.1.0/24 \! -d 172.16.1.0/24 -j MASQUERADE To access VMs managed by OpenStack it is needed to provide IP addresses from -Floating IP range. When OpenStack cluster is deployed and VM is provisioned there, +Floating IP range. When OpenStack environment is deployed and VM is provisioned there, you have to associate one of the Floating IP addresses from the pool to this VM, whether in Horizon or via Nova CLI. By default, OpenStack blocking all the traffic to the VM. To allow the connectivity to the VM, you need to configure security groups. diff --git a/pages/reference-architecture/0010-overview.rst b/pages/reference-architecture/0010-overview.rst index 866b83ba1..4c2c2a597 100644 --- a/pages/reference-architecture/0010-overview.rst +++ b/pages/reference-architecture/0010-overview.rst @@ -23,7 +23,7 @@ As you know, OpenStack provides the following basic services: `nova-compute` controls the life-cycle of these VMs. **Networking:** - Because an OpenStack cluster (virtually) always includes + Because an OpenStack environment (virtually) always includes multiple servers, the ability for them to communicate with each other and with the outside world is crucial. Networking was originally handled by the `nova-network` service, but it has given way to the newer Neutron (formerly @@ -47,8 +47,7 @@ As you know, OpenStack provides the following basic services: These services can be combined in many different ways. Out of the box, Fuel supports the following deployment configurations: -- :ref:`Non-HA Simple ` -- :ref:`HA Compact ` -- :ref:`HA Full ` -- :ref:`RHOS Non-HA Simple ` -- :ref:`RHOS HA Compact ` +- :ref:`Multi-node ` +- :ref:`Multi-node with HA ` +- :ref:`RHOS Multi-node ` +- :ref:`RHOS Multi-node with HA ` diff --git a/pages/reference-architecture/0012-simple.rst b/pages/reference-architecture/0012-simple.rst index 14d5ba4b6..adbc80d50 100644 --- a/pages/reference-architecture/0012-simple.rst +++ b/pages/reference-architecture/0012-simple.rst @@ -2,14 +2,14 @@ PageBreak -.. index:: Reference Architectures: Non-HA Simple, Non-HA Simple +.. index:: Reference Architectures: Multi-node -.. _Simple: +.. _Multi-node: -Simple (no High Availability) Deployment +Multi-node Deployment ======================================== -In a production environment, you will never have a Simple non-HA +In a production environment, you will not likely ever have a Multi-node deployment of OpenStack, partly because it forces you to make a number of compromises as to the number and types of services that you can deploy. It is, however, extremely useful if you just want to see how diff --git a/pages/reference-architecture/0014-compact.rst b/pages/reference-architecture/0014-compact.rst index 043796a54..8adec972b 100644 --- a/pages/reference-architecture/0014-compact.rst +++ b/pages/reference-architecture/0014-compact.rst @@ -2,12 +2,12 @@ PageBreak -.. index:: Reference Architectures: HA Compact, HA Compact +.. index:: Reference Architectures: Multi-node with HA -.. _HA_Compact: +.. _Multi-node_HA: -Multi-node (HA) Deployment (Compact) -==================================== +Multi-node with HA Deployment +============================= Production environments typically require high availability, which involves several architectural requirements. Specifically, you will @@ -21,4 +21,4 @@ nodes: :align: center We'll take a closer look at the details of this deployment configuration in -:ref:`Close_look_Compact` section. +:ref:`Close_look_Multi-node_HA` section. diff --git a/pages/reference-architecture/0015-closer-look.rst b/pages/reference-architecture/0015-closer-look.rst index 73f91771f..78d536caf 100644 --- a/pages/reference-architecture/0015-closer-look.rst +++ b/pages/reference-architecture/0015-closer-look.rst @@ -2,14 +2,14 @@ PageBreak -.. index:: Reference Architectures: HA Compact Details, HA Compact Details +.. index:: Reference Architectures: Multi-node with HA Details -.. _Close_look_Compact: +.. _Close_look_Multi-node_HA: -Details of HA Compact Deployment -================================ +Details of Multi-node with HA Deployment +=================================== -In this section, you'll learn more about the Multi-node (HA) Compact +In this section, you'll learn more about the Multi-node with HA deployment configuration and how it achieves high availability. As you may recall, this configuration looks something like this: diff --git a/pages/reference-architecture/0016-full.rst b/pages/reference-architecture/0016-full.rst deleted file mode 100644 index aa76dfdb1..000000000 --- a/pages/reference-architecture/0016-full.rst +++ /dev/null @@ -1,24 +0,0 @@ -.. raw:: pdf - - PageBreak - -.. index:: Reference Architectures: HA Full, HA Full - -.. _HA_Full: - -Multi-node (HA) Deployment (Full) -================================= - -For large production deployments, its more common to provide -dedicated hardware for storage. This architecture gives you the advantages of -high availability, but this clean separation makes your cluster more -maintainable by separating storage and controller functionality: - -.. image:: /_images/deployment-ha-full_svg.jpg - :align: center - -Where Fuel really shines is in the creation of more complex architectures, so -in this document you'll learn how to use Fuel to easily create a multi-node HA -OpenStack cluster. To reduce the amount of hardware you'll need to follow the -installation, however, the guide focuses on the Multi-node HA Compact -architecture. diff --git a/pages/reference-architecture/0018-red-hat-differences.rst b/pages/reference-architecture/0018-red-hat-differences.rst index a76837604..fc93043fb 100644 --- a/pages/reference-architecture/0018-red-hat-differences.rst +++ b/pages/reference-architecture/0018-red-hat-differences.rst @@ -13,7 +13,7 @@ Red Hat has partnered with Mirantis to offer an end-to-end supported distribution of OpenStack powered by Fuel. Because Red Hat offers support for a subset of all available open source packages, the reference architecture has been slightly modified to meet Red Hat's support requirements to provide -a highly available OpenStack cluster. +a highly available OpenStack environment. Below is the list of modifications: @@ -35,14 +35,14 @@ Below is the list of modifications: fixed in a future release. As a result, Fuel for Red Hat OpenStack Platform will only support Nova networking. -.. index:: Reference Architectures: RHOS Non-HA Simple, RHOS Non-HA Simple +.. index:: Reference Architectures: RHOS Multi-node -.. _RHOS_Simple: +.. _RHOS_Multi-node: -Simple (non-HA) Red Hat OpenStack Deployment +Multi-node Red Hat OpenStack Deployment -------------------------------------------- -In a production environment, you will never have a Simple non-HA +In a production environment, it is not likely you will ever have a Multi-node deployment of OpenStack, partly because it forces you to make a number of compromises as to the number and types of services that you can deploy. It is, however, extremely useful if you just want to see how @@ -59,12 +59,12 @@ enable you to achieve this separation while still keeping your hardware investment relatively modest is to house your storage on your controller nodes. -.. index:: Reference Architectures: RHOS HA Compact, RHOS HA Compact +.. index:: Reference Architectures: RHOS Multi-node with HA -.. _RHOS_Compact: +.. _RHOS_Multi-node_HA: -Multi-node (HA) Red Hat OpenStack Deployment (Compact) ------------------------------------------------------- +Multi-node with HA Red Hat OpenStack Deployment +----------------------------------------------- Production environments typically require high availability, which involves several architectural requirements. Specifically, you will diff --git a/pages/reference-architecture/0020-logical-setup.rst b/pages/reference-architecture/0020-logical-setup.rst index 4c1d46e05..9c5f5f646 100644 --- a/pages/reference-architecture/0020-logical-setup.rst +++ b/pages/reference-architecture/0020-logical-setup.rst @@ -9,8 +9,8 @@ HA Logical Setup .. contents :local: -An OpenStack HA cluster involves, at a minimum, three types of nodes: -controller nodes, compute nodes, and storage nodes. +An OpenStack Multi-node HA environment involves, at a minimum, three types of +nodes: controller nodes, compute nodes, and storage nodes. Controller Nodes ---------------- @@ -34,7 +34,7 @@ keystone-api, quantum-api, nova-scheduler, MySQL or RabbitMQ, the request goes to the live controller node currently holding the External VIP, and the connection gets terminated by HAProxy. When the next request comes in, HAProxy handles it, and may send it to the original -controller or another in the cluster, depending on load conditions. +controller or another in the environment, depending on load conditions. Each of the services housed on the controller nodes has its own mechanism for achieving HA: @@ -53,7 +53,7 @@ Compute Nodes ------------- OpenStack compute nodes are, in many ways, the foundation of your -cluster; they are the servers on which your users will create their +environment; they are the servers on which your users will create their Virtual Machines (VMs) and host their applications. Compute nodes need to talk to controller nodes and reach out to essential services such as RabbitMQ and MySQL. They use the same approach that provides @@ -66,7 +66,7 @@ controller nodes using the VIP and going through HAProxy. Storage Nodes ------------- -In this OpenStack cluster reference architecture, shared storage acts +In this OpenStack environment reference architecture, shared storage acts as a backend for Glance, so that multiple Glance instances running on controller nodes can store images and retrieve images from it. To achieve this, you are going to deploy Swift. This enables you to use diff --git a/pages/reference-architecture/0030-cluster-sizing.rst b/pages/reference-architecture/0030-cluster-sizing.rst index e95eb2730..fa4b4bb80 100644 --- a/pages/reference-architecture/0030-cluster-sizing.rst +++ b/pages/reference-architecture/0030-cluster-sizing.rst @@ -38,7 +38,7 @@ well by raising the bar to 9 nodes: Of course, you are free to choose how to deploy OpenStack based on the amount of available hardware and on your goals (such as whether you -want a compute-oriented or storage-oriented cluster). +want a compute-oriented or storage-oriented environment). For a typical OpenStack compute deployment, you can use this table as high-level guidance to determine the number of controllers, compute, diff --git a/pages/reference-architecture/0040-network-setup.rst b/pages/reference-architecture/0040-network-setup.rst index 9c22c337a..5d2a64e4d 100644 --- a/pages/reference-architecture/0040-network-setup.rst +++ b/pages/reference-architecture/0040-network-setup.rst @@ -31,7 +31,7 @@ relevant nodes and networks. .. image:: /_images/080-networking-diagram_svg.jpg :align: center -Lets take a closer look at each network and how its used within the cluster. +Lets take a closer look at each network and how its used within the environment. .. index:: Public Network @@ -50,7 +50,7 @@ To enable Internet access to VMs, the public network provides the address space for the floating IPs assigned to individual VM instances by the project administrator. Nova-network or Neutron (formerly Quantum) services can then configure this address on the public network interface of the Network controller -node. Clusters based on nova-network use iptables to create a +node. Environments based on nova-network use iptables to create a Destination NAT from this address to the fixed IP of the corresponding VM instance through the appropriate virtual bridge interface on the Network controller node. @@ -68,10 +68,10 @@ connect to OpenStack services APIs. Internal (Management) Network ----------------------------- -The internal network connects all OpenStack nodes in the cluster. All components -of an OpenStack cluster communicate with each other using this network. This -network must be isolated from both the private and public networks for security -reasons. +The internal network connects all OpenStack nodes in the environment. All +components of an OpenStack environment communicate with each other using this +network. This network must be isolated from both the private and public +networks for security reasons. The internal network can also be used for serving iSCSI protocol exchanges between Compute and Storage nodes. @@ -89,4 +89,4 @@ network address spaces are part of the enterprise network address space. Fixed IPs of virtual instances are directly accessible from the rest of Enterprise network. The private network can be segmented into separate isolated VLANs, which are -managed by nova-network or Neutron (formerly Quantum) services. \ No newline at end of file +managed by nova-network or Neutron (formerly Quantum) services. diff --git a/pages/reference-architecture/0060-quantum-vs-nova-network.rst b/pages/reference-architecture/0060-quantum-vs-nova-network.rst index fec35b72f..ae7975bdf 100644 --- a/pages/reference-architecture/0060-quantum-vs-nova-network.rst +++ b/pages/reference-architecture/0060-quantum-vs-nova-network.rst @@ -13,11 +13,11 @@ common of them, called Provider Router with Private Networks. It provides each tenant with one or more private networks, which can communicate with the outside world via a Neutron router. -Neutron is not, however, required in order to run an OpenStack cluster. If you -don't need (or want) this added functionality, it's perfectly acceptable to +Neutron is not, however, required in order to run an OpenStack environment. If +you don't need (or want) this added functionality, it's perfectly acceptable to continue using nova-network. In order to deploy Neutron, you need to enable it in the Fuel configuration. Fuel will then set up an additional node in the OpenStack installation to act as an L3 router, or, depending on the configuration options you've chosen, -install Neutron on the controllers. \ No newline at end of file +install Neutron on the controllers. diff --git a/pages/user-guide/advanced-topics/0010-introduction.rst b/pages/user-guide/advanced-topics/0010-introduction.rst index 9edb17cf3..a8ed69f5c 100644 --- a/pages/user-guide/advanced-topics/0010-introduction.rst +++ b/pages/user-guide/advanced-topics/0010-introduction.rst @@ -1,3 +1,3 @@ -This section covers subjects that go beyond the standard OpenStack cluster, +This section covers subjects that go beyond the standard OpenStack environment, from configuring OpenStack Networking for high-availability to adding your own -custom components to your cluster using Fuel. \ No newline at end of file +custom components to your environment using Fuel. diff --git a/pages/user-guide/advanced-topics/0020-custom-plug-ins.rst b/pages/user-guide/advanced-topics/0020-custom-plug-ins.rst index d42d61a46..a95a45970 100644 --- a/pages/user-guide/advanced-topics/0020-custom-plug-ins.rst +++ b/pages/user-guide/advanced-topics/0020-custom-plug-ins.rst @@ -7,66 +7,128 @@ Advanced Configurations ========================================== -This section covers subjects that go beyond the standard OpenStack cluster, +This section covers subjects that go beyond the standard OpenStack environment, from configuring OpenStack Networking for high-availability to adding your own -custom components to your cluster using Fuel. +custom components to your environment using Fuel. Adding And Configuring Custom Services -------------------------------------- -Fuel is designed to help you easily install a standard OpenStack cluster, but what do you do if your cluster is not standard? What if you need services or components that are not included with the standard Fuel distribution? This document gives you all of the information you need to add custom services and packages to a Fuel-deployed cluster. +Fuel is designed to help you easily install a standard OpenStack environment, +but what do you do if your environment is not standard? What if you need +services or components that are not included with the standard Fuel +distribution? This document gives you all of the information you need to add +custom services and packages to a Fuel-deployed environment. Fuel usage scenarios and how they affect installation ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ Two basic Fuel usage scenarios exist: -* In the first scenario, a deployment engineer uses the Fuel ISO image to create a master node, make necessary changes to configuration files, and deploy OpenStack. In this scenario, each node gets a clean OpenStack installation. +* In the first scenario, a deployment engineer uses the Fuel ISO image to +create a master node, make necessary changes to configuration files, and deploy +OpenStack. In this scenario, each node gets a clean OpenStack installation. -* In the second scenario, the master node and other nodes in the cluster have already been installed, and the deployment engineer has to deploy OpenStack to an existing configuration. +* In the second scenario, the Fuel Master node and other nodes in the +environment have already been installed, and the deployment engineer has to +deploy OpenStack to an existing configuration. -For this discussion, the first scenario requires that any customizations needed must be applied during the deployment and the second scenario already has customizations applied. +For this discussion, the first scenario requires that any customizations needed +must be applied during the deployment and the second scenario already has +customizations applied. -In most cases, best practices dictate that you deploy and test OpenStack first, later adding any custom services. Fuel works using puppet manifests, so the simplest way to install a new service is to edit the current site.pp file on the Puppet Master to add any additional deployment paths for the target nodes. There are, however, certain components that must be installed prior to the installation of OpenStack (i.e., hardware drivers, management software, etc...). In cases like these, Puppet can only be used to perform these installations using a separate, custom site.pp file that prepares the target system(s) for OpenStack installation. An advantage to this method, however, is that it helps isolate version mismatches and the various OpenStack dependencies. +In most cases, best practices dictate that you deploy and test OpenStack first, +later adding any custom services. Fuel works using puppet manifests, so the +simplest way to install a new service is to edit the current site.pp file on +the Puppet Master to add any additional deployment paths for the target nodes. +There are, however, certain components that must be installed prior to the +installation of OpenStack (i.e., hardware drivers, management software, etc...). + In cases like these, Puppet can only be used to perform these installations +using a separate, custom site.pp file that prepares the target system(s) for +OpenStack installation. An advantage to this method, however, is that it helps +isolate version mismatches and the various OpenStack dependencies. -If a pre-deployment site.pp approach is not an option, you can inject a custom component installation into the existing Fuel manifests. If you elect to go this route, you'll need to be aware of software source compatibility issues, as well as installation stages, component versions, incompatible dependencies, and declared resource names. +If a pre-deployment site.pp approach is not an option, you can inject a custom +component installation into the existing Fuel manifests. If you elect to go +this route, you'll need to be aware of software source compatibility issues, as +well as installation stages, component versions, incompatible dependencies, and +declared resource names. -In short, simple custom component installation may be accomplished by editing the site.pp file, but more complex components should be added as new Fuel components. +In short, simple custom component installation may be accomplished by editing +the site.pp file, but more complex components should be added as new Fuel +components. In the next section we take a closer look at what you need to know. Installing the new service along with Fuel ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -When it comes to installing your new service or component alongside Fuel, you have several options. How you go about it depends on where in the process the component needs to be available. Let's look at each step and how it can impact your installation. +When it comes to installing your new service or component alongside Fuel, you +have several options. How you go about it depends on where in the process the +component needs to be available. Let's look at each step and how it can impact +your installation. **Boot the master node** -In most cases, you will be installing the master node from the Fuel ISO. This is a semi-automated step, and doesn't allow for any custom components. If for some reason you need to install a node at this level, you will need to use the manual Fuel installation procedure. +In most cases, you will be installing the master node from the Fuel ISO. This +is a semi-automated step, and doesn't allow for any custom components. If for +some reason you need to install a node at this level, you will need to use the +manual Fuel installation procedure. **Cobbler configuration** -If your customizations need to take place before the install of the operating system, or even as part of the operating system install, this is where you will add them to the configuration process. This is also where you would make customizations to other services. At this stage, you are making changes to the operating system kickstart/pre-seed files, and may include any custom software source and components required to install the operating system for a node. Anything that needs to be installed before OpenStack should be configured during this step. +If your customizations need to take place before the install of the operating +system, or even as part of the operating system install, this is where you will +add them to the configuration process. This is also where you would make +customizations to other services. At this stage, you are making changes to the +operating system kickstart/pre-seed files, and may include any custom software +source and components required to install the operating system for a node. +Anything that needs to be installed before OpenStack should be configured +during this step. **OpenStack installation** -It is during this stage that you perform any Puppet, Astute, or mCollective configuration. In most cases, this means customizing the Puppet site.pp file to add any custom components during the actual OpenStack installation. +It is during this stage that you perform any Puppet, Astute, or mCollective +configuration. In most cases, this means customizing the Puppet site.pp file +to add any custom components during the actual OpenStack installation. -This step actually includes several different stages. (In fact, Puppet STDLib defines several additional default stages that fuel does not use.) These stages include: +This step actually includes several different stages. (In fact, Puppet STDLib +defines several additional default stages that Fuel does not use.) These stages +include: - 0. ``Puppetlabs-repo``. mCollective uses this stage to add the Puppetlabs repositories during operating system and Puppet deployment. + 0. ``Puppetlabs-repo``. mCollective uses this stage to add the + Puppetlabs repositories during operating system and Puppet deployment. - 1. ``Openstack-custom-repo``. Additional repositories required by OpenStack are configured at this stage. Additionally, to avoid compatibility issues, the Puppetlabs repositories are switched off at this stage. As a general rule, it is a good idea to turn off any unnecessary software repositories defined for operating system installation. + 1. ``Openstack-custom-repo``. Additional repositories required by OpenStack + are configured at this stage. Additionally, to avoid compatibility issues, + the Puppetlabs repositories are switched off at this stage. As a general + rule, it is a good idea to turn off any unnecessary software repositories + defined for operating system installation. - 2. ``FUEL``. During this stage, Fuel performs any actions defined for the current operating system. + 2. ``FUEL``. During this stage, Fuel performs any actions defined for the + current operating system. - 3. ``Netconfig``. During this stage, Fuel performs all network configuration actions. This means that you should include any custom components that are related to the network in this stage. + 3. ``Netconfig``. During this stage, Fuel performs all network configuration + actions. This means that you should include any custom components that + are related to the network in this stage. - 4. ``Main``. The actual OpenStack installation process happens during this stage. Install any remaining non-network-related components during or after this stage. + 4. ``Main``. The actual OpenStack installation process happens during this + stage. Install any remaining non-network-related components during or + after this stage. **Post-OpenStack install** -At this point, OpenStack is installed. You may add any components you like at this point. We suggest that you take care at this point so as not to break OpenStack. This is a good place to make an image of the nodes to have a roll-back in case of any catestrophic errors that render OpenStack or any other components inoperable. If you are preparing to deploy a large-scale environment, you may want to perform a small-scale test to familiarize yourself with the entire process and make yourself aware of any potential gotchas that are specific to your infrastructure. You should perform this small-scale test using the same hardware that the large-scale deployment will use and not VirtualBox. VirtualBox does not offer the ability to test any custom hardware driver installations your physical hardware may require. +At this point, OpenStack is installed. You may add any components you like at +this point. We suggest that you take care at this point so as not to break +OpenStack. This is a good place to make an image of the nodes to have a +roll-back in case of any catestrophic errors that render OpenStack or any other +components inoperable. If you are preparing to deploy a large-scale +environment, you may want to perform a small-scale test to familiarize yourself +with the entire process and make yourself aware of any potential gotchas that +are specific to your infrastructure. You should perform this small-scale test +using the same hardware that the large-scale deployment will use and not +VirtualBox. VirtualBox does not offer the ability to test any custom hardware +driver installations your physical hardware may require. Defining a new component ^^^^^^^^^^^^^^^^^^^^^^^^ @@ -75,14 +137,23 @@ In general, we recommend you follow these steps to define a new component: #. **Custom stages. Optional.** - Declare a custom stage or stages to help Puppet understand the required installation sequence. Stages are special markers indicating the sequence of actions. Best practice is to use the input parameter Before for every stage, to help define the correct sequence. The default built-in stage is "main". Every Puppet action is automatically assigned to the main stage if no stage is explicitly specified for the action. + Declare a custom stage or stages to help Puppet understand the required + installation sequence. Stages are special markers indicating the sequence of + actions. Best practice is to use the input parameter Before for every stage, + to help define the correct sequence. The default built-in stage is "main". + Every Puppet action is automatically assigned to the main stage if no stage + is explicitly specified for the action. - Note that since Fuel installs almost all of OpenStack during the main stage, custom stages may not help, so future plans include breaking the OpenStack installation into several sub-stages. + Note that since Fuel installs almost all of OpenStack during the main stage, + custom stages may not help, so future plans include breaking the OpenStack + installation into several sub-stages. - Don't forget to take into account other existing stages; training several parallel sequences of stages increases the chances that Puppet will order them in correctly if you do not explicitly specify the order. + Don't forget to take into account other existing stages; training several + parallel sequences of stages increases the chances that Puppet will order + them in correctly if you do not explicitly specify the order. *Example*:: - + stage {'Custom stage 1': before => Stage['Custom stage 2'], } @@ -90,19 +161,30 @@ In general, we recommend you follow these steps to define a new component: before => Stage['main'], } - Note that there are several limitations to stages, and they should be used with caution and only with the simplest of classes. You can find more information regarding stages and limitations here: http://docs.puppetlabs.com/puppet/2.7/reference/lang_run_stages.html. - + Note that there are several limitations to stages, and they should be used + with caution and only with the simplest of classes. You can find more + information regarding stages and limitations here: + http://docs.puppetlabs.com/puppet/2.7/reference/lang_run_stages.html. + #. **Custom repositories. Optional.** - If the custom component requires a custom software source, you may declare a new repository and add it during one of the early stages of the installation. - + If the custom component requires a custom software source, you may declare + a new repository and add it during one of the early stages of the + installation. + #. **Common variable definition** - It is a good idea to have all common variables defined in a single place. Unlike variables in many other languages, Puppet variables are actually constants, and may be assigned only once inside a given scope. - + It is a good idea to have all common variables defined in a single place. + Unlike variables in many other languages, Puppet variables are actually + constants, and may be assigned only once inside a given scope. + #. **OS and condition-dependent variable definition** - We suggest that you assign all common operating system or condition-dependent variables to a single location, preferably near the other common variables. Also, be sure to always use a ``default`` section when defining conditional operators or you could experience configuration issues. + We suggest that you assign all common operating system or + condition-dependent variables to a single location, preferably near the + other common variables. Also, be sure to always use a ``default`` section + when defining conditional operators or you could experience configuration + issues. *Example*:: @@ -125,7 +207,12 @@ In general, we recommend you follow these steps to define a new component: #. **Define installation procedures for independent custom components as classes** - You can think of public classes as singleton collections, or as a named block of code with its own namespace. Each class should be defined only once, but every class may be used with different input variable sets. The best practice is to define a separate class for every component, define required sub-classes for sub-components, and include class-dependent required resources within the actual class/subclass. + You can think of public classes as singleton collections, or as a named + block of code with its own namespace. Each class should be defined only + once, but every class may be used with different input variable sets. A + best practice is to define a separate class for every component, define + required sub-classes for sub-components, and include class-dependent + required resources within the actual class/subclass. *Example*:: @@ -179,7 +266,14 @@ In general, we recommend you follow these steps to define a new component: #. **Target nodes** - Every component should be explicitly assigned to a particular target node or nodes. To do that, declare the node or nodes within site.pp. When Puppet runs the manifest for each node, it compares each node definition with the name of the current hostname and applies only to classes assigned to the current node. Node definitions may include regular expressions. For example, you can apply the class 'add custom service' to all controller nodes with hostnames fuel-controller-00 to fuel-controller-xxx, where xxx = any integer value using the following definition: + Every component should be explicitly assigned to a particular target node + or nodes. To do that, declare the node or nodes within site.pp. When Puppet + runs the manifest for each node, it compares each node definition with the + name of the current hostname and applies only to classes assigned to the + current node. Node definitions may include regular expressions. For + example, you can apply the class 'add custom service' to all controller + nodes with hostnames fuel-controller-00 to fuel-controller-xxx, where + xxx represents any integer value using the following definition: *Example*:: @@ -199,7 +293,9 @@ Fuel API Reference **add_haproxy_service** Location: Top level -As the name suggests, this function enables you to create a new HAProxy service. The service is defined in the ``/etc/haproxy/haproxy.cfg`` file, and generally looks something like this:: +As the name suggests, this function enables you to create a new HAProxy +service. The service is defined in the ``/etc/haproxy/haproxy.cfg`` file, and +generally looks something like this:: listen keystone-2 bind 10.0.74.253:35357 @@ -248,86 +344,141 @@ Let's look at how this command works. ``<'Service name'>`` -The name of the new HAProxy listener section. In our example it was ``keystone-2``. If you want to include an IP address or port in the listener name, you have the option to use a name such as:: +The service name is specified in the name of the new HAProxy listener. In our +example it was ``keystone-2``. If you want to include an IP address or port in +the listener name, you have the option to use a name such as:: 'stats 0.0.0.0:9000 #Listen on all IP's on port 9000' ``order`` -This parameter determines the order of the file fragments. It is optional, but we strongly recommend setting it manually. Fuel already has several different order values from 1 to 100 hardcoded for HAProxy configuration. If your HAProxy configuration fragments appear in the wrong places in ``/etc/haproxy/haproxy.cfg`` this is likely due to an incorrect order value. It is acceptable to set order values greater than 100 in order to place your custom configuration block at the end of ``haproxy.cfg``. +This parameter determines the order of the file fragments. It is optional, but +we strongly recommend setting it manually. Fuel already has several different +order values from 1 to 100 hardcoded for HAProxy configuration. If your +HAProxy configuration fragments appear in the wrong places in +``/etc/haproxy/haproxy.cfg`` this is likely due to an incorrect order value. +It is acceptable to set order values greater than 100 in order to place your +custom configuration block at the end of ``haproxy.cfg``. -Puppet assembles configuration files from fragments. First it creates several configuration fragments and temporarily stores all of them as separate files. Every fragment has a name such as ``${order}-${fragment_name}``, so the order determines the number of the current fragment in the fragment sequence. After all the fragments are created, Puppet reads the fragment names and sorts them in ascending order, concatenating all the fragments in that order. In other words, a fragment with a smaller order value always goes before all fragments with a greater order value. +Puppet assembles configuration files from fragments. First it creates several +configuration fragments and temporarily stores all of them as separate files. +Every fragment has a name such as ``${order}-${fragment_name}``, so the order +determines the number of the current fragment in the fragment sequence. After +all the fragments are created, Puppet reads the fragment names and sorts them +in ascending order, concatenating all the fragments in that order. In other +words, a fragment with a smaller order value always goes before all fragments +with a greater order value. -The ``keystone-2`` fragment from the example above has ``order = 30`` so it's placed after the ``keystone-1`` section (``order = 20``) and the ``nova-api-1`` section (order = 40). +The ``keystone-2`` fragment from the example above has ``order = 30``, so it +gets placed after the ``keystone-1`` section (``order = 20``) and the +``nova-api-1`` section (order = 40). ``balancers`` -Balancers (or **Backends** in HAProxy terms) are a hash of ``{ "$::hostname" => $::ipaddress }`` values. -The default is ``{ "" => }``, but that value is set for compatability only, and may not work correctly in HA mode. Instead, the default for HA mode is to explicitly set the Balancers as :: +Balancers (or **Backends** in HAProxy terms) are a hash of +``{ "$::hostname" => $::ipaddress }`` values. +The default is ``{ "" => }``, but that +value is set for compatability only, and may not work correctly in HA mode. +Instead, the default for HA mode is to explicitly set the Balancers as :: Haproxy_service { balancers => $controller_internal_addresses } -where ``$controller_internal_addresses`` represents a hash of all the controllers with a corresponding internal IP address; this value is set in ``site.pp``. +where ``$controller_internal_addresses`` represents a hash of all the +controllers with a corresponding internal IP address; this value is set in +``site.pp``. -The ``balancers`` parameter is a list of HAProxy listener balance members (hostnames) with corresponding IP addresses. The following strings from the ``keystone-2`` listener example represent balancers:: +The ``balancers`` parameter is a list of HAProxy listener balance members +(hostnames) with corresponding IP addresses. The following strings from the +``keystone-2`` listener example represent balancers:: server fuel-controller-01.example.com 10.0.0.101:35357 check server fuel-controller-02.example.com 10.0.0.102:35357 check -Every key pair in the ``balancers`` hash adds a new string to the list of balancers defined in the listener section. Different options may be set for every string. +Every key pair in the ``balancers`` hash adds a new string to the list of +balancers defined in the listener section. Different options may be set for +every string. ``virtual_ips`` -This parameter represents an array of IP addresses (or **Frontends** in HAProxy terms) of the current listener. Every IP address in this array adds a new string to the bind section of the current listeners. The following strings from the ``keystone-2`` listener example represent virtual IPs:: +This parameter represents an array of IP addresses (or **Frontends** in +HAProxy terms) of the current listener. Every IP address in this array adds +a new string to the bind section of the current listeners. The following +strings from the ``keystone-2`` listener example represent virtual IPs:: bind 10.0.74.253:35357 bind 10.0.0.110:35357 ``port`` -This parameters specifies the frontend port for the listeners. Currently you must set the same port frontends. -The following strings from the ``keystone-2`` listener example represent the frontend port, where the port is 35357:: +This parameters specifies the frontend port for the listeners. Currently you +must set the same port frontends. The following strings from the ``keystone-2`` +listener example represent the frontend port, where the port is 35357:: bind 10.0.74.253:35357 bind 10.0.0.110:35357 ``haproxy_config_options`` -This parameter represents a hash of key pairs of HAProxy listener options in the form ``{ 'option name' => 'option value' }``. Every key pair from this hash adds a new string to the listener options. +This parameter represents a hash of key pairs of HAProxy listener options in +the form ``{ 'option name' => 'option value' }``. Each key pair from this +hash adds a new string to the listener options. -**NOTE** Every HAProxy option may require a different input value type, such as strings or a list of multiple options per single string. +**NOTE** Every HAProxy option may require a different input value type, such +as strings or a list of multiple options per single string. -The '`keystone-2`` listener example has the ``{ 'option' => ['httplog'], 'balance' => 'roundrobin' }`` option array and this array is represented as the following in the resulting /etc/haproxy/haproxy.cfg: +The '`keystone-2`` listener example has the +``{ 'option' => ['httplog'], 'balance' => 'roundrobin' }`` option array and +this array is represented as the following in the resulting +/etc/haproxy/haproxy.cfg: balance roundrobin option httplog ``balancer_port`` -This parameter represents the balancer (backend) port. By default, the balancer_port is the same as the frontend ``port``. The following strings from the ``keystone-2`` listener example represent ``balancer_port``, where port is ``35357``:: +This parameter represents the balancer (backend) port. By default, the +balancer_port is the same as the frontend ``port``. The following strings from +the ``keystone-2`` listener example represent ``balancer_port``, where port is +``35357``:: server fuel-controller-01.example.com 10.0.0.101:35357 check server fuel-controller-02.example.com 10.0.0.102:35357 check ``balancermember_options`` -This is a string of options added to each balancer (backend) member. The ``keystone-2`` listener example has the single ``check`` option:: +This is a string of options added to each balancer (backend) member. The +``keystone-2`` listener example has the single ``check`` option:: server fuel-controller-01.example.com 10.0.0.101:35357 check server fuel-controller-02.example.com 10.0.0.102:35357 check ``mode`` -This optional parameter represents the HAProxy listener mode. The default value is ``tcp``, but Fuel writes ``mode http`` to the defaults section of ``/etc/haproxy/haproxy.cfg``. You can set the same option via ``haproxy_config_options``. A separate mode parameter is required to set some modes by default on every new listener addition. The ``keystone-2`` listener example has no ``mode`` option and so it works in the default Fuel-configured HTTP mode. +This optional parameter represents the HAProxy listener mode. The default +value is ``tcp``, but Fuel writes ``mode http`` to the defaults section of +``/etc/haproxy/haproxy.cfg``. You can set the same option via +``haproxy_config_options``. A separate mode parameter is required to set some +modes by default on every new listener addition. The ``keystone-2`` listener +example has no ``mode`` option and so it works in the default Fuel-configured +HTTP mode. ``define_cookies`` -This optional boolean parameter is a Fuel-only feature. The default is ``false``, but if set to ``true``, Fuel directly adds ``cookie ${hostname}`` to every balance member (backend). +This optional boolean parameter is a Fuel-only feature. The default is +``false``, but if set to ``true``, Fuel directly adds ``cookie ${hostname}`` +to every balance member (backend). -The ``keystone-2`` listener example has no ``define_cookies`` option. Typically, frontend cookies are added with ``haproxy_config_options`` and backend cookies with ``balancermember_options``. +The ``keystone-2`` listener example has no ``define_cookies`` option. +Typically, frontend cookies are added with ``haproxy_config_options`` and +backend cookies with ``balancermember_options``. ``collect_exported`` -This optional boolean parameter has a default value of ``false``. True means 'collect exported @@balancermember resources' (when every balancermember node exports itself), while false means 'rely on the existing declared balancermember resources' (for when you know the full set of balancermembers in advance and use ``haproxy::balancermember`` with array arguments, which allows you to deploy everything in one run). +This optional boolean parameter has a default value of ``false``. True means +'collect exported @@balancermember resources' (when every balancermember node +exports itself), while false means 'rely on the existing declared +balancermember resources' (for when you know the full set of balancermembers +in advance and use ``haproxy::balancermember`` with array arguments, which +allows you to deploy everything in one run). diff --git a/pages/user-guide/post-install-healthchecks.rst b/pages/user-guide/post-install-healthchecks.rst index 671568dd7..3fb489e23 100644 --- a/pages/user-guide/post-install-healthchecks.rst +++ b/pages/user-guide/post-install-healthchecks.rst @@ -58,7 +58,7 @@ Running Post-Deployment Checks ------------------------------ Now, let`s take a closer look on what should be done to execute the tests and -to understand if something is wrong with your OpenStack cluster. +to understand if something is wrong with your OpenStack environment. .. image:: /_images/healthcheck_tab.jpg :align: center @@ -101,7 +101,7 @@ health of the deployment. To do so, start by checking the following: * Under the `Health Check` tab * In the OpenStack Dashboard -* In the test execution logs (/var/log/ostf-stdout.log) +* In the test execution logs (in Environment Logs) * In the individual OpenStack components' logs Certainly there are many different conditions that can lead to system @@ -126,10 +126,9 @@ If any service is off (has “XXX” status), you can restart it using this comm If all services are on, but you`re still experiencing some issues, you can gather information from OpenStack Dashboard (exceeded number of instances, fixed IPs, etc). You may also read the logs generated by tests which are -stored in ``/var/log/ostf-stdout.log``, or go to ``/var/log/`` and -check if any operation is in ERROR status. If it looks like the last item, you -may have underprovisioned your environment and should check your math and your -project requirements. +stored in Logs -> Fuel Master -> Health Check and check if any operation is +in ERROR status. If it looks like the last item, you may have underprovisioned +our environment and should check your math and your project requirements. Sanity Tests Description ------------------------ diff --git a/pages/user-guide/troubleshooting-ug/network-issues.rst b/pages/user-guide/troubleshooting-ug/network-issues.rst index 6bfcc9c16..3e2dd3416 100644 --- a/pages/user-guide/troubleshooting-ug/network-issues.rst +++ b/pages/user-guide/troubleshooting-ug/network-issues.rst @@ -8,12 +8,12 @@ Network Issues ============== Fuel has the built-in capability to run a network check before or after -OpenStack deployment. Currently, it can check connectivity between nodes within -configured VLANs on configured server interfaces. The image below shows sample -result of such check. By using this simple table it is easy to determine which -interfaces do not receive certain VLAN IDs. Usually, it means that a switch or -multiple switches are not configured correctly and do not allow certain -tagged traffic to pass through. +OpenStack deployment. The network check includes tests for connectivity between +nodes via configured VLANs on configured host interfaces. Additionally, checks +for an unexpected DHCP server are done to ensure outside DHCP servers will not +interfere with deployment. The image below shows a sample result of the check. +If there are errors, it is either in your configuration of interfaces or +possibly the VLAN tagging feature is disabled on your switch port. .. image:: /_images/net_verify_failure.jpg :align: center