949bab37d7
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>
134 lines
5.2 KiB
Python
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
|