mirror of
https://github.com/gitpod-io/gitpod.git
synced 2025-12-08 17:36:30 +00:00
371 lines
12 KiB
Go
371 lines
12 KiB
Go
// Copyright (c) 2021 Gitpod GmbH. All rights reserved.
|
|
// Licensed under the GNU Affero General Public License (AGPL).
|
|
// See License-AGPL.txt in the project root for license information.
|
|
|
|
package wsdaemon
|
|
|
|
import (
|
|
"fmt"
|
|
|
|
"github.com/gitpod-io/gitpod/installer/pkg/cluster"
|
|
"github.com/gitpod-io/gitpod/installer/pkg/common"
|
|
config "github.com/gitpod-io/gitpod/installer/pkg/config/v1"
|
|
"github.com/gitpod-io/gitpod/installer/pkg/shiftfs"
|
|
|
|
appsv1 "k8s.io/api/apps/v1"
|
|
corev1 "k8s.io/api/core/v1"
|
|
"k8s.io/apimachinery/pkg/api/resource"
|
|
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
|
"k8s.io/apimachinery/pkg/runtime"
|
|
"k8s.io/apimachinery/pkg/util/intstr"
|
|
"k8s.io/utils/pointer"
|
|
)
|
|
|
|
func daemonset(ctx *common.RenderContext) ([]runtime.Object, error) {
|
|
cfg := ctx.Config
|
|
labels := common.CustomizeLabel(ctx, Component, common.TypeMetaDaemonset)
|
|
|
|
configHash, err := common.ObjectHash(configmap(ctx))
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
initContainers := []corev1.Container{
|
|
{
|
|
Name: "disable-kube-health-monitor",
|
|
Image: ctx.ImageName(common.ThirdPartyContainerRepo(ctx.Config.Repository, common.DockerRegistryURL), "library/ubuntu", "20.04"),
|
|
Command: []string{
|
|
"/usr/bin/nsenter",
|
|
"-t",
|
|
"1",
|
|
"-a",
|
|
"/bin/bash",
|
|
"-c",
|
|
},
|
|
Args: []string{`exec {BASH_XTRACEFD}>&1 # this causes 'set -x' to write to stdout insted of stderr
|
|
set -euExo pipefail
|
|
systemctl status kube-container-runtime-monitor.service || true
|
|
if [ "$(systemctl is-active kube-container-runtime-monitor.service)" == "active" ]
|
|
then
|
|
echo "kube-container-runtime-monitor.service is active"
|
|
systemctl stop kube-container-runtime-monitor.service
|
|
systemctl disable kube-container-runtime-monitor.service
|
|
systemctl status kube-container-runtime-monitor.service || true
|
|
else
|
|
echo "kube-container-runtime-monitor.service is not active, not doing anything"
|
|
fi
|
|
`},
|
|
SecurityContext: &corev1.SecurityContext{
|
|
Privileged: pointer.Bool(true),
|
|
ProcMount: func() *corev1.ProcMountType { r := corev1.DefaultProcMount; return &r }(),
|
|
},
|
|
Env: common.ProxyEnv(&cfg),
|
|
},
|
|
{
|
|
Name: "seccomp-profile-installer",
|
|
Image: ctx.ImageName(cfg.Repository, "seccomp-profile-installer", ctx.VersionManifest.Components.WSDaemon.UserNamespaces.SeccompProfileInstaller.Version),
|
|
Command: []string{
|
|
"/bin/sh",
|
|
"-c",
|
|
fmt.Sprintf("cp -f /installer/workspace_default.json /mnt/dst/workspace_default_%s.json", ctx.VersionManifest.Version),
|
|
},
|
|
VolumeMounts: []corev1.VolumeMount{{
|
|
Name: "hostseccomp",
|
|
MountPath: "/mnt/dst",
|
|
}},
|
|
SecurityContext: &corev1.SecurityContext{Privileged: pointer.Bool(true)},
|
|
},
|
|
{
|
|
Name: "sysctl",
|
|
Image: ctx.ImageName(cfg.Repository, "ws-daemon", ctx.VersionManifest.Components.WSDaemon.Version),
|
|
Command: []string{
|
|
"sh",
|
|
"-c",
|
|
`(
|
|
echo "running sysctls" &&
|
|
sysctl -w net.core.somaxconn=4096 &&
|
|
sysctl -w "net.ipv4.ip_local_port_range=5000 65000" &&
|
|
sysctl -w "net.ipv4.tcp_tw_reuse=1" &&
|
|
sysctl -w fs.inotify.max_user_watches=1000000 &&
|
|
sysctl -w "kernel.dmesg_restrict=1" &&
|
|
sysctl -w vm.unprivileged_userfaultfd=0
|
|
) && echo "done!" || echo "failed!"
|
|
`,
|
|
},
|
|
SecurityContext: &corev1.SecurityContext{Privileged: pointer.Bool(true)},
|
|
},
|
|
}
|
|
|
|
if cfg.Workspace.Runtime.FSShiftMethod == config.FSShiftShiftFS {
|
|
initContainers = append(initContainers, shiftfs.Container(ctx))
|
|
}
|
|
|
|
podSpec := corev1.PodSpec{
|
|
Volumes: []corev1.Volume{
|
|
{
|
|
Name: "hostfs",
|
|
VolumeSource: corev1.VolumeSource{HostPath: &corev1.HostPathVolumeSource{
|
|
Path: "/",
|
|
}},
|
|
},
|
|
{
|
|
Name: "working-area",
|
|
VolumeSource: corev1.VolumeSource{HostPath: &corev1.HostPathVolumeSource{
|
|
Path: HostWorkingArea,
|
|
Type: func() *corev1.HostPathType { r := corev1.HostPathDirectoryOrCreate; return &r }(),
|
|
}},
|
|
},
|
|
{
|
|
Name: "tls-certs",
|
|
VolumeSource: corev1.VolumeSource{Secret: &corev1.SecretVolumeSource{SecretName: TLSSecretName}},
|
|
},
|
|
{
|
|
Name: "config",
|
|
VolumeSource: corev1.VolumeSource{ConfigMap: &corev1.ConfigMapVolumeSource{
|
|
LocalObjectReference: corev1.LocalObjectReference{Name: Component},
|
|
}},
|
|
},
|
|
{
|
|
Name: "containerd-socket",
|
|
VolumeSource: corev1.VolumeSource{HostPath: &corev1.HostPathVolumeSource{
|
|
Path: ctx.Config.Workspace.Runtime.ContainerDSocket,
|
|
Type: func() *corev1.HostPathType { r := corev1.HostPathSocket; return &r }(),
|
|
}},
|
|
},
|
|
{
|
|
Name: "node-fs0",
|
|
VolumeSource: corev1.VolumeSource{HostPath: &corev1.HostPathVolumeSource{
|
|
Path: ctx.Config.Workspace.Runtime.ContainerDRuntimeDir,
|
|
Type: func() *corev1.HostPathType { r := corev1.HostPathDirectory; return &r }(),
|
|
}},
|
|
},
|
|
{
|
|
Name: "node-mounts",
|
|
VolumeSource: corev1.VolumeSource{HostPath: &corev1.HostPathVolumeSource{
|
|
Path: "/proc/mounts",
|
|
Type: func() *corev1.HostPathType { r := corev1.HostPathFile; return &r }(),
|
|
}},
|
|
},
|
|
{
|
|
Name: "node-cgroups",
|
|
VolumeSource: corev1.VolumeSource{HostPath: &corev1.HostPathVolumeSource{
|
|
Path: "/sys/fs/cgroup",
|
|
Type: func() *corev1.HostPathType { r := corev1.HostPathDirectory; return &r }(),
|
|
}},
|
|
},
|
|
{
|
|
Name: "node-hosts",
|
|
VolumeSource: corev1.VolumeSource{HostPath: &corev1.HostPathVolumeSource{
|
|
Path: "/etc/hosts",
|
|
Type: func() *corev1.HostPathType { r := corev1.HostPathFile; return &r }(),
|
|
}},
|
|
},
|
|
{
|
|
Name: "node-linux-src",
|
|
VolumeSource: corev1.VolumeSource{HostPath: &corev1.HostPathVolumeSource{
|
|
Path: "/usr/src",
|
|
Type: func() *corev1.HostPathType { r := corev1.HostPathDirectory; return &r }(),
|
|
}},
|
|
},
|
|
{
|
|
Name: "hostseccomp",
|
|
VolumeSource: corev1.VolumeSource{HostPath: &corev1.HostPathVolumeSource{Path: "/var/lib/kubelet/seccomp"}},
|
|
},
|
|
{
|
|
Name: "gcloud-tmp",
|
|
VolumeSource: corev1.VolumeSource{HostPath: &corev1.HostPathVolumeSource{
|
|
Path: HostBackupPath,
|
|
Type: func() *corev1.HostPathType { r := corev1.HostPathDirectoryOrCreate; return &r }(),
|
|
}},
|
|
},
|
|
},
|
|
InitContainers: initContainers,
|
|
Containers: []corev1.Container{
|
|
{
|
|
Name: Component,
|
|
Image: ctx.ImageName(ctx.Config.Repository, Component, ctx.VersionManifest.Components.WSDaemon.Version),
|
|
Args: []string{
|
|
"run",
|
|
"--config",
|
|
"/config/config.json",
|
|
},
|
|
Ports: []corev1.ContainerPort{{
|
|
Name: "rpc",
|
|
HostPort: ServicePort,
|
|
ContainerPort: ServicePort,
|
|
}},
|
|
Env: common.CustomizeEnvvar(ctx, Component, common.MergeEnv(
|
|
common.DefaultEnv(&cfg),
|
|
common.WorkspaceTracingEnv(ctx, Component),
|
|
common.NodeNameEnv(ctx),
|
|
)),
|
|
Resources: common.ResourceRequirements(ctx, Component, Component, corev1.ResourceRequirements{Requests: corev1.ResourceList{
|
|
"cpu": resource.MustParse("500m"),
|
|
"memory": resource.MustParse("4Gi"),
|
|
}}),
|
|
VolumeMounts: []corev1.VolumeMount{
|
|
{
|
|
Name: "working-area",
|
|
MountPath: ContainerWorkingArea,
|
|
MountPropagation: func() *corev1.MountPropagationMode { r := corev1.MountPropagationBidirectional; return &r }(),
|
|
},
|
|
{
|
|
Name: "config",
|
|
MountPath: "/config",
|
|
},
|
|
{
|
|
Name: "containerd-socket",
|
|
MountPath: "/mnt/containerd.sock",
|
|
},
|
|
{
|
|
Name: "node-fs0",
|
|
MountPath: "/mnt/node0",
|
|
},
|
|
{
|
|
Name: "node-mounts",
|
|
ReadOnly: true,
|
|
MountPath: "/mnt/mounts",
|
|
MountPropagation: func() *corev1.MountPropagationMode { r := corev1.MountPropagationHostToContainer; return &r }(),
|
|
},
|
|
{
|
|
Name: "node-cgroups",
|
|
MountPath: "/mnt/node-cgroups",
|
|
MountPropagation: func() *corev1.MountPropagationMode { r := corev1.MountPropagationHostToContainer; return &r }(),
|
|
},
|
|
{
|
|
Name: "node-hosts",
|
|
MountPath: "/mnt/hosts",
|
|
},
|
|
{
|
|
Name: "tls-certs",
|
|
MountPath: "/certs",
|
|
},
|
|
{
|
|
Name: "gcloud-tmp",
|
|
MountPath: "/mnt/sync-tmp",
|
|
},
|
|
},
|
|
ImagePullPolicy: corev1.PullIfNotPresent,
|
|
SecurityContext: &corev1.SecurityContext{
|
|
Privileged: pointer.Bool(true),
|
|
},
|
|
ReadinessProbe: &corev1.Probe{
|
|
ProbeHandler: corev1.ProbeHandler{
|
|
HTTPGet: &corev1.HTTPGetAction{
|
|
Path: "/ready",
|
|
Port: intstr.IntOrString{IntVal: ReadinessPort},
|
|
},
|
|
},
|
|
InitialDelaySeconds: 5,
|
|
PeriodSeconds: 5,
|
|
TimeoutSeconds: 1,
|
|
SuccessThreshold: 2,
|
|
FailureThreshold: 5,
|
|
},
|
|
LivenessProbe: &corev1.Probe{
|
|
ProbeHandler: corev1.ProbeHandler{
|
|
HTTPGet: &corev1.HTTPGetAction{
|
|
Path: "/live",
|
|
Port: intstr.IntOrString{IntVal: ReadinessPort},
|
|
},
|
|
},
|
|
InitialDelaySeconds: 5,
|
|
PeriodSeconds: 10,
|
|
TimeoutSeconds: 1,
|
|
SuccessThreshold: 1,
|
|
FailureThreshold: 5,
|
|
},
|
|
},
|
|
*common.KubeRBACProxyContainer(ctx),
|
|
{
|
|
Name: "node-labeler",
|
|
Image: ctx.ImageName(ctx.Config.Repository, Component, ctx.VersionManifest.Components.WSDaemon.Version),
|
|
Command: []string{
|
|
"/app/ready-probe-labeler",
|
|
fmt.Sprintf("--label=gitpod.io/ws-daemon_ready_ns_%v", ctx.Namespace),
|
|
fmt.Sprintf(`--probe-url=http://localhost:%v/ready`, ReadinessPort),
|
|
},
|
|
Env: common.CustomizeEnvvar(ctx, Component, common.MergeEnv(
|
|
common.NodeNameEnv(ctx),
|
|
common.ProxyEnv(&ctx.Config),
|
|
)),
|
|
ImagePullPolicy: corev1.PullIfNotPresent,
|
|
Lifecycle: &corev1.Lifecycle{
|
|
PreStop: &corev1.LifecycleHandler{
|
|
Exec: &corev1.ExecAction{
|
|
Command: []string{
|
|
"/app/ready-probe-labeler",
|
|
fmt.Sprintf("--label=gitpod.io/ws-daemon_ready_ns_%v", ctx.Namespace),
|
|
"--shutdown",
|
|
},
|
|
},
|
|
},
|
|
},
|
|
},
|
|
},
|
|
RestartPolicy: "Always",
|
|
TerminationGracePeriodSeconds: pointer.Int64(30),
|
|
DNSPolicy: "ClusterFirst",
|
|
ServiceAccountName: Component,
|
|
HostPID: true,
|
|
Affinity: common.NodeAffinity(cluster.AffinityLabelWorkspacesRegular, cluster.AffinityLabelWorkspacesHeadless),
|
|
Tolerations: []corev1.Toleration{
|
|
{
|
|
Key: "node.kubernetes.io/disk-pressure",
|
|
Operator: "Exists",
|
|
Effect: "NoExecute",
|
|
},
|
|
{
|
|
Key: "node.kubernetes.io/memory-pressure",
|
|
Operator: "Exists",
|
|
Effect: "NoExecute",
|
|
},
|
|
{
|
|
Key: "node.kubernetes.io/out-of-disk",
|
|
Operator: "Exists",
|
|
Effect: "NoExecute",
|
|
},
|
|
},
|
|
PriorityClassName: common.SystemNodeCritical,
|
|
EnableServiceLinks: pointer.Bool(false),
|
|
}
|
|
|
|
err = common.AddStorageMounts(ctx, &podSpec, Component)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
if vol, mnt, env, ok := common.CustomCACertVolume(ctx); ok {
|
|
podSpec.Volumes = append(podSpec.Volumes, *vol)
|
|
pod := podSpec.Containers[0]
|
|
pod.VolumeMounts = append(pod.VolumeMounts, *mnt)
|
|
pod.Env = append(pod.Env, env...)
|
|
podSpec.Containers[0] = pod
|
|
}
|
|
|
|
return []runtime.Object{&appsv1.DaemonSet{
|
|
TypeMeta: common.TypeMetaDaemonset,
|
|
ObjectMeta: metav1.ObjectMeta{
|
|
Name: Component,
|
|
Namespace: ctx.Namespace,
|
|
Labels: labels,
|
|
Annotations: common.CustomizeAnnotation(ctx, Component, common.TypeMetaDaemonset),
|
|
},
|
|
Spec: appsv1.DaemonSetSpec{
|
|
Selector: &metav1.LabelSelector{MatchLabels: common.DefaultLabels(Component)},
|
|
Template: corev1.PodTemplateSpec{
|
|
ObjectMeta: metav1.ObjectMeta{
|
|
Labels: labels,
|
|
Annotations: common.CustomizeAnnotation(ctx, Component, common.TypeMetaDaemonset, func() map[string]string {
|
|
return map[string]string{
|
|
"seccomp.security.alpha.kubernetes.io/shiftfs-module-loader": "unconfined",
|
|
common.AnnotationConfigChecksum: configHash,
|
|
}
|
|
}),
|
|
},
|
|
Spec: podSpec,
|
|
},
|
|
},
|
|
}}, nil
|
|
}
|