Skip to content

Commit cdd0822

Browse files
committed
can work inside cluster
1 parent 1f42814 commit cdd0822

File tree

10 files changed

+168
-7
lines changed

10 files changed

+168
-7
lines changed

Dockerfile

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
FROM golang:latest
2+
3+
WORKDIR /app
4+
COPY go.mod go.sum ./
5+
RUN go mod download
6+
COPY ./app/main.go .
7+
RUN go build -o main .
8+
CMD ["./main"]

README.md

Lines changed: 61 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,60 @@ Once this tool detect pod failure, this tool send alert to MS Teams.
1919

2020
# Usage
2121

22+
**This tool works as both inside cluster pod and go application outside cluster.**
23+
24+
# Inside Cluster
25+
26+
## Configuration
27+
28+
**Set environment variables like below**
29+
30+
Please modify kubernetes/deploy_pod_monitoring_tool.yaml like below.
31+
32+
```
33+
env:
34+
# !! replace TEAMS_ENDPOINT with your Teams webhook endpoint
35+
# - name: TEAMS_ENDPOINT
36+
# value: "https://outlook.office.com/webhook/XXXXXXXX"
37+
- name: OBSERVE_PERIOD
38+
value: "10"
39+
- name: OBSERVED_NAMESPACE
40+
value: "default"
41+
```
42+
43+
## Launch
44+
45+
**Run this tool simply**
46+
47+
```
48+
kubectl apply -f ./kubernetes/prerequisite.yaml
49+
kubectl apply -f ./kubernetes/deploy_pod_monitoring_tool.yaml
50+
```
51+
52+
```
53+
❯ kubectl get po -n pod-monitoring
54+
NAME READY STATUS RESTARTS AGE
55+
pod-monitoring-tool-555688b96-b2z2t 1/1 Running 0 4s
56+
```
57+
58+
## Verification
59+
60+
**The following manifests can be used to verify that this tool works successfully.**
61+
62+
```
63+
❯ kubectl apply -f ./kubernetes/failure_test
64+
deployment.apps/nginx created
65+
deployment.apps/nginx2 created
66+
```
67+
68+
**And then, you can find 2 pods is in failed state.**
69+
70+
The alert can be found in your MS Teams like below.
71+
72+
![](./assets/teams_alert.PNG)
73+
74+
# Outside Cluster
75+
2276
## Configuration
2377

2478
**Set environment variables like below**
@@ -45,7 +99,7 @@ OBSERVE_PERIOD=10
4599
**The following manifests can be used to verify that this tool works successfully.**
46100

47101
```
48-
❯ kubectl apply -f .
102+
❯ kubectl apply -f ./kubernetes/failure_test
49103
deployment.apps/nginx created
50104
deployment.apps/nginx2 created
51105
```
@@ -64,4 +118,9 @@ deployment.apps/nginx2 created
64118

65119
The alert can be found in your MS Teams like below.
66120

67-
![](teams_alert.PNG)
121+
![](./assets/teams_alert.PNG)
122+
123+
# Options
124+
125+
if you set TEAMS_HEARTBEAT_ENDPOINT variable, succesful notification can be notified every observation period like below.
126+
![](./assets/heartbeat.png)

main.go renamed to app/main.go

Lines changed: 34 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@ import (
2020
)
2121

2222
// namespace which is observed
23-
var namespace string = getEnv("NAMESPACE", "default")
23+
var namespace string = getEnv("OBSERVED_NAMESPACE", "default")
2424

2525
// observe period (sec)
2626
var observePeriod = 10
@@ -30,6 +30,9 @@ var observePeriod = 10
3030
// TODO Erace Specific endpoint
3131
var teamsEndpoint string = getEnv("TEAMS_ENDPOINT", "")
3232

