Skip to content
This repository was archived by the owner on Sep 30, 2024. It is now read-only.

Commit 59ad280

Browse files
authored
1 parent 72e1838 commit 59ad280

File tree

113 files changed

+891
-13
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

113 files changed

+891
-13
lines changed

internal/appliance/config/spec.go

Lines changed: 21 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -88,6 +88,10 @@ type IndexedSearchSpec struct {
8888
Replicas int32 `json:"replicas,omitempty"`
8989
}
9090

91+
type NodeExporterSpec struct {
92+
StandardConfig
93+
}
94+
9195
type OtelAgentSpec struct {
9296
StandardConfig
9397
}
@@ -230,8 +234,12 @@ type SourcegraphSpec struct {
230234
// IndexedSearch defines the desired state of the Indexed Search service.
231235
IndexedSearch IndexedSearchSpec `json:"indexedSearch,omitempty"`
232236

237+
// Jaeger defines the desired state of the Jaeger service.
233238
Jaeger JaegerSpec `json:"jaeger,omitempty"`
234239

240+
// NodeExporter defines the desired state of the NodeExporter service.
241+
NodeExporter NodeExporterSpec `json:"nodeExporter,omitempty"`
242+
235243
OtelAgent OtelAgentSpec `json:"openTelemetryAgent,omitempty"`
236244
OtelCollector OtelCollectorSpec `json:"openTelemetryCollector,omitempty"`
237245

@@ -272,24 +280,25 @@ type SourcegraphSpec struct {
272280
// SourcegraphServicesToReconcile is a list of all Sourcegraph services that will be reconciled by appliance.
273281
var SourcegraphServicesToReconcile = []string{
274282
"blobstore",
275-
"repo-updater",
276-
"symbols",
277-
"gitserver",
278-
"redis",
279-
"pgsql",
280-
"syntect",
281-
"precise-code-intel",
283+
"cadvisor",
282284
"code-insights-db",
283285
"code-intel-db",
284-
"prometheus",
285-
"cadvisor",
286-
"worker",
287286
"frontend",
288-
"searcher",
289-
"indexed-searcher",
287+
"gitserver",
290288
"grafana",
289+
"indexed-searcher",
291290
"jaeger",
291+
"nodeexporter",
292292
"otel",
293+
"pgsql",
294+
"precise-code-intel",
295+
"prometheus",
296+
"redis",
297+
"repo-updater",
298+
"searcher",
299+
"symbols",
300+
"syntect",
301+
"worker",
293302
}
294303

295304
// SourcegraphStatus defines the observed state of Sourcegraph

internal/appliance/reconciler/BUILD.bazel

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@ go_library(
1414
"indexed_search.go",
1515
"jaeger.go",
1616
"kubernetes.go",
17+
"nodeexporter.go",
1718
"otel_agent.go",
1819
"pgsql.go",
1920
"precise_code_intel.go",
@@ -87,6 +88,7 @@ go_test(
8788
"helpers_test.go",
8889
"indexed_search_test.go",
8990
"jaeger_test.go",
91+
"nodeexporter_test.go",
9092
"otel_agent_test.go",
9193
"pgsql_test.go",
9294
"precise_code_intel_test.go",
Lines changed: 163 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,163 @@
1+
package reconciler
2+
3+
import (
4+
"context"
5+
6+
appsv1 "k8s.io/api/apps/v1"
7+
corev1 "k8s.io/api/core/v1"
8+
rbacv1 "k8s.io/api/rbac/v1"
9+
"k8s.io/apimachinery/pkg/api/resource"
10+
"k8s.io/apimachinery/pkg/util/intstr"
11+
"sigs.k8s.io/controller-runtime/pkg/client"
12+
13+
"github.com/sourcegraph/sourcegraph/internal/appliance/config"
14+
"github.com/sourcegraph/sourcegraph/internal/k8s/resource/container"
15+
"github.com/sourcegraph/sourcegraph/internal/k8s/resource/daemonset"
16+
"github.com/sourcegraph/sourcegraph/internal/k8s/resource/pod"
17+
"github.com/sourcegraph/sourcegraph/internal/k8s/resource/role"
18+
"github.com/sourcegraph/sourcegraph/internal/k8s/resource/rolebinding"
19+
"github.com/sourcegraph/sourcegraph/internal/k8s/resource/service"
20+
"github.com/sourcegraph/sourcegraph/lib/pointers"
21+
)
22+
23+
func (r *Reconciler) reconcileNodeExporter(ctx context.Context, sg *config.Sourcegraph, owner client.Object) error {
24+
if err := r.reconcileNodeExporterRole(ctx, sg, owner); err != nil {
25+
return err
26+
}
27+
if err := r.reconcileNodeExporterRoleBinding(ctx, sg, owner); err != nil {
28+
return err
29+
}
30+
if err := r.reconcileNodeExporterService(ctx, sg, owner); err != nil {
31+
return err
32+
}
33+
if err := r.reconcileNodeExporterDaemonSet(ctx, sg, owner); err != nil {
34+
return err
35+
}
36+
37+
return nil
38+
}
39+
40+
func (r *Reconciler) reconcileNodeExporterDaemonSet(ctx context.Context, sg *config.Sourcegraph, owner client.Object) error {
41+
name := "node-exporter"
42+
cfg := sg.Spec.NodeExporter
43+
44+
ctr := container.NewContainer(name, cfg, config.ContainerConfig{
45+
Image: config.GetDefaultImage(sg, name),
46+
Resources: &corev1.ResourceRequirements{
47+
Requests: corev1.ResourceList{
48+
corev1.ResourceCPU: resource.MustParse("200m"),
49+
corev1.ResourceMemory: resource.MustParse("100Mi"),
50+
},
51+
Limits: corev1.ResourceList{
52+
corev1.ResourceCPU: resource.MustParse("1"),
53+
corev1.ResourceMemory: resource.MustParse("1Gi"),
54+
},
55+
},
56+
})
57+
ctr.Args = []string{
58+
"--web.listen-address=:9100",
59+
"--path.sysfs=/host/sys",
60+
"--path.rootfs=/host/root",
61+
"--path.procfs=/host/proc",
62+
"--no-collector.wifi",
63+
"--no-collector.hwmon",
64+
"--collector.filesystem.ignored-mount-points=^/(dev|proc|sys|var/lib/docker/.+|var/lib/kubelet/pods/.+)($|/)",
65+
"--collector.netclass.ignored-devices=^(veth.*)$",
66+
"--collector.netdev.device-exclude=^(veth.*)$",
67+
}
68+
ctr.SecurityContext = &corev1.SecurityContext{
69+
RunAsUser: pointers.Ptr[int64](65534),
70+
RunAsGroup: pointers.Ptr[int64](65534),
71+
AllowPrivilegeEscalation: pointers.Ptr(false),
72+
ReadOnlyRootFilesystem: pointers.Ptr(true),
73+
}
74+
ctr.Ports = []corev1.ContainerPort{
75+
{Name: "metrics", ContainerPort: 9100, Protocol: corev1.ProtocolTCP},
76+
}
77+
ctr.VolumeMounts = []corev1.VolumeMount{
78+
{Name: "rootfs", MountPath: "/host/root", MountPropagation: pointers.Ptr(corev1.MountPropagationHostToContainer), ReadOnly: true},
79+
{Name: "sys", MountPath: "/host/sys", MountPropagation: pointers.Ptr(corev1.MountPropagationHostToContainer), ReadOnly: true},
80+
{Name: "proc", MountPath: "/host/proc", MountPropagation: pointers.Ptr(corev1.MountPropagationHostToContainer), ReadOnly: true},
81+
}
82+
83+
probe := &corev1.Probe{
84+
ProbeHandler: corev1.ProbeHandler{
85+
HTTPGet: &corev1.HTTPGetAction{
86+
Port: intstr.FromString("metrics"),
87+
Scheme: corev1.URISchemeHTTP},
88+
},
89+
InitialDelaySeconds: 0,
90+
PeriodSeconds: 10,
91+
SuccessThreshold: 1,
92+
TimeoutSeconds: 1,
93+
FailureThreshold: 3,
94+
}
95+
ctr.ReadinessProbe = probe
96+
ctr.LivenessProbe = probe
97+
98+
template := pod.NewPodTemplate(name, cfg)
99+
template.Template.Spec.Containers = []corev1.Container{ctr}
100+
template.Template.Spec.SecurityContext = &corev1.PodSecurityContext{
101+
RunAsUser: pointers.Ptr[int64](65534),
102+
RunAsGroup: pointers.Ptr[int64](65534),
103+
FSGroup: pointers.Ptr[int64](65534),
104+
RunAsNonRoot: pointers.Ptr(true),
105+
}
106+
107+
template.Template.Spec.Volumes = []corev1.Volume{
108+
pod.NewVolumeHostPath("rootfs", "/"),
109+
pod.NewVolumeHostPath("sys", "/sys"),
110+
pod.NewVolumeHostPath("proc", "/proc"),
111+
}
112+
113+
ds := daemonset.New(name, sg.Namespace, sg.Spec.RequestedVersion)
114+
ds.Spec.Template = template.Template
115+
116+
return reconcileObject(ctx, r, sg.Spec.NodeExporter, &ds, &appsv1.DaemonSet{}, sg, owner)
117+
}
118+
119+
func (r *Reconciler) reconcileNodeExporterService(ctx context.Context, sg *config.Sourcegraph, owner client.Object) error {
120+
svc := service.NewService("node-exporter", sg.Namespace, sg.Spec.NodeExporter)
121+
svc.Spec.Ports = []corev1.ServicePort{
122+
{Name: "metrics", TargetPort: intstr.FromString("metrics"), Port: 9100},
123+
}
124+
svc.Spec.Selector = map[string]string{"app": "node-exporter"}
125+
126+
return reconcileObject(ctx, r, sg.Spec.NodeExporter, &svc, &corev1.Service{}, sg, owner)
127+
}
128+
129+
func (r *Reconciler) reconcileNodeExporterRole(ctx context.Context, sg *config.Sourcegraph, owner client.Object) error {
130+
name := "node-exporter"
131+
cfg := sg.Spec.NodeExporter
132+
133+
role := role.NewRole(name, sg.Namespace)
134+
135+
readVerbs := []string{"use"}
136+
role.Rules = []rbacv1.PolicyRule{
137+
{
138+
APIGroups: []string{"policy"},
139+
Resources: []string{"podsecuritypolicies"},
140+
Verbs: readVerbs,
141+
ResourceNames: []string{name},
142+
},
143+
}
144+
145+
return reconcileObject(ctx, r, cfg, &role, &rbacv1.Role{}, sg, owner)
146+
}
147+
148+
func (r *Reconciler) reconcileNodeExporterRoleBinding(ctx context.Context, sg *config.Sourcegraph, owner client.Object) error {
149+
name := "node-exporter"
150+
binding := rolebinding.NewRoleBinding(name, sg.Namespace)
151+
binding.RoleRef = rbacv1.RoleRef{
152+
Kind: "ClusterRole",
153+
Name: name,
154+
}
155+
binding.Subjects = []rbacv1.Subject{
156+
{
157+
Kind: "ServiceAccount",
158+
Name: name,
159+
Namespace: sg.Namespace,
160+
},
161+
}
162+
return reconcileObject(ctx, r, sg.Spec.NodeExporter, &binding, &rbacv1.RoleBinding{}, sg, owner)
163+
}
Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
package reconciler
2+
3+
func (suite *ApplianceTestSuite) TestDeployNodeExporter() {
4+
for _, tc := range []struct {
5+
name string
6+
}{
7+
{name: "nodeexporter/default"},
8+
} {
9+
suite.Run(tc.name, func() {
10+
namespace := suite.createConfigMapAndAwaitReconciliation(tc.name)
11+
suite.makeGoldenAssertions(namespace, tc.name)
12+
})
13+
}
14+
}

internal/appliance/reconciler/otel_agent.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -70,7 +70,7 @@ func (r *Reconciler) reconcileOtelAgentDaemonset(ctx context.Context, sg *config
7070

7171
probe := &corev1.Probe{
7272
ProbeHandler: corev1.ProbeHandler{
73-
HTTPGet: &corev1.HTTPGetAction{Path: "/", Port: intstr.FromInt(13133)},
73+
HTTPGet: &corev1.HTTPGetAction{Path: "/", Port: intstr.FromInt32(13133)},
7474
},
7575
}
7676
ctr.ReadinessProbe = probe

internal/appliance/reconciler/reconcile.go

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -142,6 +142,9 @@ func (r *Reconciler) Reconcile(ctx context.Context, req ctrl.Request) (ctrl.Resu
142142
if err := r.reconcileOtel(ctx, &sourcegraph, &applianceSpec); err != nil {
143143
return ctrl.Result{}, errors.Newf("failed to reconcile OpenTelemetry Collector: %w", err)
144144
}
145+
if err := r.reconcileNodeExporter(ctx, &sourcegraph, &applianceSpec); err != nil {
146+
return ctrl.Result{}, errors.Newf("failed to reconcile NodeExporter: %w", err)
147+
}
145148

146149
// Set the current version annotation in case migration logic depends on it.
147150
applianceSpec.Annotations[config.AnnotationKeyCurrentVersion] = sourcegraph.Spec.RequestedVersion

internal/appliance/reconciler/testdata/golden-fixtures/blobstore/default.yaml

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -114,6 +114,9 @@ resources:
114114
indexedSearch:
115115
disabled: true
116116
117+
nodeExporter:
118+
disabled: true
119+
117120
openTelemetryCollector:
118121
disabled: true
119122

internal/appliance/reconciler/testdata/golden-fixtures/cadvisor/default.yaml

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -151,6 +151,9 @@ resources:
151151
indexedSearch:
152152
disabled: true
153153
154+
nodeExporter:
155+
disabled: true
156+
154157
openTelemetryCollector:
155158
disabled: true
156159

internal/appliance/reconciler/testdata/golden-fixtures/codeinsights/default.yaml

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -303,6 +303,9 @@ resources:
303303
indexedSearch:
304304
disabled: true
305305
306+
nodeExporter:
307+
disabled: true
308+
306309
openTelemetryCollector:
307310
disabled: true
308311

internal/appliance/reconciler/testdata/golden-fixtures/codeintel/default.yaml

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -323,6 +323,9 @@ resources:
323323
indexedSearch:
324324
disabled: true
325325
326+
nodeExporter:
327+
disabled: true
328+
326329
openTelemetryCollector:
327330
disabled: true
328331

0 commit comments

Comments
 (0)