mirror of https://github.com/apache/cloudstack.git
Address review comments: plan CKS cluster deployment based on the node type
This commit is contained in:
parent
89effc7eda
commit
36a02b81d0
|
|
@ -1037,7 +1037,8 @@ public class KubernetesClusterManagerImpl extends ManagerBase implements Kuberne
|
|||
Long serviceOfferingId = map.getOrDefault(key, defaultServiceOfferingId);
|
||||
ServiceOffering serviceOffering = serviceOfferingId != null ? serviceOfferingDao.findById(serviceOfferingId) : null;
|
||||
if (serviceOffering == null) {
|
||||
throw new InvalidParameterValueException("No service offering found with ID: " + serviceOfferingId);
|
||||
throw new InvalidParameterValueException("When serviceofferingid is not specified, " +
|
||||
"service offerings for each node type must be specified in the nodeofferings parameter.");
|
||||
}
|
||||
try {
|
||||
validateServiceOffering(serviceOffering, clusterKubernetesVersion);
|
||||
|
|
@ -1294,7 +1295,7 @@ public class KubernetesClusterManagerImpl extends ManagerBase implements Kuberne
|
|||
|
||||
protected boolean isAnyNodeOfferingEmpty(Map<String, Long> map) {
|
||||
if (MapUtils.isEmpty(map)) {
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
return map.values().stream().anyMatch(Objects::isNull);
|
||||
}
|
||||
|
|
@ -1479,13 +1480,12 @@ public class KubernetesClusterManagerImpl extends ManagerBase implements Kuberne
|
|||
final KubernetesClusterVO cluster = Transaction.execute(new TransactionCallback<KubernetesClusterVO>() {
|
||||
@Override
|
||||
public KubernetesClusterVO doInTransaction(TransactionStatus status) {
|
||||
final ServiceOffering defaultServiceOffering = serviceOfferingDao.findById(defaultServiceOfferingId);
|
||||
Pair<Long, Long> capacityPair = calculateClusterCapacity(serviceOfferingNodeTypeMap, nodeTypeCount, defaultServiceOfferingId);
|
||||
final long cores = capacityPair.first();
|
||||
final long memory = capacityPair.second();
|
||||
|
||||
KubernetesClusterVO newCluster = new KubernetesClusterVO(cmd.getName(), cmd.getDisplayName(), zone.getId(), clusterKubernetesVersion.getId(),
|
||||
defaultServiceOffering.getId(), Objects.nonNull(finalTemplate) ? finalTemplate.getId() : null,
|
||||
defaultServiceOfferingId, Objects.nonNull(finalTemplate) ? finalTemplate.getId() : null,
|
||||
defaultNetwork.getId(), owner.getDomainId(), owner.getAccountId(), controlNodeCount, clusterSize,
|
||||
KubernetesCluster.State.Created, cmd.getSSHKeyPairName(), cores, memory,
|
||||
cmd.getNodeRootDiskSize(), "", KubernetesCluster.ClusterType.CloudManaged);
|
||||
|
|
|
|||
|
|
@ -128,6 +128,10 @@ import com.cloud.vm.VmDetailConstants;
|
|||
import com.cloud.vm.dao.UserVmDao;
|
||||
import com.cloud.vm.dao.UserVmDetailsDao;
|
||||
|
||||
import static com.cloud.kubernetes.cluster.KubernetesServiceHelper.KubernetesClusterNodeType.CONTROL;
|
||||
import static com.cloud.kubernetes.cluster.KubernetesServiceHelper.KubernetesClusterNodeType.ETCD;
|
||||
import static com.cloud.kubernetes.cluster.KubernetesServiceHelper.KubernetesClusterNodeType.WORKER;
|
||||
|
||||
|
||||
public class KubernetesClusterActionWorker {
|
||||
|
||||
|
|
@ -144,6 +148,8 @@ public class KubernetesClusterActionWorker {
|
|||
|
||||
protected Logger logger = LogManager.getLogger(getClass());
|
||||
|
||||
protected final static List<KubernetesClusterNodeType> CLUSTER_NODES_TYPES_LIST = Arrays.asList(WORKER, CONTROL, ETCD);
|
||||
|
||||
protected StateMachine2<KubernetesCluster.State, KubernetesCluster.Event, KubernetesCluster> _stateMachine = KubernetesCluster.State.getStateMachine();
|
||||
|
||||
@Inject
|
||||
|
|
|
|||
|
|
@ -259,13 +259,35 @@ public class KubernetesClusterResourceModifierActionWorker extends KubernetesClu
|
|||
throw new InsufficientServerCapacityException(msg, DataCenter.class, zone.getId());
|
||||
}
|
||||
|
||||
protected DeployDestination plan(Long domainId, Long accountId, Hypervisor.HypervisorType hypervisorType) throws InsufficientServerCapacityException {
|
||||
ServiceOffering offering = serviceOfferingDao.findById(kubernetesCluster.getServiceOfferingId());
|
||||
/**
|
||||
* Plan Kubernetes Cluster Deployment
|
||||
* @return a map of DeployDestination per node type
|
||||
*/
|
||||
protected Map<String, DeployDestination> planKubernetesCluster(Long domainId, Long accountId, Hypervisor.HypervisorType hypervisorType) throws InsufficientServerCapacityException {
|
||||
Map<String, DeployDestination> destinationMap = new HashMap<>();
|
||||
DataCenter zone = dataCenterDao.findById(kubernetesCluster.getZoneId());
|
||||
if (logger.isDebugEnabled()) {
|
||||
logger.debug(String.format("Checking deployment destination for Kubernetes cluster : %s in zone : %s", kubernetesCluster.getName(), zone.getName()));
|
||||
}
|
||||
return plan(kubernetesCluster.getTotalNodeCount(), zone, offering, domainId, accountId, hypervisorType);
|
||||
long controlNodeCount = kubernetesCluster.getControlNodeCount();
|
||||
long clusterSize = kubernetesCluster.getNodeCount();
|
||||
long etcdNodes = kubernetesCluster.getEtcdNodeCount();
|
||||
Map<String, Long> nodeTypeCount = Map.of(WORKER.name(), clusterSize,
|
||||
CONTROL.name(), controlNodeCount, ETCD.name(), etcdNodes);
|
||||
|
||||
for (KubernetesClusterNodeType nodeType : CLUSTER_NODES_TYPES_LIST) {
|
||||
Long nodes = nodeTypeCount.getOrDefault(nodeType.name(), kubernetesCluster.getServiceOfferingId());
|
||||
if (nodes == null || nodes == 0) {
|
||||
continue;
|
||||
}
|
||||
ServiceOffering nodeOffering = getServiceOfferingForNodeTypeOnCluster(nodeType, kubernetesCluster);
|
||||
if (logger.isDebugEnabled()) {
|
||||
logger.debug(String.format("Checking deployment destination for %s nodes on Kubernetes cluster : %s in zone : %s", nodeType.name(), kubernetesCluster.getName(), zone.getName()));
|
||||
}
|
||||
DeployDestination planForNodeType = plan(nodes, zone, nodeOffering, domainId, accountId, hypervisorType);
|
||||
destinationMap.put(nodeType.name(), planForNodeType);
|
||||
}
|
||||
return destinationMap;
|
||||
}
|
||||
|
||||
protected void resizeNodeVolume(final UserVm vm) throws ManagementServerException {
|
||||
|
|
@ -288,7 +310,7 @@ public class KubernetesClusterResourceModifierActionWorker extends KubernetesClu
|
|||
}
|
||||
}
|
||||
|
||||
protected void startKubernetesVM(final UserVm vm, final Long domainId, final Long accountId) throws ManagementServerException {
|
||||
protected void startKubernetesVM(final UserVm vm, final Long domainId, final Long accountId, KubernetesClusterNodeType nodeType) throws ManagementServerException {
|
||||
CallContext vmContext = null;
|
||||
if (!ApiCommandResourceType.VirtualMachine.equals(CallContext.current().getEventResourceType())); {
|
||||
vmContext = CallContext.register(CallContext.current(), ApiCommandResourceType.VirtualMachine);
|
||||
|
|
@ -298,7 +320,8 @@ public class KubernetesClusterResourceModifierActionWorker extends KubernetesClu
|
|||
if (Objects.nonNull(domainId) && !listDedicatedHostsInDomain(domainId).isEmpty()) {
|
||||
DeployDestination dest = null;
|
||||
try {
|
||||
dest = plan(domainId, accountId, vm.getHypervisorType());
|
||||
Map<String, DeployDestination> destinationMap = planKubernetesCluster(domainId, accountId, vm.getHypervisorType());
|
||||
dest = destinationMap.get(nodeType.name());
|
||||
} catch (InsufficientCapacityException e) {
|
||||
logTransitStateAndThrow(Level.ERROR, String.format("Provisioning the cluster failed due to insufficient capacity in the Kubernetes cluster: %s", kubernetesCluster.getUuid()), kubernetesCluster.getId(), KubernetesCluster.Event.CreateFailed, e);
|
||||
}
|
||||
|
|
@ -341,7 +364,7 @@ public class KubernetesClusterResourceModifierActionWorker extends KubernetesClu
|
|||
if (kubernetesCluster.getNodeRootDiskSize() > 0) {
|
||||
resizeNodeVolume(vm);
|
||||
}
|
||||
startKubernetesVM(vm, domainId, accountId);
|
||||
startKubernetesVM(vm, domainId, accountId, WORKER);
|
||||
vm = userVmDao.findById(vm.getId());
|
||||
if (vm == null) {
|
||||
throw new ManagementServerException(String.format("Failed to provision worker VM for Kubernetes cluster : %s", kubernetesCluster.getName()));
|
||||
|
|
|
|||
|
|
@ -34,6 +34,7 @@ import java.util.stream.Collectors;
|
|||
import com.cloud.exception.InvalidParameterValueException;
|
||||
import com.cloud.exception.NetworkRuleConflictException;
|
||||
import com.cloud.exception.PermissionDeniedException;
|
||||
import com.cloud.kubernetes.cluster.KubernetesServiceHelper;
|
||||
import com.cloud.network.vpc.NetworkACL;
|
||||
import com.cloud.storage.VMTemplateVO;
|
||||
import com.cloud.user.UserDataVO;
|
||||
|
|
@ -85,6 +86,7 @@ import org.apache.logging.log4j.Level;
|
|||
|
||||
import static com.cloud.kubernetes.cluster.KubernetesServiceHelper.KubernetesClusterNodeType.CONTROL;
|
||||
import static com.cloud.kubernetes.cluster.KubernetesServiceHelper.KubernetesClusterNodeType.ETCD;
|
||||
import static com.cloud.kubernetes.cluster.KubernetesServiceHelper.KubernetesClusterNodeType.WORKER;
|
||||
|
||||
public class KubernetesClusterStartWorker extends KubernetesClusterResourceModifierActionWorker {
|
||||
|
||||
|
|
@ -515,7 +517,7 @@ public class KubernetesClusterStartWorker extends KubernetesClusterResourceModif
|
|||
if (kubernetesCluster.getNodeRootDiskSize() > 0) {
|
||||
resizeNodeVolume(k8sControlVM);
|
||||
}
|
||||
startKubernetesVM(k8sControlVM, domainId, accountId);
|
||||
startKubernetesVM(k8sControlVM, domainId, accountId, CONTROL);
|
||||
k8sControlVM = userVmDao.findById(k8sControlVM.getId());
|
||||
if (k8sControlVM == null) {
|
||||
throw new ManagementServerException(String.format("Failed to provision control VM for Kubernetes cluster : %s" , kubernetesCluster.getName()));
|
||||
|
|
@ -538,7 +540,7 @@ public class KubernetesClusterStartWorker extends KubernetesClusterResourceModif
|
|||
if (kubernetesCluster.getNodeRootDiskSize() > 0) {
|
||||
resizeNodeVolume(vm);
|
||||
}
|
||||
startKubernetesVM(vm, domainId, accountId);
|
||||
startKubernetesVM(vm, domainId, accountId, CONTROL);
|
||||
vm = userVmDao.findById(vm.getId());
|
||||
if (vm == null) {
|
||||
throw new ManagementServerException(String.format("Failed to provision additional control VM for Kubernetes cluster : %s" , kubernetesCluster.getName()));
|
||||
|
|
@ -560,7 +562,7 @@ public class KubernetesClusterStartWorker extends KubernetesClusterResourceModif
|
|||
for (int i = 0; i < kubernetesCluster.getEtcdNodeCount(); i++) {
|
||||
UserVm vm = createEtcdNode(etcdNodeGuestIps, etcdHostnames, i, domainId, accountId);
|
||||
addKubernetesClusterVm(kubernetesCluster.getId(), vm.getId(), false, false, true, true);
|
||||
startKubernetesVM(vm, domainId, accountId);
|
||||
startKubernetesVM(vm, domainId, accountId, ETCD);
|
||||
vm = userVmDao.findById(vm.getId());
|
||||
if (vm == null) {
|
||||
throw new ManagementServerException(String.format("Failed to provision additional control VM for Kubernetes cluster : %s" , kubernetesCluster.getName()));
|
||||
|
|
@ -669,7 +671,9 @@ public class KubernetesClusterStartWorker extends KubernetesClusterResourceModif
|
|||
}
|
||||
try {
|
||||
resizeNodeVolume(vm);
|
||||
startKubernetesVM(vm, domainId, accountId);
|
||||
KubernetesClusterVmMapVO map = kubernetesClusterVmMapDao.findByVmId(vm.getId());
|
||||
KubernetesServiceHelper.KubernetesClusterNodeType nodeType = getNodeTypeFromClusterVMMapRecord(map);
|
||||
startKubernetesVM(vm, domainId, accountId, nodeType);
|
||||
} catch (ManagementServerException ex) {
|
||||
logger.warn(String.format("Failed to start VM : %s in Kubernetes cluster : %s due to ", vm.getDisplayName(), kubernetesCluster.getName()) + ex);
|
||||
// don't bail out here. proceed further to stop the reset of the VM's
|
||||
|
|
@ -683,6 +687,16 @@ public class KubernetesClusterStartWorker extends KubernetesClusterResourceModif
|
|||
}
|
||||
}
|
||||
|
||||
private KubernetesServiceHelper.KubernetesClusterNodeType getNodeTypeFromClusterVMMapRecord(KubernetesClusterVmMapVO map) {
|
||||
if (map.isControlNode()) {
|
||||
return CONTROL;
|
||||
} else if (map.isEtcdNode()) {
|
||||
return ETCD;
|
||||
} else {
|
||||
return WORKER;
|
||||
}
|
||||
}
|
||||
|
||||
private boolean isKubernetesClusterKubeConfigAvailable(final long timeoutTime) {
|
||||
if (StringUtils.isEmpty(publicIpAddress)) {
|
||||
KubernetesClusterDetailsVO kubeConfigDetail = kubernetesClusterDetailsDao.findDetail(kubernetesCluster.getId(), "kubeConfigData");
|
||||
|
|
@ -733,7 +747,8 @@ public class KubernetesClusterStartWorker extends KubernetesClusterResourceModif
|
|||
DeployDestination dest = null;
|
||||
try {
|
||||
VMTemplateVO clusterTemplate = templateDao.findById(kubernetesCluster.getTemplateId());
|
||||
dest = plan(domainId, accountId, clusterTemplate.getHypervisorType());
|
||||
Map<String, DeployDestination> destinationMap = planKubernetesCluster(domainId, accountId, clusterTemplate.getHypervisorType());
|
||||
dest = destinationMap.get(WORKER.name());
|
||||
} catch (InsufficientCapacityException e) {
|
||||
logTransitStateAndThrow(Level.ERROR, String.format("Provisioning the cluster failed due to insufficient capacity in the Kubernetes cluster: %s", kubernetesCluster.getUuid()), kubernetesCluster.getId(), KubernetesCluster.Event.CreateFailed, e);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -370,7 +370,7 @@ public class KubernetesClusterManagerImplTest {
|
|||
|
||||
@Test
|
||||
public void testIsAnyNodeOfferingEmptyNullMap() {
|
||||
Assert.assertFalse(kubernetesClusterManager.isAnyNodeOfferingEmpty(null));
|
||||
Assert.assertTrue(kubernetesClusterManager.isAnyNodeOfferingEmpty(null));
|
||||
}
|
||||
|
||||
@Test
|
||||
|
|
|
|||
Loading…
Reference in New Issue