Skip to content

Commit

Permalink
helm chart publishing and documentation for using it
Browse files Browse the repository at this point in the history
  • Loading branch information
AndrewFarley committed Jan 3, 2022
1 parent 76c169f commit b678aa8
Show file tree
Hide file tree
Showing 7 changed files with 306 additions and 8 deletions.
4 changes: 4 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -3,3 +3,7 @@ requirements.lock
deployment/*/charts
unused
__pycache__
helm-chart/templates/*
values.yaml.upstream
to_be_applied.yaml

61 changes: 53 additions & 8 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,30 +1,75 @@
# Kubernetes Volume Autoscaler (with Prometheus)

This repository contains a service that automatically adjusts the size of a Persistent Volume Claim in Kubernetes. Initially engineered based on AWS EKS, this should support any Kubernetes cluster or cloud provider which supports dynamically resizing volumes in Kubernetes.
This repository contains a service that automatically increases the size of a Persistent Volume Claim in Kubernetes when its nearing full. Initially engineered based on AWS EKS, this should support any Kubernetes cluster or cloud provider which supports dynamically resizing storage volumes in Kubernetes.


# Requirements
## Requirements

- [Kubernetes 1.17+ Cluster](https://kubernetes.io/releases/)
- [kubectl binary](https://kubernetes.io/docs/tasks/tools/#kubectl) installed and setup with your cluster
- [The helm 3.0+ binary](https://github.com/helm/helm/releases)
- [Prometheus](https://prometheus.io) installed on your cluster [Example 1](https://artifacthub.io/packages/helm/prometheus-community/prometheus) / [Example 2 (old)](https://github.com/helm/charts/tree/master/stable/prometheus)


### Installation with Helm

```bash
$ helm repo add devops-nirvana https://devops-nirvana.s3.amazonaws.com/helm-charts/

# Example 1 - Using autodiscovery, must be in the same namespace as Prometheus
$ helm install volume-autoscaler devops-nirvana/volume-autoscaler \
--namespace REPLACEME_WITH_PROMETHEUS_NAMESPACE

# Example 2 - Manually setting where Prometheus is
$ helm install volume-autoscaler devops-nirvana/volume-autoscaler \
--set "prometheus_url=http://prometheus-server.namespace.svc.cluster.local"

# Example 3 - Full Example, manually setting where Prometheus is and having slack notifications
$ helm install volume-autoscaler devops-nirvana/volume-autoscaler \
--namespace NAMESPACE_FOR_VOLUME_AUTOSCALER \
--set "slack_webhook_url=https://hooks.slack.com/services/123123123/4564564564/789789789789789789" \
--set "slack_channel=my-slack-channel-name" \
--set "prometheus_url=http://prometheus-server.namespace.svc.cluster.local"
```


### Installation with `kubectl`

```bash
# Simple example, as long as you put this in the same namespace as Prometheus it will work
# The default namespace this yaml is hardcoded to is `infrastructure`. If you'd like to change
# the namespace you can run the first few commands below...

# IF YOU USE `infrastructure` AS THE NAMESPACE FOR PROMETHEUS SIMPLY...
$ kubectl --namespace infrastructure apply https://devops-nirvana.s3.amazonaws.com/helm-charts/volume-autoscaler-1.0.0.yaml

# OR, IF YOU NEED TO CHANGE THE NAMESPACE...
# #1: Download the yaml...
$ wget https://devops-nirvana.s3.amazonaws.com/helm-charts/volume-autoscaler-1.0.0.yaml
# #1: Or download with curl
$ curl https://devops-nirvana.s3.amazonaws.com/helm-charts/volume-autoscaler-1.0.0.yaml -o volume-autoscaler-1.0.0.yaml
# #2: Then replace the namespace in this, replacing
cat volume-autoscaler-1.0.0.yaml | sed 's/"infrastructure"/"PROMETHEUS_NAMESPACE_HERE"/g' > ./to_be_applied.yaml
# #3: Finally, apply it...
$ kubectl --namespace REPLACEME_WITH_PROMETHEUS_NAMESPACE apply ./to_be_applied.yaml
```


# TODO

* Publish helm chart
* Add simple example of how to install this in Kubernetes cluster with Helm
* Add simple example of how to install this in Kubernetes cluster with an simple `kubectl apply`
* Add more documentation / diagramming
* Push to helm repo in a Github Action and push the static yaml as well

* Add tests coverage to ensure the software works as intended moving forward
* Do some load testing to see how well this software deals with scale (100+ PVs, 500+ PVs, etc)
* Figure out what type of Memory/CPU is necessary for 500+ PVs, see above
* Add more documentation / diagramming
* Add simple example of how to install this in Kubernetes cluster with Helm
* Add simple example of how to install this in Kubernetes cluster with an simple `kubectl apply`
* Add verbosity levels for print statements, to be able to quiet things down in the logs
* Make Slack alert on resize happening or on resizing failing for some reason
* Push to helm repo in a Github Action
* Generate kubernetes EVENTS (add to rbac) so everyone knows we are doing things, to be a good controller
* Add badges to the README
* Listen/watch to events of the PV/PVC to monitor and ensure the resizing happens, log it accordingly
* Listen/watch to events of the PV/PVC to monitor and ensure the resizing happens, log and/or slack it accordingly
* Test it and add working examples of using this on other cloud providers (Azure / Google Cloud)
* Make per-PVC annotations to (re)direct Slack to different webhooks and/or different channel(s)
* Discuss what the ideal "default" amount of time before scaling. Currently is 5 minutes (5, 60 minute intervals)
23 changes: 23 additions & 0 deletions helm-chart/.helmignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
# Patterns to ignore when building packages.
# This supports shell glob matching, relative path matching, and
# negation (prefixed with !). Only one pattern per line.
.DS_Store
# Common VCS dirs
.git/
.gitignore
.bzr/
.bzrignore
.hg/
.hgignore
.svn/
# Common backup files
*.swp
*.bak
*.tmp
*~
# Various IDEs
.project
.idea/
*.tmproj
*.sh
values.yaml.upstream
15 changes: 15 additions & 0 deletions helm-chart/Chart.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
apiVersion: v2
appVersion: 1.0.0
description: Volume Autoscaler scales Kubernetes volumes up automatically based on metrics from Prometheus, helm chart based on Universal Helm Charts from DevOps Nirvana
home: https://github.com/DevOps-Nirvana/Kubernetes-Volume-Autoscaler
icon: https://raw.githubusercontent.com/DevOps-Nirvana/Kubernetes-Volume-Autoscaler/master/icon.png
maintainers:
- email: [email protected]
name: Farley
name: volume-autoscaler
sources:
- https://github.com/devops-nirvana/volume-autoscaler/
- https://devops-nirvana.s3.amazonaws.com/helm-charts/index.yaml
- https://github.com/DevOps-Nirvana/Universal-Kubernetes-Helm-Charts
type: application
version: 1.0.0
45 changes: 45 additions & 0 deletions helm-chart/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
# Volume Autoscaler

This helm chart is just using an import/overwrite of an [standardized Deployment helm chart](https://github.com/DevOps-Nirvana/Universal-Kubernetes-Helm-Charts/tree/master/charts/deployment)

## Introduction

This chart bootstraps a Volume Autoscaler deployment on a [Kubernetes](http://kubernetes.io) cluster using the [Helm](https://helm.sh) package manager.

## Prerequisites

- [Kubernetes 1.17+ Cluster](https://kubernetes.io/releases/)
- [The kubectl binary](https://kubernetes.io/docs/tasks/tools/#kubectl)
- [The helm 3.0+ binary](https://github.com/helm/helm/releases)
- [Prometheus](https://prometheus.io) installed on your cluster [Example 1](https://artifacthub.io/packages/helm/prometheus-community/prometheus) / [Example 2 (old)](https://github.com/helm/charts/tree/master/stable/prometheus)
- [Helm diff plugin](https://github.com/databus23/helm-diff) (optional)

## Installing the Chart

To install the chart (if you check out this codebase...)

```bash
export SERVICE_NAME="volume-autoscaler"
# Change this namespace, this should be the same namespace that Prometheus is installed in
# generally the author's "best practice" is to install all critical Kubernetes components in infrastructure
export K8S_NAMESPACE=infrastructure
# Assuming you're CLI at the project root...
export PATH_TO_HELM_CHART="./helm-chart"
# OR... If your CLI is in this folder already...
# export PATH_TO_HELM_CHART="./"

# To view a diff of what you're about to deploy (vs what you maybe already deployed)
# Note: This requires you installed the helm diff plugin (from prerequisites above)
helm diff upgrade --namespace $K8S_NAMESPACE --allow-unreleased $SERVICE_NAME $PATH_TO_HELM_CHART
# Alternatively, render out the full yaml to see and preview what is about to be deployed
helm template --namespace $K8S_NAMESPACE $SERVICE_NAME $PATH_TO_HELM_CHART
# Optionally, diff this from above with kubectl cli
helm template --namespace $K8S_NAMESPACE $SERVICE_NAME $PATH_TO_HELM_CHART > to_be_applied.yaml
kubectl diff -f to_be_applied.yaml
# Actually deploy/upgrade it
helm upgrade --namespace $K8S_NAMESPACE --install $SERVICE_NAME $PATH_TO_HELM_CHART
```

## Configuration

For configuration options possible, please see our [helm-charts](#todo) repository
27 changes: 27 additions & 0 deletions helm-chart/update-templates-from-foundational-template.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
#!/bin/bash -e
#
# Usage Note: Please use this script before re-publishing a new version of volume-autoscaler, incase there was fixes upstream
######################

# Config
export TMPFOLDER=/tmp/devops-nirvana-universal-helm-charts

# Remove previous templates
rm -f ./templates/*
rm -Rf $TMPFOLDER || true

# Clone the latest of our upstream/example/foundation repo with a "deployment" object
git clone https://github.com/DevOps-Nirvana/Universal-Kubernetes-Helm-Charts.git $TMPFOLDER

# Copy it to our repo
cp -L -a $TMPFOLDER/charts/deployment/templates/* ./templates/
cp -a $TMPFOLDER/charts/deployment/values.yaml ./values.yaml.upstream

# Remove cloned folder
rm -Rf $TMPFOLDER

# This is another way to do it, uses a local copy, aka not the latest "live" ones, used temporarily for debugging/development
# Disabled this by default
# cp -L -a /Users/farley/Projects/universal-kubernetes-helm-charts/charts/deployment/templates/* ./templates/

echo "Completed update from upstream template"
139 changes: 139 additions & 0 deletions helm-chart/values.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,139 @@
# The name of the service and pods/deployment/etc being deployed
name: volume-autoscaler

# Number of pods in deployment, we only support 1 running
replicaCount: 1

# Can only have 1 running at a time, this service is not highly-available
deploymentStrategy:
type: Recreate

# Our image is on DockerHub, replace tag during builds automatically
image:
repository: devopsnirvana/kubernetes-volume-autoscaler
tag: latest # This should be replaced with an semver tag release automatically during CI for releases

globalEnvs:
# This is how we confiure the Slack integration, set the two values below
- name: SLACK_WEBHOOK_URL
value: "{{ .Values.slack_webhook_url }}"
- name: SLACK_CHANNEL
value: "{{ .Values.slack_channel }}"
# This is how we we can deploy this chart to a different namespace than Prometheus, by telling it where to access Prometheus
# Eg: http://prometheus-server.namespace.svc.cluster.local
- name: PROMETHEUS_URL
value: "{{ .Values.prometheus_url }}"

# Additional pod annotations
podAnnotations: {}
# tick: "1528451892"

# Additional labels put onto anything that can be labelled (pods, services)
labels: {}

# This adds lifecycle events for the deployment
lifecycle: {}

# Lower the ndots value, to reduce the search path expansion of DNS queries
# https://kubernetes.io/docs/concepts/services-networking/dns-pod-service/#pod-s-dns-config
dnsConfig:
enabled: false
ndots: 2

# container resource requests/limits
# some suggested values are below, but will likely only get you into about 100 pvcs. Your usage may vary
# so dial this if and as you wish based on your setup
# Note: Limits are HARD Limits
# Requests are "soft" limits and are what affects HPA (autoscaling) aggressiveness and are what resources are is guaranteed
# To use below, remove the {} and uncomment the following 6 lines and customize them as desired
resources: {}
# limits:
# cpu: 100m
# memory: 64Mi
# requests:
# cpu: 100m
# memory: 64Mi

# Assign pods to nodes based on nodeSelector labels, define a default here if desired
# To use below, remove the {} and uncomment the following 1 lines and/or add your own lines
nodeSelector: []
# purpose: node-feature-name

# Assign pods to nodes based on tolerations and taints
tolerations: []

# Init container(s)
initContainers: []
# - name: volume-mount-hack
# image: busybox
# command: ["sh", "-c", "chown -R 1000:1000 /var/chaindata"]
# volumeMounts:
# - name: data
# mountPath: /var/chaindata

# Additional containers to be added to the pod (eg: add the cloudsql proxy)
extraContainers: []

# Volumes added to the pod eg: for cloudsql
volumes: []
volumeMounts: []

# For AWS Security Groups, if you wish to use this specify the sg-123123123 in an list here
securityGroupIDs: []

serviceAccount:
enabled: true
# Add annotations if desited to your service account
annotations: {}
# Here's an example of assigning an IAM role to a pod, remove the {} above and uncomment this if needed
# eks.amazonaws.com/role-arn: arn:aws:iam::123123123:role/role-name-goes-here

# This is absolutely necessary, this is how this service reads and updates PVCs and talks to Kubernetes
# Do not change any of this, or the volume autoscaler will not function any more
rbac:
create: true
clusterWideAccess: true
rules:
# This is how we listen and update PVCs
- apiGroups: ['*']
resources: ['persistentvolumeclaims']
verbs:
- list
- patch
# This is so we can send events into Kubernetes viewable in the event viewer
- apiGroups: [""]
resources:
- events
verbs:
- create
- patch
# So we can to check StorageClasses for if they have AllowVolumeExpansion set to true
- apiGroups: ["storage.k8s.io"]
resources:
- storageclasses
verbs:
- list

# This is to use new kubernetes standard labeling, should be true on both always
usingNewRecommendedLabels: true
labelsEnableDefault: true

# We don't use a lot of features from the upstream chart, so disable them
service:
enabled: false
livenessProbe:
enabled: false
readinessProbe:
enabled: false
podDistuptionBudget:
enabled: false
ingress:
enabled: false
ingress_secondary:
enabled: false
autoscaling:
enabled: false
security:
runAsNonRoot: false
sidecar:
enabled: false

0 comments on commit b678aa8

Please sign in to comment.