Path: blob/main/install/installer/pkg/components/public-api-server/deployment.go
2501 views
// Copyright (c) 2022 Gitpod GmbH. All rights reserved.1/// Licensed under the GNU Affero General Public License (AGPL).2// See License.AGPL.txt in the project root for license information.34package public_api_server56import (7"fmt"89"github.com/gitpod-io/gitpod/installer/pkg/components/auth"10"github.com/gitpod-io/gitpod/installer/pkg/config/v1/experimental"1112"github.com/gitpod-io/gitpod/common-go/baseserver"13"github.com/gitpod-io/gitpod/common-go/kubernetes"1415"github.com/gitpod-io/gitpod/installer/pkg/cluster"16"github.com/gitpod-io/gitpod/installer/pkg/common"17appsv1 "k8s.io/api/apps/v1"18corev1 "k8s.io/api/core/v1"19"k8s.io/apimachinery/pkg/api/resource"20metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"21"k8s.io/apimachinery/pkg/runtime"22"k8s.io/apimachinery/pkg/util/intstr"23"k8s.io/utils/pointer"24)2526const (27configmapVolume = "config"28configMountPath = "/config.json"29)3031func deployment(ctx *common.RenderContext) ([]runtime.Object, error) {32configHash, err := common.ObjectHash(configmap(ctx))33if err != nil {34return nil, err35}3637databaseSecretVolume, databaseSecretMount, _ := common.DatabaseEnvSecret(ctx.Config)3839volumes := []corev1.Volume{40{41Name: configmapVolume,42VolumeSource: corev1.VolumeSource{43ConfigMap: &corev1.ConfigMapVolumeSource{44LocalObjectReference: corev1.LocalObjectReference{45Name: Component,46},47},48},49},50databaseSecretVolume,51common.CAVolume(),52}53volumeMounts := []corev1.VolumeMount{54{55Name: configmapVolume,56ReadOnly: true,57MountPath: configMountPath,58SubPath: configJSONFilename,59},60databaseSecretMount,61common.CAVolumeMount(),62}6364_ = ctx.WithExperimental(func(cfg *experimental.Config) error {65volume, mount, _, ok := getStripeConfig(cfg)66if !ok {67return nil68}6970volumes = append(volumes, volume)71volumeMounts = append(volumeMounts, mount)72return nil73})7475_ = ctx.WithExperimental(func(cfg *experimental.Config) error {76volume, mount, _, ok := getPersonalAccessTokenSigningKey(cfg)77if !ok {78return nil79}8081volumes = append(volumes, volume)82volumeMounts = append(volumeMounts, mount)83return nil84})8586authVolumes, authMounts, _ := auth.GetConfig(ctx)87volumes = append(volumes, authVolumes...)88volumeMounts = append(volumeMounts, authMounts...)8990labels := common.CustomizeLabel(ctx, Component, common.TypeMetaDeployment)9192imageName := ctx.ImageName(ctx.Config.Repository, Component, ctx.VersionManifest.Components.PublicAPIServer.Version)93return []runtime.Object{94&appsv1.Deployment{95TypeMeta: common.TypeMetaDeployment,96ObjectMeta: metav1.ObjectMeta{97Name: Component,98Namespace: ctx.Namespace,99Labels: labels,100Annotations: common.CustomizeAnnotation(ctx, Component, common.TypeMetaDeployment),101},102Spec: appsv1.DeploymentSpec{103Selector: &metav1.LabelSelector{MatchLabels: common.DefaultLabels(Component)},104Replicas: common.Replicas(ctx, Component),105Strategy: common.DeploymentStrategy,106Template: corev1.PodTemplateSpec{107ObjectMeta: metav1.ObjectMeta{108Name: Component,109Namespace: ctx.Namespace,110Labels: labels,111Annotations: common.CustomizeAnnotation(ctx, Component, common.TypeMetaDeployment, func() map[string]string {112return map[string]string{113common.AnnotationConfigChecksum: configHash,114kubernetes.ImageNameAnnotation: imageName,115}116}),117},118Spec: corev1.PodSpec{119Affinity: cluster.WithNodeAffinityHostnameAntiAffinity(Component, cluster.AffinityLabelMeta),120TopologySpreadConstraints: cluster.WithHostnameTopologySpread(Component),121ServiceAccountName: Component,122EnableServiceLinks: pointer.Bool(false),123DNSPolicy: corev1.DNSClusterFirst,124RestartPolicy: corev1.RestartPolicyAlways,125TerminationGracePeriodSeconds: pointer.Int64(30),126InitContainers: []corev1.Container{127*common.DatabaseMigrationWaiterContainer(ctx),128*common.RedisWaiterContainer(ctx),129},130Containers: []corev1.Container{131{132Name: Component,133Image: imageName,134Args: []string{135"run",136fmt.Sprintf("--config=%s", configMountPath),137"--json-log=true",138},139ImagePullPolicy: corev1.PullIfNotPresent,140Resources: common.ResourceRequirements(ctx, Component, Component, corev1.ResourceRequirements{141Requests: corev1.ResourceList{142"cpu": resource.MustParse("100m"),143"memory": resource.MustParse("32Mi"),144},145}),146Ports: []corev1.ContainerPort{147{148ContainerPort: GRPCContainerPort,149Name: GRPCPortName,150},151},152SecurityContext: &corev1.SecurityContext{153Privileged: pointer.Bool(false),154AllowPrivilegeEscalation: pointer.Bool(false),155},156Env: common.CustomizeEnvvar(ctx, Component, common.MergeEnv(157common.DefaultEnv(&ctx.Config),158common.ConfigcatEnv(ctx),159common.DatabaseEnv(&ctx.Config),160)),161LivenessProbe: &corev1.Probe{162ProbeHandler: corev1.ProbeHandler{163HTTPGet: &corev1.HTTPGetAction{164Path: "/live",165Port: intstr.IntOrString{IntVal: baseserver.BuiltinHealthPort},166Scheme: corev1.URISchemeHTTP,167},168},169FailureThreshold: 3,170SuccessThreshold: 1,171TimeoutSeconds: 1,172},173ReadinessProbe: &corev1.Probe{174ProbeHandler: corev1.ProbeHandler{175HTTPGet: &corev1.HTTPGetAction{176Path: "/ready",177Port: intstr.IntOrString{IntVal: baseserver.BuiltinHealthPort},178Scheme: corev1.URISchemeHTTP,179},180},181FailureThreshold: 3,182SuccessThreshold: 1,183TimeoutSeconds: 1,184},185VolumeMounts: volumeMounts,186},187*common.KubeRBACProxyContainer(ctx),188},189Volumes: volumes,190Tolerations: common.WithTolerationWorkspaceComponentNotReady(ctx),191},192},193},194},195}, nil196}197198199