33+
// (Optional) teamsHeartbeatEndpoint is a endpoint where this tool alert when all pod works successfully
34+
var teamsHeartbeatEndpoint string = getEnv("TEAMS_HEARTBEAT_ENDPOINT", "")
35+
3336
func getEnv(key, fallback string) string {
3437
if value, ok := os.LookupEnv(key); ok {
3538
return value
@@ -43,6 +46,12 @@ func main() {
4346
log.Fatal("please set TEAMS_ENDPOINT\n")
4447
return
4548
}
49+
50+
if teamsHeartbeatEndpoint != "" {
51+
// send heartbeat to teams at every observation period
52+
log.Printf("Heartbeat will be notified every %v seconds\n", observePeriod)
53+
}
54+
4655
observePeriod, err := strconv.Atoi(getEnv("OBSERVE_PERIOD", string(10)))
4756
if err != nil {
4857
log.Fatal(err)
@@ -81,9 +90,14 @@ func listPod(clientset *kubernetes.Clientset) {
8190
// There is no NotReady Pods
8291
if len(notReadyPods) == 0 {
8392
log.Println("All Pod work succesfully")
93+
if teamsHeartbeatEndpoint != "" {
94+
// send heartbeat to teams at every observation period
95+
sendAlertToTeams("PodMonitoringTool Heartbeat", "All Pod work succesfully", teamsHeartbeatEndpoint)
96+
}
97+
8498
} else {
8599
msg := generateAlertMsg(notReadyPods)
86-
sendAlertToTeams(msg)
100+
sendAlertToTeams("Pod Defect Alert", msg, teamsEndpoint)
87101
}
88102

89103
}
@@ -128,26 +142,41 @@ func hasNotReadyContainer(p v1.Pod) bool {
128142
}
129143

130144
func getKubeConfig() *rest.Config {
145+
// Inside Cluster Config
146+
if exists("/run/secrets/kubernetes.io/serviceaccount") {
147+
config, err := rest.InClusterConfig()
148+
if err != nil {
149+
panic(err.Error())
150+
}
151+
return config
152+
}
153+
// Outside Cluster Config
131154
var kubeconfig *string
132155
if home := homeDir(); home != "" {
133156
kubeconfig = flag.String("kubeconfig", filepath.Join(home, ".kube", "config"), "(optional) absolute path to the kubeconfig file")
134157
} else {
135158
kubeconfig = flag.String("kubeconfig", "", "absolute path to the kubeconfig file")
136159
}
160+
137161
flag.Parse()
138162

139163
// use the current context in kubeconfig
140164
config, err := clientcmd.BuildConfigFromFlags("", *kubeconfig)
141165
if err != nil {
142166
panic(err.Error())
143167
}
168+
144169
return config
145170
}
171+
func exists(name string) bool {
172+
_, err := os.Stat(name)
173+
return !os.IsNotExist(err)
174+
}
146175

147-
func sendAlertToTeams(msg string) {
148-
b := fmt.Sprintf(`{ "title": "Pod Defect Alert", "text": "%v"}`, msg)
176+
func sendAlertToTeams(title, msg, endpoint string) {
177+
b := fmt.Sprintf(`{ "title": "%v", "text": "%v"}`, title, msg)
149178
body := strings.NewReader(b)
150-
req, err := http.NewRequest("POST", teamsEndpoint, body)
179+
req, err := http.NewRequest("POST", endpoint, body)
151180
if err != nil {
152181
log.Println(err)
153182
return

assets/heartbeat.png

20.6 KB
Loading
File renamed without changes.

dev/build.sh

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
docker build . -t pod_monitoring_tool
2+
kind load docker-image pod_monitoring_tool:latest
Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
apiVersion: apps/v1
2+
kind: Deployment
3+
metadata:
4+
labels:
5+
app: pod-monitoring-tool
6+
name: pod-monitoring-tool
7+
namespace: pod-monitoring
8+
spec:
9+
replicas: 1
10+
selector:
11+
matchLabels:
12+
app: pod-monitoring-tool
13+
strategy: {}
14+
template:
15+
metadata:
16+
labels:
17+
app: pod-monitoring-tool
18+
spec:
19+
serviceAccountName: pod-monitoring
20+
serviceAccount: pod-monitoring
21+
containers:
22+
- image: pod_monitoring_tool
23+
name: pod-monitoring-tool
24+
imagePullPolicy: Never
25+
env:
26+
# !! replace TEAMS_ENDPOINT with your Teams webhook endpoint
27+
# - name: TEAMS_ENDPOINT
28+
# value: "https://outlook.office.com/webhook/XXXXXXXX"
29+
# - name: TEAMS_HEARTBEAT_ENDPOINT
30+
# value: "https://outlook.office.com/webhook/XXXXXXXX"
31+
- name: OBSERVE_PERIOD
32+
value: "10"
33+
- name: OBSERVED_NAMESPACE
34+
value: "default"
35+
resources:
36+
requests:
37+
memory: "64Mi"
38+
cpu: 10m
39+

kubernetes/prerequisite.yaml

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
---
2+
apiVersion: v1
3+
kind: Namespace
4+
metadata:
5+
name: pod-monitoring
6+
---
7+
apiVersion: rbac.authorization.k8s.io/v1
8+
kind: ClusterRoleBinding
9+
metadata:
10+
name: pod-monitoring
11+
roleRef:
12+
apiGroup: rbac.authorization.k8s.io
13+
kind: ClusterRole
14+
name: cluster-admin
15+
subjects:
16+
- kind: ServiceAccount
17+
name: pod-monitoring
18+
namespace: pod-monitoring
19+
---
20+
apiVersion: v1
21+
kind: ServiceAccount
22+
metadata:
23+
name: pod-monitoring
24+
namespace: pod-monitoring

0 commit comments

Comments
 (0)