Deploying apps in Cloud Foundry




The best place to start with Cloud Foundry is to get the experience of deploying applications locally in the machine. This is what we called 'Mirco Cloud Foundry'.  For a novice Cloud Foundry developer, a full scale PaaS deployment is not possible and it is not an affordable choice. To address this issue, Cloud Foundry team released BoshLite which provides developers a method to deploy it locally in their machine.

It is important to understand the meaning of several terms prior to the deployment process. So let's concentrate on the terms, stemcell, release and deployment.

What is a stemcell?

Stemcell is a versioned Operating System image wrapped with IaaS specific packaging. A typical stemcell contains a bare minimum OS skeleton, a few common utilities pre-installed, a BOSH Agent, and a few configuration files to securely configure the OS by default. 

This clear separation between base Operating System and later-installed software is what makes stemcells a powerful concept. Stemcells for one OS (e.g. all Ubuntu Trusty stemcells) are exactly the same for all infrastructures. This property of stemcells allows BOSH users to quickly and reliably switch between different infrastructures . The Cloud Foundry BOSH team is responsible for producing and maintaining an official set of stemcells. 

By introducing the concept of a stemcell, the following problems have been solved: 

                           - Capturing a base OS image
                           - Versioning changes to the OS omage
                           - Reusing base OS image across Vms of different types
                           - Reusing base OS images across different IaaS

What is a release?

A release is a versioned collection of configuration properties, configuration templates, start up scripts, source code, binary artifacts and anything else required to build and deploy software in a reproducible way.A release is the layer placed on top of a stemcell. They are self-contained and provide very specific software for the purpose of that release. For example, a Redis release might include start-up and shutdown scripts for redis-server. 

The following tasks are done by a release: 

                          - Capturing all needed configuration options and scripts for deployment of the software 
                          - Recording and keeping track of all dependencies for the software 
                          - Versioning and keeping track of software releases
                          - Creating releases that can be IaaS agnostic 
                          - Creating releases that are self-contained and do not require internet access for deployment.

What is a deployment?

A deployment is a collection of VMs, built from a stemcell that has been populated with specific releases and disks that keep persistent data.These resources are created based on a manifest file in the IaaS and managed by the BOSH Director, a centralized management server.

The deployment process begins with deciding which Operating System images (stemcells) need to be used and which software (releases) need to be deployed. Combination of stemcells, releases, and operator-specified properties are contained in a human readable file called a deployment manifest. When a deployment manifest is uploaded to a BOSH Director, requested resources are allocated and stored. These resources form a deployment. A user can manage a deployment via its deployment manifest. A deployment manifest contains all needed information for tracking, managing, and updating software on the deployment’s VMs. 



Other than the above terms, there are some specific concepts relevant to user access control. Cloud Foundry uses role-based access control (RBAC), with each role granting permissions in either  an org or a space.

Orgs, Spaces, Roles and Permissions 

Orgs 

Development account that an individual or multiple collaborators can own and use. All collaborators access an org with user accounts. Collaborators in an org share a resource quota plan, applications, services availability, and custom domains. 

User Accounts

Represents an individual person within the context of a Cloud Foundry installation. A user can have different roles in different spaces within an org.

Spaces

Every application and service is scoped to a space. Each org contains at least one space. A space provides users with access to a shared location for application development, deployment, and maintenance. 

Roles and Permissions

A user can have one or more roles. The combination of these roles defines the user’s overall permissions in the org and within specific spaces. Then there are different roles like org manger, org auditor, billing manger, space manger, space developer, space auditor.


Install BOSH Lite

We are going to use bosh lite here. bosh-lite is a vagrant VM that comes with pre-installed BOSH server (Director). Once VM with Director is running we are going to use BOSH CLI to send commands to the Director.

Now we are almost ready to deploy applications in Cloud Foundry. After figuring out all the bits and pieces, I wrote down the following procedure of steps so anyone with an average IT knowledge who wishes to try out Cloud Foundry can get up and running a bit quicker than I did.

The main tutorial for deploying Cloud Foundry on Vagrant can be found on the following URL:
This tutorial is aimed at Linux users and comes with commands and scripts for such systems. I have listed the steps that I used to deploy Cloud Foundry and elaborated where I deviated from the tutorial.

Note:

This installation is only for 64-bit systems, as the stem cells are packaged as 64-bit images. This also means that this installation will only work on systems that support VT-x or some other hardware virtualization technology (AMD-V for AMD machines). It will also not work if you try and run this setup on a virtual machine, since you will be required another VM. Currently, VT-X can only be used by a single virtual machine.

Step1: Install latest version of bosh_cli

BOSH CLI is a command line interface to the Director. It is distributed as a Ruby gem.First we need to install Bosh-Lite. So we need to prepare the environment for that. As the first step, we install latest version of bosh_cli which is the Command Line Interface tool to interact with Bosh_Lite director (VM running the Bosh_Lite server). The README.md mentions the following command to install bosh_cli using gem.

$ gem install bosh_cli --no-ri --no-rdoc
This will give the following output. 
nanduni@nanduni-TECRA-M11:~$ gem install bosh_cli --no-ri --no-rdoc
Fetching: jmespath-1.1.3.gem (100%)
Successfully installed jmespath-1.1.3
Fetching: aws-sdk-core-2.2.0.gem (100%)
Successfully installed aws-sdk-core-2.2.0
Fetching: aws-sdk-resources-2.2.0.gem (100%)
Successfully installed aws-sdk-resources-2.2.0
Fetching: little-plugger-1.1.4.gem (100%)
Successfully installed little-plugger-1.1.4
Fetching: logging-1.8.2.gem (100%)
Successfully installed logging-1.8.2
Fetching: semi_semantic-1.1.0.gem (100%)
Successfully installed semi_semantic-1.1.0
Fetching: bosh_common-1.3184.0.gem (100%)
Successfully installed bosh_common-1.3184.0
Fetching: httpclient-2.4.0.gem (100%)
Successfully installed httpclient-2.4.0
Fetching: blobstore_client-1.3184.0.gem (100%)
Successfully installed blobstore_client-1.3184.0
Fetching: bosh-template-1.3184.0.gem (100%)
Successfully installed bosh-template-1.3184.0
Fetching: minitar-0.5.4.gem (100%)
Successfully installed minitar-0.5.4
Fetching: netaddr-1.5.0.gem (100%)
Successfully installed netaddr-1.5.0
Fetching: net-ssh-2.9.2.gem (100%)
Successfully installed net-ssh-2.9.2
Fetching: net-scp-1.1.2.gem (100%)
Successfully installed net-scp-1.1.2
Fetching: net-ssh-gateway-1.2.0.gem (100%)
Successfully installed net-ssh-gateway-1.2.0
Fetching: progressbar-0.9.2.gem (100%)
Successfully installed progressbar-0.9.2
Fetching: sshkey-1.7.0.gem (100%)
Successfully installed sshkey-1.7.0
Fetching: terminal-table-1.4.5.gem (100%)
Successfully installed terminal-table-1.4.5
Fetching: bosh_cli-1.3184.0.gem (100%)
Successfully installed bosh_cli-1.3184.0
19 gems installed

If this command does not work out for you, try the following command.
$ gem install --user-install bosh_cli


Step2: Install Vagrant

If you are not familiar about Vagrant and VirtualBox, go through my blog post

Check that you have Vagrant installed in your machine by using the following command.

$ vagrant --version
Vagrant 1.7.4


Step3: Install VirtualBox

Check that you have Vagrant installed in your machine by using the following command.
$ VBoxManage --version
5.0.10r104061


Step4: Clone the repository

$ cd ~/workspace
$ git clone https://github.com/cloudfoundry/bosh-lite


Step5: Start Vagrant

Navigate into the cloned repository. Start Vagrant from the base directory of this repository, which contains the Vagrantfile. The most recent version of the BOSH Lite boxes will be downloaded by default from the Vagrant Cloud when you run vagrant up. If you have already downloaded an older version you will be warned that your version is out of date.

