├── README.md ├── autoscale.tick ├── labs ├── 01-minikube.md ├── 02-helm.md ├── 03-influxdb.md ├── 04-telegraf.md ├── 05-chronograf.md ├── 06-kapacitor.md └── 07-autoscaling.md ├── replicasets └── app.yaml └── services └── app.yaml /README.md: -------------------------------------------------------------------------------- 1 | # OSCON Tutorial: Measure all the things 2 | 3 | ## Labs 4 | 5 | * [Verify the Minikube installation](labs/01-minikube.md) 6 | * [Install Helm](labs/02-helm.md) 7 | * [Install InfluxDB](labs/03-influxdb.md) 8 | * [Install Telegraf](labs/04-telegraf.md) 9 | * [Install Chronograf](labs/05-chronograf.md) 10 | * [Install Kapacitor](labs/06-kapacitor.md) 11 | * [Autoscaling with Kapacitor](labs/07-autoscaling.md) 12 | -------------------------------------------------------------------------------- /autoscale.tick: -------------------------------------------------------------------------------- 1 | // Target is the desired number of requests per second per host. 2 | var target = 2.0 3 | 4 | // Only one increase event will be triggered per increase_cooldown. 5 | var increase_cooldown = 1m 6 | 7 | // Only one decrease event will be triggered per decrease_cooldown 8 | var decrease_cooldown = 2m 9 | 10 | // Moving_avg_count is the number of points to use in a moving average 11 | // as input to the k8sAutoscale node. 12 | // Points arrive at one per second. 13 | var moving_avg_count = 60 14 | 15 | // Scale each replicaset that is reporting is request counts to Kapacitor. 16 | stream 17 | |from() 18 | .measurement('requests') 19 | .groupBy('host', 'replicaset') 20 | // we get points evey second so drop any noise on the data 21 | .truncate(1s) 22 | // Compute the rate of requests per second per host 23 | |derivative('value') 24 | .as('requests_per_second') 25 | .unit(1s) 26 | .nonNegative() 27 | // Compute the total_requests_per_second per replicaset across all hosts 28 | |groupBy('replicaset') 29 | |sum('requests_per_second') 30 | .as('total_requests_per_second') 31 | // Compute the moving average of the total_requests_per_second per replicaset 32 | |movingAverage('total_requests_per_second', moving_avg_count) 33 | .as('avg_requests_per_second') 34 | // Using the avg_requests_per_second autoscale each replicaset. 35 | |k8sAutoscale() 36 | // We are scaling a replicaset. 37 | .kind('replicasets') 38 | // The name of the replicaset to scale is found in the 'replicaset' tag. 39 | .resourceNameTag('replicaset') 40 | // Set the cool down timer values. 41 | .increaseCooldown(increase_cooldown) 42 | .decreaseCooldown(decrease_cooldown) 43 | // Compute the desired number of replicas based on the 44 | // avg_requests_per_second and target values. 45 | .replicas(lambda: int(ceil("avg_requests_per_second" / target))) 46 | -------------------------------------------------------------------------------- /labs/01-minikube.md: -------------------------------------------------------------------------------- 1 | # Minikube 2 | 3 | In this lab you will make sure that [minikube](https://github.com/kubernetes/minikube) is installed and running. 4 | 5 | ## Verify the Minikube Installation 6 | 7 | Ensure minikube is running: 8 | 9 | ``` 10 | minikube status 11 | ``` 12 | 13 | ``` 14 | minikubeVM: Running 15 | localkube: Running 16 | ``` 17 | 18 | Verify kubectl is set to the minikube context: 19 | 20 | ``` 21 | kubectl config current-context 22 | ``` 23 | ``` 24 | minikube 25 | ``` 26 | 27 | Verify the kubectl version: 28 | 29 | ``` 30 | kubectl version 31 | ``` 32 | 33 | ``` 34 | Client Version: version.Info{Major:"1", Minor:"6", GitVersion:"v1.6.2", GitCommit:"477efc3cbe6a7effca06bd1452fa356e2201e1ee", GitTreeState:"clean", BuildDate:"2017-04-19T20:33:11Z", GoVersion:"go1.7.5", Compiler:"gc", Platform:"darwin/amd64"} 35 | Server Version: version.Info{Major:"1", Minor:"6", GitVersion:"v1.6.0", GitCommit:"fff5156092b56e6bd60fff75aad4dc9de6b6ef37", GitTreeState:"dirty", BuildDate:"2017-04-07T20:46:46Z", GoVersion:"go1.7.3", Compiler:"gc", Platform:"linux/amd64"} 36 | ``` 37 | 38 | 39 | -------------------------------------------------------------------------------- /labs/02-helm.md: -------------------------------------------------------------------------------- 1 | # Helm 2 | 3 | In this lab you will install [helm](https://github.com/kubernetes/helm) on your local machine. 4 | 5 | ## What is Helm? 6 | 7 | [Introduction to Helm](https://github.com/kubernetes/helm#kubernetes-helm) 8 | 9 | ## Install Helm 10 | 11 | Install helm using the [installation docs](https://github.com/kubernetes/helm#install) 12 | 13 | ## Initialize Helm and install Tiller 14 | 15 | ``` 16 | helm init 17 | ``` 18 | 19 | ``` 20 | helm repo update 21 | ``` 22 | 23 | Install a sample chart: 24 | 25 | ``` 26 | helm install --name oscon-mysql stable/mysql 27 | ``` 28 | 29 | List installed charts: 30 | 31 | ``` 32 | helm ls 33 | ``` 34 | 35 | Delete the mysql deployment 36 | 37 | ``` 38 | helm delete oscon-mysql --purge 39 | ``` 40 | -------------------------------------------------------------------------------- /labs/03-influxdb.md: -------------------------------------------------------------------------------- 1 | # InfluxDB 2 | 3 | In this tutorial you will install the influxdb CLI tool and deploy the influxDB into your local Kubernetes cluster using Helm. 4 | 5 | ## What is InfluxDB 6 | 7 | [Introduction to InfluxDB](https://docs.influxdata.com/influxdb/v1.2) 8 | 9 | ## Deploy InfluxDB 10 | 11 | In this section you will deploy a InfluxDB server into your Kubernetes cluster. 12 | 13 | ``` 14 | helm install stable/influxdb --name influxdb \ 15 | --set service.type=NodePort 16 | ``` 17 | 18 | ## Install the influx client 19 | 20 | In this section you will download and test the influxdb CLI client. 21 | 22 | [https://docs.influxdata.com/influxdb/v1.2/introduction/installation](https://docs.influxdata.com/influxdb/v1.2/introduction/installation) 23 | 24 | Set the InfluxDB server host and port: 25 | 26 | ``` 27 | INFLUX_HOST=$(minikube service influxdb-influxdb --format "{{.IP}}") 28 | ``` 29 | 30 | ``` 31 | INFLUX_PORT=$(minikube service influxdb-influxdb --format "{{.Port}}") 32 | ``` 33 | 34 | Connect to the InfluxDB server: 35 | 36 | ``` 37 | influx --host ${INFLUX_HOST} --port ${INFLUX_PORT} 38 | ``` 39 | 40 | List the available databases: 41 | 42 | ``` 43 | show databases 44 | ``` 45 | 46 | Exit the influx interactive prompt: 47 | 48 | ``` 49 | exit 50 | ``` 51 | -------------------------------------------------------------------------------- /labs/04-telegraf.md: -------------------------------------------------------------------------------- 1 | # Telegraf 2 | 3 | 4 | ## What is Telegraf? 5 | 6 | [Introduction to Telegraf](https://docs.influxdata.com/telegraf/v1.3) 7 | 8 | ## Install Telegraf 9 | 10 | Set the minikube cluster IP address: 11 | 12 | ``` 13 | KUBERNETES_HOST=$(minikube ip) 14 | ``` 15 | 16 | Install telegraf using helm: 17 | 18 | ``` 19 | helm install --name telegraf \ 20 | --set daemonset.config.outputs.influxdb.urls={http://influxdb-influxdb:8086} \ 21 | --set daemonset.config.inputs.kubernetes.url=http://${KUBERNETES_HOST}:10255 \ 22 | stable/telegraf 23 | ``` 24 | 25 | Verify telegraf is running: 26 | 27 | ``` 28 | kubectl get pods 29 | ``` 30 | 31 | ## Exploring Telegraf Metrics 32 | 33 | Connect to the influxDB server: 34 | 35 | ``` 36 | influx --host ${INFLUX_HOST} --port ${INFLUX_PORT} 37 | ``` 38 | 39 | List the databases: 40 | 41 | ``` 42 | show databases 43 | ``` 44 | 45 | Use the `telegraf` database: 46 | 47 | ``` 48 | use telegraf 49 | ``` 50 | 51 | List the available measurements: 52 | 53 | ``` 54 | SHOW MEASUREMENTS 55 | ``` 56 | 57 | Find the container consuming the most memory: 58 | 59 | ``` 60 | select pod_name,max(memory_usage_bytes) from kubernetes_pod_container 61 | ``` 62 | 63 | Exit the influx interactive prompt: 64 | 65 | ``` 66 | exit 67 | ``` 68 | -------------------------------------------------------------------------------- /labs/05-chronograf.md: -------------------------------------------------------------------------------- 1 | # Chronograf 2 | 3 | ## What is Chronograf? 4 | 5 | [Introduction to Chronograf](https://docs.influxdata.com/chronograf/v1.3) 6 | 7 | ## Install Chronograf 8 | 9 | ``` 10 | helm install stable/chronograf --name chronograf \ 11 | --set image.tag=1.3.0 \ 12 | --set service.type=NodePort 13 | ``` 14 | 15 | Verify that chronograf is running: 16 | 17 | ``` 18 | kubectl get pods 19 | ``` 20 | 21 | ## Visit the Chronograf Dashboard 22 | 23 | Use minikube to connect to the Chronograf service: 24 | 25 | ``` 26 | minikube service chronograf-chronograf 27 | ``` 28 | 29 | Configure the InfluxDB connection details: 30 | 31 | ``` 32 | Connection String: http://influxdb-influxdb:8086 33 | Name: minikube 34 | ``` 35 | 36 | Click the "Add Source" button. At this point you can explore the Chronograf dashboard. 37 | -------------------------------------------------------------------------------- /labs/06-kapacitor.md: -------------------------------------------------------------------------------- 1 | # Kapacitor 2 | 3 | ## What is Kapacitor? 4 | 5 | [Introduction to Kapacitor](https://docs.influxdata.com/kapacitor/v1.2) 6 | 7 | ## Install Kapacitor 8 | 9 | ``` 10 | helm install stable/kapacitor --name kapacitor \ 11 | --set service.type=NodePort \ 12 | --set influxURL=http://influxdb-influxdb:8086 13 | ``` 14 | 15 | Verify kapacitor is running: 16 | 17 | ``` 18 | kubectl get pods 19 | ``` 20 | 21 | ## Enable Kubernetes Integration 22 | 23 | Edit the kapacitor deployment: 24 | 25 | ``` 26 | kubectl edit deployment kapacitor-kapacitor 27 | ``` 28 | 29 | Add the following env vars: 30 | 31 | ``` 32 | - name: "KAPACITOR_KUBERNETES_ENABLED" 33 | value: "true" 34 | - name: "KAPACITOR_KUBERNETES_IN_CLUSTER" 35 | value: "true" 36 | ``` 37 | 38 | ## Verify The Kapacitor Installation 39 | 40 | Install the kapacitor CLI tool: 41 | 42 | [https://portal.influxdata.com/downloads#kapacitor](https://portal.influxdata.com/downloads#kapacitor) 43 | 44 | ``` 45 | export KAPACITOR_URL=$(minikube service kapacitor-kapacitor --url) 46 | ``` 47 | 48 | ``` 49 | kapacitor stats general 50 | ``` 51 | -------------------------------------------------------------------------------- /labs/07-autoscaling.md: -------------------------------------------------------------------------------- 1 | # Autoscaling with Kapacitor 2 | 3 | In this lab you will follow the [Kapacitor + Kubernetes Autoscaling](https://github.com/influxdata/k8s-kapacitor-autoscale) tutorial on your local Kubernetes clusters. 4 | 5 | ## Deploy the Example Application 6 | 7 | Create the `app` replicaset: 8 | 9 | ``` 10 | kubectl create -f https://raw.githubusercontent.com/kelseyhightower/oscon-metrics-tutorial/master/replicasets/app.yaml 11 | ``` 12 | 13 | Create the `app` service: 14 | 15 | ``` 16 | kubectl create -f https://raw.githubusercontent.com/kelseyhightower/oscon-metrics-tutorial/master/services/app.yaml 17 | ``` 18 | 19 | ## Define and Enable the Autoscale Task 20 | 21 | Pull autoscale TICKscript task: 22 | ``` 23 | curl -O https://raw.githubusercontent.com/influxdata/k8s-kapacitor-autoscale/master/autoscale.tick 24 | ``` 25 | 26 | ``` 27 | kapacitor define autoscale -tick autoscale.tick -type stream -dbrp autoscale.autogen 28 | ``` 29 | 30 | ``` 31 | kapacitor enable autoscale 32 | ``` 33 | 34 | ``` 35 | kapacitor show autoscale 36 | ``` 37 | 38 | ``` 39 | watch kubectl get pods 40 | ``` 41 | 42 | ### Load test the Example Application 43 | 44 | ``` 45 | export APP_URL=$(minikube service app --url) 46 | ``` 47 | 48 | ``` 49 | while true; do curl $APP_URL; done 50 | ``` 51 | -------------------------------------------------------------------------------- /replicasets/app.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: extensions/v1beta1 2 | kind: ReplicaSet 3 | metadata: 4 | name: app 5 | spec: 6 | template: 7 | metadata: 8 | labels: 9 | app: app 10 | spec: 11 | containers: 12 | - name: app 13 | image: quay.io/influxdb/k8s-kapacitor-autoscale:0.0.1 14 | imagePullPolicy: IfNotPresent 15 | ports: 16 | - containerPort: 8000 17 | env: 18 | - name: "APP_REPLICASET" 19 | value: "app" 20 | - name: "APP_INFLUXDB_URL" 21 | value: "http://kapacitor-kapacitor:9092/write?db=autoscale&rp=autogen&precision=s" 22 | -------------------------------------------------------------------------------- /services/app.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: v1 2 | kind: Service 3 | metadata: 4 | name: app 5 | spec: 6 | ports: 7 | - port: 8000 8 | targetPort: 8000 9 | selector: 10 | app: app 11 | type: NodePort 12 | --------------------------------------------------------------------------------