Path: blob/main/install/installer/pkg/components/registry-facade/daemonset.go
2506 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 registryfacade56import (7"fmt"89"github.com/gitpod-io/gitpod/installer/pkg/cluster"10"github.com/gitpod-io/gitpod/installer/pkg/common"11dockerregistry "github.com/gitpod-io/gitpod/installer/pkg/components/docker-registry"12wsmanagermk2 "github.com/gitpod-io/gitpod/installer/pkg/components/ws-manager-mk2"13"github.com/gitpod-io/gitpod/installer/pkg/config/v1/experimental"1415appsv1 "k8s.io/api/apps/v1"16corev1 "k8s.io/api/core/v1"17"k8s.io/apimachinery/pkg/api/resource"18metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"19"k8s.io/apimachinery/pkg/runtime"20"k8s.io/apimachinery/pkg/util/intstr"21"k8s.io/utils/pointer"22)2324const wsManagerMk2ClientTlsVolume = "ws-manager-mk2-client-tls-certs"2526func daemonset(ctx *common.RenderContext) ([]runtime.Object, error) {27labels := common.CustomizeLabel(ctx, Component, common.TypeMetaDaemonset)2829var hashObj []runtime.Object30if objs, err := configmap(ctx); err != nil {31return nil, err32} else {33hashObj = append(hashObj, objs...)34}3536var (37volumes = []corev1.Volume{38{39Name: "config-certificates",40VolumeSource: corev1.VolumeSource{41Secret: &corev1.SecretVolumeSource{42SecretName: "builtin-registry-facade-cert",43},44},45},46{47Name: wsManagerMk2ClientTlsVolume,48VolumeSource: corev1.VolumeSource{49Secret: &corev1.SecretVolumeSource{50SecretName: wsmanagermk2.TLSSecretNameClient,51},52},53},54}55volumeMounts = []corev1.VolumeMount{56{57Name: "config-certificates",58MountPath: "/mnt/certificates",59},60{61Name: wsManagerMk2ClientTlsVolume,62MountPath: "/ws-manager-mk2-client-tls-certs",63ReadOnly: true,64},65}66)6768if objs, err := common.DockerRegistryHash(ctx); err != nil {69return nil, err70} else {71hashObj = append(hashObj, objs...)72}7374configHash, err := common.ObjectHash(hashObj, nil)75if err != nil {76return nil, err77}7879name := "pull-secret"80var secretName string81if pointer.BoolDeref(ctx.Config.ContainerRegistry.InCluster, false) {82secretName = dockerregistry.BuiltInRegistryAuth83} else if ctx.Config.ContainerRegistry.External != nil {84secretName = ctx.Config.ContainerRegistry.External.Certificate.Name85} else {86return nil, fmt.Errorf("%s: invalid container registry config", Component)87}8889var envvars []corev1.EnvVar90err = ctx.WithExperimental(func(ucfg *experimental.Config) error {91if ucfg.Workspace == nil {92return nil93}9495if ucfg.Workspace.RegistryFacade.IPFSCache.Enabled && !ucfg.Workspace.RegistryFacade.RedisCache.Enabled {96return fmt.Errorf("IPFS cache requires Redis")97}9899if ucfg.Workspace.RegistryFacade.IPFSCache.Enabled {100envvars = []corev1.EnvVar{101{102Name: "IPFS_HOST",103ValueFrom: &corev1.EnvVarSource{104FieldRef: &corev1.ObjectFieldSelector{105FieldPath: "status.hostIP",106},107},108},109}110}111112if ucfg.Workspace.RegistryFacade.RedisCache.Enabled {113if scr := ucfg.Workspace.RegistryFacade.RedisCache.PasswordSecret; scr != "" {114envvars = append(envvars, corev1.EnvVar{115Name: "REDIS_PASSWORD",116ValueFrom: &corev1.EnvVarSource{117SecretKeyRef: &corev1.SecretKeySelector{118LocalObjectReference: corev1.LocalObjectReference{119Name: scr,120},121Key: "password",122},123},124})125}126}127128return nil129})130if err != nil {131return nil, err132}133134initContainers := []corev1.Container{135{136Name: "setup",137Image: ctx.ImageName(ctx.Config.Repository, Component, ctx.VersionManifest.Components.RegistryFacade.Version), ImagePullPolicy: corev1.PullIfNotPresent,138Args: []string{139"setup",140"--hostfs=/mnt/dst",141fmt.Sprintf("--hostname=reg.%s", ctx.Config.Domain),142fmt.Sprintf("--port=%v", ServicePort),143},144SecurityContext: &corev1.SecurityContext{RunAsUser: pointer.Int64(0)},145VolumeMounts: []corev1.VolumeMount{146{147Name: "hostfs",148MountPath: "/mnt/dst",149},150{151Name: "ca-certificate",152MountPath: "/usr/local/share/ca-certificates/gitpod-ca.crt",153SubPath: "gitpod-ca.crt",154ReadOnly: true,155},156},157Env: common.ProxyEnv(&ctx.Config),158},159}160161return []runtime.Object{&appsv1.DaemonSet{162TypeMeta: common.TypeMetaDaemonset,163ObjectMeta: metav1.ObjectMeta{164Name: Component,165Namespace: ctx.Namespace,166Labels: labels,167Annotations: common.CustomizeAnnotation(ctx, Component, common.TypeMetaDaemonset),168},169Spec: appsv1.DaemonSetSpec{170Selector: &metav1.LabelSelector{MatchLabels: common.DefaultLabels(Component)},171Template: corev1.PodTemplateSpec{172ObjectMeta: metav1.ObjectMeta{173Name: Component,174Labels: labels,175Annotations: common.CustomizeAnnotation(ctx, Component, common.TypeMetaDaemonset, func() map[string]string {176return map[string]string{177common.AnnotationConfigChecksum: configHash,178}179}),180},181Spec: corev1.PodSpec{182PriorityClassName: common.SystemNodeCritical,183Affinity: cluster.WithNodeAffinity(cluster.AffinityLabelWorkspacesRegular, cluster.AffinityLabelWorkspacesHeadless),184ServiceAccountName: Component,185EnableServiceLinks: pointer.Bool(false),186DNSPolicy: corev1.DNSClusterFirst,187RestartPolicy: corev1.RestartPolicyAlways,188TerminationGracePeriodSeconds: pointer.Int64(30),189InitContainers: initContainers,190Tolerations: []corev1.Toleration{191{192Operator: "Exists",193},194},195Containers: []corev1.Container{{196Name: Component,197Image: ctx.ImageName(ctx.Config.Repository, Component, ctx.VersionManifest.Components.RegistryFacade.Version),198ImagePullPolicy: corev1.PullIfNotPresent,199Args: []string{"run", "/mnt/config/config.json"},200Resources: common.ResourceRequirements(ctx, Component, Component, corev1.ResourceRequirements{201Requests: corev1.ResourceList{202"cpu": resource.MustParse("100m"),203"memory": resource.MustParse("32Mi"),204},205}),206Ports: []corev1.ContainerPort{{207Name: ContainerPortName,208ContainerPort: ServicePort,209HostPort: ServicePort,210}},211SecurityContext: &corev1.SecurityContext{212Privileged: pointer.Bool(false),213AllowPrivilegeEscalation: pointer.Bool(false),214RunAsUser: pointer.Int64(1000),215},216Env: common.CustomizeEnvvar(ctx, Component, common.MergeEnv(217common.DefaultEnv(&ctx.Config),218common.WorkspaceTracingEnv(ctx, Component),219[]corev1.EnvVar{220{221Name: "GRPC_GO_RETRY",222Value: "on",223},224},225envvars,226)),227VolumeMounts: append(228[]corev1.VolumeMount{229{230Name: "cache",231MountPath: "/mnt/cache",232},233{234Name: "config",235MountPath: "/mnt/config",236ReadOnly: true,237},238{239Name: name,240MountPath: "/mnt/pull-secret",241},242common.CAVolumeMount(),243},244volumeMounts...,245),246ReadinessProbe: &corev1.Probe{247ProbeHandler: corev1.ProbeHandler{248HTTPGet: &corev1.HTTPGetAction{249Path: "/ready",250Port: intstr.IntOrString{IntVal: ReadinessPort},251},252},253InitialDelaySeconds: 10,254PeriodSeconds: 5,255TimeoutSeconds: 2,256SuccessThreshold: 2,257FailureThreshold: 5,258},259LivenessProbe: &corev1.Probe{260ProbeHandler: corev1.ProbeHandler{261HTTPGet: &corev1.HTTPGetAction{262Path: "/live",263Port: intstr.IntOrString{IntVal: ReadinessPort},264},265},266InitialDelaySeconds: 5,267PeriodSeconds: 10,268TimeoutSeconds: 2,269SuccessThreshold: 1,270FailureThreshold: 3,271},272},273*common.KubeRBACProxyContainer(ctx),274},275Volumes: append([]corev1.Volume{276{277Name: "cache",278VolumeSource: corev1.VolumeSource{EmptyDir: &corev1.EmptyDirVolumeSource{}},279},280{281Name: "config",282VolumeSource: corev1.VolumeSource{ConfigMap: &corev1.ConfigMapVolumeSource{283LocalObjectReference: corev1.LocalObjectReference{Name: Component},284}},285},286{287Name: name,288VolumeSource: corev1.VolumeSource{289Secret: &corev1.SecretVolumeSource{290SecretName: secretName,291Items: []corev1.KeyToPath{{Key: ".dockerconfigjson", Path: "pull-secret.json"}},292},293},294},295{296Name: "hostfs",297VolumeSource: corev1.VolumeSource{HostPath: &corev1.HostPathVolumeSource{298Path: "/",299}},300},301{302Name: "ca-certificate",303VolumeSource: corev1.VolumeSource{304ConfigMap: &corev1.ConfigMapVolumeSource{305LocalObjectReference: corev1.LocalObjectReference{Name: "gitpod-ca"},306},307},308},309common.CAVolume(),310}, volumes...),311},312},313UpdateStrategy: common.DaemonSetRolloutStrategy(),314},315}}, nil316}317318319