From b5d05fc9558fff60e19768a4da8ae7903988d434 Mon Sep 17 00:00:00 2001 From: Michal Jura Date: Tue, 2 Aug 2016 14:52:47 +0200 Subject: [PATCH] Add openSUSE driver support to Magnum Change-Id: I3eb83867cca1f4d47b84d31d75d9f8f333af372b Closes-bug: #1600197 --- contrib/drivers/k8s_opensuse_v1/README.md | 19 + contrib/drivers/k8s_opensuse_v1/__init__.py | 0 contrib/drivers/k8s_opensuse_v1/setup.py | 36 ++ .../drivers/k8s_opensuse_v1/template_def.py | 150 +++++ .../drivers/k8s_opensuse_v1/templates/COPYING | 202 +++++++ .../k8s_opensuse_v1/templates/README.md | 143 +++++ .../templates/fragments/configure-docker.sh | 58 ++ .../templates/fragments/configure-etcd.sh | 21 + .../fragments/configure-flanneld-master.sh | 74 +++ .../fragments/configure-flanneld-minion.sh | 25 + .../fragments/configure-kubernetes-master.sh | 55 ++ .../fragments/configure-kubernetes-minion.sh | 50 ++ .../fragments/create-kubernetes-user.yaml | 9 + .../fragments/write-heat-params-master.yaml | 25 + .../fragments/write-heat-params.yaml | 32 ++ .../templates/kubecluster.yaml | 513 ++++++++++++++++++ .../k8s_opensuse_v1/templates/kubemaster.yaml | 280 ++++++++++ .../k8s_opensuse_v1/templates/kubeminion.yaml | 313 +++++++++++ contrib/drivers/k8s_opensuse_v1/version.py | 16 + 19 files changed, 2021 insertions(+) create mode 100644 contrib/drivers/k8s_opensuse_v1/README.md create mode 100644 contrib/drivers/k8s_opensuse_v1/__init__.py create mode 100644 contrib/drivers/k8s_opensuse_v1/setup.py create mode 100644 contrib/drivers/k8s_opensuse_v1/template_def.py create mode 100644 contrib/drivers/k8s_opensuse_v1/templates/COPYING create mode 100644 contrib/drivers/k8s_opensuse_v1/templates/README.md create mode 100644 contrib/drivers/k8s_opensuse_v1/templates/fragments/configure-docker.sh create mode 100644 contrib/drivers/k8s_opensuse_v1/templates/fragments/configure-etcd.sh create mode 100644 contrib/drivers/k8s_opensuse_v1/templates/fragments/configure-flanneld-master.sh create mode 100644 contrib/drivers/k8s_opensuse_v1/templates/fragments/configure-flanneld-minion.sh create mode 100644 contrib/drivers/k8s_opensuse_v1/templates/fragments/configure-kubernetes-master.sh create mode 100644 contrib/drivers/k8s_opensuse_v1/templates/fragments/configure-kubernetes-minion.sh create mode 100644 contrib/drivers/k8s_opensuse_v1/templates/fragments/create-kubernetes-user.yaml create mode 100644 contrib/drivers/k8s_opensuse_v1/templates/fragments/write-heat-params-master.yaml create mode 100644 contrib/drivers/k8s_opensuse_v1/templates/fragments/write-heat-params.yaml create mode 100644 contrib/drivers/k8s_opensuse_v1/templates/kubecluster.yaml create mode 100644 contrib/drivers/k8s_opensuse_v1/templates/kubemaster.yaml create mode 100644 contrib/drivers/k8s_opensuse_v1/templates/kubeminion.yaml create mode 100644 contrib/drivers/k8s_opensuse_v1/version.py diff --git a/contrib/drivers/k8s_opensuse_v1/README.md b/contrib/drivers/k8s_opensuse_v1/README.md new file mode 100644 index 0000000000..0b3b338c28 --- /dev/null +++ b/contrib/drivers/k8s_opensuse_v1/README.md @@ -0,0 +1,19 @@ +# Magnum openSUSE K8s driver + +This is openSUSE Kubernetes driver for Magnum, which allow to deploy Kubernetes cluster on openSUSE. + +## Installation + +### 1. Install the openSUSE K8s driver in Magnum + +- To install the driver, from this directory run: + + `python ./setup.py install` + +### 2. Enable driver in magnum.conf + + enabled_definitions = ...,magnum_vm_opensuse_k8s + +### 2. Restart Magnum + + Both Magnum services has to restarted `magnum-api` and `magnum-conductor` diff --git a/contrib/drivers/k8s_opensuse_v1/__init__.py b/contrib/drivers/k8s_opensuse_v1/__init__.py new file mode 100644 index 0000000000..e69de29bb2 diff --git a/contrib/drivers/k8s_opensuse_v1/setup.py b/contrib/drivers/k8s_opensuse_v1/setup.py new file mode 100644 index 0000000000..284a6f2019 --- /dev/null +++ b/contrib/drivers/k8s_opensuse_v1/setup.py @@ -0,0 +1,36 @@ +#!/usr/bin/env python +# Copyright (c) 2015 Rackspace Inc. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or +# implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +import setuptools + +setuptools.setup( + name="k8s_opensuse_v1", + version="1.0", + packages=['k8s_opensuse_v1'], + package_data={ + 'k8s_opensuse_v1': ['templates/*', 'templates/fragments/*'] + }, + author="Michal Jura", + author_email="mjura@suse.com", + description="Magnum openSUSE Kubernetes driver", + license="Apache", + keywords="magnum opensuse driver", + entry_points={ + 'magnum.template_definitions': [ + 'k8s_opensuse_v1 = k8s_opensuse_v1:JeOSK8sTemplateDefinition' + ] + } +) diff --git a/contrib/drivers/k8s_opensuse_v1/template_def.py b/contrib/drivers/k8s_opensuse_v1/template_def.py new file mode 100644 index 0000000000..015f181037 --- /dev/null +++ b/contrib/drivers/k8s_opensuse_v1/template_def.py @@ -0,0 +1,150 @@ +# Copyright 2016 Rackspace Inc. All rights reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"); you may +# not use this file except in compliance with the License. You may obtain +# a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT +# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the +# License for the specific language governing permissions and limitations +# under the License. + +import os + +from magnum.drivers.common import template_def +from oslo_config import cfg + +CONF = cfg.CONF +KUBE_SECURE_PORT = '6443' +KUBE_INSECURE_PORT = '8080' + + +class K8sApiAddressOutputMapping(template_def.OutputMapping): + + def set_output(self, stack, baymodel, bay): + if self.bay_attr is None: + return + + output_value = self.get_output_value(stack) + if output_value is not None: + # TODO(yuanying): port number is hardcoded, this will be fix + protocol = 'https' + port = KUBE_SECURE_PORT + if baymodel.tls_disabled: + protocol = 'http' + port = KUBE_INSECURE_PORT + + params = { + 'protocol': protocol, + 'address': output_value, + 'port': port, + } + value = "%(protocol)s://%(address)s:%(port)s" % params + setattr(bay, self.bay_attr, value) + + +class K8sTemplateDefinition(template_def.BaseTemplateDefinition): + """Base Kubernetes template.""" + + def __init__(self): + super(K8sTemplateDefinition, self).__init__() + self.add_parameter('master_flavor', + baymodel_attr='master_flavor_id') + self.add_parameter('minion_flavor', + baymodel_attr='flavor_id') + self.add_parameter('number_of_minions', + bay_attr='node_count') + self.add_parameter('external_network', + baymodel_attr='external_network_id', + required=True) + self.add_parameter('network_driver', + baymodel_attr='network_driver') + self.add_parameter('volume_driver', + baymodel_attr='volume_driver') + self.add_parameter('tls_disabled', + baymodel_attr='tls_disabled', + required=True) + self.add_parameter('registry_enabled', + baymodel_attr='registry_enabled') + self.add_parameter('bay_uuid', + bay_attr='uuid', + param_type=str) + self.add_parameter('insecure_registry_url', + baymodel_attr='insecure_registry') + + self.add_output('api_address', + bay_attr='api_address', + mapping_type=K8sApiAddressOutputMapping) + self.add_output('kube_minions_private', + bay_attr=None) + self.add_output('kube_minions', + bay_attr='node_addresses') + self.add_output('kube_masters_private', + bay_attr=None) + self.add_output('kube_masters', + bay_attr='master_addresses') + + def get_params(self, context, baymodel, bay, **kwargs): + extra_params = kwargs.pop('extra_params', {}) + scale_mgr = kwargs.pop('scale_manager', None) + if scale_mgr: + hosts = self.get_output('kube_minions_private') + extra_params['minions_to_remove'] = ( + scale_mgr.get_removal_nodes(hosts)) + + extra_params['discovery_url'] = self.get_discovery_url(bay) + osc = self.get_osc(context) + extra_params['magnum_url'] = osc.magnum_url() + + if baymodel.tls_disabled: + extra_params['loadbalancing_protocol'] = 'HTTP' + extra_params['kubernetes_port'] = 8080 + + label_list = ['flannel_network_cidr', 'flannel_backend', + 'flannel_network_subnetlen'] + for label in label_list: + extra_params[label] = baymodel.labels.get(label) + + if baymodel.registry_enabled: + extra_params['swift_region'] = CONF.docker_registry.swift_region + extra_params['registry_container'] = ( + CONF.docker_registry.swift_registry_container) + + return super(K8sTemplateDefinition, + self).get_params(context, baymodel, bay, + extra_params=extra_params, + **kwargs) + + +class JeOSK8sTemplateDefinition(K8sTemplateDefinition): + """Kubernetes template for openSUSE/SLES JeOS VM.""" + + provides = [ + {'server_type': 'vm', + 'os': 'opensuse', + 'coe': 'kubernetes'}, + ] + + def __init__(self): + super(JeOSK8sTemplateDefinition, self).__init__() + self.add_parameter('docker_volume_size', + baymodel_attr='docker_volume_size') + + def get_params(self, context, baymodel, bay, **kwargs): + extra_params = kwargs.pop('extra_params', {}) + + extra_params['username'] = context.user_name + extra_params['tenant_name'] = context.tenant + + return super(JeOSK8sTemplateDefinition, + self).get_params(context, baymodel, bay, + extra_params=extra_params, + **kwargs) + + @property + def template_path(self): + return os.path.join(os.path.dirname(os.path.realpath(__file__)), + 'templates/kubecluster.yaml') diff --git a/contrib/drivers/k8s_opensuse_v1/templates/COPYING b/contrib/drivers/k8s_opensuse_v1/templates/COPYING new file mode 100644 index 0000000000..d645695673 --- /dev/null +++ b/contrib/drivers/k8s_opensuse_v1/templates/COPYING @@ -0,0 +1,202 @@ + + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + Copyright [yyyy] [name of copyright owner] + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. diff --git a/contrib/drivers/k8s_opensuse_v1/templates/README.md b/contrib/drivers/k8s_opensuse_v1/templates/README.md new file mode 100644 index 0000000000..a9052835e5 --- /dev/null +++ b/contrib/drivers/k8s_opensuse_v1/templates/README.md @@ -0,0 +1,143 @@ +A Kubernetes cluster with Heat +============================== + +These [Heat][] templates will deploy a [Kubernetes][] cluster that +supports automatic scaling based on CPU load. + +[heat]: https://wiki.openstack.org/wiki/Heat +[kubernetes]: https://github.com/GoogleCloudPlatform/kubernetes + +The cluster uses [Flannel][] to provide an overlay network connecting +pods deployed on different minions. + +[flannel]: https://github.com/coreos/flannel + +## Requirements + +### OpenStack + +These templates will work with the Kilo version of Heat. They *may* +work with Juno as well as soon as [#1402894][] is resolved. + +[#1402894]: https://bugs.launchpad.net/heat/+bug/1402894 + +### Guest image + +These templates will work with either CentOS Atomic Host or Fedora 21 +Atomic or OpenSUSE Atomic. + +You can enable docker registry v2 by setting the "registry_enabled" +parameter to "true". + +## Creating the stack + +Creating an environment file `local.yaml` with parameters specific to +your environment: + + parameters: + ssh_key_name: testkey + external_network: public + dns_nameserver: 192.168.200.1 + server_image: openSUSELeap42.1-jeos-k8s + registry_enabled: true + registry_username: username + registry_password: password + registry_domain: domain + registry_trust_id: trust_id + registry_auth_url: auth_url + registry_region: region + registry_container: container + +And then create the stack, referencing that environment file: + + heat stack-create -f kubecluster.yaml -e local.yaml my-kube-cluster + +You must provide values for: + +- `ssh_key_name` +- `server_image` + +If you enable docker registry v2, you must provide values for: + +- `registry_username` +- `registry_password` +- `registry_domain` +- `registry_trust_id` +- `registry_auth_url` +- `registry_region` +- `registry_container + +## Interacting with Kubernetes + +You can get the ip address of the Kubernetes master using the `heat +output-show` command: + + $ heat output-show my-kube-cluster kube_masters + "192.168.200.86" + +You can ssh into that server as the `minion` user: + + $ ssh minion@192.168.200.86 + +And once logged in you can run `kubectl`, etc: + + $ kubectl get minions + NAME LABELS STATUS + 10.0.0.4 Ready + +You can log into your minions using the `minion` user as well. You +can get a list of minion addresses by running: + + $ heat output-show my-kube-cluster kube_minions + [ + "192.168.200.182" + ] + +You can get the docker registry v2 address: + $ heat output-show my-kube-cluster registry_address + localhost:5000 + +## Testing + +The templates install an example Pod and Service description into +`/etc/kubernetes/examples`. You can deploy this with the following +commands: + + $ kubectl create -f /etc/kubernetes/examples/web.service + $ kubectl create -f /etc/kubernetes/examples/web.pod + +This will deploy a minimal webserver and a service. You can use +`kubectl get pods` and `kubectl get services` to see the results of +these commands. + +## License + +Copyright 2014 Lars Kellogg-Stedman + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use these files except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. + +## Contributing + +Please submit bugs and pull requests via the [GitHub repository][] at +https://github.com/larsks/heat-kubernetes/. + +When submitting pull requests: + +- Please ensure that each pull request contains a single commit and + contains only related changes. Put unrelated changes in multiple + pull requests. + +- Please avoid conflating new features with + stylistic/formatting/cleanup changes. + +[github repository]: https://github.com/larsks/heat-kubernetes/ diff --git a/contrib/drivers/k8s_opensuse_v1/templates/fragments/configure-docker.sh b/contrib/drivers/k8s_opensuse_v1/templates/fragments/configure-docker.sh new file mode 100644 index 0000000000..59b72bde95 --- /dev/null +++ b/contrib/drivers/k8s_opensuse_v1/templates/fragments/configure-docker.sh @@ -0,0 +1,58 @@ +#!/bin/sh + +. /etc/sysconfig/heat-params + +echo "stopping docker" +systemctl stop docker +ip link del docker0 + +if [ "$NETWORK_DRIVER" == "flannel" ]; then + FLANNEL_ENV=/run/flannel/subnet.env + + attempts=60 + while [[ ! -f $FLANNEL_ENV && $attempts != 0 ]]; do + echo "waiting for file $FLANNEL_ENV" + sleep 1 + let attempts-- + done + + source $FLANNEL_ENV + + if ! [ "\$FLANNEL_SUBNET" ] && [ "\$FLANNEL_MTU" ] ; then + echo "ERROR: missing required environment variables." >&2 + exit 1 + fi + + sed -i ' + /^DOCKER_OPTS=/ s/=.*/="--storage-driver=btrfs"/ + /^DOCKER_NETWORK_OPTIONS=/ s|=.*|="--bip='"$FLANNEL_SUBNET"' --mtu='"$FLANNEL_MTU"'"| + ' /etc/sysconfig/docker +fi + +DOCKER_DEV=/dev/disk/by-id/virtio-${DOCKER_VOLUME:0:20} + +attempts=60 +while [[ ! -b $DOCKER_DEV && $attempts != 0 ]]; do + echo "waiting for disk $DOCKER_DEV" + sleep 0.5 + udevadm trigger + let attempts-- +done + +if ! [ -b $DOCKER_DEV ]; then + echo "ERROR: device $DOCKER_DEV does not exist" >&2 + exit 1 +fi + +mkfs.btrfs $DOCKER_DEV + +mount $DOCKER_DEV /var/lib/docker + +# make sure we pick up any modified unit files +systemctl daemon-reload + +echo "activating docker service" +systemctl enable docker + +echo "starting docker service" +systemctl --no-block start docker diff --git a/contrib/drivers/k8s_opensuse_v1/templates/fragments/configure-etcd.sh b/contrib/drivers/k8s_opensuse_v1/templates/fragments/configure-etcd.sh new file mode 100644 index 0000000000..4573978590 --- /dev/null +++ b/contrib/drivers/k8s_opensuse_v1/templates/fragments/configure-etcd.sh @@ -0,0 +1,21 @@ +#!/bin/sh + +. /etc/sysconfig/heat-params + +myip="$KUBE_NODE_IP" + +sed -i ' + /ETCD_NAME=/c ETCD_NAME="'$myip'" + /ETCD_DATA_DIR=/c ETCD_DATA_DIR="/var/lib/etcd/default.etcd" + /ETCD_LISTEN_CLIENT_URLS=/c ETCD_LISTEN_CLIENT_URLS="http://0.0.0.0:2379" + /ETCD_LISTEN_PEER_URLS=/c ETCD_LISTEN_PEER_URLS="http://'$myip':2380" + /ETCD_ADVERTISE_CLIENT_URLS=/c ETCD_ADVERTISE_CLIENT_URLS="http://'$myip':2379" + /ETCD_INITIAL_ADVERTISE_PEER_URLS=/c ETCD_INITIAL_ADVERTISE_PEER_URLS="http://'$myip':2380" + /ETCD_DISCOVERY=/c ETCD_DISCOVERY="'$ETCD_DISCOVERY_URL'" +' /etc/sysconfig/etcd + +echo "activating etcd service" +systemctl enable etcd + +echo "starting etcd service" +systemctl --no-block start etcd diff --git a/contrib/drivers/k8s_opensuse_v1/templates/fragments/configure-flanneld-master.sh b/contrib/drivers/k8s_opensuse_v1/templates/fragments/configure-flanneld-master.sh new file mode 100644 index 0000000000..78fb3f124f --- /dev/null +++ b/contrib/drivers/k8s_opensuse_v1/templates/fragments/configure-flanneld-master.sh @@ -0,0 +1,74 @@ +#!/bin/sh + +. /etc/sysconfig/heat-params + +if [ "$NETWORK_DRIVER" == "flannel" ]; then + exit 0 +fi + +FLANNEL_ETCD="http://127.0.0.1:2379" +FLANNEL_JSON=/etc/sysconfig/flannel-network.json +FLANNELD_CONFIG=/etc/sysconfig/flanneld +FLANNEL_NETWORK_CIDR="$FLANNEL_NETWORK_CIDR" +FLANNEL_NETWORK_SUBNETLEN="$FLANNEL_NETWORK_SUBNETLEN" +FLANNEL_USE_VXLAN="$FLANNEL_USE_VXLAN" + +sed -i ' + /^FLANNEL_ETCD=/ s/=.*/="http:\/\/127.0.0.1:2379"/ + /^#FLANNEL_OPTIONS=/ s//FLANNEL_OPTIONS="-iface eth0 --ip-masq"/ +' /etc/sysconfig/flanneld + +cat >> /etc/sysconfig/flanneld < $FLANNEL_JSON <> $FLANNEL_JSON <> $FLANNEL_JSON <> /etc/sysconfig/flanneld <> /etc/kubernetes/apiserver < /etc/sysconfig/kubernetes_openstack_config <> /etc/environment < + This template will boot a Kubernetes cluster with one or more + minions (as specified by the number_of_minions parameter, which + defaults to 1). + +parameters: + + ssh_key_name: + type: string + description: name of ssh key to be provisioned on our server + + external_network: + type: string + description: uuid/name of a network to use for floating ip addresses + default: public + + server_image: + type: string + description: glance image used to boot the server + + master_flavor: + type: string + default: m1.small + description: flavor to use when booting the server + + minion_flavor: + type: string + default: m1.small + description: flavor to use when booting the server + + dns_nameserver: + type: string + description: address of a dns nameserver reachable in your environment + default: 8.8.8.8 + + number_of_masters: + type: number + description: how many kubernetes masters to spawn + default: 1 + + number_of_minions: + type: number + description: how many kubernetes minions to spawn + default: 1 + + fixed_network_cidr: + type: string + description: network range for fixed ip network + default: 10.0.0.0/24 + + portal_network_cidr: + type: string + description: > + address range used by kubernetes for service portals + default: 10.254.0.0/16 + + network_driver: + type: string + description: network driver to use for instantiating container networks + default: flannel + + flannel_network_cidr: + type: string + description: network range for flannel overlay network + default: 10.100.0.0/16 + + flannel_network_subnetlen: + type: string + description: size of subnet assigned to each minion + default: 24 + + flannel_backend: + type: string + description: > + specify the backend for flannel, default udp backend + default: "udp" + constraints: + - allowed_values: ["udp", "vxlan", "host-gw"] + + kube_allow_priv: + type: string + description: > + whether or not kubernetes should permit privileged containers. + default: "true" + constraints: + - allowed_values: ["true", "false"] + + docker_volume_size: + type: number + description: > + size of a cinder volume to allocate to docker for container/image + storage + default: 25 + + wait_condition_timeout: + type: number + description: > + timeout for the Wait Conditions + default: 600 + + minions_to_remove: + type: comma_delimited_list + description: > + List of minions to be removed when doing an update. Individual minion may + be referenced several ways: (1) The resource name (e.g. ['1', '3']), + (2) The private IP address ['10.0.0.4', '10.0.0.6']. Note: the list should + be empty when doing an create. + default: [] + + discovery_url: + type: string + description: > + Discovery URL used for bootstrapping the etcd cluster. + + registry_enabled: + type: boolean + description: > + Indicates whether the docker registry is enabled. + default: false + + registry_port: + type: number + description: port of registry service + default: 5000 + + registry_username: + type: string + description: username used by docker registry + default: "username" + + registry_password: + type: string + description: password used by docker registry + default: "password" + hidden: true + + registry_domain: + type: string + description: domain used by docker registry + default: "domain" + + registry_trust_id: + type: string + description: trust_id used by docker registry + default: "trust_id" + hidden: true + + registry_auth_url: + type: string + description: auth_url for keystone + default: "auth_url" + + registry_region: + type: string + description: region of swift service + default: "region" + + registry_container: + type: string + description: > + name of swift container which docker registry stores images in + default: "container" + + registry_insecure: + type: boolean + description: > + indicates whether to skip TLS verification between registry and backend storage + default: true + + registry_chunksize: + type: number + description: > + size fo the data segments for the swift dynamic large objects + default: 5242880 + + auth_url: + type: string + description: > + url for kubernetes to authenticate before sending request to neutron + must be v2 since kubernetes backend only suppor v2 at this point + + username: + type: string + description: > + user account + + password: + type: string + description: > + user password, not set in current implementation, only used to + fill in for Kubernetes config file + default: + ChangeMe + + tenant_name: + type: string + description: > + tenant name + + loadbalancing_protocol: + type: string + description: > + The protocol which is used for load balancing. If you want to change + tls_disabled option to 'True', please change this to "HTTP". + default: TCP + constraints: + - allowed_values: ["TCP", "HTTP"] + + tls_disabled: + type: boolean + description: whether or not to disable TLS + default: False + + kubernetes_port: + type: number + description: > + The port which are used by kube-apiserver to provide Kubernetes + service. + default: 6443 + + bay_uuid: + type: string + description: identifier for the bay this template is generating + + magnum_url: + type: string + description: endpoint to retrieve TLS certs from + + trustee_domain_id: + type: string + description: domain id of the trustee + default: "" + + trustee_user_id: + type: string + description: user id of the trustee + default: "" + + trustee_username: + type: string + description: username of the trustee + default: "" + + trustee_password: + type: string + description: password of the trustee + default: "" + hidden: true + + trust_id: + type: string + description: id of the trust which is used by the trustee + default: "" + hidden: true + +resources: + + ###################################################################### + # + # network resources. allocate a network and router for our server. + # Important: the Load Balancer feature in Kubernetes requires that + # the name for the fixed_network must be "private" for the + # address lookup in Kubernetes to work properly + # + + fixed_network: + type: OS::Neutron::Net + properties: + name: private + + fixed_subnet: + type: OS::Neutron::Subnet + properties: + cidr: {get_param: fixed_network_cidr} + network: {get_resource: fixed_network} + dns_nameservers: + - {get_param: dns_nameserver} + + extrouter: + type: OS::Neutron::Router + properties: + external_gateway_info: + network: {get_param: external_network} + + extrouter_inside: + type: OS::Neutron::RouterInterface + properties: + router_id: {get_resource: extrouter} + subnet: {get_resource: fixed_subnet} + + ###################################################################### + # + # 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 + + secgroup_kube_master: + type: OS::Neutron::SecurityGroup + properties: + rules: + - protocol: tcp + port_range_min: 7080 + port_range_max: 7080 + - protocol: tcp + port_range_min: 8080 + port_range_max: 8080 + - protocol: tcp + port_range_min: 2379 + port_range_max: 2379 + - protocol: tcp + port_range_min: 2380 + port_range_max: 2380 + - protocol: tcp + port_range_min: 6443 + port_range_max: 6443 + + secgroup_kube_minion: + type: OS::Neutron::SecurityGroup + properties: + rules: + - protocol: icmp + - protocol: tcp + - protocol: udp + + ###################################################################### + # + # load balancers. + # + + api_monitor: + type: OS::Neutron::HealthMonitor + properties: + type: TCP + delay: 5 + max_retries: 5 + timeout: 5 + + api_pool: + type: OS::Neutron::Pool + properties: + protocol: {get_param: loadbalancing_protocol} + monitors: [{get_resource: api_monitor}] + subnet: {get_resource: fixed_subnet} + lb_method: ROUND_ROBIN + vip: + protocol_port: {get_param: kubernetes_port} + + api_pool_floating: + type: OS::Neutron::FloatingIP + depends_on: + - extrouter_inside + properties: + floating_network: {get_param: external_network} + port_id: {get_attr: [api_pool, vip, port_id]} + + etcd_monitor: + type: OS::Neutron::HealthMonitor + properties: + type: TCP + delay: 5 + max_retries: 5 + timeout: 5 + + etcd_pool: + type: OS::Neutron::Pool + properties: + protocol: HTTP + monitors: [{get_resource: etcd_monitor}] + subnet: {get_resource: fixed_subnet} + lb_method: ROUND_ROBIN + vip: + protocol_port: 2379 + + ###################################################################### + # + # kubernetes masters. This is a resource group that will create + # masters. + # + + kube_masters: + type: OS::Heat::ResourceGroup + depends_on: + - extrouter_inside + properties: + count: {get_param: number_of_masters} + resource_def: + type: kubemaster.yaml + properties: + api_public_address: {get_attr: [api_pool_floating, floating_ip_address]} + api_private_address: {get_attr: [api_pool, vip, address]} + ssh_key_name: {get_param: ssh_key_name} + server_image: {get_param: server_image} + master_flavor: {get_param: master_flavor} + external_network: {get_param: external_network} + kube_allow_priv: {get_param: kube_allow_priv} + wait_condition_timeout: {get_param: wait_condition_timeout} + network_driver: {get_param: network_driver} + flannel_backend: {get_param: flannel_backend} + flannel_network_cidr: {get_param: flannel_network_cidr} + flannel_network_subnetlen: {get_param: flannel_network_subnetlen} + portal_network_cidr: {get_param: portal_network_cidr} + discovery_url: {get_param: discovery_url} + bay_uuid: {get_param: bay_uuid} + magnum_url: {get_param: magnum_url} + fixed_network: {get_resource: fixed_network} + fixed_subnet: {get_resource: fixed_subnet} + api_pool_id: {get_resource: api_pool} + etcd_pool_id: {get_resource: etcd_pool} + auth_url: {get_param: auth_url} + username: {get_param: username} + password: {get_param: password} + tenant_name: {get_param: tenant_name} + kubernetes_port: {get_param: kubernetes_port} + tls_disabled: {get_param: tls_disabled} + secgroup_base_id: {get_resource: secgroup_base} + secgroup_kube_master_id: {get_resource: secgroup_kube_master} + + ###################################################################### + # + # kubernetes minions. This is an resource group that will initially + # create minions, and needs to be manually scaled. + # + + kube_minions: + type: OS::Heat::ResourceGroup + depends_on: + - extrouter_inside + - kube_masters + properties: + count: {get_param: number_of_minions} + removal_policies: [{resource_list: {get_param: minions_to_remove}}] + resource_def: + type: kubeminion.yaml + properties: + ssh_key_name: {get_param: ssh_key_name} + server_image: {get_param: server_image} + minion_flavor: {get_param: minion_flavor} + fixed_network: {get_resource: fixed_network} + fixed_subnet: {get_resource: fixed_subnet} + network_driver: {get_param: network_driver} + kube_master_ip: {get_attr: [api_pool, vip, address]} + etcd_server_ip: {get_attr: [etcd_pool, vip, address]} + external_network: {get_param: external_network} + kube_allow_priv: {get_param: kube_allow_priv} + docker_volume_size: {get_param: docker_volume_size} + wait_condition_timeout: {get_param: wait_condition_timeout} + registry_enabled: {get_param: registry_enabled} + registry_port: {get_param: registry_port} + registry_username: {get_param: registry_username} + registry_password: {get_param: registry_password} + registry_domain: {get_param: registry_domain} + registry_trust_id: {get_param: registry_trust_id} + registry_auth_url: {get_param: registry_auth_url} + registry_region: {get_param: registry_region} + registry_container: {get_param: registry_container} + registry_insecure: {get_param: registry_insecure} + registry_chunksize: {get_param: registry_chunksize} + bay_uuid: {get_param: bay_uuid} + magnum_url: {get_param: magnum_url} + kubernetes_port: {get_param: kubernetes_port} + tls_disabled: {get_param: tls_disabled} + secgroup_kube_minion_id: {get_resource: secgroup_kube_minion} + kube_minion_id: 'kube_minion_%index%' + +outputs: + + api_address: + value: + str_replace: + template: api_ip_address + params: + api_ip_address: {get_attr: [api_pool_floating, floating_ip_address]} + description: > + This is the API endpoint of the Kubernetes server. Use this to access + the Kubernetes API from outside the cluster. + + registry_address: + value: + str_replace: + template: localhost:port + params: + port: {get_param: registry_port} + description: + This is the url of docker registry server where you can store docker + images. + + kube_masters: + value: {get_attr: [kube_masters, kube_master_external_ip]} + description: > + This is a list of "public" ip addresses of all Kubernetes master servers. + Use these addresses to log in to the Kubernetes masters via ssh. + + kube_minions: + value: {get_attr: [kube_minions, kube_minion_ip]} + description: > + This is a list of the "private" addresses of all the Kubernetes minions. + + kube_minions_external: + value: {get_attr: [kube_minions, kube_minion_external_ip]} + description: > + This is a list of the "public" addresses of all the Kubernetes minions. Use + these addresses to, e.g., log into the minions. diff --git a/contrib/drivers/k8s_opensuse_v1/templates/kubemaster.yaml b/contrib/drivers/k8s_opensuse_v1/templates/kubemaster.yaml new file mode 100644 index 0000000000..bd2cc42b0b --- /dev/null +++ b/contrib/drivers/k8s_opensuse_v1/templates/kubemaster.yaml @@ -0,0 +1,280 @@ +heat_template_version: 2013-05-23 + +description: > + This is a nested stack that defines a single Kubernetes master, This stack is + included by an ResourceGroup resource in the parent template + (kubecluster.yaml). + +parameters: + + server_image: + type: string + description: glance image used to boot the server + + master_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 + default: lars + + external_network: + type: string + description: uuid/name of a network to use for floating ip addresses + + portal_network_cidr: + type: string + description: > + address range used by kubernetes for service portals + default: 10.254.0.0/16 + + kube_allow_priv: + type: string + description: > + whether or not kubernetes should permit privileged containers. + default: "false" + constraints: + - allowed_values: ["true", "false"] + + flannel_network_cidr: + type: string + description: network range for flannel overlay network + default: 10.100.0.0/16 + + flannel_network_subnetlen: + type: string + description: size of subnet assigned to each master + default: 24 + + flannel_backend: + type: string + description: > + specify the backend for flannel, default udp backend + constraints: + - allowed_values: ["udp", "vxlan", "host-gw"] + + discovery_url: + type: string + description: > + Discovery URL used for bootstrapping the etcd cluster. + + tls_disabled: + type: boolean + description: whether or not to enable TLS + default: False + + kubernetes_port: + type: number + description: > + The port which are used by kube-apiserver to provide Kubernetes + service. + default: 6443 + + bay_uuid: + type: string + description: identifier for the bay this template is generating + + magnum_url: + type: string + description: endpoint to retrieve TLS certs from + + # The following are all generated in the parent template. + api_public_address: + type: string + description: Public IP address of the Kubernetes master server. + api_private_address: + type: string + description: Private IP address of the Kubernetes master server. + fixed_network: + type: string + description: Network from which to allocate fixed addresses. + fixed_subnet: + type: string + description: Subnet from which to allocate fixed addresses. + network_driver: + type: string + description: network driver to use for instantiating container networks + wait_condition_timeout: + type: number + description : > + timeout for the Wait Conditions + secgroup_base_id: + type: string + description: ID of the security group for base. + secgroup_kube_master_id: + type: string + description: ID of the security group for kubernetes master. + api_pool_id: + type: string + description: ID of the load balancer pool of k8s API server. + etcd_pool_id: + type: string + description: ID of the load balancer pool of etcd server. + auth_url: + type: string + description: > + url for kubernetes to authenticate before sending request to neutron + username: + type: string + description: > + user account + password: + type: string + description: > + user password + tenant_name: + type: string + description: > + tenant name + +resources: + + master_wait_handle: + type: OS::Heat::WaitConditionHandle + + master_wait_condition: + type: OS::Heat::WaitCondition + depends_on: kube_master + properties: + handle: {get_resource: master_wait_handle} + timeout: {get_param: wait_condition_timeout} + + ###################################################################### + # + # software configs. these are components that are combined into + # a multipart MIME user-data archive. + # + + write_heat_params: + type: OS::Heat::SoftwareConfig + properties: + group: ungrouped + config: + str_replace: + template: {get_file: fragments/write-heat-params-master.yaml} + params: + "$KUBE_NODE_PUBLIC_IP": {get_attr: [kube_master_floating, floating_ip_address]} + "$KUBE_NODE_IP": {get_attr: [kube_master_eth0, fixed_ips, 0, ip_address]} + "$KUBE_API_PORT": {get_param: kubernetes_port} + "$KUBE_ALLOW_PRIV": {get_param: kube_allow_priv} + "$NETWORK_DRIVER": {get_param: network_driver} + "$FLANNEL_NETWORK_CIDR": {get_param: flannel_network_cidr} + "$FLANNEL_NETWORK_SUBNETLEN": {get_param: flannel_network_subnetlen} + "$FLANNEL_BACKEND": {get_param: flannel_backend} + "$PORTAL_NETWORK_CIDR": {get_param: portal_network_cidr} + "$ETCD_DISCOVERY_URL": {get_param: discovery_url} + "$AUTH_URL": {get_param: auth_url} + "$USERNAME": {get_param: username} + "$PASSWORD": {get_param: password} + "$TENANT_NAME": {get_param: tenant_name} + "$CLUSTER_SUBNET": {get_param: fixed_subnet} + "$TLS_DISABLED": {get_param: tls_disabled} + "$BAY_UUID": {get_param: bay_uuid} + "$MAGNUM_URL": {get_param: magnum_url} + + configure_etcd: + type: OS::Heat::SoftwareConfig + properties: + group: ungrouped + config: {get_file: fragments/configure-etcd.sh} + + configure_flanneld: + type: OS::Heat::SoftwareConfig + properties: + group: ungrouped + config: {get_file: fragments/configure-flanneld-master.sh} + + create_kubernetes_user: + type: OS::Heat::SoftwareConfig + properties: + group: ungrouped + config: {get_file: fragments/create-kubernetes-user.yaml} + + configure_kubernetes: + type: OS::Heat::SoftwareConfig + properties: + group: ungrouped + config: {get_file: fragments/configure-kubernetes-master.sh} + + master_wc_notify: + type: OS::Heat::SoftwareConfig + properties: + group: ungrouped + config: + str_replace: + template: | + #!/bin/bash -v + wc_notify --data-binary '{"status": "SUCCESS"}' + params: + wc_notify: {get_attr: [master_wait_handle, curl_cli]} + + kube_master_init: + type: OS::Heat::MultipartMime + properties: + parts: + - config: {get_resource: write_heat_params} + - config: {get_resource: configure_etcd} + - config: {get_resource: configure_flanneld} + - config: {get_resource: create_kubernetes_user} + - config: {get_resource: configure_kubernetes} + - config: {get_resource: master_wc_notify} + + ###################################################################### + # + # a single kubernetes master. + # + + kube_master: + type: OS::Nova::Server + properties: + name: kube_master + image: {get_param: server_image} + flavor: {get_param: master_flavor} + key_name: {get_param: ssh_key_name} + user_data_format: RAW + user_data: {get_resource: kube_master_init} + config_drive: true + networks: + - port: {get_resource: kube_master_eth0} + + kube_master_eth0: + type: OS::Neutron::Port + properties: + network: {get_param: fixed_network} + security_groups: + - {get_param: secgroup_base_id} + - {get_param: secgroup_kube_master_id} + fixed_ips: + - subnet: {get_param: fixed_subnet} + replacement_policy: AUTO + + kube_master_floating: + type: OS::Neutron::FloatingIP + properties: + floating_network: {get_param: external_network} + port_id: {get_resource: kube_master_eth0} + + api_pool_member: + type: OS::Neutron::PoolMember + properties: + pool_id: {get_param: api_pool_id} + address: {get_attr: [kube_master_eth0, fixed_ips, 0, ip_address]} + protocol_port: {get_param: kubernetes_port} + + etcd_pool_member: + type: OS::Neutron::PoolMember + properties: + pool_id: {get_param: etcd_pool_id} + address: {get_attr: [kube_master_eth0, fixed_ips, 0, ip_address]} + protocol_port: 2379 + +outputs: + + kube_master_ip: + value: {get_attr: [kube_master_eth0, fixed_ips, 0, ip_address]} + + kube_master_external_ip: + value: {get_attr: [kube_master_floating, floating_ip_address]} diff --git a/contrib/drivers/k8s_opensuse_v1/templates/kubeminion.yaml b/contrib/drivers/k8s_opensuse_v1/templates/kubeminion.yaml new file mode 100644 index 0000000000..ae1c5a9a60 --- /dev/null +++ b/contrib/drivers/k8s_opensuse_v1/templates/kubeminion.yaml @@ -0,0 +1,313 @@ +heat_template_version: 2013-05-23 + +description: > + This is a nested stack that defines a single Kubernetes minion, This stack is + included by an AutoScalingGroup resource in the parent template + (kubecluster-jeos.yaml). + +parameters: + + server_image: + type: string + description: glance image used to boot the server + + minion_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 + default: lars + + external_network: + type: string + description: uuid/name of a network to use for floating ip addresses + + kube_allow_priv: + type: string + description: > + whether or not kubernetes should permit privileged containers. + default: "false" + constraints: + - allowed_values: ["true", "false"] + + docker_volume_size: + type: number + description: > + size of a cinder volume to allocate to docker for container/image + storage + default: 25 + + tls_disabled: + type: boolean + description: whether or not to enable TLS + default: False + + kubernetes_port: + type: number + description: > + The port which are used by kube-apiserver to provide Kubernetes + service. + default: 6443 + + bay_uuid: + type: string + description: identifier for the bay this template is generating + + magnum_url: + type: string + description: endpoint to retrieve TLS certs from + + + # The following are all generated in the parent template. + kube_master_ip: + type: string + description: IP address of the Kubernetes master server. + etcd_server_ip: + type: string + description: IP address of the Etcd server. + fixed_network: + type: string + description: Network from which to allocate fixed addresses. + fixed_subnet: + type: string + description: Subnet from which to allocate fixed addresses. + network_driver: + type: string + description: network driver to use for instantiating container networks + wait_condition_timeout: + type: number + description : > + timeout for the Wait Conditions + + registry_enabled: + type: boolean + description: > + Indicates whether the docker registry is enabled. + default: false + + registry_port: + type: number + description: port of registry service + default: 5000 + + registry_username: + type: string + description: username used by docker registry + default: "username" + + registry_password: + type: string + description: password used by docker registry + default: "password" + + registry_domain: + type: string + description: domain used by docker registry + default: "domain" + + registry_trust_id: + type: string + description: trust_id used by docker registry + default: "trust_id" + + registry_auth_url: + type: string + description: auth_url for keystone + default: "auth_url" + + registry_region: + type: string + description: region of swift service + default: "region" + + registry_container: + type: string + description: > + name of swift container which docker registry stores images in + default: "container" + + registry_insecure: + type: boolean + description: > + indicates whether to skip TLS verification between registry and backend storage + default: true + + registry_chunksize: + type: number + description: > + size fo the data segments for the swift dynamic large objects + default: 5242880 + + secgroup_kube_minion_id: + type: string + description: ID of the security group for kubernetes minion. + + kube_minion_id: + type: string + description: ID of for kubernetes minion. + +resources: + + minion_wait_handle: + type: OS::Heat::WaitConditionHandle + + minion_wait_condition: + type: OS::Heat::WaitCondition + depends_on: kube-minion + properties: + handle: {get_resource: minion_wait_handle} + timeout: {get_param: wait_condition_timeout} + + ###################################################################### + # + # software configs. these are components that are combined into + # a multipart MIME user-data archive. + # + + write_heat_params: + type: OS::Heat::SoftwareConfig + properties: + group: ungrouped + config: + str_replace: + template: {get_file: fragments/write-heat-params.yaml} + params: + $KUBE_ALLOW_PRIV: {get_param: kube_allow_priv} + $KUBE_MASTER_IP: {get_param: kube_master_ip} + $KUBE_API_PORT: {get_param: kubernetes_port} + $ETCD_SERVER_IP: {get_param: etcd_server_ip} + $DOCKER_VOLUME: {get_resource: docker_volume} + $NETWORK_DRIVER: {get_param: network_driver} + $REGISTRY_ENABLED: {get_param: registry_enabled} + $REGISTRY_PORT: {get_param: registry_port} + $REGISTRY_AUTH_URL: {get_param: registry_auth_url} + $REGISTRY_REGION: {get_param: registry_region} + $REGISTRY_USERNAME: {get_param: registry_username} + $REGISTRY_PASSWORD: {get_param: registry_password} + $REGISTRY_DOMAIN: {get_param: registry_domain} + $REGISTRY_TRUST_ID: {get_param: registry_trust_id} + $REGISTRY_CONTAINER: {get_param: registry_container} + $REGISTRY_INSECURE: {get_param: registry_insecure} + $REGISTRY_CHUNKSIZE: {get_param: registry_chunksize} + $TLS_DISABLED: {get_param: tls_disabled} + $BAY_UUID: {get_param: bay_uuid} + $MAGNUM_URL: {get_param: magnum_url} + $NODE_FIXED_IP: {get_attr: [kube_minion_eth0, fixed_ips, 0, ip_address]} + + configure_flanneld: + type: OS::Heat::SoftwareConfig + properties: + group: ungrouped + config: {get_file: fragments/configure-flanneld-minion.sh} + + configure_docker: + type: OS::Heat::SoftwareConfig + properties: + group: ungrouped + config: {get_file: fragments/configure-docker.sh} + + create_kubernetes_user: + type: OS::Heat::SoftwareConfig + properties: + group: ungrouped + config: {get_file: fragments/create-kubernetes-user.yaml} + + configure_kubernetes: + type: OS::Heat::SoftwareConfig + properties: + group: ungrouped + config: {get_file: fragments/configure-kubernetes-minion.sh} + + minion_wc_notify: + type: OS::Heat::SoftwareConfig + properties: + group: ungrouped + config: + str_replace: + template: | + #!/bin/bash -v + wc_notify --data-binary '{"status": "SUCCESS"}' + params: + wc_notify: {get_attr: [minion_wait_handle, curl_cli]} + + kube_minion_init: + type: OS::Heat::MultipartMime + properties: + parts: + - config: {get_resource: write_heat_params} + - config: {get_resource: configure_flanneld} + - config: {get_resource: configure_docker} + - config: {get_resource: create_kubernetes_user} + - config: {get_resource: configure_kubernetes} + - config: {get_resource: minion_wc_notify} + + ###################################################################### + # + # a single kubernetes minion. + # Important: the name for the heat resource kube-minion below must + # not contain "_" (underscore) because it will be used in the + # hostname. Because DNS domain name does not allow "_", the "_" + # will be converted to a "-" and this will make the hostname different + # from the Nova instance name. This in turn will break the load + # balancer feature in Kubernetes. + # + + kube-minion: + type: OS::Nova::Server + properties: + name: {get_param: kube_minion_id} + image: {get_param: server_image} + flavor: {get_param: minion_flavor} + key_name: {get_param: ssh_key_name} + user_data_format: RAW + user_data: {get_resource: kube_minion_init} + networks: + - port: {get_resource: kube_minion_eth0} + + kube_minion_eth0: + type: OS::Neutron::Port + properties: + network: {get_param: fixed_network} + security_groups: + - get_param: secgroup_kube_minion_id + fixed_ips: + - subnet: {get_param: fixed_subnet} + replacement_policy: AUTO + + kube_minion_floating: + type: OS::Neutron::FloatingIP + properties: + floating_network: {get_param: external_network} + port_id: {get_resource: kube_minion_eth0} + + ###################################################################### + # + # docker storage. This allocates a cinder volume and attaches it + # to the minion. + # + + docker_volume: + type: OS::Cinder::Volume + properties: + size: {get_param: docker_volume_size} + + docker_volume_attach: + type: OS::Cinder::VolumeAttachment + properties: + instance_uuid: {get_resource: kube-minion} + volume_id: {get_resource: docker_volume} + mountpoint: /dev/vdb + +outputs: + + kube_minion_ip: + value: {get_attr: [kube_minion_eth0, fixed_ips, 0, ip_address]} + + kube_minion_external_ip: + value: {get_attr: [kube_minion_floating, floating_ip_address]} + + OS::stack_id: + value: {get_attr: [kube_minion_eth0, fixed_ips, 0, ip_address]} diff --git a/contrib/drivers/k8s_opensuse_v1/version.py b/contrib/drivers/k8s_opensuse_v1/version.py new file mode 100644 index 0000000000..9e70713250 --- /dev/null +++ b/contrib/drivers/k8s_opensuse_v1/version.py @@ -0,0 +1,16 @@ +# Copyright 2016 - Rackspace Hosting +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +version = '1.0.0' +driver = 'k8s_opensuse'