Showing posts with label OCM. Show all posts
Showing posts with label OCM. Show all posts

Monday, April 24, 2017

A quick look at using Quota on the Oracle Cloud Machine

Introduction

On OCM racks prior to version 17.1.6 they have the option to place a quota limitation on their tenancies.  Without a quota the tenant is able to use compute resources up to the physical limits of the rack that has been subscribed to.  It may be appropriate to limit the resource that one tenancy can utilise, this can be achieved using the quota object which is assigned to each tenancy.

There are a number of resources that can be limited on a per-tenant basis, these are.

  • Compute
    • Instances
    • Memory
    • CPUs
    • Instance Restrictions
  • Storage
  • Machine Image
    • Number
    • Megabytes
  • Network
    • IP reservations
Figure 1 shows an example listing of a quota that has been applied to a tenancy.   It shows both the quota limits set and what the current usage is so it becomes a fairly simple task to work out how close to the current quota the tenancy is getting.

# oc list quota -u /quota-test/administrator /quota-test -f json
{
 "list": [
  {
   "usage": {
    "machineimage": {
     "number": 1,
     "megabytes": 2466
    },
    "vnet": {
     "vnetreservations": 0
    },
    "compute": {
     "instances": 7,
     "ram": 24576,
     "instance_restrictions": {},
     "cpus": 6.0
    },
    "nds": {
     "megabytes": 0
    }
   },
   "uri": "https://api/quota/quota-test",
   "description": "Default quota for \"quota-test\"",
   "name": "/quota-test",
   "allowance": {
    "machineimage": {
     "number": 2,
     "megabytes": 4096
    },
    "vnet": {
     "vnetreservations": 2
    },
    "compute": {
     "instances": 8,
     "ram": 41000,
     "instance_restrictions": {},
     "cpus": 6.0
    },
    "nds": {
     "megabytes": 4096
    }
   }
  }
 ]
}
Figure 1 - Example quota output

In general these are fairly self explanatory as to what each restriction will do but there are some subtlties.

Compute

The restrictions for compute are split into Instances, Memory, CPU and "Instance Restrictions."   The instances number in a quota directly relates to the number of  VM instances that have been created within the tenancy.  This quota is checked as soon as an orchestration attempts to start and if the quota is exceeded it will cause the orchestration to fail to startup until other instances (orchestrations) are stopped.  Note - Stopped rather than simply shutdown as a shutdown instance remains in existence.

Memory and CPU quota are very similar to instance restrictions.  The main difference is that a VM has to be actually running to consume the quota so if this limit is reached then existing VMs have to be shutdown to allow the new instance to startup but they do not have to be "stopped".

Figure 2 below shows the errors reported when the quota is exceeded in a couple of examples.

