Tuesday, April 7, 2015

Murano: How to prepare an image for Kubernetes

Before I am going into details about an image preparation let me explain what is Kubernetes.  The long definition of Kubernetes can be found here: https://github.com/GoogleCloudPlatform/kubernetes/blob/master/DESIGN.md. I will just quote the first lines which defines in high level what Kubernetes is.
"Kubernetes is a system for managing containerized applications across multiple hosts, providing basic mechanisms for deployment, maintenance, and scaling of applications. Its APIs are intended to serve as the foundation for an open ecosystem of tools, automation systems, and higher-level API layers."[1]

Murano does support Kubernetes as a Murano application. It is possible to quickly roll out a Kubernetes cluster on top of OpenStack, making sure that it is properly configured and integrated to OpenStack infrastructure. More detailed information can be found here: https://www.mirantis.com/blog/integrating-openstack-and-kubernetes-with-murano/.

Lets return to the topic and discuss an image preparation for Kubernetes. Image preparation is automated by using OpenStack Disk Image Builder tool. There is a DIB element provided by Murano team to build Kubernetes image on Ubuntu: https://github.com/stackforge/murano/tree/master/contrib/elements/kubernetes 

File /install.d/57-kubernetes contains all necessary steps to pre-install all necessary component for Kubernetes cluster:
  • ETCD - a distributed /etc service used in CoreOS and required by Kubernetes to store its configuration
  • Go - Go language compiler to build Kubernetes and ETCD from sources
  • Kubernetes - the latest version of Kubernetes source code
  • Flannel - a GRE based overlay network service to connect Docker containers in Kubernetes VMs
When Murano creates a new Kubernetes cluster it executes several shell scripts on each VM. The shell scripts to configure Kubernetes can be found here: https://github.com/stackforge/murano-apps/tree/master/kubernetes/io.murano.apps.docker.kubernetes.KubernetesCluster/Resources/scripts

Workflow with the logic and step-by-step installation flow can be found in Murano workflow definition for Kubernetes: https://github.com/stackforge/murano-apps/blob/master/kubernetes/io.murano.apps.docker.kubernetes.KubernetesCluster/Classes/KubernetesCluster.yaml


-------------------------------------------------------------------------------------------------------------------

[1] https://github.com/GoogleCloudPlatform/kubernetes/blob/master/DESIGN.md

Monday, April 6, 2015

Murano: How to find network ids for automatically created networks

Murano deploys the specific network topology for a Murano environment by default. Murano creates a new private network then adds a new subnet and finally attaches this new network to the router.

If someone is writing an application, which wants to add some  Heat resources into the stack it might be a requirement to pass some network ids to the resource.

As networking is usually hidden from an user in the depth of Core library and it is not so obvious how to get these ids.

Here is a way I do this in my apps:

- $net: $.environment.defaultNetworks.environment
- If: $net != null
  Then:
     - $.environment.reporter.report($this, '[VMCluster]Using existing external network')
- $netRef: $net._getNetworkName() 
- $subnetRef: $net._getSubnetName()
- $extNetId: $net._getExternalNetId()

[Note: in Icehouse version there is no underscore in the name of these functions]

defaultNetwroks property of Environment contains a networking information for created networks.  Actual implementation of networking could be found here (https://github.com/stackforge/murano/blob/master/meta/io.murano/Classes/resources/NeutronNetwork.yaml) [Note that it should be moved soon to guthub.com/openstack/murano]


In the example above I got all necassary information for my networks:
  • $netRef: will contain a Heat resource name for the network so that in embeded Heat template I can just use {get_resource: $netRef }
  • $subnetRef: will contain a Heat resource name for subnet resource. Could be used as a reference in Embeded Heat template as {get_resource: $subnetRef }
  • $extNetId: will contain an id of external network attached to a router. It is a network where application will allocate floating IPs. You might need this network id for LBaaS Pool resource.

On Juno version of OpenStack and Murano it will be necessary to explicitly cast network to NeutronNetwork like in the example below:

- $netRef: $net.cast('io.murano.resources.NeutronNetwork')._getNetworkName()
- $subnetRef: $net.cast('io.murano.resources.NeutronNetwork')._getSubnetName()
- $extNetId: $net.cast('io.murano.resources.NeutronNetwork')._getExternalNetId()

That is it about networks ids.
Enjoy!

Friday, April 3, 2015

Murano: Configuring Security Groups for an application

Close every door to me
Hide all the world from me
Bar all the windows
And shut out the light


(Andrew Lloyd-Webber)


Security groups are the key component of application security on a shared cloud environment. Each Murano application definition most probably contains security group rules to open or close ports which are exposed by an application.

There are two ways to configure security groups in a workflows. The first way is to use Murano security manager code which wraps all internals of Heat template handling and expose simple functions.

Here is an example of how it could be done:

- $securityGroupIngress:
    - ToPort: 65535       
      FromPort: 1       
      IpProtocol: tcp
      External: false
    - ToPort: 80 
      FromPort: 80 
      IpProtocol: tcp
      External: true
    - ToPort: 443 
      FromPort: 443       
      IpProtocol: tcp
      External: true
- $.environment.securityGroupManager.addGroupIngress($securityGroupIngress)

In this example the application will open all tcp ports (1-65535) between VMs who are participating in the same group (Note this line)

External: false


So these ports will be open only for internal communication between VMs.
In contrary, ports 80 and 443 are opened for external access from the outside (internet if you use floating IPs).

SecurityManager uses Heat updates to update security rules inside stack but it does not initiates these updates. Usually this update happens when you have an instance creation as a next step. If you are openning ports after your VMs are provisioned you can initiate stack update by adding:

- $.environment.stack.push()

Another way to do security groups is to embed Heat resources directly int he workflow and use stack updates to push security group resources into the stack.


And Heat resources are documented here: http://docs.openstack.org/developer/heat/template_guide/openstack.html#OS::Neutron::SecurityGroup


 
Enjoy!