From e0de6af3ecb68e9a80bdb9e666aaecacf7d79753 Mon Sep 17 00:00:00 2001
From: Daneyon Hansen <danehans@cisco.com>
Date: Mon, 16 Feb 2015 21:37:03 +0000
Subject: [PATCH] Implements: blueprint heat-template

Previously, the kolla heat template was maintained outside of
the project in the larsks/heat-kubernetes repo. This patch adds
the templates to the project's devenv directory. Additionally,
the patch updates the templates and documentation to reflect
the design changes outlined in the following spec:

https://github.com/stackforge/kolla/blob/master/specs/containerize-openstack.rst

Change-Id: I11305f87cceb2495478d458a7e381d20838e664a
---
 README.md                 | 216 +++++++++-----------------------------
 devenv/README.md          | 143 +++++++++++++++++++++++++
 devenv/kollacluster.yaml  | 109 +++++++++++++++++++
 devenv/kollanet.png       | Bin 0 -> 26014 bytes
 devenv/kollanode.yaml     | 199 +++++++++++++++++++++++++++++++++++
 devenv/local.yaml.example |   3 +
 6 files changed, 502 insertions(+), 168 deletions(-)
 create mode 100644 devenv/README.md
 create mode 100644 devenv/kollacluster.yaml
 create mode 100644 devenv/kollanet.png
 create mode 100644 devenv/kollanode.yaml
 create mode 100644 devenv/local.yaml.example

diff --git a/README.md b/README.md
index caaf6803c1..354656d08e 100644
--- a/README.md
+++ b/README.md
@@ -1,30 +1,36 @@
-Kolla
-=====
+Kolla Overview
+==============
 
-The Kolla project is part of the OpenStack TripleO effort, focused on
-deploying OpenStack environments using [Kubernetes][] and [Docker][]
-containers.
+The Kolla project is part of the OpenStack [TripleO][] effort, focused
+on deploying OpenStack services using [Docker][] containers. The initial
+system [spec][] provides additional details of Kolla and the use cases
+it addresses.
 
-[kubernetes]: https://github.com/GoogleCloudPlatform/kubernetes
-[docker]: http://docker.com/
+[TripleO]: https://wiki.openstack.org/wiki/TripleO
+[Docker]: http://docker.com/
+[spec]: https://github.com/stackforge/kolla/blob/master/specs/containerize-openstack.rst
 
 Getting Started
 ===============
 