$ vagrant up --provider=virtualbox


Step6: Target director

Let CLI know about bosh-lite Director. So target the BOSH Director.
If you work behind a proxy, exclude both the VM's private IP and xip.io by setting no_proxy.

$ bosh target 192.168.50.4 lite
Target set to 'Bosh Lite Director'


Step6: Login

Now login to Bosh. When prompted to log in, use admin/admin.
$ bosh login
Your username: admin
Enter password: *****
Logged in as 'admin'

If you logged in successfully, it should display the message that you have logged in successfully.


Step7: Add route entries


This is an important step that you should not miss. When I was installing Bosh Lite, I accidentally missed this step and it took me hours to find out the error.
 
Add a set of route entries to your local route table to enable direct Warden container access every time your networking gets reset (e.g. reboot or connect to a different network). Your sudo password may be required.

$ bin/add-route


Start deployment


Now that you have Bosh Lite installed in your machine, you require some kind of application to start with.  You have already completed the steps of preparing the required environment for deployment. I followed this tutorial to start with. It is guide to using BOSH.
This tutorial gives a simple introduction to BOSH. If you have never deployed with BOSH or never heard about it that step-by-step guide will bring you up to speed.

Before we proceed we need to understand what BOSH needs to deploy software.


What to deploy

Software that is deployed with BOSH needs to be packaged in a special format called release. For each service that will be deployed release needs to contain its source files, configuration files, installation scripts, etc. For example, for a redis-release, the source code for redis, redis configuration defaults and redis init scripts are part of the release.

How to deploy
Each BOSH deployment needs to provide a specially structured configuration file - deployment manifest. This file defines what resources are going to be deployed, what services are going to be running on each of resources and properties that will be passed to services configuration files. For example, for a redis deployment manifest, there are entries for how many and what size redis VMs there should be and how redis should be configured.

Step1: Create Bosh release

We are going to use a simple BOSH release that deploys a sinatra server. Clone the repository containing the application.

$ git clone https://github.com/mariash/learn-bosh-release learn-bosh-release
$ cd learn-bosh-release
$ bosh create release
What happens when you create a release is that it downloads all the ruby/bundler and other necessary packages and libraries for the release. Then if the packages are downloaded properly, then it will request a development release name. I gave it the name 'learn-bosh' . Then within the DevReleases folder, it will create a folder with that release name. This folder contains the release manifest, which is a yaml file.

Step2: Upload release

Upload generated release to Director.
$ bosh upload release


Step3: Check release

Now that you can check the uploaded releases.

$ bosh releases
Then it will show an output like this.

Acting as user 'admin' on 'Bosh Lite Director'
+------------+----------+-------------+
| Name | Versions | Commit Hash |
+------------+----------+-------------+
| learn-bosh | 0+dev.1 | 1867f1d2 |
+------------+----------+-------------+ 
Releases total: 1

Step4: Set deployment manifest

Deployment manifest specifies what services to deploy, their properties and resources configuration. The manifest in the folder contains a placeholder director_uuid that needs replacing. In order to obtain the correct uuid, use the following command.
$ bosh status --uuid

Or else use bosh status command and you will easily find the uuid.
Now set the deployment manifest.

$ bosh deployment manifest.yml
Deployment set to '...learn-bosh-release/manifest.yml'


Step5: Upload stemcell

A Stemcell is an operating system image that BOSH uses to create VMs. Official BOSH stemcells are maintained with security updates at bosh.io.

Upload stemcell to Director using the following command.

$ wget --content-disposition https://bosh.io/d/stemcells/bosh-warden-boshlite-ubuntu-trusty-go_agent
$ bosh upload stemcell bosh-stemcell-3147-warden-boshlite-ubuntu-trusty-go_agent.tgz


Step6: Check stemcells

