DEV Community

Cover image for How to auto scale down GKE node pool (In Staging cluster) to save money (via slack notify)
Huynh Thanh Phuc
Huynh Thanh Phuc

Posted on

How to auto scale down GKE node pool (In Staging cluster) to save money (via slack notify)

Overview

This guide demonstrates how to implement an automated/manual solution for scaling down Kubernetes nodepools during off-hours while keeping your team informed through Slack notifications. This approach can significantly reduce cloud costs by ensuring compute resource aren't idle during non-business hours.

Prerequisites

  • Kubernetes cluster (in post, I will use GKE)
  • Slack workspace with permissions to create Webhooks
  • KubeCTL access to your cluster
  • ... ## Solution Components
    1. Golang CronJob to push notify yes/no scale up/down
    2. Slack notify and recieve message confirm from user
    3. Node Scale exc

Implement:

1. Create Slack bot and workspace

https://slack.com/help/articles/206845317-Create-a-Slack-workspace
https://programmingpercy.tech/blog/develop-a-slack-bot-using-golang/

2. Create GKE cluster and create node pool on it

https://cloud.google.com/kubernetes-engine/docs/deploy-app-cluster

3. Prepare k8s conf and bot

Prepare conf

  • connect to cluster and get kube/congfig Image description Check config
cat ~/.kube/config
Enter fullscreen mode Exit fullscreen mode

Image description

  • Code push message to Slack
type TypeQuestionType string

const (
    QuestionTypeYesNoScaleDown TypeQuestionType = "yes_no_scale_down"
    QuestionTypeYesNoScaleUp TypeQuestionType = "yes_no_scale_up"
)

func sendYesNoQuestion(client *slack.Client, channelID string, question string, typeQuestion TypeQuestionType) (string, error) {
    attachment := slack.Attachment{
        Text: question,
        CallbackID: string(typeQuestion),
        Actions: []slack.AttachmentAction{
            {
                Name: "yes",
                Text: "Yes",
                Type: "button",
                Value: "yes",
            },
            {
                Name: "no", 
                Text: "No",
                Type: "button",
                Value: "no",
            },
        },
    }
    _, timestamp, err := client.PostMessage(
        channelID,
        slack.MsgOptionAttachments(attachment),
    )
    if err != nil {
        return "", err
    }
    lastQuestionTimestamp = timestamp
    return "Response pending", nil
}

Enter fullscreen mode Exit fullscreen mode

result test:

Image description

Flow chart

Image description

DEMO

https://www.youtube.com/watch?v=EybkQ9KJJbo
github: https://github.com/thanhphuchuynh/bot-slack-autoscale-gke

Top comments (0)