Error starting orchestration that exceeds the allowed number of instances
     "status": "error",
     "info": {
      "errors": {
       "0": "don05 is in error: {'/quota-test': u'Reservation exceeded quotas: instances exceeded by 1.0'}"
      }


Error starting orchestration that exceeds the allowed Memory
     "status": "error",
     "info": {
      "errors": {
       "0": "don06 is in error: {'/quota-test': u'Reservation exceeded quotas: ram exceeded by 3576.0'}"
}
Figure 2 - Error message when exceeding quota for instance or memory

Instance Restrictions is a special tagging mechanism that would allow a machine image (template) to be tagged and it is then possible to restrict the number of instances created from that specific machine image.  This is currently not supported on the OCM so the instance_restrictions quota value should be left blank.

Storage

The storage figure given applies to additional storage volumes and not to the root disks.  i.e. If you need to restrict storage space used by the root disks then you need to apply a quota to the instances in the compute section.  If you hit the limit then it is necessary to actively stop any storage volumes to delete the storage and free up resource.

Machine Image

The machine image quota can be specified either in terms of the numbers of machine images held within the quota or by the storage volume space taken up.  Typically this would be used to limit the number of snapshots that a tenancy can use.  (Taking a snapshot of a VM will take a copy of the root disks at the time of snapshotting and create a new machine image.)

Network

When networks are defined for a tenancy there are several choices on their configuration which can be used as a limit in themselves.  For example if a tenant has a public or EoIB network assigned to them then the number of IP addresses the tenancy can use will be determined by the subnet and within the subnet further limited by the IP Range defined.  Private networks can also be created but again these have a defined size which cannot be exceeded.

However, in OCM releases prior to 17.1.6 the concept of a service network was available where a tenancy would be given access to a network and the same network could be handed out to other tenancies as well.  If a "vnetreservation" quota is setup then the system will prevent a tenancy using more than the quota value of IP addresses from these service networks.

An example failure to create a VM is shown in figure 3 when the tenancy has run out of IP addresses on a network.

     "info": {
      "errors": {
       "0": "{u'/cloud/public/EoIB-OMS': u'1 IP(s) requested, but only 0 IP(s) available in the vnet.'}"
      },
Figure 3 - No IP addresses available


Conclusion

If a customer has divided their rack into multiple tenancies to run different environments then the quota system is a powerful and useful mechanism to ensure that no users of the system hog the available compute resource.


Friday, January 27, 2017

Expanding the root volume in an OCM template

Introduction

The OCM is delivered to you with two templates that are specifically ready for use by the Infrastructure as a Service interfaces.  These templates are OL5 and OL6 and by default the root volume has approximately 11Gb of space available.  This should be ample as a root volume for 90% of customer uses.  However from time to time it might be useful to increase this disk space in a template.  For example a customer might want to have a number of applications deployed into the base template, things like specific package installs, monitoring tools etc.  These could use up much of the disk space making management of logs etc. more space critical than would be liked.

This blog posting goes through a process that will enable the root disk structure to be increased in size.  Specifically for the OL6 template.  The process revolves around three actions.

  1. Download the base template from your OCM rack.
  2. Make use of "EKIT" to increase the disk space
  3. Add the new template back onto the OCM and make it available for use.

Step 1 - Download the template

The first activity is to download the template.  This can be done easily from the Command line - oracle-compute.


# oracle-compute download machineimage /oracle/public/linux6_16.3.1_64 


This will create a directory structure where the file is downloaded as a gziped tar file.

Step 2 - Use ModifyJeosLVM.sh to increase disk space

Handily there is a toolkit known as the "Exalogic Kinetic Infrastructure Tools" or EKIT for short which contains a script called ModifyJeosLVM.sh which has been designed to extend the root volume (or swap space) of an OL LVM based image.  EKIT is available from My Oracle Support and can be easily found using MOS document ID of 1933252.1.

Install the EKIT into an appropriate environment according to the toolkit installation instructions.  (Can be on a laptop, VM on a laptop or a VM on OCM itself although you will need to ensure that the VMs have enough disk space to handle files as large as you intend to make the root volume.)  Once installed copy the downloaded <template>.tar.gz file to your EKIT environment.   Extract the machineimage (will be a System.img file)  And run ModifyJEOSLVM.sh as shown below.  This adds space to the current image file and then tar/gzip the image file and you have a machineimage ready to upload into your OCM rack.



[root@utility ocm-ol6]# gunzip linux6_16.3.1_64.tar.gz
[root@utility ocm-ol6]# ls
linux6_16.3.1_64.tar
[root@utility ocm-ol6]# tar xvf linux6_16.3.1_64.tar
System.img
[root@utility ocm-ol6]# ls -lh
total 37G
-rw-r--r--+ 1 root root 19G Jan 27 08:29 linux6_16.3.1_64.tar
-rw-r--r--+ 1 root root 18G Sep 26 05:31 System.img

 [root@utility ocm-ol6]# ModifyJeosLVM.sh --resize -if System.img -er 20
Img File Array: System.img
***********************************************
*** Modifying System.img
***********************************************
Block size: 1024
Base Image Size 19327352832
Base Image 18874368 blocks
Adding 20971520 blocks to root file system
Adding 0 blocks to swap file system
Adding 0 blocks free space to Volume Group
Adding 524288 spare blocks
Resizing image file to 40370176
***********************************************
*** Checking Primary Partition Status System.img
***********************************************
***********************************************
*** Using loop /dev/loop0
***********************************************

Disk /dev/loop0: 19.3 GB, 19327352832 bytes
255 heads, 63 sectors/track, 2349 cylinders
Units = cylinders of 16065 * 512 = 8225280 bytes
Sector size (logical/physical): 512 bytes / 512 bytes
I/O size (minimum/optimal): 512 bytes / 512 bytes
Disk identifier: 0x000c520c

      Device Boot      Start         End      Blocks   Id  System
/dev/loop0p1   *           1          32      256000   83  Linux
Partition 1 does not end on cylinder boundary.
/dev/loop0p2              32        2349    18611318+  8e  Linux LVM
1. Found /dev/loop0p1
2. Found /dev/loop0p2
***********************************************
*** Extending System.img
***********************************************
0+0 records in
0+0 records out
0 bytes (0 B) copied, 0.000268591 s, 0.0 kB/s
***********************************************
*** Using loop /dev/loop0
***********************************************

Disk /dev/loop0: 41.3 GB, 41339060224 bytes
255 heads, 63 sectors/track, 5025 cylinders
Units = cylinders of 16065 * 512 = 8225280 bytes
Sector size (logical/physical): 512 bytes / 512 bytes
I/O size (minimum/optimal): 512 bytes / 512 bytes
Disk identifier: 0x000c520c

      Device Boot      Start         End      Blocks   Id  System
/dev/loop0p1   *           1          32      256000   83  Linux
Partition 1 does not end on cylinder boundary.
/dev/loop0p2              32        2349    18611318+  8e  Linux LVM
1. Found /dev/loop0p1
2. Found /dev/loop0p2
Creating new Primary partition 3

***********************************************
(echo n; echo p; echo 3; echo ; echo ; echo t; echo 3; echo 8e; echo w) | fdisk /dev/loop0
***********************************************


WARNING: DOS-compatible mode is deprecated. It's strongly recommended to
         switch off the mode (command 'c') and change display units to
         sectors (command 'u').

Command (m for help): Command action
   e   extended
   p   primary partition (1-4)
Partition number (1-4): First cylinder (2350-5025, default 2350): Using default value 2350
Last cylinder, +cylinders or +size{K,M,G} (2350-5025, default 5025): Using default value 5025

Command (m for help): Partition number (1-4): Hex code (type L to list codes): Changed system type of partition 3 to 8e (Linux LVM)

Command (m for help): The partition table has been altered!

Calling ioctl() to re-read partition table.

WARNING: Re-reading the partition table failed with error 22: Invalid argument.
The kernel still uses the old table. The new table will be used at
the next reboot or after you run partprobe(8) or kpartx(8)
Syncing disks.


Disk /dev/loop0: 41.3 GB, 41339060224 bytes
255 heads, 63 sectors/track, 5025 cylinders
Units = cylinders of 16065 * 512 = 8225280 bytes
Sector size (logical/physical): 512 bytes / 512 bytes
I/O size (minimum/optimal): 512 bytes / 512 bytes
Disk identifier: 0x000c520c

      Device Boot      Start         End      Blocks   Id  System
/dev/loop0p1   *           1          32      256000   83  Linux
Partition 1 does not end on cylinder boundary.
/dev/loop0p2              32        2349    18611318+  8e  Linux LVM
/dev/loop0p3            2350        5025    21494970   8e  Linux LVM

loop: can't delete device /dev/loop0: Device or resource busy
===============================================
loop0p1|:|0|512000|/dev/loop0|2048
loopId: loop0p1
loop0p2|:|0|37222637|/dev/loop0|514048
loopId: loop0p2
loop0p3|:|0|42989940|/dev/loop0|37736685
loopId: loop0p3
loop|deleted|:|/dev/loop0

[root@utility ocm-ol6]# ll -h
total 37G
-rw-r--r--+ 1 root root 19G Jan 27 08:29 linux6_16.3.1_64.tar
-rw-r--r--+ 1 root root 39G Jan 27 08:41 System.img
loopId: loop0p3
Using loopId: loop0p3
===============================================

################################################################################
####                         getRunningSystemInfo                           ####
################################################################################

********************************************************************************
***
*** utility has Volume Group
***
*** RHEL Version : 6.7
*** OL Version   : 6.7
***
*** File System  : lvm
***
*** Volume Group : VGEKITUtility
*** Root Log Vol : LVRoot
*** Swap Log Vol : LVSwap
***
********************************************************************************


################################################################################
####                         createLoopFileSystem                           ####
################################################################################


################################################################################
####                          getSystemImgFSType                            ####
################################################################################

********************************************************************************
***
*** Mounted Image File System
***
*** File System  : ext3
***
********************************************************************************

Loop device is /dev/loop0
add map loop0p1 (252:2): 0 512000 linear /dev/loop0 2048
add map loop0p2 (252:3): 0 37222637 linear /dev/loop0 514048
add map loop0p3 (252:4): 0 42989940 linear /dev/loop0 37736685

################################################################################
####                           getSystemImgInfo                             ####
################################################################################

********************************************************************************
***
*** Mounted Image has no Volume Group
***
*** RHEL Version :
*** OL Version   :
***
*** File System  : ext3
***
********************************************************************************


################################################################################
####                      validateLoopFileSystemType                        ####
################################################################################


********************************************************************************
***
*** Specified System Image file has ext3 file system so we should be okay.
***
********************************************************************************
***********************************************
*** Scanning Volume Groups
***********************************************
  Reading all physical volumes.  This may take a while...
  Found volume group "VolGroup00" using metadata type lvm2
  Found volume group "VGEKITUtility" using metadata type lvm2
***********************************************
*** Extending VolGroup00
***********************************************
===============================================
  Physical volume "/dev/mapper/loop0p3" successfully created
  Volume group "VolGroup00" successfully extended
===============================================
***********************************************
***** Extending Root LogVol00
***********************************************
  Size of logical volume VolGroup00/LogVol00 changed from 11.00 GiB (2816 extents) to 31.00 GiB (7936 extents).
  Logical volume LogVol00 successfully resized
***********************************************
*** Changing VolGroup00
***********************************************
  3 logical volume(s) in volume group "VolGroup00" now active
***********************************************
*** Listing Directories
***********************************************
*** ls -lh /dev/mapper
***********************************************
total 0
crw-rw---- 1 root root 10, 236 Jan 16 05:43 control
lrwxrwxrwx 1 root root       7 Jan 27 08:41 loop0p1 -> ../dm-2
lrwxrwxrwx 1 root root       7 Jan 27 08:41 loop0p2 -> ../dm-3
lrwxrwxrwx 1 root root       7 Jan 27 08:41 loop0p3 -> ../dm-4
lrwxrwxrwx 1 root root       7 Jan 16 05:43 VGEKITUtility-LVRoot -> ../dm-1
lrwxrwxrwx 1 root root       7 Jan 16 05:43 VGEKITUtility-LVSwap -> ../dm-0
lrwxrwxrwx 1 root root       7 Jan 27 08:41 VolGroup00-LogVol00 -> ../dm-6
lrwxrwxrwx 1 root root       7 Jan 27 08:41 VolGroup00-LogVol01 -> ../dm-5
lrwxrwxrwx 1 root root       7 Jan 27 08:41 VolGroup00-LogVol02 -> ../dm-7
*** ls -lh /dev/V*
***********************************************
/dev/VGEKITUtility:
total 0
lrwxrwxrwx 1 root root 7 Jan 16 05:43 LVRoot -> ../dm-1
lrwxrwxrwx 1 root root 7 Jan 16 05:43 LVSwap -> ../dm-0

/dev/VolGroup00:
total 0
lrwxrwxrwx 1 root root 7 Jan 27 08:41 LogVol00 -> ../dm-6
lrwxrwxrwx 1 root root 7 Jan 27 08:41 LogVol01 -> ../dm-5
lrwxrwxrwx 1 root root 7 Jan 27 08:41 LogVol02 -> ../dm-7
Oracle Linux 6 (6.7)
***********************************************
***** Checking Root LogVol00
***********************************************
/dev/VolGroup00/LogVol00: 154624/720896 files (0.1% non-contiguous), 925814/2883584 blocks
***********************************************
***** Resizing Root LogVol00
***********************************************
resize2fs 1.43-WIP (20-Jun-2013)
Resizing the filesystem on /dev/VolGroup00/LogVol00 to 8126464 (4k) blocks.
The filesystem on /dev/VolGroup00/LogVol00 is now 8126464 blocks long.

***********************************************
***** Setting Swap LogVol01
***********************************************
mkswap: /dev/VolGroup00/LogVol01: warning: don't erase bootbits sectors
        on whole disk. Use -f to force.
Setting up swapspace version 1, size = 4194300 KiB
no label, UUID=73a92d9c-4c00-4013-9681-a8e5ae2994b6
  0 logical volume(s) in volume group "VolGroup00" now active
***********************************************
***** Changing UUID of VolGroup00
***********************************************
  Volume group "VolGroup00" successfully changed

################################################################################
####                         deleteLoopFileSystem                           ####
################################################################################

***********************************************
*** Unmounting /dev/loop0
***********************************************
Processing System.img
***********************************************
*** System.img Modified
*** Start Size : -rw-r--r--+ 1 root root 18G Sep 26 05:31 System.img
*** End Size   : -rw-r--r--+ 1 root root 39G Jan 27 08:41 System.img
***********************************************

[root@utility ocm-ol6]# tar cvf linux6-40G_16.3.1_64.tar System.img
System.img

[root@utility ocm-ol6]# ls -lh
total 39G
-rw-r--r--+ 1 root root  19G Jan 27 08:29 linux6_16.3.1_64.tar
-rw-r--r--+ 1 root root 2.5G Jan 27 08:44 linux6-40G_16.3.1_64.tar.gz
-rw-r--r--+ 1 root root  39G Jan 27 08:41 System.img
 

Step 3 - Adding the new machineimage to your OCM

The final step in the process is to copy the new <template>.tar.gz file back to where the OCM CLI has been installed and then add it to the environment.  To make a machine image available for use there are three steps.

  1. Add the machineimage file 
  2. Add an imagelist to the environment
  3. Add a imagelistentry to link the machine image to the imagelist.
The OCM makes use of an imagelist  when specifying which template to use as the base OS for a VM.  By abstracting the connection between the VM and its machineimage we introduce a useful mechanism for version control of the VM so VM creation scripts do not change even if we want to change the underlying machineimage.

The steps to make it available for use are shown below:-



# oc add machineimage /oracle/public/linux6-40G-16.3.1_64 /root/nimbula-machineimages-2017-01-27/linux6-40G_16.3.1_64.tar.gz
[====================================================================================================]
# oc add imagelist /oracle/public/linux6-40G-16.3.1_64 "Image list for base template expanded to 40G in size"
uri                                                          name                                    description                                              default     entries   
https://api/imagelist/oracle/public/linux6-40G-16.3.1_64     /oracle/public/linux6-40G-16.3.1_64     Image list for base template expanded to 40G in size     1                      

#
# oc add imagelistentry /oracle/public/linux6-40G-16.3.1_64 /oracle/public/linux6-40G-16.3.1_64 1
uri                                        imagelist                                                                                               machineimages                  versi a
https://api/imagelist/oracle/public/linux6 {"default": 1, "description": null, "entries": null, "uri": "imagelist/oracle/public/linux6-40G-16.3.1_ /oracle/public/linux6-40G-16.3 1     {
#

Note - In the example above I have used the /oracle tenancy to host the template.  This is a tenancy that only oracle cloud operations have access to and by placing the imagelist in this tenancy it makes the template available to all tenancies on the rack.  If you want this to be the situation then you must raise a request for cloud operations to add the objects.  However you can also do this within another tenancy in which case the imagelist will only be available for use within that tenancy.

Below is a screenshot from the self service portal showing the imagelist as available for use as a template.




Friday, September 23, 2016

Using Reporting in Enterprise Manager

Introduction

A common question that arises when talking to customers is to have visibility on the quantity of compute resource (CPU, Memory and Storage) that is being used.  This information is fairly easy to extract from the oracle-compute command line but it also is surfaced in Enterprise Manager.  As an exercise I wanted to try and produce a report from Enterprise Manager which gives the detail on the compute resource used.  This blog posting is just a capture of my experiences and not necessarily a best practice approach to reporting using EM12c against an OCM.

EM12c Reporting Overview

Enterprise Manager, as a monitoring tool, captures a great deal of information about anything it is monitoring.  Both configuration details and of course some historical information on the usage.  Provided you are logged in to the tool as a user with permissions to access reports and use the BI Publisher to create custom reports you will be able to find the reports under the Enterprise menu which typically is in the top left corner of the screen.


There are two options under reports, Information Publisher Reports which is a list of pre-defined reports that can be run to pull out commonly used reports and the BI Publisher Enterprise Reports.  The BI Publisher approach is the preferred route to use as this is now the report generator of choice for Enterprise Manager, others are deprecated and may eventually be dropped.  Like the Information Publisher Reports there are a series of out-the-box reports you can utilise but for many cases a custom report is the way to go. 

Creating a BI Publisher Report

BI Publisher is an incredibly powerful reporting tool that can query any database (or indeed even other sources of data) and push that data into an on-line report that can then be run on a regular basis, converted into PDF e-mailed out or run ad-hoc as needed.  With Enterprise Manager the main source of data is the underlying database of EM12c.

To create a report the process is essentially a two step process.  Firstly you must create a datamodel where you specify which tables to query, what the associations are between the tables, add filters and conditions to extract the specific data of interest.  Once the model has been defined you can optionally add in additional query parameters which can tune the report at run-time.  Once done you build a report up based on the data in the model, the report is built using simple wizards to produce tables of data, total up columns, display details on various graph types etc.

Building the DataModel for OCM

The Oracle Cloud Machine makes use of an EM12c Virtual Infrastructure plugin for most of the monitoring and management functionality.  This plugin stores much of its data in the tables that are prefixed with "MGMT$VI" and using BI Publisher we can create a new data model  that will pick the data we are interested.  When creating a new data model the default data source is called EMREPOS which is the database used by Enterprise Manager.  We can then simply type in the SQL if we know it in advance or alternatively use a "Query Builder" which allows us to dynamically build up the query using a fairly intuitive web based GUI.




The query builder allows us to drag and drop the tables onto a palate and select the fields we are interested in.  We can add conditions to the query, define linkage between tables etc.



In our specific use case we are looking to understand the resource used by the virtual machines, specifically allocated CPU, Memory and the storage volumes that have been added to the VMs.  This information is available in two tables, MGMT$VI_NM_OSV_CFG_DETAILS and MGMT$VI_NM_STORAGE_CFG.

BI Publisher has a mechanism to allow the report user to specify "parameters" which can be used to filter the data returned by the model.  It seems sensible to be able to query the model by tenancy I have added into the data model a parameter which will allow the user to specify one or more tenancies to report on.  For these tables the tenancy is effectively defined in the Quota. (an alternative breakdown might be per-orchestration)  To build up a parameter we have to create a "list of values" which the user can select from, as with the main data set this is defined via SQL queries against the database.  To show all tenancies I used the following SQL query:-


select "MGMT$VI_NM_OSV_CFG_DETAILS"."QUOTA" as "QUOTA" from "MGMT_VIEW"."MGMT$VI_NM_OSV_CFG_DETAILS" "MGMT$VI_NM_OSV_CFG_DETAILS" 
 where "MGMT$VI_NM_OSV_CFG_DETAILS"."QUOTA" !='RANDOMTEXT' 
   AND VNC_URL=(SELECT MAX(VNC_URL) from MGMT_VIEW.MGMT$VI_NM_OSV_CFG_DETAILS "B" WHERE b.QUOTA=MGMT$VI_NM_OSV_CFG_DETAILS.QUOTA)

This allows me to build up a list of tenancies (quota) which has been de-duplicated via the where clause.  (Could not get select distinct to work....)  This value list (the tenancies) is used as the selection for the Parameter which will be presented on the report to allow the user to narrow the report down to specific tenancies.



As shown in the screnshot I have selected to allow the user to chose multiple tenancies to report on or all the tenancies.  If all then a comma separated list of all tenancies on the rack is passed in as the parameter to the report.

Building the report

Once done we can turn attention to the report.  The first thing to do is to click on the data tab in the data model and press View to have a look at what data is actually returned by your datamodel.  If it looks like the correct information is being returned then click on "Save as Sample Data" and the data you returned is saved and used as the basis for data shown as the report is developed.

The easiest way to create the report from here is to click the "Create Report" button on the top right of the screen, this will open up a wizard to allow you to create the report and add charts and data tables to the report.




Having completed the report design we can then run the report.  In the screenshot below I have picked out three of the tenancies I am interested in and we can see at a moments glance that the JCS Demo tenancy is using most memory and CPU while the DBCS demo account is using most storage space.  Exactly as we would expect for a relatively small application.


Conclusion

Even although the OCM is managed by Oracle as a tenant user of the OCM rack it is fairly easy to use Enterprise Manager to gain insight into the usage of the OCM and BI Publisher provides a way to extract data to put into useful management reports.

Tuesday, June 7, 2016

Encrypting "disks" on Oracle Cloud Machine

Introduction


The Oracle Cloud Machine, like the public cloud, is administered by Oracle.  While the Oracle staff who manage the rack are highly skilled professionals and all their actions audited there is an obvious concern about the security of customer data at rest.  On the OCM the administrators of the rack have no direct access to the customer's virtual machines.  This article demonstrates how storage volumes can be used by a tenant to mount block storage devices that are encrypted and hence further obscured from system administrators.

(As a side effect of demonstrating the security aspect this is also a useful reference for using cryptsetup to encrypt disks.)

Setup


In order to demonstrate that a storage volume is encrypted and hence not visible to cloud administrators we do a very simple setup where two storage volumes are created, one to be encrypted and the other left in plain text.  These volumes are "attached" to a virtual machine and then within the virtual machine we use the linux utility cryptsetup to encrypt one of the volumes the other is simply mounted with an ext4 filesystem on it.  Plain text files are created in both volumes and then we will switch to the cloud administration side of things to see if it is possible to read the content of the two volumes.

Virtual Machine Instance Creation



First of all we create two storage volumes.  This can be done from the command line easily.


# oracle-compute add storagevolume /osc/public/encrypt-storage-001 10G /oracle/public/storage/default --description "A test 10Gb storage volume that we will try to have encrypted" 

# oracle-compute add storagevolume /osc/public/plain-storage-001 10G /oracle/public/storage/default --description "A test 10Gb storage volume that we will try to have encrypted"


Then we create a virtual machine via an orchestration defined in a json file

# cat simple_vm_with_storage.json
{
"name": "/osc/public/encryption-vm",
"oplans": [
{
 "obj_type": "launchplan",
 "ha_policy": "active",
 "label": "encryption volume launch plan",
 "objects": [
 {
 "instances": [
 {
 "label": "encryption-vm001",
 "imagelist": "/oracle/public/linux6_16.1.2_64",
 "networking":
 {
   "net0": { "vnet": "/osc/public/vnet-eoib-1706" }
 },
 "storage_attachments": [
 { "volume": "/osc/public/encrypt-storage-001", "index": 1},{"volume": "/osc/public/plain-storage-001", "index": 2}],
 "shape": "ot1",
 "sshkeys": ["/osc/public/labkey"],
 "attributes":
 {
 "userdata":
 {
 "key1": "value 1",
 "key2": "value 2"
 }
 }
 } ]
 } ]
} ]
}



This json file will create a single instance called encryption-vm001 based on the OL6 base template, connect it to the EoIB public network and attach the two storage volumes that we created earlier.  (Storage volumes created independently of this orchestration in this case.)

We upload the orchestration and start it.  Once up and running then the instance will be listed as running and we can see the IP address assigned to it.

# oracle-compute add orchestration ./simple_vm_with_storage.json 


(see above for json)

# oracle-compute start orchestration /osc/public/encrytption-vm

# oracle-compute list instance /osc -Fname,state,ip


Configuring volumes within instance


Having created and started up our instance we can look at the attached volumes and run through the process using Oracle Linux to setup one of the volumes as an encrypted one.   To see the volumes on the instance we use the fdisk command.



# fdisk -l

Disk /dev/xvda: 19.3 GB, 19327352832 bytes
255 heads, 63 sectors/track, 2349 cylinders
Units = cylinders of 16065 * 512 = 8225280 bytes
Sector size (logical/physical): 512 bytes / 512 bytes
I/O size (minimum/optimal): 512 bytes / 512 bytes
Disk identifier: 0x000c520c


    Device Boot      Start         End      Blocks   Id  System
/dev/xvda1   *           1          32      256000   83  Linux
Partition 1 does not end on cylinder boundary.
/dev/xvda2              32        2349    18611318+  8e  Linux LVM



Disk /dev/xvdb: 10.7 GB, 10737418240 bytes

255 heads, 63 sectors/track, 1305 cylinders
Units = cylinders of 16065 * 512 = 8225280 bytes
Sector size (logical/physical): 512 bytes / 512 bytes
I/O size (minimum/optimal): 512 bytes / 512 bytes
Disk identifier: 0x00000000



Disk /dev/xvdc: 10.7 GB, 10737418240 bytes
255 heads, 63 sectors/track, 1305 cylinders
Units = cylinders of 16065 * 512 = 8225280 bytes
Sector size (logical/physical): 512 bytes / 512 bytes
I/O size (minimum/optimal): 512 bytes / 512 bytes
Disk identifier: 0x00000000

Disk /dev/mapper/VolGroup00-LogVol01: 4294 MB, 4294967296 bytes
255 heads, 63 sectors/track, 522 cylinders
Units = cylinders of 16065 * 512 = 8225280 bytes
Sector size (logical/physical): 512 bytes / 512 bytes
I/O size (minimum/optimal): 512 bytes / 512 bytes
Disk identifier: 0x00000000

Disk /dev/mapper/VolGroup00-LogVol00: 11.8 GB, 11811160064 bytes
255 heads, 63 sectors/track, 1435 cylinders
Units = cylinders of 16065 * 512 = 8225280 bytes
Sector size (logical/physical): 512 bytes / 512 bytes
I/O size (minimum/optimal): 512 bytes / 512 bytes
Disk identifier: 0x00000000

Disk /dev/mapper/VolGroup00-LogVol02: 2147 MB, 2147483648 bytes
255 heads, 63 sectors/track, 261 cylinders
Units = cylinders of 16065 * 512 = 8225280 bytes
Sector size (logical/physical): 512 bytes / 512 bytes
I/O size (minimum/optimal): 512 bytes / 512 bytes
Disk identifier: 0x00000000


With the OCM each volume that is attached gets an index, in the orchestration above we use indexes 1 and 2.  These numbers equate to the xvd<char> devices that appear in the fdisk output.where 1 equates to b, 2 equates to c etc.  Thus in the output above the two attached volumes are /dev/xvdb and /dev/xvdc.  The next step is to setup one of the volumes as an block device encrypted one.  To do this I used the linux command cryptsetup defining cipher information etc.  In the example shown below I show it run twice as the first time I answered the question with a lower case yes.  The command mandated uppercase YES as an answer.  Easy mistake to make!



# cryptsetup --verbose --cipher aes-xts-plain64 --key-size 512 --hash sha512 --iter-time 5000 --use-random luksFormat /dev/xvdb



WARNING!
========
This will overwrite data on /dev/xvdb irrevocably.


Are you sure? (Type uppercase yes): yes
Command failed with code 22: Invalid argument

# cryptsetup --verbose --cipher aes-xts-plain64 --key-size 512 --hash sha512 --iter-time 5000 --use-random luksFormat /dev/xvdb

WARNING!
========

This will overwrite data on /dev/xvdb irrevocably.
Are you sure? (Type uppercase yes): YES
Enter LUKS passphrase:
Verify passphrase:
Command successful.




Now we can open the encrypted drive such that it appears as normal.  This will create the /dev/mapper/<name> device file and allow it to be mounted by the OS.  The luksOpen command will prompt for the passphrase used earlier.

# cryptsetup luksOpen /dev/xvdb encrypted-drive

# cryptsetup -v status encrypted-drive
/dev/mapper/encrypted-drive is active.
  type:  LUKS1
  cipher:  aes-xts-plain64
  keysize: 512 bits
  device:  /dev/xvdb
  offset:  4096 sectors
  size:    20967424 sectors
  mode:    read/write
Command successful.


This is a new raw volume so we need to put some sort of filesystem onto it.  In this case I use the ext4 filesystem.


# mkfs.ext4 /dev/mapper/encrypted-drive
mke2fs 1.43-WIP (20-Jun-2013)
Filesystem label=
OS type: Linux
Block size=4096 (log=2)
Fragment size=4096 (log=2)
Stride=0 blocks, Stripe width=0 blocks
655360 inodes, 2620928 blocks
131046 blocks (5.00%) reserved for the super user
First data block=0
Maximum filesystem blocks=2684354560
80 block groups
32768 blocks per group, 32768 fragments per group
8192 inodes per group
Superblock backups stored on blocks:
    32768, 98304, 163840, 229376, 294912, 819200, 884736, 1605632
Allocating group tables: done                           
Writing inode tables: done                           
Creating journal (32768 blocks): done
Writing superblocks and filesystem accounting information: done

Now simply create a directory where we can mount the encrypted drive and create a simple text file.

# mkdir /u01
# mount /dev/mapper/encrypted-drive /u01
# df -kh
Filesystem                       Size  Used Avail Use% Mounted on
/dev/mapper/VolGroup00-LogVol00   11G  3.3G  7.0G  32% /
tmpfs                            3.8G     0  3.8G   0% /dev/shm
/dev/xvda1                       239M   55M  168M  25% /boot
/dev/mapper/VolGroup00-LogVol02  2.0G  3.0M  1.9G   1% /opt/emagent_instance
/dev/mapper/encrypted-drive      9.8G   23M  9.2G   1% /u01


 Having done this we can do a quick check to ensure that we can unmount and close the encrypted disk and re-open it providing the passphrase and mount it for use.


#umount /u01
# cryptsetup luksClose encrypted-drive
# mount /dev/mapper/encrypted-drive /u01
mount: you must specify the filesystem type



# cryptsetup luksOpen /dev/xvdb encrypted-drive
Enter passphrase for /dev/xvdb:
# mount /dev/mapper/encrypted-drive /u01
# df -kh
Filesystem                       Size  Used Avail Use% Mounted on
/dev/mapper/VolGroup00-LogVol00   11G  3.3G  7.0G  32% /
tmpfs                            3.8G     0  3.8G   0% /dev/shm
/dev/xvda1                       239M   55M  168M  25% /boot
/dev/mapper/VolGroup00-LogVol02  2.0G  3.0M  1.9G   1% /opt/emagent_instance
/dev/mapper/encrypted-drive      9.8G   23M  9.2G   1% /u01




Using fdisk we can format the /dev/xvdc volume, create a file system on this volume and mount it into another directory.  Then create a plain text file in this volume as well.   If the encryption has all worked then cloud operations may be able to access the plain text volume and read the content but the encrypted volume content is kept secret unless the passphrase is known.

Testing

As a general rule cloud operations do not have access to the customer's virtual machines unless the customer shares the login credentials or the ssh keys with Oracle.  However, because the OCM stores the volumes as raw disk images on the internal ZFS storage appliance in the EPC_<rack>/storagepool1 filesystem it is possible for cloud operations to access these files and mount the images directly to access the content.


As a cloud operations user I have accessed the ZFS storage device and can copy the storage volume disks off the rack.  In a linux server I attempt to mount these volumes to see the content.

# file plain_storage.raw
plain_storage.raw: Linux rev 1.0 ext4 filesystem data (extents) (large files) (huge files)
# mount -o loop ./plain_storage.raw /mnt/don
# cat /mnt/don/don-plain

This text is in the unencrypted volume and hence should be readable by anyone.....
# unmount /mnt/don




So it is obviously fairly easy to access the unencrypted storage.  Now lets see what is involved in accessing the encrypted storage volume.

# file encrypted_storage.raw
encrypted_storage.raw: LUKS encrypted file, ver 1 [aes, xts-plain64, sha512] UUID: edff3d80-3813-4abc-a58c-e2f1862

# mount -o loop ./encrypted_storage.raw /mnt/don
mount: unknown filesystem type 'crypto_LUKS'

# losetup /dev/loop0 ./encrypted_storage.raw
# mount /dev/loop0 /mnt/don
mount: unknown filesystem type 'crypto_LUKS'


# cryptsetup luksOpen /dev/loop0 encrypted-dev
Enter passphrase for /dev/loop0:

# mount /dev/mapper/encrypted-dev /mnt/don

# cat /mnt/don/don

some text

#


In the above I attempt to mount the encrypted filesystem using the same mechanism as previously was successful but to no effect.  The only way to mount the disk is to make use of the cryptsetup command which mandated entering the passphrase.  Obviously the passphrase is not something that is shared with cloud operations so they would be unable to access the content of the raw file.

Conclusion

Certainly using the standard linux command of cryptsetup it is a relatively simple task to encrypt any storage volume that is mounted on a VM such that the data is kept private to the end customer/tenant and cloud operations has no mechanism of seeing the content.

The down side of encrypting is that it means that the administrator of the virtual machine (end customer) has to log on and provide the passphrase to mount the volume.  Not a major problem unless you are looking at trying to automatically start up the applications deployed that use the encrypted volume, in this case it becomes necessary to have a manual startup procedure.

Monday, June 6, 2016

Introducing Oracle Cloud Machine


As mentioned in my exablurb blog I am now working beyond the bounds of Oracle Engineered Systems to incorporate the Oracle Cloud Machine as introduced here.  As such this blog will include postings that apply to both Exalogic and the Cloud Machine.


I'll start by quoting one of the PM's from the cloud machine to explain just what the cloud machine actually is:

"Oracle Cloud Machine is a cloud offering which gives you new choices for the Oracle Cloud Platform by bringing the Oracle Cloud to your data center. Leveraging our Public Cloud’s PaaS and IaaS capabilities, it enables the innovation that cloud provides, at the same time meeting the business and regulatory requirements behind your firewall. It provides a stepping-stone in the journey to cloud, as it allows you to get the advantages of cloud faster, easier and with less disruption. As an on- premises implementation of Oracle Cloud, Oracle Cloud Machine lets you run your applications seamlessly wherever you want, as workloads are completely portable between the public cloud and your data center. You can now leverage the latest innovations for rapid development that cloud provides, all while meeting any data sovereignty and residence requirements. It also provides subscription based pricing in your data center, managed by Oracle, with single vendor accountability."

Or to put it simply the cloud machine is a bunch of compute services that Oracle come along and install in your data center and then run it as a service such that you, as a customer, can consume IaaS and PaaS services without having to worry about building up the management infrastructure and on-going operational management of the platform.


Lots more information can be found from the public documentation.