-Kubernetes deployment on bare metal is a complex topic which is beyond the
-scope of this project at this time.  The developers require a development test
-environment.  As a result, one of the developers has created a Heat based
-deployment tool that can be
-found [here](https://github.com/larsks/heat-kubernetes).
+Deployment on bare metal is a complex topic which is beyond the scope of
+the project at this time. An environment to simplify the deployment of a
+single or multi-node Kolla cluster is required for development purposes.
+As a result, a [Heat template][] has been created for deploying a Kolla
+cluster to an existing OpenStack cloud.
 
+[Heat template]: (https://github.com/stackforge/kolla/blob/master/devenv/README.md)
 
-Build Docker Images
--------------------
+Docker Images
+-------------
 
-Images are built by the Kolla project maintainers.  It is possible to build
-unique images with specific changes, but these would end up in a personal
-namespace.  Read the docs directory image workflow documentation for more
-details.
+The [Docker images][] are built by the Kolla project maintainers. A detailed
+process for contributing to the images can be found [here][]. Images reside
+in the Docker Hub [Kollaglue repo][].
+
+[here]: https://github.com/stackforge/kolla/blob/master/docs/image-building.md
+[Docker images]: https://docs.docker.com/userguide/dockerimages/
+[Kollaglue repo]: https://registry.hub.docker.com/repos/kollaglue/
 
 The Kolla developers build images in the kollaglue namespace for the following
 services:
@@ -45,161 +51,35 @@ $ sudo docker search kollaglue
 ```
 A list of the upstream built docker images will be shown.
 
-Use Kubernetes to Deploy OpenStack
-----------------------------------
-
-At this point, we believe the key features for a minimum viable feature set
-are implemented.  This includes the capability to launch virtual machines in
-Nova.  One key fact is that networking may not entirely work properly yet
-until Neutron is finished, so the virtual machines may not actually behave
-as expected for an end user deployment.
-
-Two options exist for those without an existing Kubernetes environment:
-
-The upstream Kubernetes community provides instructions for running Kubernetes
-using Vagrant, available from:
-https://github.com/GoogleCloudPlatform/kubernetes/blob/master/docs/getting-started-guides/vagrant.md
-
-The Kolla developers develop Kolla in OpenStack, using Heat to provision the
-necessary servers and other resources.  If you are familiar with Heat and
-have a correctly configured environment available, this allows deployment
-of a working Kubernetes cluster automatically.  The Heat templates are
-available from https://github.com/larsks/heat-kubernetes/.  The templates
-require at least Heat 2014.1.3 (earlier versions have a bug that will prevent
-the templates from working).
-
-Here are some simple steps to get things rolling using the Heat templates:
-
-1. Clone the repository:
-   ```
-   git clone https://github.com/larsks/heat-kubernetes/
-   cd heat-kubernetes
-   ```
-
-2. Create an appropriate image by running the get_image.sh script in this
-   repository.  This will generate an image called `fedora-20-k8s.qcow2`.
-   Upload this image to Glance.  You can also obtain an appropriate image from
-   https://fedorapeople.org/groups/heat/kolla/fedora-20-k8s.qcow2
-
-3. Create a file `local.yaml` with settings appropriate to your OpenStack
-   environment. It should look something like:
-   ```
-   parameters:
-     server_image: fedora-20-k8s
-     ssh_key_name: sdake
-
-
-     dns_nameserver: 8.8.8.8
-     external_network_id: 6e7e7701-46a0-49c0-9f06-ac5abc79d6ae
-     number_of_minions: 1
-     server_flavor: m1.large
-   ```
-   You *must* provide settings for external_network_id and ssh_key_name; these
-   are local to your environment. You will probably also need to provide
-   a value for server_image, which should be the name (or UUID) of a Fedora 20
-   cloud image or derivative.
-
-4. `heat stack-create -f kubecluster.yaml -e local.yaml my-kube-cluster`
-
-5. Determine the ip addresses of your cluster hosts by running:
-   ```
-   heat output-show my-kube-cluster kube_minions_external
-   ```
-
-6. Connect to the minion node with `ssh fedora@${minion-ip}`
-
-7. On the minion node:
-   ```
-   minion$ git clone http://github.com/stackforge/kolla
-   minion$ cd kolla
-   minion$ ./tools/start
-   ```
-
-Debugging
-==========
-A few commands for debugging the system.
-
-```
-$ sudo docker images
-```
-Lists all images that have been pulled from the upstream kollaglue repository
-thus far.  This can be run on the minion during the `./start` operation to
-check on the download progress.
-
-
-```
-$ sudo docker ps -a
-```
-This will show all processes that docker has started.  Removing the `-a` will
-show only active processes.  This can be run on the minion during the `./start`
-operation to check that the containers are orchestrated.
-
-
-```
-$ sudo docker logs <containerid>
-```
-This shows the logging output of each service in a container.  The containerid
-can be obtained via the `docker ps` operation.  This can be run on the minion
-during the `./start` operation to debug the container.
-
-```
-$ kubectl get pods
-```
-This lists all pods of which Kubernetes is aware.  This can be run on the
-master or minion.
-
-```
-$ sudo systemctl restart kube-apiserver
-$ sudo systemctl restart kube-scheduler
-```
-This command is needed on the master after heat finishes the creation of the
-Kubernetes system (ie: my-kube-cluster is in CREATE_COMPLETE state).  This is
-just a workaround for a bug in kubernetes that should be fixed soon.
-
-
-```
-$ journalctl -f -l -xn -u kube-apiserver -u etcd -u kube-scheduler
-```
-This shows log output on the server for the various daemons and can be filed
-in bug reports in the upstream launchpad tracker.
+Directories
+===========
 
-```
-$ journalctl -f -l -xn -u kubelet.service -u kube-proxy -u docker
-```
-This shows log output on the minion for the various daemons and can be filed
-in bug reports in the upstream launchpad tracker.
+* docker - contains artifacts for use with docker build to build appropriate
+  images
+* k8s - contains service and pod configuration information for Kubernetes
+* tools - contains different tools for interacting with Kolla
+* devenv - A collection of tools and resources for managing a Kolla
+  development environment.
 
-```
-$ telnet minion_ip 3306
-```
-This shows that the Mariadb service is running on the minions.  Output should
-appear as follows
+Getting Involved
+================
 
-```
-$ telnet 10.0.0.4 3306
-Trying 10.0.0.4...
-Connected to 10.0.0.4.
-Escape character is '^]'.
+Need a feature? Find a bug? Let us know! Contributions are much appreciated
+and should follow the standard [Gerrit workflow][].
 
-5.5.39-MariaDB-wsrep
-```
+- We communicate using the #tripleo irc channel.
+- File bugs, blueprints, track releases, etc on [Launchpad][].
+- Attend weekly [meetings][].
+- Contribute [code][]
 
-If the connection closes before mysql responds then the proxy is not properly
-connecting to the database.  This can be seen by using jounalctl and watching
-for a connection error on the node that you can't connect to mysql through.
+[Gerrit workflow]: https://wiki.openstack.org/wiki/Gerrit_Workflow
+[Launchpad]: https://launchpad.net/kolla
+[meetings]: https://wiki.openstack.org/wiki/Meetings/Kolla
+[code]: https://github.com/stackforge/kolla
 
-```
-$ journalctl -f -l -xn -u kube-proxy
-```
-If you can conect though one and not the other there's probably a problem with
-the overlay network. Double check that you're tunning kernel 3.16+ because
-vxlan support is required. If you kernel version is good try restarting
-openvswitch on both nodes. This has usually fixed the connection issues.
+Contributors
+============
 
-Directories
-===========
+Check out who's [contributing][].
 
-* docker - contains artifacts for use with docker build to build appropriate
-  images
-* k8s - contains service and pod configuration information for Kubernetes
-* tools - contains different tools for interacting with Kolla
+[contributing]: https://github.com/stackforge/kolla/graphs/contributors
diff --git a/devenv/README.md b/devenv/README.md
new file mode 100644
index 0000000000..406b60e427
--- /dev/null
+++ b/devenv/README.md
@@ -0,0 +1,143 @@
+A Kolla Cluster with Heat
+=========================
+
+These [Heat][] templates will deploy an *N*-node [Kolla][] cluster,
+where *N* is the value of the `number_of_nodes` parameter you
+specify when creating the stack.
+
+Kolla has recently undergone a considerable design change. The details
+of the design change is addressed in this [spec][]. As part of the
+design change, containers share pid and networking namespaces with
+the Docker host. Therefore, containers no longer connect to a docker0
+bridge and have separate networking from the host. As a result, Kolla
+networking has a configuration similar to:
+
+![Image](https://raw.githubusercontent.com/stackforge/kolla/master/devenv/kollanet.png)
+
+Sharing pid and networking namespaces is detailed in the 
+[super privileged containers][] concept.
+
+The Kolla cluster is based on Fedora 21, and makes use of the
+[pkilambi/docker][] [COPR][] repository for Docker packages. This
+is because Kolla requires a newer version of Docker not currently
+packaged in Fedora 21.
+
+These templates are designed to work with the Icehouse or Juno
+versions of Heat. If using Icehouse Heat, this [patch][] is
+required to correct a bug with template validation when using the
+"Fn::Join" function).
+
+[heat]: https://wiki.openstack.org/wiki/Heat
+[kolla]: https://launchpad.net/kolla
+[pkilambi/docker]: https://copr.fedoraproject.org/coprs/pkilambi/docker
+[copr]: https://copr.fedoraproject.org/
+[spec]: https://review.openstack.org/#/c/153798/
+[super privileged containers]: http://sdake.io/2015/01/28/an-atomic-upgrade-process-for-openstack-compute-nodes/
+[patch]: https://review.openstack.org/#/c/121139/
+
+Create the Glance Image
+=======================
+
+After cloning the project, run the get-image.sh script from the project's
+devenv directory:
+
+    $ ./get-image.sh
+
+The script will create a Fedora 21 image with the required modifications.
+
+Copy the image to your Glance image store:
+
+    $ glance image-create --name "fedora-21-x86_64" \
+    --file /var/lib/libvirt/images/fedora-21-x86_64 \
+    --disk-format qcow2 --container-format bare \
+    --is-public True --progress
+
+Create the Stack
+================
+
+Copy local.yaml.example to local.yaml and edit the contents to match
+your deployment environment. Here is an example of a customized
+local.yaml:
+
+    parameters:
+      ssh_key_name: admin-key
+      external_network_id: 028d70dd-67b8-4901-8bdd-0c62b06cce2d
+      dns_nameserver: 192.168.200.1
+
+Review the parameters section of kollacluster.yaml for a full list of
+configuration options. **Note:** You must provide values for:
+
+- `ssh_key_name`
+- `external_network_id`
+
+And then create the stack, referencing that environment file:
+
+    $ heat stack-create -f kollacluster.yaml -e local.yaml kolla-cluster
+
+Access the Kolla Nodes
+======================
+
+You can get the ip address of the Kolla nodes using the `heat
+output-show` command:
+
+    $ heat output-show kolla-cluster kolla_node_external_ip
+    "192.168.200.86"
+
+You can ssh into that server as the `fedora` user:
+
+    $ ssh fedora@192.168.200.86
+
+And once logged in you can run Docker commands, etc:
+
+    $ sudo docker images
+
+Debugging
+==========
+A few commands for debugging the system.
+
+```
+$ sudo docker images
+```
+Lists all images that have been pulled from the upstream kollaglue repository
+thus far.  This can be run on the node during the `./start` operation to
+check on the download progress.
+
+```
+$ sudo docker ps -a
+```
+This will show all processes that docker has started.  Removing the `-a` will
+show only active processes.  This can be run on the node during the `./start`
+operation to check that the containers are orchestrated.
+
+```
+$ sudo docker logs <containerid>
+```
+This shows the logging output of each service in a container.  The containerid
+can be obtained via the `docker ps` operation.  This can be run on the node
+during the `./start` operation to debug the container.
+
+```
+$ sudo systemctl restart docker
+```
+Restarts the Docker service on the node.
+
+```
+$ journalctl -f -l -xn -u docker
+```
+This shows log output on the server for the docker daemon and can be filed
+in bug reports in the upstream launchpad tracker.
+
+```
+$ telnet <NODE_IP> 3306
+```
+You can use telnet to test connectivity to a container. This example demonstrates
+the Mariadb service is running on the node.  Output should appear as follows
+
+```
+$ telnet 10.0.0.4 3306
+Trying 10.0.0.4...
+Connected to 10.0.0.4.
+Escape character is '^]'.
+
+5.5.39-MariaDB-wsrep
+```
diff --git a/devenv/kollacluster.yaml b/devenv/kollacluster.yaml
new file mode 100644
index 0000000000..0c8c65a956
--- /dev/null
+++ b/devenv/kollacluster.yaml
@@ -0,0 +1,109 @@
+heat_template_version: 2013-05-23
+
+description: >
+  This template will boot a Kolla cluster with one or more
+  nodes (as specified by the number_of_nodes parameter,
+  which defaults to "1").
+
+parameters:
+  #
+  # REQUIRED PARAMETERS
+  #
+  ssh_key_name:
+    type: string
+    description: name of ssh key to be provisioned on the Nova instances
+
+  external_network_id:
+    type: string
+    description: uuid of a network to use for floating ip addresses
+  #
+  # OPTIONAL PARAMETERS
+  #
+  server_image:
+    type: string
+    default: fedora-21-x86_64
+    description: glance image used to boot the Nova instance
+
+  server_flavor:
+    type: string
+    default: m1.small
+    description: flavor to use when booting the Nova instance
+
+  dns_nameserver:
+    type: string
+    description: address of a dns nameserver reachable in your environment
+    default: 8.8.8.8
+
+  number_of_nodes:
+    type: string
+    description: how many kolla nodes to spawn
+    default: 1
+
+  fixed_network_cidr:
+    type: string
+    description: network range for fixed ip network
+    default: 10.0.0.0/24
+
+resources:
+
+  ######################################################################
+  #
+  # network resources.  allocate a network and router for our server.
+  # it would also be possible to take advantage of existing network
+  # resources (and have the deployer provide network and subnet ids,
+  # etc, as parameters), but I wanted to minmize the amount of
+  # configuration necessary to make this go.
+  fixed_network:
+    type: "OS::Neutron::Net"
+
+  # This is the subnet on which we will deploy our server eth0.
+  fixed_subnet:
+    type: "OS::Neutron::Subnet"
+    properties:
+      cidr: {get_param: fixed_network_cidr}
+      network_id:
+        get_resource: fixed_network
+      dns_nameservers:
+        - get_param: dns_nameserver
+
+  # create a router attached to the external network provided as a
+  # parameter to this stack.
+  extrouter:
+    type: "OS::Neutron::Router"
+    properties:
+      external_gateway_info:
+        network:
+          get_param: external_network_id
+
+  # attached fixed_subnet to our extrouter router.
+  extrouter_inside:
+    type: "OS::Neutron::RouterInterface"
+    properties:
+      router_id:
+        get_resource: extrouter
+      subnet_id:
+        get_resource:
+          fixed_subnet
+
+  kolla_nodes:
+    type: "OS::Heat::ResourceGroup"
+    depends_on:
+      - extrouter_inside
+    properties:
+      count: {get_param: number_of_nodes}
+      resource_def:
+        type: kollanode.yaml
+        properties:
+          ssh_key_name: {get_param: ssh_key_name}
+          server_image: {get_param: server_image}
+          server_flavor: {get_param: server_flavor}
+          fixed_network_id: {get_resource: fixed_network}
+          fixed_subnet_id: {get_resource: fixed_subnet}
+          external_network_id: {get_param: external_network_id}
+outputs:
+
+  kolla_node_internal_ip:
+    value: {get_attr: [kolla_nodes, kolla_node_ip_eth0]}
+
+  kolla_node_external_ip:
+    value: {get_attr: [kolla_nodes, kolla_node_external_ip]}
diff --git a/devenv/kollanet.png b/devenv/kollanet.png
new file mode 100644
index 0000000000000000000000000000000000000000..cfb0c60140b25710a2979f2e3c6a98f41449752e
GIT binary patch
literal 26014
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

literal 0
HcmV?d00001

diff --git a/devenv/kollanode.yaml b/devenv/kollanode.yaml
new file mode 100644
index 0000000000..915c53a012
--- /dev/null
+++ b/devenv/kollanode.yaml
@@ -0,0 +1,199 @@
+heat_template_version: 2013-05-23
+
+description: >
+  This is a nested stack that defines a single Kolla node,
+  based on a Fedora 21 cloud image. This stack is included by
+  a ResourceGroup resource in the parent template (kollacluster.yaml).
+
+parameters:
+
+  server_image:
+    type: string
+    default: fedora-21-x86_64
+    description: glance image used to boot the server
+
+  server_flavor:
+    type: string
+    default: m1.small
+    description: flavor to use when booting the server
+
+  ssh_key_name:
+    type: string
+    description: name of ssh key to be provisioned on our server
+
+  external_network_id:
+    type: string
+    description: uuid of a network to use for kolla host floating ip addresses
+
+  # The following are all generated in the parent template.
+  fixed_network_id:
+    type: string
+    description: Network from which to allocate fixed addresses.
+  fixed_subnet_id:
+    type: string
+    description: Subnet from which to allocate fixed addresses.
+
+resources:
+
+  node_wait_handle:
+    type: "AWS::CloudFormation::WaitConditionHandle"
+
+  node_wait_condition:
+    type: "AWS::CloudFormation::WaitCondition"
+    depends_on:
+      - kolla_node
+    properties:
+      Handle:
+        get_resource: node_wait_handle
+      Timeout: "6000"
+
+  ######################################################################
+  #
+  # security groups.  we need to permit network traffic of various
+  # sorts.
+  #
+  secgroup_base:
+    type: "OS::Neutron::SecurityGroup"
+    properties:
+      rules:
+        - protocol: icmp
+        - protocol: tcp
+          port_range_min: 22
+          port_range_max: 22
+
+  # Use by eth1 to permit all traffic to instances.
+  # Let the Neutron container apply security to this traffic.
+  secgroup_all_open:
+    type: "OS::Neutron::SecurityGroup"
+    properties:
+      rules:
+        - protocol: icmp
+        - protocol: tcp
+        - protocol: udp
+
+  secgroup_kolla:
+    type: "OS::Neutron::SecurityGroup"
+    properties:
+      rules:
+        - protocol: tcp
+          port_range_min: 8773
+          port_range_max: 8776
+        - protocol: tcp
+          port_range_min: 6080
+          port_range_max: 6080
+        - protocol: tcp
+          port_range_min: 6081
+          port_range_max: 6081
+        - protocol: tcp
+          port_range_min: 35357
+          port_range_max: 35357
+        - protocol: tcp
+          port_range_min: 5000
+          port_range_max: 5000
+        - protocol: tcp
+          port_range_min: 9191
+          port_range_max: 9191
+        - protocol: tcp
+          port_range_min: 9292
+          port_range_max: 9292
+        - protocol: tcp
+          port_range_min: 9696
+          port_range_max: 9696
+        - protocol: tcp
+          port_range_min: 80
+          port_range_max: 80
+        - protocol: tcp
+          port_range_min: 443
+          port_range_max: 443
+        - protocol: tcp
+          port_range_min: 8000
+          port_range_max: 8000
+        - protocol: tcp
+          port_range_min: 8004
+          port_range_max: 8004
+        - protocol: tcp
+          port_range_min: 8003
+          port_range_max: 8003
+        - protocol: tcp
+          port_range_min: 8080
+          port_range_max: 8080
+        - protocol: tcp
+          port_range_min: 8777
+          port_range_max: 8777
+
+  kolla_node:
+    type: "OS::Nova::Server"
+    properties:
+      image:
+        get_param: server_image
+      flavor:
+        get_param: server_flavor
+      key_name:
+        get_param: ssh_key_name
+      user_data_format: RAW
+      user_data:
+        str_replace:
+          template: |
+            #!/bin/sh
+
+            yum -y upgrade
+
+            yum -y remove NetworkManager
+            chkconfig network on
+
+            # enable dnf command
+            yum -y install dnf dnf-plugins-core
+
+            # Docker packages
+            dnf -y copr enable pkilambi/docker
+            dnf -y install docker
+
+            # Start Docker
+            systemctl enable docker
+            systemctl start docker
+
+            cfn-signal -e0 --data 'OK' -r 'Setup complete' '$WAIT_HANDLE'
+          params:
+            "$WAIT_HANDLE":
+              get_resource: node_wait_handle
+      networks:
+        - port:
+            get_resource: kolla_node_eth0
+        - port:
+            get_resource: kolla_node_eth1
+
+  kolla_node_eth0:
+    type: "OS::Neutron::Port"
+    properties:
+      network_id:
+        get_param: fixed_network_id
+      security_groups:
+        - get_resource: secgroup_base
+        - get_resource: secgroup_kolla
+      fixed_ips:
+        - subnet_id:
+            get_param: fixed_subnet_id
+
+  kolla_node_eth1:
+    type: "OS::Neutron::Port"
+    properties:
+      network_id:
+        get_param: external_network_id
+      security_groups:
+        - get_resource: secgroup_all_open
+
+  kolla_node_floating:
+    type: "OS::Neutron::FloatingIP"
+    properties:
+      floating_network_id:
+        get_param: external_network_id
+      port_id:
+        get_resource: kolla_node_eth0
+
+outputs:
+
+  kolla_node_ip_eth0:
+    value: {get_attr: [kolla_node_eth0, fixed_ips, 0, ip_address]}
+
+  kolla_node_external_ip:
+    value: {get_attr: [kolla_node_floating, floating_ip_address]}
diff --git a/devenv/local.yaml.example b/devenv/local.yaml.example
new file mode 100644
index 0000000000..b642526e26
--- /dev/null
+++ b/devenv/local.yaml.example
@@ -0,0 +1,3 @@
+parameters:
+  ssh_key_name: <YOUR_NOVA_KEYPAIR>
+  external_network_id: <NEUTRON_EXTERNAL_NET_ID>
-- 
GitLab