Implement a Heat k8s template for Ironic

Ironic instance doesn't create using "OS::Neutron::Port".
So we should modify this template to below order.

1. Create master vm (and assign fixed ip on given private network)
2. Create minion vm (and assign fixed ip on given private network)
3. Configure minion vm (with master address)
4. Configure master vm (with minion address)

This uses "SoftwareDeployment" to handle dependency.

And there is some limitations derived from ironic:

- Security group doesn't set.
- Disable cinder volume for docker storage.
- Require private network name parameter which provides baremetal network.
- Disable default user `minion` at master.

Implements: blueprint ironic-heat-template

Change-Id: Ia661c6ed08887a6a6961fb0ba5d34f2278794658
This commit is contained in:
OTSUKA, Yuanying 2015-02-10 21:04:39 +09:00
parent 699c1b146f
commit 6d02ff33e8
7 changed files with 448 additions and 0 deletions

View File

@ -0,0 +1,29 @@
Kubernetes elements
===================
This directory contains `[diskimage-builder](https://github.com/openstack/diskimage-builder)`
elements to build an image which contains kubernetes required to use kubecluster-fedora-ironic.yaml.
An example fedora based image and uploaded to glance with the following:
git clone https://git.openstack.org/stackforge/magnum
git clone https://git.openstack.org/openstack/diskimage-builder.git
git clone https://git.openstack.org/openstack/tripleo-image-elements.git
git clone https://git.openstack.org/openstack/heat-templates.git
git clone https://git.openstack.org/openstack/dib-utils.git
export PATH="${PWD}/dib-utils/bin:$PATH"
export ELEMENTS_PATH=tripleo-image-elements/elements:heat-templates/hot/software-config/elements
export ELEMENTS_PATH=${ELEMENTS_PATH}:magnum/etc/magnum/templates/heat-kubernetes/elements
export DIB_RELEASE=21
diskimage-builder/bin/disk-image-create baremetal \
fedora selinux-permissive \
os-collect-config \
os-refresh-config \
os-apply-config \
heat-config-script \
kubernetes \
-o fedora-21-kubernetes.qcow2
KERNEL_ID=`glance image-create --name fedora-k8s-kernel --is-public True --disk-format=aki --container-format=aki --file=fedora-21-kubernetes.vmlinuz | grep id | tr -d '| ' | cut --bytes=3-57`
RAMDISK_ID=`glance image-create --name fedora-k8s-ramdisk --is-public True --disk-format=ari --container-format=ari --file=fedora-21-kubernetes.initrd | grep id | tr -d '| ' | cut --bytes=3-57`
BASE_ID=`glance image-create --name fedora-k8s --is-public True --disk-format=qcow2 --container-format=bare --property kernel_id=$KERNEL_ID --property ramdisk_id=$RAMDISK_ID --file=fedora-21-kubernetes.qcow2 | grep -v kernel | grep -v ramdisk | grep id | tr -d '| ' | cut --bytes=3-57`

View File

@ -0,0 +1 @@
package-installs

View File

@ -0,0 +1,4 @@
kubernetes:
etcd:
flannel:
docker-io:

View File

@ -0,0 +1,6 @@
#!/bin/sh
echo starting etcd
systemctl enable etcd
systemctl --no-block start etcd

View File

@ -0,0 +1,10 @@
#!/bin/sh
cat << _EOT_ > /etc/sysconfig/heat-params
MINION_ADDRESSES="$MINION_ADDRESSES"
KUBE_ALLOW_PRIV="$KUBE_ALLOW_PRIV"
FLANNEL_NETWORK_CIDR="$FLANNEL_NETWORK_CIDR"
FLANNEL_NETWORK_SUBNETLEN="$FLANNEL_NETWORK_SUBNETLEN"
FLANNEL_USE_VXLAN="$FLANNEL_USE_VXLAN"
PORTAL_NETWORK_CIDR="$PORTAL_NETWORK_CIDR"
_EOT_

View File

