/// <summary> /// Create a new <see cref="DeploymentV1Beta1"/>. /// </summary> /// <param name="name"> /// The deployment name. /// </param> /// <param name="spec"> /// A <see cref="DeploymentSpecV1Beta1"/> representing the deployment specification. /// </param> /// <param name="labels"> /// An optional <see cref="Dictionary{TKey, TValue}"/> containing labels to apply to the deployment. /// </param> /// <param name="annotations"> /// An optional <see cref="Dictionary{TKey, TValue}"/> containing annotations to apply to the deployment. /// </param> /// <param name="kubeNamespace"> /// An optional target Kubernetes namespace. /// </param> /// <returns> /// The configured <see cref="DeploymentV1Beta1"/>. /// </returns> public DeploymentV1Beta1 Deployment(string name, DeploymentSpecV1Beta1 spec, Dictionary <string, string> labels = null, Dictionary <string, string> annotations = null, string kubeNamespace = null) { if (String.IsNullOrWhiteSpace(name)) { throw new ArgumentException("Argument cannot be null, empty, or entirely composed of whitespace: 'name'.", nameof(name)); } if (spec == null) { throw new ArgumentNullException(nameof(spec)); } return(new DeploymentV1Beta1 { ApiVersion = "apps/v1beta1", Kind = "Deployment", Metadata = new ObjectMetaV1 { Name = name, Namespace = kubeNamespace, Labels = labels, Annotations = annotations }, Spec = spec }); }
/// <summary> /// Build a <see cref="DeploymentSpecV1Beta1"/> for the specified server. /// </summary> /// <param name="server"> /// A <see cref="DatabaseServer"/> representing the target server. /// </param> /// <returns> /// The configured <see cref="DeploymentSpecV1Beta1"/>. /// </returns> public DeploymentSpecV1Beta1 Deployment(DatabaseServer server) { if (server == null) { throw new ArgumentNullException(nameof(server)); } string baseName = Names.BaseName(server); var deploymentSpec = new DeploymentSpecV1Beta1 { Replicas = 1, MinReadySeconds = 30, Strategy = new DeploymentStrategyV1Beta1 { Type = "Recreate" // Shut down the old instance before starting the new one }, Selector = new LabelSelectorV1 { MatchLabels = new Dictionary <string, string> { ["k8s-app"] = baseName } }, Template = new PodTemplateSpecV1 { Metadata = new ObjectMetaV1 { Labels = new Dictionary <string, string> { ["k8s-app"] = baseName, ["cloud.dimensiondata.daas.server-id"] = server.Id, ["cloud.dimensiondata.daas.server-kind"] = server.Kind.ToString() } }, Spec = new PodSpecV1 { TerminationGracePeriodSeconds = 60, ImagePullSecrets = new List <LocalObjectReferenceV1> { new LocalObjectReferenceV1 { Name = "daas-registry" } }, Containers = new List <ContainerV1>(), Volumes = new List <VolumeV1> { new VolumeV1 { Name = "data", PersistentVolumeClaim = new PersistentVolumeClaimVolumeSourceV1 { ClaimName = Names.DataVolumeClaim(server) } } } } } }; PodSpecV1 podSpec = deploymentSpec.Template.Spec; switch (server.Kind) { case DatabaseServerKind.SqlServer: { // SQL Server podSpec.Containers.Add(new ContainerV1 { Name = "sql-server", Image = ProvisioningOptions.Images.SQL, Resources = new ResourceRequirementsV1 { Requests = new Dictionary <string, string> { ["memory"] = "4Gi" // SQL Server for Linux requires at least 4 GB of RAM }, Limits = new Dictionary <string, string> { ["memory"] = "6Gi" // If you're using more than 6 GB of RAM, then you should probably host stand-alone } }, Env = new List <EnvVarV1> { new EnvVarV1 { Name = "ACCEPT_EULA", Value = "Y" }, new EnvVarV1 { Name = "SA_PASSWORD", ValueFrom = new EnvVarSourceV1 { SecretKeyRef = new SecretKeySelectorV1 { Name = Names.CredentialsSecret(server), Key = "sa-password" } } } }, Ports = new List <ContainerPortV1> { new ContainerPortV1 { ContainerPort = 1433 } }, VolumeMounts = new List <VolumeMountV1> { new VolumeMountV1 { Name = "data", SubPath = baseName, MountPath = "/var/opt/mssql" } } }); // Prometheus exporter podSpec.Containers.Add(new ContainerV1 { Name = "prometheus-exporter", Image = ProvisioningOptions.Images.SQLExporter, Env = new List <EnvVarV1> { new EnvVarV1 { Name = "SERVER", Value = "127.0.0.1", }, new EnvVarV1 { Name = "USERNAME", Value = "sa" }, new EnvVarV1 { Name = "PASSWORD", ValueFrom = new EnvVarSourceV1 { SecretKeyRef = new SecretKeySelectorV1 { Name = Names.CredentialsSecret(server), Key = "sa-password" } } }, new EnvVarV1 { Name = "DEBUG", Value = "app" } }, Ports = new List <ContainerPortV1> { new ContainerPortV1 { ContainerPort = 4000 } } }); break; } case DatabaseServerKind.RavenDB: { podSpec.Containers.Add(new ContainerV1 { Name = "ravendb", Image = ProvisioningOptions.Images.RavenDB, Resources = new ResourceRequirementsV1 { Requests = new Dictionary <string, string> { ["memory"] = "1Gi" }, Limits = new Dictionary <string, string> { ["memory"] = "3Gi" } }, Env = new List <EnvVarV1> { new EnvVarV1 { Name = "UNSECURED_ACCESS_ALLOWED", Value = "PublicNetwork" } }, Ports = new List <ContainerPortV1> { new ContainerPortV1 { Name = "http", ContainerPort = 8080 }, new ContainerPortV1 { Name = "tcp", ContainerPort = 38888 } }, VolumeMounts = new List <VolumeMountV1> { new VolumeMountV1 { Name = "data", SubPath = baseName, MountPath = "/databases" } } }); break; } default: { throw new NotSupportedException($"Unsupported server kind ({server.Kind})."); } } return(deploymentSpec); }