kuma
270 строк · 8.5 Кб
1package observability
2
3import (
4"fmt"
5"net"
6
7. "github.com/onsi/ginkgo/v2"
8. "github.com/onsi/gomega"
9
10. "github.com/kumahq/kuma/test/framework"
11"github.com/kumahq/kuma/test/framework/client"
12"github.com/kumahq/kuma/test/framework/deployments/testserver"
13"github.com/kumahq/kuma/test/framework/envs/kubernetes"
14)
15
16func MeshAndMetricsAggregate(name string) InstallFunc {
17mesh := fmt.Sprintf(`
18apiVersion: kuma.io/v1alpha1
19kind: Mesh
20metadata:
21name: %s
22spec:
23metrics:
24enabledBackend: prom-1
25backends:
26- name: prom-1
27type: prometheus
28conf:
29port: 1234
30path: /metrics
31envoy:
32filterRegex: concurrency
33skipMTLS: true
34aggregate:
35- name: path-stats
36path: "/path-stats"
37port: 80
38- name: mesh-default
39path: "/mesh-default"
40port: 80
41- name: service-to-override
42path: "/service-to-override"
43port: 80
44- name: not-working-service
45path: "/not-working-service"
46port: 81`, name)
47return YamlK8s(mesh)
48}
49
50func MeshAndMetricsEnabled(name string) InstallFunc {
51mesh := fmt.Sprintf(`
52apiVersion: kuma.io/v1alpha1
53kind: Mesh
54metadata:
55name: %s
56spec:
57metrics:
58enabledBackend: prom-1
59backends:
60- name: prom-1
61type: prometheus
62conf:
63envoy:
64filterRegex: concurrency
65port: 1234
66path: /metrics
67skipMTLS: true`, name)
68return YamlK8s(mesh)
69}
70
71func MeshAndEnvoyMetricsFilters(name string, usedOnly string) InstallFunc {
72mesh := fmt.Sprintf(`
73apiVersion: kuma.io/v1alpha1
74kind: Mesh
75metadata:
76name: %s
77spec:
78metrics:
79enabledBackend: prom-1
80backends:
81- name: prom-1
82type: prometheus
83conf:
84port: 5555
85path: /metrics/stats
86envoy:
87filterRegex: http2_act.*
88usedOnly: %s
89skipMTLS: true
90aggregate:
91- name: path-stats
92path: "/path-stats"
93port: 80`, name, usedOnly)
94return YamlK8s(mesh)
95}
96
97func ApplicationsMetrics() {
98const namespace = "applications-metrics"
99const mesh = "applications-metrics"
100const meshNoAggregate = "applications-metrics-no-aggregeate"
101const meshEnvoyFilter = "applications-metrics-envoy-filter"
102
103BeforeAll(func() {
104err := NewClusterSetup().
105Install(MeshAndMetricsAggregate(mesh)).
106Install(MeshAndMetricsEnabled(meshNoAggregate)).
107Install(MeshAndEnvoyMetricsFilters(meshEnvoyFilter, "false")).
108Install(NamespaceWithSidecarInjection(namespace)).
109Install(testserver.Install(
110testserver.WithNamespace(namespace),
111testserver.WithMesh(mesh),
112testserver.WithName("test-server"),
113)).
114Install(testserver.Install(
115testserver.WithNamespace(namespace),
116testserver.WithMesh(meshEnvoyFilter),
117testserver.WithName("test-server-filter"),
118)).
119Install(testserver.Install(
120testserver.WithNamespace(namespace),
121testserver.WithMesh(meshNoAggregate),
122testserver.WithName("test-server-dp-metrics"),
123testserver.WithoutProbes(), // when application binds to localhost you cannot access it
124testserver.WithEchoArgs("--ip", "localhost"),
125testserver.WithPodAnnotations(map[string]string{
126"prometheus.metrics.kuma.io/aggregate-app-path": "/my-app",
127"prometheus.metrics.kuma.io/aggregate-app-port": "80",
128"prometheus.metrics.kuma.io/aggregate-app-address": "localhost",
129"prometheus.metrics.kuma.io/aggregate-other-app-path": "/other-app",
130"prometheus.metrics.kuma.io/aggregate-other-app-port": "80",
131}))).
132Install(testserver.Install(
133testserver.WithNamespace(namespace),
134testserver.WithMesh(mesh),
135testserver.WithName("test-server-override-mesh"),
136testserver.WithPodAnnotations(map[string]string{
137"prometheus.metrics.kuma.io/aggregate-path-stats-enabled": "false",
138"prometheus.metrics.kuma.io/aggregate-app-path": "/my-app",
139"prometheus.metrics.kuma.io/aggregate-app-port": "80",
140"prometheus.metrics.kuma.io/aggregate-service-to-override-path": "/overridden",
141"prometheus.metrics.kuma.io/aggregate-service-to-override-port": "80",
142}))).
143Setup(kubernetes.Cluster)
144Expect(err).To(Succeed())
145})
146E2EAfterAll(func() {
147Expect(kubernetes.Cluster.TriggerDeleteNamespace(namespace)).To(Succeed())
148Expect(kubernetes.Cluster.DeleteMesh(mesh)).To(Succeed())
149Expect(kubernetes.Cluster.DeleteMesh(meshNoAggregate)).To(Succeed())
150})
151
152It("should scrape metrics defined in mesh and not fail when defined service doesn't exist", func() {
153// given
154podIp, err := PodIPOfApp(kubernetes.Cluster, "test-server", namespace)
155Expect(err).ToNot(HaveOccurred())
156
157// when
158stdout, _, err := client.CollectResponse(
159kubernetes.Cluster, "test-server", "http://"+net.JoinHostPort(podIp, "1234")+"/metrics",
160client.FromKubernetesPod(namespace, "test-server"),
161)
162
163// then
164Expect(err).ToNot(HaveOccurred())
165Expect(stdout).ToNot(BeNil())
166// response returned by test-server
167Expect(stdout).To(ContainSubstring("path-stats"))
168// metric from envoy
169Expect(stdout).To(ContainSubstring("envoy_server_concurrency"))
170// response doesn't exist
171Expect(stdout).ToNot(ContainSubstring("not-working-service"))
172})
173
174It("should override mesh configuration with annotation", func() {
175// given
176podIp, err := PodIPOfApp(kubernetes.Cluster, "test-server-override-mesh", namespace)
177Expect(err).ToNot(HaveOccurred())
178
179// when
180stdout, _, err := client.CollectResponse(
181kubernetes.Cluster, "test-server-override-mesh", "http://"+net.JoinHostPort(podIp, "1234")+"/metrics",
182client.FromKubernetesPod(namespace, "test-server-override-mesh"),
183)
184
185// then
186Expect(err).ToNot(HaveOccurred())
187Expect(stdout).ToNot(BeNil())
188
189// response doesn't exist because was disabled
190Expect(stdout).ToNot(ContainSubstring("path-stats"))
191// path has been overridden
192Expect(stdout).ToNot(ContainSubstring("service-to-override"))
193// response doesn't exist
194Expect(stdout).ToNot(ContainSubstring("not-working-service"))
195
196// overridden by pod
197Expect(stdout).To(ContainSubstring("overridden"))
198// overridden by pod
199Expect(stdout).To(ContainSubstring("mesh-default"))
200// added in pod
201Expect(stdout).To(ContainSubstring("my-app"))
202// metric from envoy
203Expect(stdout).To(ContainSubstring("envoy_server_concurrency"))
204})
205
206It("should use only configuration from dataplane", func() {
207// given
208podIp, err := PodIPOfApp(kubernetes.Cluster, "test-server-dp-metrics", namespace)
209Expect(err).ToNot(HaveOccurred())
210
211// when
212stdout, _, err := client.CollectResponse(
213kubernetes.Cluster, "test-server-dp-metrics", "http://"+net.JoinHostPort(podIp, "1234")+"/metrics",
214client.FromKubernetesPod(namespace, "test-server-dp-metrics"),
215)
216
217// then
218Expect(err).ToNot(HaveOccurred())
219Expect(stdout).ToNot(BeNil())
220
221// response doesn't exist because was disabled
222Expect(stdout).ToNot(ContainSubstring("path-stats"))
223// path has been overridden
224Expect(stdout).ToNot(ContainSubstring("service-to-override"))
225
226// overridden by pod
227Expect(stdout).To(ContainSubstring("my-app"))
228// overridden by pod but binding to localhost so it's not available
229Expect(stdout).ToNot(ContainSubstring("other-app"))
230// metric from envoy
231Expect(stdout).To(ContainSubstring("envoy_server_concurrency"))
232})
233
234It("should return filtered Envoy metrics and react for change of usedOnly parameter", func() {
235// given
236podIp, err := PodIPOfApp(kubernetes.Cluster, "test-server-filter", namespace)
237Expect(err).ToNot(HaveOccurred())
238
239// when
240stdout, _, err := client.CollectResponse(
241kubernetes.Cluster, "test-server-filter", "http://"+net.JoinHostPort(podIp, "5555")+"/metrics/stats",
242client.FromKubernetesPod(namespace, "test-server-filter"),
243)
244
245// then
246Expect(err).ToNot(HaveOccurred())
247Expect(stdout).ToNot(BeNil())
248
249// other application metrics
250Expect(stdout).To(ContainSubstring("path-stats"))
251// metric from envoy
252Expect(stdout).To(ContainSubstring("kuma_envoy_admin"))
253
254// when usedOnly is enabled
255Expect(MeshAndEnvoyMetricsFilters(meshEnvoyFilter, "true")(kubernetes.Cluster)).To(Succeed())
256
257// then
258Eventually(func(g Gomega) {
259stdout, _, err := client.CollectResponse(
260kubernetes.Cluster, "test-server-filter", "http://"+net.JoinHostPort(podIp, "5555")+"/metrics/stats",
261client.FromKubernetesPod(namespace, "test-server-filter"),
262)
263g.Expect(err).ToNot(HaveOccurred())
264g.Expect(stdout).To(And(
265ContainSubstring("path-stats"),
266Not(ContainSubstring("kuma_envoy_admin")),
267))
268}, "30s", "1s").Should(Succeed())
269})
270}
271