blob: 8d4094717f46c3acf28f031931d0514d2749b676 [file] [log] [blame]
Radek Pietruszewskif5844312023-10-27 22:41:18 +02001local kube = import "../../../kube/hscloud.libsonnet";
Serge Bazanski363bf4f2020-08-24 21:00:56 +02002
3{
4 // Global sets up a global tier instance of the hscloud monitoring infrastructure.
5 //
6 // This currently consists of Victoria Metrics, to which the agent tier sends metrics data via
7 // the prometheus remote_write protocol.
8 // Victoria Metrics is here used as a long-term storage solution. However, right now, it
9 // just keeps data locally on disk. In the future, S3 snapshots/backups should be introduced.
10 Global(name):: {
11 local global = self,
12 local cfg = global.cfg,
13
14 cfg:: {
15 name: name,
16 namespace: "monitoring-global-%s" % [cfg.name],
17
18 images: {
19 victoria: "victoriametrics/victoria-metrics:v1.40.0",
20 vmauth: "victoriametrics/vmauth:v1.40.0",
Serge Bazanski4f7caf82020-10-10 17:58:09 +020021 grafana: "grafana/grafana:7.2.1",
Serge Bazanski363bf4f2020-08-24 21:00:56 +020022 },
23
24 hosts: {
25 // DNS hostname that this global tier will use. Ingress will run under it.
26 globalAPI: error "hosts.globalAPI must be set",
Serge Bazanski4f7caf82020-10-10 17:58:09 +020027 globalDashboard: error "hosts.globalDashboard must be set",
Serge Bazanski363bf4f2020-08-24 21:00:56 +020028 },
29
30 storageClasses: {
31 // Storage class used for main data retention.
32 victoria: error "storageClasses.victoria must be set",
33 },
34
Serge Bazanski4f7caf82020-10-10 17:58:09 +020035 oauth: {
36 clientId: error "oauth.clientId must be set",
37 clientSecret: error "oauth.clientSecret must be set",
38 },
39
Serge Bazanski363bf4f2020-08-24 21:00:56 +020040 // A list of agents that will push metrics to this instance.
41 // List of:
42 // {
43 // username: the username that the agent will authenticate with
44 // password: the password that the agent will authenticate with
45 // }
46 agents: [],
47 },
48
49 // Generated URLs that agents should use to ship metrics over. Both require HTTP basic
50 // auth, configured via cfg.agents.
Serge Bazanski4f7caf82020-10-10 17:58:09 +020051 // The internal URL that should be used for agents colocated in the same Kubernetes cluster.
Serge Bazanski363bf4f2020-08-24 21:00:56 +020052 internalIngestURL:: "http://%s/api/v1/write" % [global.victoria.serviceAPI.host_colon_port],
Serge Bazanski4f7caf82020-10-10 17:58:09 +020053 // The internal URL that should be used for readers colocated in the same Kubernetes cluster.
54 internalReadURL:: "http://%s/" % [global.victoria.serviceAPI.host_colon_port],
55 // The global URL that should be used for agents sending data over the internet.
Serge Bazanski363bf4f2020-08-24 21:00:56 +020056 globalIngestURL:: "https://%s/api/v1/write" % [cfg.hosts.globalAPI],
Serge Bazanski4f7caf82020-10-10 17:58:09 +020057 // The global URL that should be used for readers over the internet.
58 globalReadURL:: "https://%s" % [cfg.hosts.globalAPI],
Serge Bazanski363bf4f2020-08-24 21:00:56 +020059
60 namespace: kube.Namespace(cfg.namespace),
61 local ns = global.namespace,
62
63 victoria: {
64 local victoria = self,
65
66 pvc: ns.Contain(kube.PersistentVolumeClaim("victoria-data")) {
radex36964dc2023-11-24 11:19:46 +010067 storage:: "64Gi",
68 storageClass:: cfg.storageClasses.victoria,
Serge Bazanski363bf4f2020-08-24 21:00:56 +020069 },
70
71 authSecret: ns.Contain(kube.Secret("vmauth")) {
72 data+: {
73 "config.yaml": std.base64(std.manifestJson({
74 users: [
75 {
76 username: a.username,
77 password: a.password,
78 url_prefix: "http://localhost:8428",
79 }
Serge Bazanski4f7caf82020-10-10 17:58:09 +020080 for a in (cfg.agents + [cfg.loopbackGrafanaUser])
Serge Bazanski363bf4f2020-08-24 21:00:56 +020081 ],
82 }) + "\n")
83 },
84 },
85
86 deploy: ns.Contain(kube.Deployment("victoria")) {
87 spec+: {
88 template+: {
89 spec+: {
radex7a4c27d2023-11-24 13:20:10 +010090 default_container: "vmauth",
Serge Bazanski363bf4f2020-08-24 21:00:56 +020091 containers_: {
92 default: kube.Container("default") {
93 image: cfg.images.victoria,
94 volumeMounts_: {
95 data: { mountPath: "/victoria-metrics-data", },
96 },
97 },
98 vmauth: kube.Container("vmauth") {
99 image: cfg.images.vmauth,
100 command: [
101 "/vmauth-prod",
102 "-auth.config", "/mnt/secret/config.yaml",
103 ],
104 volumeMounts_: {
105 secret: { mountPath: "/mnt/secret", },
106 },
107 ports_: {
108 api: { containerPort: 8427 }
109 },
110 }
111 },
112 volumes_: {
radex4ffc64d2023-11-24 13:28:57 +0100113 data: victoria.pvc.volume,
Serge Bazanski363bf4f2020-08-24 21:00:56 +0200114 secret: kube.SecretVolume(victoria.authSecret),
115 },
116 },
117 },
118 },
119 },
120
121 serviceAPI: ns.Contain(kube.Service("victoria-api")) {
radex8b8f3872023-11-24 11:09:46 +0100122 target:: victoria.deploy,
Serge Bazanski363bf4f2020-08-24 21:00:56 +0200123 },
124
Radek Pietruszewskif5844312023-10-27 22:41:18 +0200125 ingressAPI: ns.Contain(kube.SimpleIngress("victoria-api")) {
126 hosts:: [cfg.hosts.globalAPI],
radexd45584a2023-11-24 12:51:57 +0100127 target:: victoria.serviceAPI,
Serge Bazanski363bf4f2020-08-24 21:00:56 +0200128 },
129 },
Serge Bazanski4f7caf82020-10-10 17:58:09 +0200130
131 grafana: {
132 local grafana = self,
133
134 // grafana.ini, serialized to secret.
135 ini:: {
136 sections: {
137 "auth": {
138 "disable_login_form": true,
139 "oauth_auto_login": true,
140 },
141 "security": {
142 # We do not disable basic auth, as we want to use builtin
143 # users as API users (eg for config reload), but we want
144 # to disable the default admin:admin user.
145 "disable_initial_admin_creation": true,
146 },
147 "auth.generic_oauth": {
148 enabled: true,
149 client_id: cfg.oauth.clientId,
150 client_secret: cfg.oauth.clientSecret,
Serge Bazanskicc2ff792021-01-30 17:26:47 +0100151 auth_url: "https://sso.hackerspace.pl/oauth/authorize",
152 token_url: "https://sso.hackerspace.pl/oauth/token",
153 api_url: "https://sso.hackerspace.pl/api/1/userinfo",
Serge Bazanski4f7caf82020-10-10 17:58:09 +0200154 scopes: "openid",
155 email_attribute_path: "email",
156 allow_sign_up: true,
157 role_attribute_path: "contains(groups, 'grafana-admin')",
158 },
159 "server": {
160 domain: cfg.hosts.globalDashboard,
161 root_url: "https://%s/" % [ cfg.hosts.globalDashboard ],
162 },
163 },
164 },
165
166 datasources:: {
167 apiVersion: 1,
168 datasources: [
169 {
170 name: "victoria-global",
171 type: "prometheus",
172 uid: "victoria-global",
173 isDefault: true,
174 url: global.internalReadURL,
175 basicAuth: true,
176 basicAuthUser: cfg.loopbackGrafanaUser.username,
177 secureJsonData: {
178 basicAuthPassword: cfg.loopbackGrafanaUser.password,
179 },
180 },
181 ],
182 },
183
184 config: ns.Contain(kube.Secret("grafana-config")) {
185 data+: {
186 "grafana.ini": std.base64(std.manifestIni(grafana.ini)),
187 "datasources.yaml": std.base64(std.manifestYamlDoc(grafana.datasources)),
188 },
189 },
190
191 pvc: ns.Contain(kube.PersistentVolumeClaim("grafana-data")) {
radex36964dc2023-11-24 11:19:46 +0100192 storage:: "8Gi",
193 storageClass:: cfg.storageClasses.grafana,
Serge Bazanski4f7caf82020-10-10 17:58:09 +0200194 },
195
196 deploy: ns.Contain(kube.Deployment("grafana")) {
197 spec+: {
198 template+: {
199 spec+: {
200 containers_: {
201 default: kube.Container("default") {
202 image: cfg.images.grafana,
203 ports_: {
204 public: { containerPort: 3000 },
205 },
206 env_: {
207 GF_PATHS_CONFIG: "/etc/hscloud-config/grafana.ini",
208 GF_PATHS_PROVISIONING: "/etc/hscloud-config/provisioning",
209 GF_PATHS_DATA: "/var/lib/grafana",
210 },
211 volumeMounts_: {
212 config: { mountPath: "/etc/hscloud-config", },
213 data: { mountPath: "/var/lib/grafana", },
214 },
215 resources: {
216 requests: { cpu: "100m", memory: "256M", },
217 limits: { cpu: "200m", memory: "512M", },
218 },
219 },
220 },
221 volumes_: {
radex4ffc64d2023-11-24 13:28:57 +0100222 data: grafana.pvc.volume,
Serge Bazanski4f7caf82020-10-10 17:58:09 +0200223 config: kube.SecretVolume(grafana.config) {
224 secret+: {
225 items: [
226 { key: "grafana.ini", path: "grafana.ini", },
227 { key: "datasources.yaml", path: "provisioning/datasources/datasources.yaml", },
228 ],
229 },
230 },
231 },
232 },
233 },
234 },
235 },
236
237 service: ns.Contain(kube.Service("grafana-public")) {
radex8b8f3872023-11-24 11:09:46 +0100238 target:: grafana.deploy,
Serge Bazanski4f7caf82020-10-10 17:58:09 +0200239 },
240
Radek Pietruszewskif5844312023-10-27 22:41:18 +0200241 ingress: ns.Contain(kube.SimpleIngress("grafana-public")) {
242 hosts:: [cfg.hosts.globalDashboard],
radexd45584a2023-11-24 12:51:57 +0100243 target:: grafana.service,
Serge Bazanski4f7caf82020-10-10 17:58:09 +0200244 },
245 },
Serge Bazanski363bf4f2020-08-24 21:00:56 +0200246 }
247}