8000 [Feature] Add exporter (#730) · sharekey/kube-arangodb@44dea2c · GitHub
[go: up one dir, main page]

Skip to content

Commit 44dea2c

Browse files
authored
[Feature] Add exporter (arangodb#730)
1 parent 43f7dbc commit 44dea2c

File tree

14 files changed

+701
-28
lines changed

14 files changed

+701
-28
lines changed

exporter.go

Lines changed: 123 additions & 0 deletions
67
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,123 @@
1+
//
2+
// DISCLAIMER
3+
//
4+
// Copyright 2021 ArangoDB GmbH, Cologne, Germany
5+
//
6+
// Licensed under the Apache License, Version 2.0 (the "License");
7+
// you may not use this file except in compliance with the License.
8+
// You may obtain a copy of the License at
9+
//
10+
// http://www.apache.org/licenses/LICENSE-2.0
11+
//
12+
// Unless required by applicable law or agreed to in writing, software
13+
// distributed under the License is distributed on an "AS IS" BASIS,
14+
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15+
// See the License for the specific language governing permissions and
16+
// limitations under the License.
17+
//
18+
// Copyright holder is ArangoDB GmbH, Cologne, Germany
19+
//
20+
// Author Adam Janikowski
21+
//
22+
23+
package main
24+
25+
import (
26+
"io/ioutil"
27+
"os"
28+
"os/signal"
29+
"syscall"
30+
"time"
31+
32+
"github.com/arangodb/kube-arangodb/pkg/exporter"
33+
34+
"github.com/rs/zerolog/log"
35+
"github.com/spf13/cobra"
36+
)
37+
38+
var (
39+
cmdExporter = &cobra.Command{
40+
Use: "exporter",
41+
Run: cmdExporterCheck,
42+
}
43+
44+
exporterInput struct {
45+
listenAddress string
46+
47+
endpoint string
48+
jwtFile string
49+
timeout time.Duration
50+
51+
keyfile string
52+
}
53+
)
54+
55+
func init() {
56+
f := cmdExporter.PersistentFlags()
57+
58+
f.StringVar(&exporterInput.listenAddress, "server.address", ":9101", "Address the exporter will listen on (IP:port)")
59+
f.StringVar(&exporterInput.keyfile, "ssl.keyfile", "", "File containing TLS certificate used for the metrics server. Format equal to ArangoDB keyfiles")
60+
61+
f.StringVar(&exporterInput.endpoint, "arangodb.endpoint", "http://127.0.0.1:8529", "Endpoint used to reach the ArangoDB server")
62+
f.StringVar(&exporterInput.jwtFile, "arangodb.jwt-file", "", "File containing the JWT for authentication with ArangoDB server")
63+
f.DurationVar(&exporterInput.timeout, "arangodb.timeout", time.Second*15, "Timeout of statistics requests for ArangoDB")
64+
65+
cmdMain.AddCommand(cmdExporter)
66+
}
+
68+
func cmdExporterCheck(cmd *cobra.Command, args []string) {
69+
if err := cmdExporterCheckE(); err != nil {
70+
log.Error().Err(err).Msgf("Fatal")
71+
os.Exit(1)
72+
}
73+
}
74+
75+
func onSigterm(f func()) {
76+
sigs := make(chan os.Signal, 1)
77+
78+
signal.Notify(sigs, syscall.SIGINT, syscall.SIGTERM)
79+
80+
go func() {
81+
defer f()
82+
<-sigs
83+
}()
84+
}
85+
86+
func cmdExporterCheckE() error {
87+
p, err := exporter.NewPassthru(exporterInput.endpoint, func() (string, error) {
88+
if exporterInput.jwtFile == "" {
89+
return "", nil
90+
}
91+
92+
data, err := ioutil.ReadFile(exporterInput.jwtFile)
93+
if err != nil {
94+
return "", err
95+
}
96+
97+
return string(data), nil
98+
}, false, 15*time.Second)
99+
if err != nil {
100+
return err
101+
}
102+
103+
exporter := exporter.NewExporter(exporterInput.listenAddress, "/metrics", p)
104+
if exporterInput.keyfile != "" {
105+
if e, err := exporter.WithKeyfile(exporterInput.keyfile); err != nil {
106+
return err
107+
} else {
108+
if r, err := e.Start(); err != nil {
109+
return err
110+
} else {
111+
onSigterm(r.Stop)
112+
return r.Wait()
113+
}
114+
}
115+
} else {
116+
if r, err := exporter.Start(); err != nil {
117+
return err
118+
} else {
119+
onSigterm(r.Stop)
120+
return r.Wait()
121+
}
122+
}
123+
}

pkg/deployment/features/metrics.go

Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
//
2+
// DISCLAIMER
3+
//
4+
// Copyright 2021 ArangoDB GmbH, Cologne, Germany
5+
//
6+
// Licensed under the Apache License, Version 2.0 (the "License");
7+
// you may not use this file except in compliance with the License.
8+
// You may obtain a copy of the License at
9+
//
10+
// http://www.apache.org/licenses/LICENSE-2.0
11+
//
12+
// Unless required by applicable law or agreed to in writing, software
13+
// distributed under the License is distributed on an "AS IS" BASIS,
14+
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15+
// See the License for the specific language governing permissions and
16+
// limitations under the License.
17+
//
18+
// Copyright holder is ArangoDB GmbH, Cologne, Germany
19+
//
20+
// Author Adam Janikowski
21+
//
22+
23+
package features
24+
25+
func init() {
26+
registerFeature(metricsExporter)
27+
}
28+
29+
var metricsExporter = &feature{
30+
name: "metrics-exporter",
31+
description: "Define if internal metrics-exporter should be used",
32+
version: "3.6.0",
33+
enterpriseRequired: false,
34+
enabledByDefault: false,
35+
}
36+
37+
func MetricsExporter() Feature {
38+
return metricsExporter
39+
}

pkg/deployment/images.go

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -322,7 +322,8 @@ func (i *ImageUpdatePod) GetVolumes() ([]core.Volume, []core.VolumeMount) {
322322
return volumes, volumeMounts
323323
}
324324

325-
func (i *ImageUpdatePod) GetSidecars(*core.Pod) {
325+
func (i *ImageUpdatePod) GetSidecars(*core.Pod) error {
326+
return nil
326327
}
327328

328329
func (i *ImageUpdatePod) GetInitContainers(cachedStatus interfaces.Inspector) ([]core.Container, error) {

pkg/deployment/resources/exporter.go

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,8 @@ package resources
2323
import (
2424
"path/filepath"
2525

26+
"github.com/arangodb/go-driver"
27+
2628
api "github.com/arangodb/kube-arangodb/pkg/apis/deployment/v1"
2729
"github.com/arangodb/kube-arangodb/pkg/util/k8sutil/probes"
2830

@@ -59,6 +61,39 @@ func ArangodbExporterContainer(image string, args []string, livenessProbe *probe
5961
return c
6062
}
6163

64+
func createInternalExporterArgs(spec api.DeploymentSpec, groupSpec api.ServerGroupSpec, version driver.Version) []string {
65+
tokenpath := filepath.Join(k8sutil.ExporterJWTVolumeMountDir, constants.SecretKeyToken)
66+
options := k8sutil.CreateOptionPairs(64)
67+
68+
options.Add("--arangodb.jwt-file", tokenpath)
69+
70+
path := k8sutil.ArangoExporterInternalEndpoint
71+
if version.CompareTo("3.8.0") >= 0 {
72+
path = k8sutil.ArangoExporterInternalEndpointV2
73+
}
74+
75+
if port := groupSpec.InternalPort; port == nil {
76+
scheme := "http"
77+
if spec.IsSecure() {
78+
scheme = "https"
79+
}
80+
options.Addf("--arangodb.endpoint", "%s://localhost:%d%s", scheme, k8sutil.ArangoPort, path)
81+
} else {
82+
options.Addf("--arangodb.endpoint", "http://localhost:%d%s", *port, path)
83+
}
84+
85+
keyPath := filepath.Join(k8sutil.TLSKeyfileVolumeMountDir, constants.SecretTLSKeyfile)
86+
if spec.IsSecure() && spec.Metrics.IsTLS() {
87+
options.Add("--ssl.keyfile", keyPath)
88+
}
89+
90+
if port := spec.Metrics.GetPort(); port != k8sutil.ArangoExporterPort {
91+
options.Addf("--server.address", ":%d", port)
92+
}
93+
94+
return options.Sort().AsArgs()
95+
}
96+
6297
func createExporterArgs(spec api.DeploymentSpec, groupSpec api.ServerGroupSpec) []string {
6398
tokenpath := filepath.Join(k8sutil.ExporterJWTVolumeMountDir, constants.SecretKeyToken)
6499
options := k8sutil.CreateOptionPairs(64)
Lines changed: 68 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,68 @@
1+
//
2+
// Copyright 2021 ArangoDB GmbH, Cologne, Germany
3+
//
4+
// Licensed under the Apache License, Version 2.0 (the "License");
5+
// you may not use this file except in compliance with the License.
6+
// You may obtain a copy of the License at
7+
//
8+
// http://www.apache.org/licenses/LICENSE-2.0
9+
//
10+
// Unless required by applicable law or agreed to in writing, software
11+
// distributed under the License is distributed on an "AS IS" BASIS,
12+
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
// See the License for the specific language governing permissions and
14+
// limitations under the License.
15+
//
16+
// Copyright holder is ArangoDB GmbH, Cologne, Germany
17+
//
18+
// Author Adam Janikowski
19+
//
20+
21+
package resources
22+
23+
import (
24+
"os"
25+
"path/filepath"
26+
27+
api "github.com/arangodb/kube-arangodb/pkg/apis/deployment/v1"
28+
"github.com/arangodb/kube-arangodb/pkg/util/errors"
29+
"github.com/arangodb/kube-arangodb/pkg/util/k8sutil/probes"
30+
31+
"github.com/arangodb/kube-arangodb/pkg/util/k8sutil"
32+
v1 "k8s.io/api/core/v1"
33+
)
34+
35+
// ArangodbInternalExporterContainer creates metrics container based on internal exporter
36+
func ArangodbInternalExporterContainer(image string, args []string, livenessProbe *probes.HTTPProbeConfig,
37+
resources v1.ResourceRequirements, securityContext *v1.SecurityContext,
38+
spec api.DeploymentSpec) (v1.Container, error) {
39+
40+
binaryPath, err := os.Executable()
41+
if err != nil {
42+
return v1.Container{}, errors.WithStack(err)
43+
}
44+
exePath := filepath.Join(k8sutil.LifecycleVolumeMountDir, filepath.Base(binaryPath))
45+
46+
c := v1.Container{
47+
Name: k8sutil.ExporterContainerName,
48+
Image: image,
49+
Command: append([]string{exePath, "exporter"}, args...),
50+
Ports: []v1.ContainerPort{
51+
{
52+
Name: "exporter",
53+
ContainerPort: int32(spec.Metrics.GetPort()),
54+
Protocol: v1.ProtocolTCP,
55+
},
56+
},
57+
Resources: k8sutil.ExtractPodResourceRequirement(resources),
58+
ImagePullPolicy: v1.PullIfNotPresent,
59+
SecurityContext: securityContext,
60+
VolumeMounts: []v1.VolumeMount{k8sutil.LifecycleVolumeMount()},
61+
}
62+
63+
if livenessProbe != nil {
64+
c.LivenessProbe = livenessProbe.Create()
65+
}
66+
67+
return c, nil
68+
}

pkg/deployment/resources/pod_creator.go

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -652,7 +652,9 @@ func RenderArangoPod(cachedStatus inspectorInterface.Inspector, deployment k8sut
652652

653653
p.Spec.Volumes, c.VolumeMounts = podCreator.GetVolumes()
654654
p.Spec.Containers = append(p.Spec.Containers, c)
655-
podCreator.GetSidecars(&p)
655+
if err := podCreator.GetSidecars(&p); err != nil {
656+
return nil, err
657+
}
656658

657659
if err := podCreator.ApplyPodSpec(&p.Spec); err != nil {
658660
return nil, err

0 commit comments

Comments
 (0)
0