Path: blob/main/install/installer/pkg/components/ws-proxy/deployment.go
2501 views
// Copyright (c) 2021 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 wsproxy56import (7"github.com/gitpod-io/gitpod/common-go/baseserver"8"github.com/gitpod-io/gitpod/installer/pkg/cluster"9"github.com/gitpod-io/gitpod/installer/pkg/common"1011wsmanagermk2 "github.com/gitpod-io/gitpod/installer/pkg/components/ws-manager-mk2"1213appsv1 "k8s.io/api/apps/v1"14corev1 "k8s.io/api/core/v1"15"k8s.io/apimachinery/pkg/api/resource"16metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"17"k8s.io/apimachinery/pkg/runtime"18"k8s.io/apimachinery/pkg/util/intstr"19"k8s.io/utils/pointer"20)2122func deployment(ctx *common.RenderContext) ([]runtime.Object, error) {23labels := common.CustomizeLabel(ctx, Component, common.TypeMetaDeployment)2425configHash, err := common.ObjectHash(configmap(ctx))26if err != nil {27return nil, err28}2930volumes := []corev1.Volume{31{32Name: "config-certificates",33VolumeSource: corev1.VolumeSource{34Secret: &corev1.SecretVolumeSource{35SecretName: ctx.Config.Certificate.Name,36},37},38},39}4041volumeMounts := []corev1.VolumeMount{42{43Name: "config-certificates",44MountPath: "/mnt/certificates"},45}4647if ctx.Config.SSHGatewayHostKey != nil {48volumes = append(volumes, corev1.Volume{49Name: "host-key",50VolumeSource: corev1.VolumeSource{51Secret: &corev1.SecretVolumeSource{52SecretName: ctx.Config.SSHGatewayHostKey.Name,53},54},55})5657volumeMounts = append(volumeMounts, corev1.VolumeMount{58Name: "host-key",59MountPath: "/mnt/host-key",60})61}6263if ctx.Config.SSHGatewayCAKey != nil {64volumes = append(volumes, corev1.Volume{65Name: "ca-key",66VolumeSource: corev1.VolumeSource{67Secret: &corev1.SecretVolumeSource{68SecretName: ctx.Config.SSHGatewayCAKey.Name,69Optional: pointer.Bool(true),70},71},72})7374volumeMounts = append(volumeMounts, corev1.VolumeMount{75Name: "ca-key",76MountPath: "/mnt/ca-key/ca.key",77SubPath: "ca.key",78ReadOnly: true,79})80}8182podSpec := corev1.PodSpec{83PriorityClassName: common.SystemNodeCritical,84Affinity: cluster.WithNodeAffinityHostnameAntiAffinity(Component, cluster.AffinityLabelServices),85TopologySpreadConstraints: cluster.WithHostnameTopologySpread(Component),86EnableServiceLinks: pointer.Bool(false),87ServiceAccountName: Component,88SecurityContext: &corev1.PodSecurityContext{89RunAsUser: pointer.Int64(31002),90},91TerminationGracePeriodSeconds: pointer.Int64(360),92Volumes: append([]corev1.Volume{93{94Name: "config",95VolumeSource: corev1.VolumeSource{96ConfigMap: &corev1.ConfigMapVolumeSource{97LocalObjectReference: corev1.LocalObjectReference{Name: Component},98},99},100},101{102Name: "ws-manager-client-tls-certs",103VolumeSource: corev1.VolumeSource{104Secret: &corev1.SecretVolumeSource{105SecretName: wsmanagermk2.TLSSecretNameClient,106},107},108},109common.CAVolume(),110}, volumes...),111Containers: []corev1.Container{{112Name: Component,113Args: []string{"run", "/config/config.json"},114Image: ctx.ImageName(ctx.Config.Repository, Component, ctx.VersionManifest.Components.WSProxy.Version),115ImagePullPolicy: corev1.PullIfNotPresent,116Resources: common.ResourceRequirements(ctx, Component, Component, corev1.ResourceRequirements{117Requests: corev1.ResourceList{118"cpu": resource.MustParse("100m"),119"memory": resource.MustParse("32Mi"),120},121}),122Ports: []corev1.ContainerPort{{123Name: HTTPProxyPortName,124ContainerPort: HTTPProxyPort,125}, {126Name: HTTPSProxyPortName,127ContainerPort: HTTPSProxyPort,128}, {129Name: baseserver.BuiltinMetricsPortName,130ContainerPort: baseserver.BuiltinMetricsPort,131}, {132Name: SSHPortName,133ContainerPort: SSHServicePort,134}},135SecurityContext: &corev1.SecurityContext{136Privileged: pointer.Bool(false),137AllowPrivilegeEscalation: pointer.Bool(false),138},139Env: common.CustomizeEnvvar(ctx, Component, common.MergeEnv(140common.DefaultEnv(&ctx.Config),141common.WorkspaceTracingEnv(ctx, Component),142common.AnalyticsEnv(&ctx.Config),143// ws-proxy and proxy may not in the same cluster144common.ConfigcatEnvOutOfCluster(ctx),145)),146ReadinessProbe: &corev1.Probe{147InitialDelaySeconds: int32(2),148PeriodSeconds: int32(5),149FailureThreshold: int32(10),150ProbeHandler: corev1.ProbeHandler{151HTTPGet: &corev1.HTTPGetAction{152Path: "/readyz",153Port: intstr.IntOrString{IntVal: ReadinessPort},154},155},156},157LivenessProbe: &corev1.Probe{158InitialDelaySeconds: int32(2),159PeriodSeconds: int32(5),160FailureThreshold: int32(10),161SuccessThreshold: int32(1),162TimeoutSeconds: int32(2),163ProbeHandler: corev1.ProbeHandler{164HTTPGet: &corev1.HTTPGetAction{165Path: "/healthz",166Port: intstr.IntOrString{IntVal: ReadinessPort},167},168},169},170VolumeMounts: append([]corev1.VolumeMount{171{172Name: "config",173MountPath: "/config",174ReadOnly: true,175},176{177Name: "ws-manager-client-tls-certs",178MountPath: "/ws-manager-client-tls-certs",179ReadOnly: true,180},181common.CAVolumeMount(),182}, volumeMounts...),183},184*common.KubeRBACProxyContainer(ctx),185},186Tolerations: common.WithTolerationWorkspaceComponentNotReady(ctx),187}188189return []runtime.Object{190&appsv1.Deployment{191TypeMeta: common.TypeMetaDeployment,192ObjectMeta: metav1.ObjectMeta{193Name: Component,194Namespace: ctx.Namespace,195Labels: labels,196Annotations: common.CustomizeAnnotation(ctx, Component, common.TypeMetaDeployment),197},198Spec: appsv1.DeploymentSpec{199Selector: &metav1.LabelSelector{MatchLabels: common.DefaultLabels(Component)},200Replicas: common.Replicas(ctx, Component),201Strategy: common.DeploymentStrategy,202Template: corev1.PodTemplateSpec{203ObjectMeta: metav1.ObjectMeta{204Name: Component,205Namespace: ctx.Namespace,206Labels: labels,207Annotations: common.CustomizeAnnotation(ctx, Component, common.TypeMetaDeployment, func() map[string]string {208return map[string]string{209common.AnnotationConfigChecksum: configHash,210}211}),212},213Spec: podSpec,214},215},216},217}, nil218}219220221