From e0de6af3ecb68e9a80bdb9e666aaecacf7d79753 Mon Sep 17 00:00:00 2001 From: Daneyon Hansen 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 | 218 +++++++++----------------------------- 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, 503 insertions(+), 169 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,157 +51,6 @@ $ 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 -``` -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. - -``` -$ 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. - -``` -$ telnet minion_ip 3306 -``` -This shows that the Mariadb service is running on the minions. 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 -``` - -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. - -``` -$ 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. - Directories =========== @@ -203,3 +58,28 @@ Directories 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. + +Getting Involved +================ + +Need a feature? Find a bug? Let us know! Contributions are much appreciated +and should follow the standard [Gerrit workflow][]. + +- We communicate using the #tripleo irc channel. +- File bugs, blueprints, track releases, etc on [Launchpad][]. +- Attend weekly [meetings][]. +- Contribute [code][] + +[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 + +Contributors +============ + +Check out who's [contributing][]. + +[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 +``` +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 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: + external_network_id: