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