config/sysinv/sysinv/sysinv/sysinv/puppet/kubernetes.py
Teresa Ho 949bab37d7 Kubernetes Cluster Network Configuration
The Kubernetes cluster network is introduced and configurable.
The cluster-host interface can be configured on any interface of the
host and is defaulted to the management interface if it is not
specified.
The infrastructure network is no longer used in kubernetes config.
SM and MTCE are setup to monitor the cluster-host if kubernetes is
enabled.
Nova live migration ip is set to use the cluster-host ip.

Tests Performed:
Containerized setup:
AIO-SX: mgmt and cluster-host shared loopback interface
AIO-DX: mgmt and cluster-host shared an interface
AIO-DX: mgmt and cluster-host on different interface
Standard 2+2+2: mgmt and cluster-host shared an interface
Standard 2+2+2: mgmt and cluster-host on different interface
For each of the setup, launch VM and connect to VM console

Non-containerized deployments
AIO-SX sanity
AIO-DX sanity
Standard 2+2 sanity

Story: 2004273
Task: 27826

Change-Id: If6b918665131f01bc62687fbdc7978c5c103e3b7
Signed-off-by: Teresa Ho <teresa.ho@windriver.com>
2019-01-09 12:41:25 -05:00

134 lines
5.2 KiB
Python

#
# Copyright (c) 2018 Wind River Systems, Inc.
#
# SPDX-License-Identifier: Apache-2.0
#
from __future__ import absolute_import
import os
import subprocess
from sysinv.common import constants
from sysinv.common import exception
from sysinv.openstack.common import log as logging
from sysinv.puppet import base
LOG = logging.getLogger(__name__)
class KubernetesPuppet(base.BasePuppet):
"""Class to encapsulate puppet operations for kubernetes configuration"""
ETCD_SERVICE_PORT = '2379'
def get_system_config(self):
config = {}
if self._kubernetes_enabled():
config.update(
{'platform::kubernetes::params::enabled': True,
'platform::kubernetes::params::pod_network_cidr':
self._get_pod_network_cidr(),
'platform::kubernetes::params::service_network_cidr':
self._get_cluster_service_subnet(),
'platform::kubernetes::params::apiserver_advertise_address':
self._get_cluster_host_address(),
'platform::kubernetes::params::etcd_endpoint':
self._get_etcd_endpoint(),
'platform::kubernetes::params::service_domain':
self._get_dns_service_domain(),
'platform::kubernetes::params::dns_service_ip':
self._get_dns_service_ip(),
})
return config
def get_secure_system_config(self):
config = {}
if self._kubernetes_enabled():
# This is retrieving the certificates that 'kubeadm init'
# generated. We will want to change this to generate the
# certificates ourselves, store in hiera and then feed those
# back into 'kubeadm init'.
if os.path.exists('/etc/kubernetes/pki/ca.crt'):
# Store required certificates in configuration.
with open('/etc/kubernetes/pki/ca.crt', 'r') as f:
ca_crt = f.read()
with open('/etc/kubernetes/pki/ca.key', 'r') as f:
ca_key = f.read()
with open('/etc/kubernetes/pki/sa.key', 'r') as f:
sa_key = f.read()
with open('/etc/kubernetes/pki/sa.pub', 'r') as f:
sa_pub = f.read()
config.update(
{'platform::kubernetes::params::ca_crt': ca_crt,
'platform::kubernetes::params::ca_key': ca_key,
'platform::kubernetes::params::sa_key': sa_key,
'platform::kubernetes::params::sa_pub': sa_pub,
})
return config
def get_host_config(self, host):
config = {}
if host.personality != constants.WORKER:
return config
if self._kubernetes_enabled():
create_node = False
try:
# Check if this host has already been configured as a
# kubernetes node.
cmd = ['kubectl',
'--kubeconfig=/etc/kubernetes/admin.conf',
'get', 'node', host.hostname]
subprocess.check_call(cmd)
except subprocess.CalledProcessError:
# The node does not exist
create_node = True
if create_node:
try:
# Generate the token and join command for this host.
cmd = ['kubeadm', 'token', 'create',
'--print-join-command', '--description',
'Bootstrap token for %s' % host.hostname]
join_cmd = subprocess.check_output(cmd)
config.update(
{'platform::kubernetes::worker::params::join_cmd':
join_cmd,
})
except subprocess.CalledProcessError:
raise exception.SysinvException(
'Failed to generate bootstrap token')
return config
def _get_etcd_endpoint(self):
addr = self._format_url_address(self._get_cluster_host_address())
protocol = "http"
url = "%s://%s:%s" % (protocol, str(addr), str(self.ETCD_SERVICE_PORT))
return url
def _get_pod_network_cidr(self):
return self._get_network_config(constants.NETWORK_TYPE_CLUSTER_POD)
def _get_cluster_service_subnet(self):
return self._get_network_config(constants.NETWORK_TYPE_CLUSTER_SERVICE)
def _get_network_config(self, networktype):
try:
network = self.dbapi.network_get_by_type(networktype)
except exception.NetworkTypeNotFound:
# network not configured
return {}
address_pool = self.dbapi.address_pool_get(network.pool_uuid)
subnet = str(address_pool.network) + '/' + str(address_pool.prefix)
return subnet
def _get_dns_service_domain(self):
# Setting this to a constant for now. Will be configurable later
return constants.DEFAULT_DNS_SERVICE_DOMAIN
def _get_dns_service_ip(self):
# Setting this to a constant for now. Will be configurable later
return constants.DEFAULT_DNS_SERVICE_IP