@ -0,0 +1,230 @@
heat_template_version: 2013-05-23
description: >
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:
#
# REQUIRED PARAMETERS
#
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 floating ip addresses
fixed_network:
type: string
description: name of private network into which servers get deployed
#
# OPTIONAL PARAMETERS
#
server_image:
type: string
default: fedora-k8s
description: glance image used to boot the server
server_flavor:
type: string
default: baremetal
description: flavor to use when booting the server
number_of_minions:
type: string
description: how many kubernetes minions to spawn
default: 1
portal_network_cidr:
type: string
description: >
address range used by kubernetes for service portals
default: "10.254.0.0/16"
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_use_vxlan:
type: string
description: >
if true use the vxlan backend, otherwise use the default
udp backend
default: "false"
constraints:
- allowed_values: ["true", "false"]
kube_allow_priv:
type: string
description: >
whether or not kubernetes should permit privileged containers.
default: "true"
constraints:
- allowed_values: ["true", "false"]
resources:
######################################################################
#
# software configs and deployments.
#
disable_selinux:
type: "OS::Heat::SoftwareConfig"
properties:
group: script
config: {get_file: fragments/disable-selinux.sh}
disable_selinux_deployment:
type: OS::Heat::SoftwareDeployment
properties:
config:
get_resource: disable_selinux
server:
get_resource: kube_master
write_heat_params:
type: "OS::Heat::SoftwareConfig"
properties:
group: script
config:
str_replace:
template: {get_file: fragments/write-heat-params-master.sh}
params:
"$MINION_ADDRESSES": {"Fn::Join": [",", {get_attr: [kube_minions, kube_node_ip]}]}
"$KUBE_ALLOW_PRIV": {get_param: kube_allow_priv}
"$FLANNEL_NETWORK_CIDR": {get_param: flannel_network_cidr}
"$FLANNEL_NETWORK_SUBNETLEN": {get_param: flannel_network_subnetlen}
"$FLANNEL_USE_VXLAN": {get_param: flannel_use_vxlan}
"$PORTAL_NETWORK_CIDR": {get_param: portal_network_cidr}
write_heat_params_deployment:
type: OS::Heat::SoftwareDeployment
depends_on: disable_selinux_deployment
properties:
config:
get_resource: write_heat_params
server:
get_resource: kube_master
configure_kubernetes:
type: "OS::Heat::SoftwareConfig"
properties:
group: script
config: {get_file: fragments/configure-kubernetes-master.sh}
configure_kubernetes_deployment:
type: OS::Heat::SoftwareDeployment
depends_on: write_heat_params_deployment
properties:
config:
get_resource: configure_kubernetes
server:
get_resource: kube_master
enable_etcd:
type: "OS::Heat::SoftwareConfig"
properties:
group: script
config: {get_file: fragments/enable-etcd.sh}
enable_etcd_deployment:
type: OS::Heat::SoftwareDeployment
depends_on: configure_kubernetes_deployment
properties:
config:
get_resource: enable_etcd
server:
get_resource: kube_master
configure_flannel:
type: "OS::Heat::SoftwareConfig"
properties:
group: script
config: {get_file: fragments/configure-flannel.sh}
configure_flannel_deployment:
type: OS::Heat::SoftwareDeployment
depends_on: enable_etcd_deployment
properties:
config:
get_resource: configure_flannel
server:
get_resource: kube_master
enable_services:
type: "OS::Heat::SoftwareConfig"
properties:
group: script
config: {get_file: fragments/enable-services-master.sh}
enable_services_deployment:
type: OS::Heat::SoftwareDeployment
depends_on: configure_flannel_deployment
properties:
config:
get_resource: enable_services
server:
get_resource: kube_master
######################################################################
#
# databases server. this sets up a Kubernetes server
#
kube_master_floating:
type: "OS::Neutron::FloatingIP"
properties:
floating_network_id:
get_param: external_network_id
port_id:
get_attr: [kube_master, addresses, {get_param: fixed_network}, 0, port]
kube_master:
type: "OS::Nova::Server"
properties:
image:
get_param: server_image
flavor:
get_param: server_flavor
key_name:
get_param: ssh_key_name
networks:
- network: {get_param: fixed_network}
user_data_format: SOFTWARE_CONFIG
kube_minions:
type: "OS::Heat::ResourceGroup"
depends_on: kube_master
properties:
count: {get_param: number_of_minions}
resource_def:
type: kubenode-fedora-ironic.yaml
properties:
ssh_key_name: {get_param: ssh_key_name}
server_image: {get_param: server_image}
server_flavor: {get_param: server_flavor}
fixed_network: {get_param: fixed_network}
kube_master_ip: {get_attr: [kube_master, networks, {get_param: fixed_network}, 0]}
external_network_id: {get_param: external_network_id}
kube_allow_priv: {get_param: kube_allow_priv}
outputs:
kube_master:
value: {get_attr: [kube_master_floating, floating_ip_address]}
kube_minions:
value: {get_attr: [kube_minions, kube_node_ip]}
kube_minions_external:
value: {get_attr: [kube_minions, kube_node_external_ip]}

