FirstApp: Edits section2

Wrap overlong lines, follow markup conventions.

Co-Authored-By: Diane Fleming <diflemin@cisco.com>
Change-Id: I4b2321dd8bbc66cf7ab84aace7a24dd6fe041bfe
This commit is contained in:
Andreas Jaeger 2015-04-22 19:36:51 +02:00 committed by Tom Fifield
parent e133ad5aaf
commit 23d59cf7a0

View File

@ -1,151 +1,174 @@
================================================================== =====================================================
Section Two: Introduction to the Fractals Application Architecture Introduction to the fractals application architecture
================================================================== =====================================================
This tutorial works with a scalable cloud application that generates This tutorial works with a scalable cloud application that generates
`fractals <http://en.wikipedia.org/wiki/Fractal>`_ - beautiful images made `fractals <http://en.wikipedia.org/wiki/Fractal>`_ - beautiful images made
using only mathematics, like the image below. using only mathematics, like the following image.
.. figure:: images/fractal-example.png .. figure:: images/fractal-example.png
:scale: 50% :scale: 50%
:align: left :align: left
This section introduces the application architecture and explains how it was designed This section introduces the application architecture and explains how it was
to take advantage of cloud features in general, and OpenStack in particular. designed to take advantage of cloud features in general and OpenStack in
It also provides explanations for some of the commands which were particular. It also describes some commands in the previous section.
referenced in the previous section.
.. todo:: (for Nick) Improve the architecture discussion. .. todo:: (for Nick) Improve the architecture discussion.
.. only:: dotnet .. only:: dotnet
.. warning:: This section has not yet been completed for the .NET SDK .. warning:: This section has not yet been completed for the .NET SDK.
.. only:: fog .. only:: fog
.. warning:: This section has not yet been completed for the fog SDK .. warning:: This section has not yet been completed for the fog SDK.
.. only:: jclouds .. only:: jclouds
.. warning:: This section has not yet been completed for the jclouds SDK .. warning:: This section has not yet been completed for the jclouds SDK.
.. only:: node .. only:: node
.. warning:: This section has not yet been completed for the pkgcloud SDK .. warning:: This section has not yet been completed for the pkgcloud SDK.
.. only:: openstacksdk .. only:: openstacksdk
.. warning:: This section has not yet been completed for the OpenStack SDK .. warning:: This section has not yet been completed for the OpenStack SDK.
.. only:: phpopencloud .. only:: phpopencloud
.. warning:: This section has not yet been completed for the PHP-OpenCloud SDK .. warning:: This section has not yet been completed for the
PHP-OpenCloud SDK.
Cloud application architecture principles Cloud application architecture principles
----------------------------------------- ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Cloud applications typically have several design principles in common. Cloud applications typically share several design principles. These principles
Many of the Fractals application design decisions were motivated by these principles. influenced many Fractals application design decisions.
Modularity and Microservices Modularity and micro-services
~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -----------------------------
`Microservices <http://en.wikipedia.org/wiki/Microservices>`_ are an important design pattern used `Micro-services <http://en.wikipedia.org/wiki/Microservices>`_ are an
to achieve application modularity. By separating logical application functions into separate services important design pattern that helps achieve application modularity. Separating
, maintainance and re-use is more simple. Decoupling components from each other logical application functions into independent services simplifies maintenance
also makes it easier to selectively scale individual components as required. Further, application modularity and re-use. Decoupling components also makes it easier to selectively scale
is a required feature of applications which scale out well and are fault tolerant. individual components, as required. Further, application modularity is a
required feature of applications that scale out well and are fault tolerant.
Scalability Scalability
~~~~~~~~~~~ -----------
Cloud applications often make usage of a large number of small instances as opposed to a small number of Cloud applications often use many small instances rather than a few large
large instances. Provided that an application is sufficiently modular, microservices may be easily spread across instances. Provided that an application is sufficiently modular, you can
as many instances is required. This architecture enables an application to grow past the limit imposed by the maximum easily distribute micro-services across as many instances as required. This
size of an instance. It's like trying to move a large number of people from one place to another; there's only architecture enables an application to grow past the limit imposed by the
so many people you can put on the largest bus, but you can use a virtually unlimited number of busses (or even small cars), maximum size of an instance. It's like trying to move a large number of people
providing just as much capacity as you need - and no more. from one place to another; there's only so many people you can put on the
largest bus, but you can use an unlimited number of buses or small cars, which
provide just the capacity you need - and no more.
Fault Tolerance Fault tolerance
~~~~~~~~~~~~~~~ ---------------
In cloud programming, there's a well-known analogy known as "cattle vs pets". If you haven't heard it before, it goes In cloud programming, there's a well-known analogy known as "cattle vs
like this: pets". If you haven't heard it before, it goes like this:
When you're dealing with pets, you name them and care for them and if they get sick, you nurse them back to health. When you're dealing with pets, you name them and care for them and if
Nursing pets back to health can be difficult and very time consuming. When you're dealing with cattle, you attach a they get sick, you nurse them back to health. Nursing pets back to
numbered tag to their ear and if they get sick you put them down and move on. health can be difficult and very time consuming. When you're dealing
with cattle, you attach a numbered tag to their ear and if they get
sick you put them down and move on.
That, as it happens, is the new reality of programming. Applications and systems used to be created on large, expensive That, as it happens, is the new reality of programming. Applications
servers, cared for by operations staff dedicated to keeping them healthy. If something went wrong with one of those and systems used to be created on large, expensive servers, cared for
servers, the staff's job was to do whatever it took to make it right again and save the server and the application. by operations staff dedicated to keeping them healthy. If something
went wrong with one of those servers, the staff's job was to do
whatever it took to make it right again and save the server and the
application.
In cloud programming, it's very different. Rather than large, expensive servers, you're dealing with virtual In cloud programming, it's very different. Rather than large,
machines that are literally disposable; if something goes wrong, you shut it down and spin up a new one. There's expensive servers, you're dealing with virtual machines that are
still operations staff, but rather than nursing individual servers back to health, their job is to monitor the literally disposable; if something goes wrong, you shut it down and
spin up a new one. There's still operations staff, but rather than
nursing individual servers back to health, their job is to monitor the
health of the overall system. health of the overall system.
There are definite advantages to this architecture. It's easy to get a "new" server, without any of the issues There are definite advantages to this architecture. It's easy to get a
that inevitably arise when a server has been up and running for months, or even years. "new" server, without any of the issues that inevitably arise when a
server has been up and running for months, or even years.
As with classical infrastructure, failures of the underpinning cloud infrastructure (hardware, networks, and software) are unavoidable. When you're As with classical infrastructure, failures of the underpinning cloud
designing for the cloud, it's crucial that your application is designed for an environment where failures infrastructure (hardware, networks, and software) are
can happen at any moment. This may sound like a liability, but it's not; by designing your application with a high unavoidable. When you're designing for the cloud, it's crucial that
degree of fault tolerance, you're also making it resilient in the face of change, and therefore more adaptable. your application is designed for an environment where failures can
happen at any moment. This may sound like a liability, but it's not;
by designing your application with a high degree of fault tolerance,
you're also making it resilient in the face of change, and therefore
more adaptable.
Fault tolerance is essential to the cloud-based application. Fault tolerance is essential to the cloud-based application.
Automation Automation
~~~~~~~~~~ ----------
If an application is meant to automatically scale up and down to meet demand, it is not feasible have any manual If an application is meant to automatically scale up and down to meet
steps in the process of deploying any component of the application. demand, it is not feasible have any manual steps in the process of
Automation also decreases the time to recovery for your application in the event of component failures, increasing deploying any component of the application. Automation also decreases
fault tolerance and resilience. the time to recovery for your application in the event of component
failures, increasing fault tolerance and resilience.
Programatic Interfaces (APIs) Programmatic interfaces (APIs)
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ------------------------------
Like many cloud applications, the Fractals app has a `RESTful API <http://en.wikipedia.org/wiki/Representational_state_transfer>`_. Like many cloud applications, the Fractals application has a
You can connect to it directly and generate fractals, or you can integrate it as a component of a larger app. `RESTful API <http://en.wikipedia.org/wiki/Representational_state_transfer>`_.
Any time a standard interface such as an API is available, automated testing becomes much more feasible, You can connect to it directly and generate fractals, or you can integrate it
increasing software quality. as a component of a larger application. Any time a standard interface such as
an API is available, automated testing becomes much more feasible, increasing
software quality.
Fractals app architecture Fractals application architecture
------------------------- ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
As you will see below, the Fractals app was designed with the principles of the previous subsection in mind. The Fractals application was designed with the principles of the previous
You'll note that in :doc:`section1` we deployed the app in an all-in-one style, on a single virtual machine. subsection in mind. You'll note that in :doc:`section1`, we deployed the
This isn't good practice, but as the app uses microservices to decouple logical application functions, we can application in an all-in-one style, on a single virtual machine. This isn't
change this easily. good practice, but because the application uses micro-services to decouple
logical application functions, we can change this easily.
.. graphviz:: images/architecture.dot .. graphviz:: images/architecture.dot
Message queues are used to facilitate communication between the Fractal app Message queues are used to facilitate communication between the
services. The Fractal app uses a so-called Fractal application services. The Fractal application uses a so-called `work queue
`work queue <https://www.rabbitmq.com/tutorials/tutorial-two-python.html>`_ (or task queue) to distribute <https://www.rabbitmq.com/tutorials/tutorial-two-python.html>`_ (or
tasks to the worker servies. task queue) to distribute tasks to the worker services.
Message queues work in a way similar to a queue (or a line, for those of us on the other side of the ocean) in a bank being Message queues work in a way similar to a queue (or a line, for those
served by multiple clerks. The message queue in our application of us on the other side of the ocean) in a bank being served by
provides a feed of work requests that can be taken one-at-a-time by worker services, multiple clerks. The message queue in our application provides a feed
of work requests that can be taken one-at-a-time by worker services,
whether there is a single worker service or hundreds of them. whether there is a single worker service or hundreds of them.
This is a `useful pattern <https://msdn.microsoft.com/en-us/library/dn568101.aspx>`_ for This is a `useful pattern <https://msdn.microsoft.com/en-us/library/dn568101.aspx>`_ for many
many cloud applications that have long lists of requests coming in and a pool of resources cloud applications that have long lists of requests coming in and a
from which to service them. This also means that a worker may crash and the tasks will be pool of resources from which to service them. This also means that a
processed by other workers. worker may crash and the tasks will be processed by other workers.
.. note:: The `RabbitMQ getting started tutorial <https://www.rabbitmq.com/getstarted.html>`_ provides a great introduction to message queues. .. note:: The `RabbitMQ getting started tutorial
<https://www.rabbitmq.com/getstarted.html>`_ provides a
great introduction to message queues.
.. graphviz:: images/work_queue.dot .. graphviz:: images/work_queue.dot
The worker service consumes messages from the work queue and then processes The worker service consumes messages from the work queue and then processes
them to create the corresponding fractal image file. them to create the corresponding fractal image file.
Of course there's also a web interface which offers a more human friendly Of course there's also a web interface which offers a more human
way of accessing the API to view the created fractal images, and a simple command line interface. friendly way of accessing the API to view the created fractal images,
and a simple command line interface.
.. figure:: images/screenshot_webinterface.png .. figure:: images/screenshot_webinterface.png
:width: 800px :width: 800px
@ -155,25 +178,31 @@ way of accessing the API to view the created fractal images, and a simple comman
:figclass: align-center :figclass: align-center
There are also multiple storage backends (to store the generated fractal images) and a database There are also multiple storage back ends (to store the generated
component (to store the state of tasks), but we'll talk about those in :doc:`/section4` and :doc:`/section5` respectively. fractal images) and a database component (to store the state of
tasks), but we'll talk about those in :doc:`/section4` and
:doc:`/section5` respectively.
How the Fractals app interacts with OpenStack How the Fractals application interacts with OpenStack
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -----------------------------------------------------
.. todo:: Description of the components of OpenStack and how they relate to the Fractals app and how it runs on the cloud. .. todo:: Description of the components of OpenStack and how they
TF notes this is already covered in the guide, just split across each section. Additing it here will force the relate to the Fractals applicaiton and how it runs on the cloud.
introduction of block storage, object storage, orchestration and neutron networking too early, TF notes this is already covered in the guide, just split
which could seriously confuse users that don't have these services in their cloud. Therefore, this should not b across each section. Adding it here forces the
done here. introduction of block storage, object storage, orchestration
and neutron networking too early, which could seriously
confuse users who don't have these services in their
cloud. Therefore, this should not be done here.
The Magic Revisited The magic revisited
------------------- ~~~~~~~~~~~~~~~~~~~
So what exactly was that request doing at the end of the previous section? So what exactly was that request doing at the end of the previous
Let's look at it again. (Note that in this subsection, we're just explaining what section? Let's look at it again. (Note that in this subsection, we're
you've already done in the previous section; you don't need to execute these commands again.) just explaining what you've already done in the previous section; you
don't need to execute these commands again.)
.. only:: libcloud .. only:: libcloud
@ -181,23 +210,31 @@ you've already done in the previous section; you don't need to execute these com
:start-after: step-1 :start-after: step-1
:end-before: step-2 :end-before: step-2
We explained image and flavor in :doc:`section1`, so in the following sections, We explained image and flavor in :doc:`section1`, so in the following
we will explain the other parameters in detail, including :code:`ex_userdata` (cloud-init) and sections, we will explain the other parameters in detail, including
:code:`ex_keyname` (key pairs). :code:`ex_userdata` (cloud-init) and :code:`ex_keyname` (key pairs).
Introduction to cloud-init Introduction to cloud-init
~~~~~~~~~~~~~~~~~~~~~~~~~~ --------------------------
`cloud-init <https://cloudinit.readthedocs.org/en/latest/>`_ is a tool that performs instance configuration tasks during the boot of a cloud instance, `cloud-init <https://cloudinit.readthedocs.org/en/latest/>`_ is a tool
and comes installed on most cloud images. :code:`ex_userdata`, which was passed to :code:`create_node`, is the configuration data passed to cloud-init. that performs instance configuration tasks during the boot of a cloud
instance, and comes installed on most cloud
images. :code:`ex_userdata`, which was passed to :code:`create_node`,
is the configuration data passed to cloud-init.
In this case, we are presenting a shell script as the `userdata <https://cloudinit.readthedocs.org/en/latest/topics/format.html#user-data-script>`_. In this case, we are presenting a shell script as the `userdata
When :code:`create_node` creates the instance, :code:`cloud-init` executes the shell script in the :code:`userdata` variable. <https://cloudinit.readthedocs.org/en/latest/topics/format.html#user-data-script>`_.
When :code:`create_node` creates the instance, :code:`cloud-init`
executes the shell script in the :code:`userdata` variable.
When an SSH public key is provided during instance creation, cloud-init will install this key on a user account. (The username varies between When an SSH public key is provided during instance creation,
cloud images.) See the `Obtaining Images <http://docs.openstack.org/image-guide/content/ch_obtaining_images.html>`_ section of the image guide cloud-init installs this key on a user account. (The user name
for some guidance on which username you should use when SSHing. If you still have problems logging in, ask your cloud provider to confirm the username. varies between cloud images.) See the `Obtaining Images <http://docs.openstack.org/image-guide/content/ch_obtaining_images.html>`_
section of the image guide for guidance about which user name you
should use when SSHing. If you still have problems logging in, ask
your cloud provider to confirm the user name.
.. only:: libcloud .. only:: libcloud
@ -206,35 +243,38 @@ for some guidance on which username you should use when SSHing. If you still ha
:end-before: step-3 :end-before: step-3
Once the instance is created, cloud-init downloads and executes a script called :code:`install.sh`. After the instance is created, cloud-init downloads and runs a script called
This script installs the Fractals app. Cloud-init is capable :code:`install.sh`. This script installs the Fractals application. Cloud-init
of consuming a number of different types of data, not just bash scripts. can consume bash scripts and a number of different types of data. You
You can even provide multiple types of data. You can find further information about can even provide multiple types of data. You can find more information
cloud-init in the about cloud-init in the `official documentation <https://cloudinit.readthedocs.org/en/latest/>`_.
`official documentation <https://cloudinit.readthedocs.org/en/latest/>`_.
Introduction to key pairs Introduction to key pairs
~~~~~~~~~~~~~~~~~~~~~~~~~ -------------------------
As you might imagine, security is important when it comes to your instances; you can't Security is important when it comes to your instances; you can't have just
have just anyone accessing them. In order to enable logging into an instance, you need to provide anyone accessing them. To enable logging into an instance, you must provide
the public key of an SSH key pair during instance creation. In section one, the public key of an SSH key pair during instance creation. In section one,
you made sure that you had a key pair and uploaded it to OpenStack, and cloud-init installed you created and uploaded a key pair to OpenStack, and cloud-init installed it
it for the user account. for the user account.
Even with a key in place, however, you'll need to have the appropriate security group rules in place to access your instance. Even with a key in place, however, you must have the appropriate
security group rules in place to access your instance.
Introduction to security groups Introduction to security groups
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -------------------------------
Security groups are sets of network access rules that are applied to an instance's networking. Security groups are sets of network access rules that are applied to
By default, only egress (outbound) traffic is allowed. You must explicitly enable ingress (inbound) network access by an instance's networking. By default, only egress (outbound) traffic
creating a security group rule. is allowed. You must explicitly enable ingress (inbound) network
access by creating a security group rule.
.. warning:: Removing the egress rule created by OpenStack will cause your instance .. warning:: Removing the egress rule created by OpenStack will cause
networking to break. your instance networking to break.
Start by creating a security group for the all-in-one instance and adding the appropriate rules, such as HTTP (TCP port 80) and SSH (TCP port 22): Start by creating a security group for the all-in-one instance and
adding the appropriate rules, such as HTTP (TCP port 80) and SSH (TCP
port 22):
.. only:: libcloud .. only:: libcloud
@ -243,7 +283,9 @@ Start by creating a security group for the all-in-one instance and adding the ap
:end-before: step-4 :end-before: step-4
.. note:: :code:`ex_create_security_group_rule()` takes ranges of ports as input. This is why ports 80 and 22 are passed twice. .. note:: :code:`ex_create_security_group_rule()` takes ranges of
ports as input. This is why ports 80 and 22 are passed
twice.
You can list available security groups with: You can list available security groups with:
@ -274,26 +316,35 @@ To see which security groups apply to an instance, you can:
.. todo:: print() ? .. todo:: print() ?
Once you've configured permissions, you'll need to know where to access the application. Once you've configured permissions, you'll need to know where to
access the application.
Introduction to Floating IPs Introduction to Floating IPs
~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ----------------------------
As in traditional IT, cloud instances are accessed via IP addresses. Rather than static IPs, however, these IP addresses are As in traditional IT, cloud instances are accessed through IP addresses that
assigned programmatically by OpenStack. How this is actually done depends on the networking setup for your cloud. In OpenStack assigns. How this is actually done depends on the networking setup
some cases, you will simply get an Internet routable IP address assigned directly to your instance. for your cloud. In some cases, you will simply get an Internet rout-able IP
address assigned directly to your instance.
The most common way for OpenStack clouds to allocate Internet routable IP addresses to instances, however, is through the use of Floating IPs. The most common way for OpenStack clouds to allocate Internet rout-able
A Floating IP is an address that exists as an entity unto itself, and can be associated to a specific instance network interface. IP addresses to instances, however, is through the use of floating
When a Floating IP address is associated to an instance network interface, OpenStack re-directs traffic bound for that address to IPs. A floating IP is an address that exists as an entity unto
the address of the instance's internal network interface address. Your cloud provider will generally offer pools of floating IPs for your use. itself, and can be associated to a specific instance network
interface. When a floating IP address is associated to an instance
network interface, OpenStack re-directs traffic bound for that address
to the address of the instance's internal network interface
address. Your cloud provider will generally offer pools of floating
IPs for your use.
To use a Floating IP, you must first allocate an IP to your project, then associate it to your instance's network interface. To use a floating IP, you must first allocate an IP to your project,
then associate it to your instance's network interface.
.. note:: .. note::
Allocating a Floating IP address to an instance does not change the IP address of the instance, Allocating a floating IP address to an instance does not change
it causes OpenStack to establish the network translation rules to allow an *additional* IP address. the IP address of the instance, it causes OpenStack to establish
the network translation rules to allow an *additional* IP address.
.. only:: libcloud .. only:: libcloud
@ -302,8 +353,10 @@ To use a Floating IP, you must first allocate an IP to your project, then associ
:end-before: step-8 :end-before: step-8
If you have no free Floating IPs that have been previously allocated for your project, first select a Floating IP pool offered by your provider. If you have no free floating IPs that have been previously allocated
In this example, we have selected the first one and assume that it has available IP addresses. for your project, first select a floating IP pool offered by your
provider. In this example, we have selected the first one and assume
that it has available IP addresses.
.. only:: libcloud .. only:: libcloud
@ -319,7 +372,8 @@ Now request that an address from this pool be allocated to your project.
:start-after: step-9 :start-after: step-9
:end-before: step-10 :end-before: step-10
Now that you have an unused floating IP address allocated to your project, attach it to an instance. Now that you have an unused floating IP address allocated to your
project, attach it to an instance.
.. only:: libcloud .. only:: libcloud
@ -327,22 +381,28 @@ Now that you have an unused floating IP address allocated to your project, attac
:start-after: step-10 :start-after: step-10
:end-before: step-11 :end-before: step-11
That brings us to where we ended up at the end of :doc:`/section1`. But where do we go from here? That brings us to where we ended up at the end of
:doc:`/section1`. But where do we go from here?
Splitting services across multiple instances Splitting services across multiple instances
-------------------------------------------- ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
We've talked about separating functions into different microservices, and how that We've talked about separating functions into different micro-services,
enables us to make use of the cloud architecture. Now let's see that in action. and how that enables us to make use of the cloud architecture. Now
let's see that in action.
The rest of this tutorial won't reference the all-in-one instance you created in section one. The rest of this tutorial won't reference the all-in-one instance you
Take a moment to delete this instance. created in section one. Take a moment to delete this instance.
It's easy to split out services into multiple instances. We will create a controller instance called :code:`app-controller`, It's easy to split out services into multiple instances. We will
which hosts the API, database, and messaging services. We'll also create a worker instance called :code:`app-worker-1`, which just generates fractals. create a controller instance called :code:`app-controller`, which
hosts the API, database, and messaging services. We'll also create a
worker instance called :code:`app-worker-1`, which just generates
fractals.
The first step is to start the controller instance. The instance has the API service, the database, and the messaging service, The first step is to start the controller instance. The instance has
as you can see from the parameters passed to the installation script. the API service, the database, and the messaging service, as you can
see from the parameters passed to the installation script.
========== ====================== ============================= ========== ====================== =============================
Parameter Description Values Parameter Description Values
@ -360,8 +420,9 @@ Parameter Description Values
:start-after: step-11 :start-after: step-11
:end-before: step-12 :end-before: step-12
Note that this time, when you create a security group, you're including a rule that only applies Note that this time, when you create a security group, you're
for instances that are part of the worker_group. including a rule that only applies for instances that are part of the
worker_group.
Next, start a second instance, which will be the worker instance: Next, start a second instance, which will be the worker instance:
@ -374,10 +435,14 @@ Next, start a second instance, which will be the worker instance:
:start-after: step-12 :start-after: step-12
:end-before: step-13 :end-before: step-13
Notice that you've added this instance to the worker_group, so it can access the controller. Notice that you've added this instance to the worker_group, so it can
access the controller.
As you can see from the parameters passed to the installation script, you are specifying that this is the worker instance, but you're also passing the address of the API instance and the message As you can see from the parameters passed to the installation script, you are
queue so the worker can pick up requests. The Fractals app installation script can take several parameters. specifying that this is the worker instance, but you're also passing the
address of the API instance and the message queue so the worker can pick up
requests. The Fractals application installation script can take several
parameters.
========== ==================================================== ==================================== ========== ==================================================== ====================================
Parameter Description Example Parameter Description Example
@ -387,14 +452,17 @@ Parameter Description Example
:code:`-d` The connection URL for the database (not used here). sqlite:////tmp/sqlite.db :code:`-d` The connection URL for the database (not used here). sqlite:////tmp/sqlite.db
========== ==================================================== ==================================== ========== ==================================================== ====================================
Now if you make a request for a new fractal, you connect to the controller instance, :code:`app-controller`, but the Now if you make a request for a new fractal, you connect to the
work will actually be performed by a separate worker instance - :code:`app-worker-1`. controller instance, :code:`app-controller`, but the work will
actually be performed by a separate worker instance -
:code:`app-worker-1`.
Login with SSH and use the Fractal app Login with SSH and use the Fractal app
-------------------------------------- ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Login to the worker instance, :code:`app-worker-1`, with SSH, using the previous added SSH key pair "demokey". Start Login to the worker instance, :code:`app-worker-1`, with SSH, using
by getting the IP address of the worker: the previous added SSH key pair "demokey". Start by getting the IP
address of the worker:
.. only:: libcloud .. only:: libcloud
@ -408,10 +476,12 @@ Now you can SSH into the instance:
$ ssh -i ~/.ssh/id_rsa USERNAME@IP_WORKER_1 $ ssh -i ~/.ssh/id_rsa USERNAME@IP_WORKER_1
.. note:: Replace :code:`IP_WORKER_1` with the IP address of the worker instance and USERNAME to the appropriate username. .. note:: Replace :code:`IP_WORKER_1` with the IP address of the
worker instance and USERNAME to the appropriate user name.
Once you've logged in, check to see whether the worker service process is running as expected. Once you've logged in, check to see whether the worker service process
You can find the logs of the worker service in the directory :code:`/var/log/supervisor/`. is running as expected. You can find the logs of the worker service
in the directory :code:`/var/log/supervisor/`.
:: ::
@ -420,38 +490,45 @@ You can find the logs of the worker service in the directory :code:`/var/log/sup
Open :code:`top` to monitor the CPU usage of the :code:`faafo-worker` process. Open :code:`top` to monitor the CPU usage of the :code:`faafo-worker` process.
Now log into the controller instance, :code:`app-controller`, also with SSH, using the previously added SSH key pair "demokey". Now log into the controller instance, :code:`app-controller`, also
with SSH, using the previously added SSH key pair "demokey".
:: ::
$ ssh -i ~/.ssh/id_rsa USERNAME@IP_CONTROLLER $ ssh -i ~/.ssh/id_rsa USERNAME@IP_CONTROLLER
.. note:: Replace :code:`IP_CONTROLLER` with the IP address of the controller instance and USERNAME to the appropriate username. .. note:: Replace :code:`IP_CONTROLLER` with the IP address of the
controller instance and USERNAME to the appropriate user name.
Check to see whether the API service process is running like expected. You can find the logs for the API service Check to see whether the API service process is running like
in the directory :code:`/var/log/supervisor/`. expected. You can find the logs for the API service in the directory
:file:`/var/log/supervisor/`.
:: ::
controller # ps ax | grep faafo-api controller # ps ax | grep faafo-api
17209 ? Sl 0:19 /usr/bin/python /usr/local/bin/faafo-api 17209 ? Sl 0:19 /usr/bin/python /usr/local/bin/faafo-api
Now call the Fractal app's command line interface (:code:`faafo`) to request a few new fractals. Now call the Fractal application's command line interface (:code:`faafo`) to
The following command will request a few fractals with random parameters: request a few new fractals. The following command requests a few
fractals with random parameters:
:: ::
controller # faafo --endpoint-url http://localhost --verbose create controller # faafo --endpoint-url http://localhost --verbose create
2015-04-02 03:55:02.708 19029 INFO faafo.client [-] generating 6 task(s) 2015-04-02 03:55:02.708 19029 INFO faafo.client [-] generating 6 task(s)
Watch :code:`top` on the worker instance. Right after calling :code:`faafo` the :code:`faafo-worker` process should start consuming a lot of CPU cycles. Watch :code:`top` on the worker instance. Right after calling
:code:`faafo` the :code:`faafo-worker` process should start consuming
a lot of CPU cycles.
:: ::
PID USER PR NI VIRT RES SHR S %CPU %MEM TIME+ COMMAND PID USER PR NI VIRT RES SHR S %CPU %MEM TIME+ COMMAND
17210 root 20 0 157216 39312 5716 R 98.8 3.9 12:02.15 faafo-worker 17210 root 20 0 157216 39312 5716 R 98.8 3.9 12:02.15 faafo-worker
To show the details of a specific fractal use the subcommand :code:`show` of the Faafo CLI. To show the details of a specific fractal use the subcommand
:code:`show` of the Faafo CLI.
:: ::
@ -471,37 +548,49 @@ To show the details of a specific fractal use the subcommand :code:`show` of the
| checksum | 103c056f709b86f5487a24dd977d3ab88fe093791f4f6b6d1c8924d122031902 | | checksum | 103c056f709b86f5487a24dd977d3ab88fe093791f4f6b6d1c8924d122031902 |
+------------+------------------------------------------------------------------+ +------------+------------------------------------------------------------------+
There are more commands available; find out more details about them with :code:`faafo get --help`, :code:`faafo list --help`, and :code:`faafo delete --help`. There are more commands available; find out more details about them
with :code:`faafo get --help`, :code:`faafo list --help`, and
:code:`faafo delete --help`.
.. note:: The application stores the generated fractal images directly in the database used by the API service instance. .. note:: The application stores the generated fractal images directly
Storing image files in database is not good practice. We're doing it here as an example only as an easy in the database used by the API service instance. Storing
way to allow multiple instances to have access to the data. For best practice, we recommend storing image files in database is not good practice. We're doing it
objects in Object Storage, which is covered in :doc:`section4`. here as an example only as an easy way to allow multiple
instances to have access to the data. For best practice, we
recommend storing objects in Object Storage, which is
covered in :doc:`section4`.
Next Steps Next steps
---------- ~~~~~~~~~~
You should now have a basic understanding of the architecture of cloud-based applications. In addition, You should now have a basic understanding of the architecture of
you now have had practice starting new instances, automatically configuring them at boot, and cloud-based applications. In addition, you now have had practice
even modularizing an application so that you may use multiple instances to run it. These are the basic starting new instances, automatically configuring them at boot, and
steps for requesting and using compute resources in order to run your application on an OpenStack cloud. even modularizing an application so that you may use multiple
instances to run it. These are the basic steps for requesting and
using compute resources in order to run your application on an
OpenStack cloud.
From here, you should go to :doc:`/section3` to learn how to scale the application further. Alternately, you may From here, you should go to :doc:`/section3` to learn how to scale the
jump to any of these sections: application further. Alternately, you may jump to any of these
sections:
* :doc:`/section4` - to learn how to make your application more durable using Object Storage * :doc:`/section4`: to learn how to make your application more durable
* :doc:`/section5` - to migrate the database to block storage, or use the database-as-as-service component using Object Storage
* :doc:`/section6` - to automatically orchestrate the application * :doc:`/section5`: to migrate the database to block storage, or use
* :doc:`/section7` - to learn about more complex networking the database-as-as-service component
* :doc:`/section8` - for advice for developers new to operations * :doc:`/section6`: to automatically orchestrate the application
* :doc:`/section7`: to learn about more complex networking
* :doc:`/section8`: for advice for developers new to operations
Full example code Full example code
----------------- ~~~~~~~~~~~~~~~~~
Here's every code snippet into a single file, in case you want to run it all in one, or Here's every code snippet into a single file, in case you want to run
you are so experienced you don't need instruction ;) If you are going to use this, it all in one, or you are so experienced you don't need instruction ;)
don't forget to set your authentication information and the flavor and image ID. If you are going to use this, don't forget to set your authentication
information and the flavor and image ID.
.. only:: libcloud .. only:: libcloud