Skip to content

Commit 83a60a9

Browse files
authored
Merge pull request #27 from jordanbean-msft/main
AKS deployment
2 parents cc5b62e + e5e37b5 commit 83a60a9

File tree

12 files changed

+953
-344
lines changed

12 files changed

+953
-344
lines changed

.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,3 +32,4 @@ debug_*
3232

3333
# .env files
3434
*.env
35+
elasticsearch_env

README.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -236,6 +236,8 @@ if you are not using Azure, you can use Linux with Docker, please refer to the [
236236

237237
![](image/image_oZJ-KGOxa5.png)
238238

239+
## Kubernetes
240+
For cloud native deployment on Kubernetes, please refer to the [Kubernetes deployment document](deploy/kubernetes.md).
239241

240242
## Congratulations, View Dashboard
241243

deploy/aks-deployment.yml

Lines changed: 265 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,265 @@
1+
# This file contains the Kubernetes deployment configuration for the Copilot Usage Advanced Dashboard
2+
# --- PersistentVolumeClaim ---
3+
apiVersion: v1
4+
kind: PersistentVolumeClaim
5+
metadata:
6+
name: shared-pvc
7+
spec:
8+
accessModes:
9+
- ReadWriteMany
10+
storageClassName: azurefile-csi-nfs
11+
resources:
12+
requests:
13+
storage: 5Gi
14+
15+
# --- Secrets ---
16+
---
17+
apiVersion: v1
18+
kind: Secret
19+
metadata:
20+
name: github-pat
21+
type: Opaque
22+
stringData:
23+
GITHUB_PAT: "__GITHUB_PAT__" # Replace with your GitHub PAT
24+
---
25+
apiVersion: v1
26+
kind: Secret
27+
metadata:
28+
name: grafana-credentials
29+
type: Opaque
30+
stringData:
31+
GRAFANA_USERNAME: "__GRAFANA_USERNAME__"
32+
GRAFANA_PASSWORD: "__GRAFANA_PASSWORD__"
33+
34+
# --- Elasticsearch Deployment ---
35+
---
36+
apiVersion: apps/v1
37+
kind: Deployment
38+
metadata:
39+
name: elasticsearch
40+
spec:
41+
replicas: 1
42+
selector:
43+
matchLabels:
44+
app: elasticsearch
45+
template:
46+
metadata:
47+
labels:
48+
app: elasticsearch
49+
spec:
50+
initContainers:
51+
- name: init-elasticsearch
52+
image: busybox:1.28
53+
command: ["/bin/sh", "-c"]
54+
args:
55+
- chown -R 1000:1000 /usr/share/elasticsearch/data && chown -R 1000:1000 /usr/share/elasticsearch/logs
56+
volumeMounts:
57+
- name: elasticsearch
58+
mountPath: /usr/share/elasticsearch/data
59+
- name: elasticsearch
60+
mountPath: /usr/share/elasticsearch/logs
61+
containers:
62+
- name: elasticsearch
63+
image: ghcr.io/satomic/copilot-usage-advanced-dashboard/elastic-search:main
64+
ports:
65+
- containerPort: 9200
66+
volumeMounts:
67+
- name: elasticsearch
68+
mountPath: /usr/share/elasticsearch/data
69+
subPath: data
70+
- name: elasticsearch
71+
mountPath: /usr/share/elasticsearch/logs
72+
subPath: logs
73+
resources:
74+
requests:
75+
cpu: "1"
76+
memory: "2Gi"
77+
limits:
78+
cpu: "2"
79+
memory: "4Gi"
80+
livenessProbe:
81+
httpGet:
82+
path: /_cluster/health
83+
port: 9200
84+
initialDelaySeconds: 30
85+
periodSeconds: 10
86+
readinessProbe:
87+
httpGet:
88+
path: /_cluster/health
89+
port: 9200
90+
initialDelaySeconds: 10
91+
periodSeconds: 10
92+
volumes:
93+
- name: elasticsearch
94+
persistentVolumeClaim:
95+
claimName: shared-pvc
96+
---
97+
apiVersion: v1
98+
kind: Service
99+
metadata:
100+
name: elasticsearch
101+
spec:
102+
selector:
103+
app: elasticsearch
104+
ports:
105+
- protocol: TCP
106+
port: 9200
107+
targetPort: 9200
108+
109+
# --- Grafana Deployment ---
110+
---
111+
apiVersion: apps/v1
112+
kind: Deployment
113+
metadata:
114+
name: grafana
115+
spec:
116+
replicas: 1
117+
selector:
118+
matchLabels:
119+
app: grafana
120+
template:
121+
metadata:
122+
labels:
123+
app: grafana
124+
spec:
125+
initContainers:
126+
- name: update-grafana
127+
image: ghcr.io/satomic/copilot-usage-advanced-dashboard/grafana-updater:main
128+
envFrom:
129+
- secretRef:
130+
name: grafana-credentials
131+
env:
132+
- name: ELASTICSEARCH_URL
133+
value: "http://elasticsearch:9200"
134+
- name: GRAFANA_URL
135+
value: "http://grafana:80"
136+
resources:
137+
requests:
138+
cpu: "0.25"
139+
memory: "256Mi"
140+
limits:
141+
cpu: "0.5"
142+
memory: "512Mi"
143+
containers:
144+
- name: grafana
145+
image: ghcr.io/satomic/copilot-usage-advanced-dashboard/grafana:main
146+
ports:
147+
- containerPort: 80
148+
envFrom:
149+
- secretRef:
150+
name: grafana-credentials
151+
env:
152+
- name: GF_LOG_LEVEL
153+
value: debug
154+
- name: GF_SERVER_HTTP_PORT
155+
value: "80"
156+
- name: GF_SECURITY_ADMIN_USER
157+
valueFrom:
158+
secretKeyRef:
159+
name: grafana-credentials
160+
key: GRAFANA_USERNAME
161+
- name: GF_SECURITY_ADMIN_PASSWORD
162+
valueFrom:
163+
secretKeyRef:
164+
name: grafana-credentials
165+
key: GRAFANA_PASSWORD
166+
volumeMounts:
167+
- name: grafana-data
168+
mountPath: /var/lib/grafana
169+
subPath: grafana
170+
resources:
171+
requests:
172+
cpu: "0.5"
173+
memory: "512Mi"
174+
limits:
175+
cpu: "1"
176+
memory: "1Gi"
177+
livenessProbe:
178+
httpGet:
179+
path: /api/health
180+
port: 80
181+
initialDelaySeconds: 30
182+
periodSeconds: 10
183+
readinessProbe:
184+
httpGet:
185+
path: /api/health
186+
port: 80
187+
initialDelaySeconds: 10
188+
periodSeconds: 10
189+
volumes:
190+
- name: grafana-data
191+
persistentVolumeClaim:
192+
claimName: shared-pvc
193+
---
194+
apiVersion: v1
195+
kind: Service
196+
metadata:
197+
name: grafana
198+
spec:
199+
selector:
200+
app: grafana
201+
ports:
202+
- protocol: TCP
203+
port: 80
204+
targetPort: 80
205+
---
206+
apiVersion: networking.k8s.io/v1
207+
kind: Ingress
208+
metadata:
209+
name: grafana-ingress
210+
spec:
211+
ingressClassName: webapprouting.kubernetes.azure.com
212+
rules:
213+
- http:
214+
paths:
215+
- backend:
216+
service:
217+
name: grafana
218+
port:
219+
number: 80
220+
path: /
221+
pathType: Prefix
222+
223+
# --- cpuad-updater CronJob ---
224+
---
225+
apiVersion: batch/v1
226+
kind: CronJob
227+
metadata:
228+
name: cpuad-updater
229+
spec:
230+
schedule: "0 */6 * * *" # every 6 hours
231+
jobTemplate:
232+
spec:
233+
template:
234+
spec:
235+
containers:
236+
- name: cpuad-updater
237+
image: ghcr.io/satomic/copilot-usage-advanced-dashboard/cpuad-updater:main
238+
envFrom:
239+
- secretRef:
240+
name: github-pat
241+
env:
242+
- name: ORGANIZATION_SLUGS
243+
value: "__ORGANIZATION_SLUGS__"
244+
- name: ELASTICSEARCH_URL
245+
value: "http://elasticsearch:9200"
246+
- name: LOG_PATH
247+
value: "logs"
248+
- name: EXECUTION_INTERVAL
249+
value: "6"
250+
volumeMounts:
251+
- name: cpuad-updater-logs
252+
mountPath: /app/logs
253+
subPath: cpuad
254+
resources:
255+
requests:
256+
cpu: "0.5"
257+
memory: "512Mi"
258+
limits:
259+
cpu: "1"
260+
memory: "1Gi"
261+
restartPolicy: OnFailure
262+
volumes:
263+
- name: cpuad-updater-logs
264+
persistentVolumeClaim:
265+
claimName: shared-pvc

deploy/kubernetes.md

Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,54 @@
1+
# About
2+
3+
Application can be deployed to a kubernetes cluster
4+
5+
## Architecture diagram
6+
7+
![](/image/aks.drawio.png)
8+
9+
## Technology stack
10+
11+
Dependent technology stack:
12+
13+
- Kubernetes (pods, jobs, services, persistent storage, ingress)
14+
- Elasticsearch
15+
- Grafana
16+
- Python3
17+
18+
## Deployment manifest
19+
20+
Available [here](aks-deployment.yml).
21+
22+
## Deploy in Kubernetes
23+
This document describes how to deploy the application in Kubernetes.
24+
25+
Variables used in the manifest:
26+
- `__GITHUB_PAT__`
27+
- `__GRAFANA_USERNAME__`
28+
- `__GRAFANA_PASSWORD__`
29+
- `__ORGANIZATION_SLUGS__`
30+
31+
Replacement can be done using `envsubst` tool:
32+
33+
```sh
34+
export __GITHUB_PAT__=your_pat
35+
export __GRAFANA_USERNAME__=your_user
36+
export __GRAFANA_PASSWORD__=your_pass
37+
export __ORGANIZATION_SLUGS__=your_orgs
38+
39+
envsubst < deploy/aks-deployment.yml | kubectl apply -f -
40+
```
41+
42+
### Deployment in Azure Kubernetes Service - AKS
43+
44+
If you're using Azure Kubernetes Service - AKS:
45+
1. Enable [App Routing](https://learn.microsoft.com/en-us/azure/aks/app-routing)
46+
2. Update variables.
47+
3. Apply the manifest in your cluster.
48+
49+
### Deployment in non-Azure Kubernetes cluster
50+
51+
1. Update PVC (Persitent Volume Claim) to one supported in your cluster
52+
2. Update Ingress
53+
3. Update variables.
54+
4. Apply the manifest in your cluster.

deploy/linux-with-docker.md

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -88,6 +88,15 @@ Server:
8888

8989
```
9090

91+
## Using existing images
92+
93+
Docker images for all app components are available in [GitHub container registry](https://github.com/satomic?tab=packages&repo_name=copilot-usage-advanced-dashboard):
94+
95+
- **Elastic Search** - `docker pull ghcr.io/satomic/copilot-usage-advanced-dashboard/elastic-search:main`
96+
- **grafana** - `docker pull ghcr.io/satomic/copilot-usage-advanced-dashboard/grafana:main`
97+
- **grafana-updater** - `docker pull ghcr.io/satomic/copilot-usage-advanced-dashboard/grafana-updater:main`
98+
- **cpuad-updater** - `docker pull ghcr.io/satomic/copilot-usage-advanced-dashboard/cpuad-updater:main`
99+
91100
## Download source code
92101

93102
Put all the work in the `/srv` directory, click [download zip archive](https://github.com/satomic/copilot-usage-advanced-dashboard/archive/refs/heads/main.zip), unzip and rename the folder to `copilot-usage-advanced-dashboard`, or directly `git clone`

image/aks.drawio.png

43.9 KB
Loading

src/cpuad-updater/grafana/dashboard-template.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@
1919
"editable": true,
2020
"fiscalYearStartMonth": 0,
2121
"graphTooltip": 0,
22+
"id": null,
2223
"links": [],
2324
"panels": [
2425
{

0 commit comments

Comments
 (0)