View File

@ -0,0 +1,168 @@
heat_template_version: 2013-05-23
description: >
This is a nested stack that defines a single Kubernetes minion,
based on a vanilla Fedora 20 cloud image. This stack is included by
a ResourceGroup resource in the parent template (kubecluster.yaml).
parameters:
server_image:
type: string
default: centos-7-atomic-20150120
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
default: lars
external_network_id:
type: string
description: uuid 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"]
# The following are all generated in the parent template.
kube_master_ip:
type: string
description: IP address of the Kubernetes master server.
fixed_network:
type: string
description: Network from which to allocate fixed addresses.
resources:
node_wait_handle:
type: "AWS::CloudFormation::WaitConditionHandle"
node_wait_condition:
type: "AWS::CloudFormation::WaitCondition"
depends_on:
- kube_node
properties:
Handle:
get_resource: node_wait_handle
Timeout: "6000"
######################################################################
#
# 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}
"$WAIT_HANDLE": {get_resource: node_wait_handle}
add_to_docker_group:
type: "OS::Heat::SoftwareConfig"
properties:
group: ungrouped
config: {get_file: fragments/add-to-docker-group.sh}
configure_kubernetes_minion:
type: "OS::Heat::SoftwareConfig"
properties:
group: ungrouped
config: {get_file: fragments/configure-kubernetes-minion.sh}
kube_user:
type: "OS::Heat::SoftwareConfig"
properties:
group: ungrouped
config: {get_file: fragments/kube-user.yaml}
kube_examples:
type: "OS::Heat::SoftwareConfig"
properties:
group: ungrouped
config: {get_file: fragments/kube-examples.yaml}
docker_service:
type: "OS::Heat::SoftwareConfig"
properties:
group: ungrouped
config: {get_file: fragments/docker.service.yaml}
enable_services:
type: "OS::Heat::SoftwareConfig"
properties:
group: ungrouped
config: {get_file: fragments/enable-services-minion.sh}
cfn_signal:
type: "OS::Heat::SoftwareConfig"
properties:
group: ungrouped
config: {get_file: fragments/cfn-signal.sh}
disable_selinux:
type: "OS::Heat::SoftwareConfig"
properties:
group: ungrouped
config: {get_file: fragments/disable-selinux.sh}
kube_node_init:
type: "OS::Heat::MultipartMime"
properties:
parts:
- config: {get_resource: disable_selinux}
- config: {get_resource: write_heat_params}
- config: {get_resource: kube_user}
- config: {get_resource: kube_examples}
- config: {get_resource: add_to_docker_group}
- config: {get_resource: configure_kubernetes_minion}
- config: {get_resource: docker_service}
- config: {get_resource: enable_services}
- config: {get_resource: cfn_signal}
kube_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: {get_resource: kube_node_init}
networks:
- network: {get_param: fixed_network}
kube_node_floating:
type: "OS::Neutron::FloatingIP"
properties:
floating_network_id:
get_param: external_network_id
port_id:
get_attr: [kube_node, addresses, {get_param: fixed_network}, 0, port]
outputs:
kube_node_ip:
value: {get_attr: [kube_node, networks, private, 0]}
kube_node_external_ip:
value: {get_attr: [kube_node_floating, floating_ip_address]}