private async Task Deploy(string name, string image, string nameSpace, int min, int max) { var isHTTP = IsHTTPTrigger(name); await CreateNamespace(nameSpace); ColoredConsole.WriteLine(); ColoredConsole.WriteLine("Deploying function to Knative..."); var knativeService = GetKnativeService(name, image, nameSpace, min, max, isHTTP); await KubectlHelper.KubectlApply(knativeService, true); var endpoint = await GetIstioClusterIngressEndpoint(); var host = GetFunctionHost(name, nameSpace); ColoredConsole.WriteLine(); ColoredConsole.WriteLine("Function deployed successfully!"); ColoredConsole.WriteLine(); if (string.IsNullOrEmpty(endpoint)) { ColoredConsole.WriteLine($"Function URL: http://{endpoint}"); } else { ColoredConsole.WriteLine("Couldn't identify Function URL: Couldn't find Istio Cluster Ingress endpoint"); } ColoredConsole.WriteLine($"Function Host: {host}"); ColoredConsole.WriteLine(); ColoredConsole.WriteLine("Plese note: it may take a few minutes for the knative service to be reachable"); }
public async override Task RunAsync() { if (DryRun) { ColoredConsole.WriteLine(KubernetesHelper.GetKedaResources(Namespace)); if (!KedaOnly) { ColoredConsole.WriteLine(KubernetesHelper.GetOsirisResources(Namespace)); } } else { var sb = new StringBuilder(); sb.AppendLine(KubernetesHelper.GetKedaResources(Namespace)); if (!KedaOnly) { sb.AppendLine(KubernetesHelper.GetOsirisResources(Namespace)); } if (!await KubernetesHelper.NamespaceExists(Namespace)) { await KubernetesHelper.CreateNamespace(Namespace); } await KubectlHelper.KubectlApply(sb.ToString(), showOutput : true); } }
private async Task Deploy(string name, string image, string nameSpace, int min, int max, double cpu, int memory, string port, string pullSecret) { await CreateNamespace(nameSpace); var deploymentName = $"{name}-deployment"; await DeleteDeploymentIfExists(deploymentName, nameSpace); ColoredConsole.WriteLine("Deploying function to Kubernetes..."); var deployment = GetDeployment(deploymentName, image, cpu, memory, port, nameSpace, min, pullSecret); var json = Newtonsoft.Json.JsonConvert.SerializeObject(deployment, Newtonsoft.Json.Formatting.None, new Newtonsoft.Json.JsonSerializerSettings { NullValueHandling = Newtonsoft.Json.NullValueHandling.Ignore }); await KubectlHelper.RunKubectl($"apply -f deployment.json --namespace {nameSpace}"); ColoredConsole.WriteLine("Deployment successful"); var service = GetService(deploymentName, nameSpace, port); try { // we can safely ignore the error here await KubectlHelper.KubectlApply(service, showOutput : false); } catch { } await TryRemoveAutoscaler(deploymentName, nameSpace); await CreateAutoscaler(deploymentName, nameSpace, min, max); var externalIP = ""; ColoredConsole.WriteLine("Waiting for External IP..."); while (string.IsNullOrEmpty(externalIP)) { var svc = await KubectlHelper.KubectlGet <JObject>($"{deploymentName}-service --namespace {nameSpace}"); if (svc != null) { var obj = svc.SelectToken("Status.LoadBalancer.Ingress[0].Ip"); if (obj != null) { externalIP = obj.ToString(); } } } ColoredConsole.WriteLine(); ColoredConsole.WriteLine("Function deployed successfully!"); ColoredConsole.WriteLine($"Function IP: {externalIP}"); }
/// <summary> /// Returns true if we /// </summary> /// <returns></returns> private async Task CreateRabbitMQService() { await _logHandler.WriteLine($"rabbitConfig.IsServiceEnabled={_rabbitConfig.Value.IsRabbitServiceEnabled}", verboseLogging); if (_rabbitConfig.Value.IsRabbitServiceEnabled) { await _logHandler.WriteLine("Installing RabbitMQ Load Balancer Service", verboseLogging); await _kubectlHelper.InstallService(KubectlHelper.GetRabbitMQService()); } }
private async Task CreateAutoscaler(string deploymentName, string nameSpace, int minInstances, int maxInstances, int cpuPercentage = 60) { var cmd = $"autoscale deploy {deploymentName} --cpu-percent={cpuPercentage} --max={maxInstances} --min={minInstances} --namespace={nameSpace}"; if (!string.IsNullOrEmpty(configFile)) { cmd += $" --kubeconfig {configFile}"; } await KubectlHelper.RunKubectl(cmd); }
public async override Task RunAsync() { if (DryRun) { ColoredConsole.WriteLine(KubernetesHelper.GetKedaResources(Namespace)); } else { if (!await KubernetesHelper.NamespaceExists(Namespace)) { await KubernetesHelper.CreateNamespace(Namespace); } await KubectlHelper.KubectlApply(KubernetesHelper.GetKedaResources(Namespace), showOutput : true); } }
private async Task <string> GetIstioClusterIngressEndpoint() { var gateway = await KubectlHelper.KubectlGet <JObject>("service istio-ingressgateway --namespace istio-system"); if (gateway == null) { return(string.Empty); } var endpoint = gateway.SelectToken("Status.LoadBalancer.Ingress[0].Hostname")?.ToString(); if (!string.IsNullOrEmpty(endpoint)) { return(endpoint); } return(gateway.SelectToken("Status.LoadBalancer.Ingress[0].Ip")?.ToString()); }
public async Task DeployModule(IModuleManagerConfig config) { _logHandler.AttachTaskIdAndUpdateHandler(config.TaskId, config.UpdateCallback); await _logHandler.WriteCmd($"{nameof(ModuleManager)}.{nameof(DeployModule)}", verboseLogging); var response = await _kubectlHelper.InstallModule(KubectlHelper.CreateModuleDeployment( config.ImageName, config.ModuleName, config.ModuleReplicas), config.LoadBalancerConfig); if (response.IsSuccessful) { await config.SuccessCallback(config.TaskId, _logHandler); } else { await _logHandler.WriteLine(response.Message); await config.FailureCallback(config.TaskId, _logHandler); } }
public override async Task RunAsync() { (var resolvedImageName, var shouldBuild) = ResolveImageName(); TriggersPayload triggers = null; if (DryRun) { if (shouldBuild) { // don't build on a --dry-run. // read files from the local dir triggers = await GetTriggersLocalFiles(); } else { triggers = await DockerHelpers.GetTriggersFromDockerImage(resolvedImageName); } } else { if (shouldBuild) { await DockerHelpers.DockerBuild(resolvedImageName, Environment.CurrentDirectory); } triggers = await DockerHelpers.GetTriggersFromDockerImage(resolvedImageName); } (var resources, var funcKeys) = await KubernetesHelper.GetFunctionsDeploymentResources( Name, resolvedImageName, Namespace, triggers, _secretsManager.GetSecrets(), PullSecret, SecretsCollectionName, ConfigMapName, UseConfigMap, PollingInterval, CooldownPeriod, ServiceType, MinReplicaCount, MaxReplicaCount, KeysSecretCollectionName, MountFuncKeysAsContainerVolume); if (DryRun) { ColoredConsole.WriteLine(KubernetesHelper.SerializeResources(resources, OutputSerializationOptions.Yaml)); } else { if (!await KubernetesHelper.NamespaceExists(Namespace)) { await KubernetesHelper.CreateNamespace(Namespace); } if (shouldBuild) { await DockerHelpers.DockerPush(resolvedImageName); } foreach (var resource in resources) { await KubectlHelper.KubectlApply(resource, showOutput : true, ignoreError : IgnoreErrors, @namespace : Namespace); } //Print the function keys message to the console await KubernetesHelper.PrintFunctionsInfo($"{Name}-http", Namespace, funcKeys, triggers); } }
private async Task TryRemoveAutoscaler(string deploymentName, string nameSpace) { await KubectlHelper.RunKubectl($"delete hpa {deploymentName} -n {nameSpace}"); }
private async Task DeleteDeploymentIfExists(string name, string nameSpace) { await KubectlHelper.RunKubectl($"delete deployment {name} --namespace {nameSpace}"); }
private async Task CreateNamespace(string name) { await KubectlHelper.RunKubectl($"create ns {name}"); }
public async Task GetKubernetesFunctionLogs(string functionName) { string nameSpace = KUBERNETES_DEFAULT_NAMESPACE; await KubectlHelper.RunKubectl($"logs -l app={functionName}-deployment -n {nameSpace}", showOutput : true); }