You can verify the uploaded stemcells using the following command.
$ bosh stemcells 
Acting as user 'admin' on 'Bosh Lite Director'
+---------------------------------------------+---------+
(*) Currently in-use
Stemcells total: 1
| Name | Version |
+---------------------------------------------+---------+
| bosh-warden-boshlite-ubuntu-trusty-go_agent | 3147 |
+---------------------------------------------+---------+


Step7: Deploy

Use the following command to deploy.

$ bosh deploy
See the list of deployed VMs as it was specified in manifest. 
$ bosh vms ...
+-----------+---------+---------------+------------+
| Job/index | State | Resource Pool | IPs |
+-----------+---------+---------------+------------+
| app/0 | running | default | 10.244.0.2 |
+-----------+---------+---------------+------------+
...


Step8: Add route

Add route to bosh-lite network.

sudo ip route add 10.244.0.0/19 via 192.168.50.4


Step9: Running service

Now you can see that the service is up and running.

$ curl 10.244.0.2:8080
Hello, Maria from ...


Modify deployment

Now we will update our deployment with new version of software. We will modify some properties.

Step1: Modify release

BOSH makes it easy to modify and deploy new versions of software. Let's modify our release source files. In release folder open src/simple_server/app.rb. I changed the name to mine.

Then I create a new version of release. force option in the command is used to ignore warning about local changes. Then I upload the new version of release to Director and deploy.

$ bosh create release --force
$ bosh upload release
$ bosh deploy


Step2: Running service

See that the updated version was deployed accordingly.

$ curl 10.244.0.2:8080
Hello, Maria from ...

Scale deployment

Step1: Modify the manifest.

With BOSH it is easy to scale deployments. All you need to do is modify number of instances in manifest file. Open manifest.yml and change number of instances under job from 1 to 2. Add another IP to list of job static IPs: 10.244.0.6.

Step2: Run deploy

$ bosh deploy

Step3: Check VMs

Check that 2 VMs were deployed.
$ bosh vms 
Acting as user 'admin' on 'Bosh Lite Director'
Director task 22
Task 22 done
+-----------+---------+---------------+------------+
VMs total: 2
Deployment `learn-bosh' 
| Job/index | State | Resource Pool | IPs |
+-----------+---------+---------------+------------+
| app/0 | running | default | 10.244.0.2 |
| app/1 | running | default | 10.244.0.6 |
+-----------+---------+---------------+------------+

Step4: Running service

$ curl 10.244.0.2:8080
Hello, you from <uuid-1>
$ curl 10.244.0.6:8080
Hello, you from <uuid-2>


Updating the Bosh Lite VM

If you wish to upgrade the BOSH Lite VM, you can run the following commands from the root of the bosh-lite directory. Make sure you have the latest version of this repository checked out. WARNING: these operations are destructive, and essentially amount to starting from scratch.

$ git pull 
$ vagrant box update 
$ vagrant destroy 
$ vagrant up --provider=DESIRED_PROVIDER


Trouble shooting instances


1. When I tried to run the service using curl 10.244.0.2:8080 command, it gave me the following error.
curl 10.244.0.2:8080 
Curl(7): Failed to connect to 10.244.0.2 port 8080: Connection timed out 
This can be resolved by the following command which was mentioned in step7 of installing BOSH Lite. Navigate to the bosh-lite directory. Then use this command.
$ bin/add-route


2. sudo ip route add 10.244.0.0/19 via 192.168.50.4 command in step8 of Start deployment section did not work for me. Instead, I changed that command a bit as follows.
sudo route add -net 10.244.0.0/19 gw 192.168.50.4

3. When installing bosh_cli using gem, it gave me the following error. 
WARNING:You don't have /home/nanduni/.gem/ruby/1.9.1/bin in your PATH, gem executables will not run.
This is because I have not set the ruby path. So execute the following command to install bosh_cli successfully.
export PATH=”/home/nanduni/.gem/ruby/1.9.1/bin:$PATH”


These are some errors that I encountered when deploying applications in vagrant using bosh-lite. I would be happy if you all can share with me any other instances that you came across.





1 comment :

  1. This post describes how to use bosh lite using the output snapshots which is really helpful. Great Post!

    ReplyDelete