diff --git a/README.md b/README.md index fac3d1f..2fb8890 100644 --- a/README.md +++ b/README.md @@ -1,7 +1,7 @@ Kubernetes deployment strategies ================================ -> In Kubernetes there is few different way to release an application, you have +> In Kubernetes there are a few different ways to release an application, you have to carefully choose the right strategy to make your infrastructure resilient. - [recreate](recreate/): terminate the old version and release the new one @@ -32,48 +32,44 @@ Before experimenting, checkout the following resources: ## Getting started These examples were created and tested on [Minikube](http://github.com/kubernetes/minikube) -running with Kubernetes v1.10.0. +running with Kubernetes v1.25.2 and [Rancher Desktop](https://rancherdesktop.io/) running +with Kubernetes 1.23.6. + +On MacOS the hypervisor VM does not have external connectivity so docker image pulls +will fail. To resolve this, install another driver such as +[VirtualBox](https://www.virtualbox.org/) and add `--vm-driver virtualbox` +to the command to be able to pull images. ``` -$ minikube start --kubernetes-version v1.10.0 --memory 8192 --cpus 2 +$ minikube start --kubernetes-version v1.25.2 --memory 8192 --cpus 2 ``` - ## Visualizing using Prometheus and Grafana The following steps describe how to setup Prometheus and Grafana to visualize the progress and performance of a deployment. -### Install Helm +### Install Helm3 -To install Helm, follow the instructions provided on their +To install Helm3, follow the instructions provided on their [website](https://github.com/kubernetes/helm/releases). -``` -$ helm init -``` - ### Install Prometheus ``` -$ helm install \ - --namespace=monitoring \ - --name=prometheus \ - --version=7.0.0 \ - stable/prometheus +$ helm install prometheus prometheus-community/prometheus \ + --create-namespace --namespace=monitoring ``` ### Install Grafana ``` -$ helm install \ +$ helm install grafana \ --namespace=monitoring \ - --name=grafana \ - --version=1.12.0 \ --set=adminUser=admin \ --set=adminPassword=admin \ --set=service.type=NodePort \ - stable/grafana + grafana/grafana ``` ### Setup Grafana @@ -95,12 +91,16 @@ Url: http://prometheus-server Access: Server ``` -Create a dashboard with a Graph. Use the following query: +Create a dashboard with a Time series or import +the [JSON export](grafana-dashboard.json). Use the following query: ``` -sum(rate(http_requests_total{app="my-app"}[5m])) by (version) +sum(rate(http_requests_total{app="my-app"}[2m])) by (version) ``` +Since we installed Prometheus with default settings, it is using the default scrape +interval of `1m` so the range cannot be lower than that. + To have a better overview of the version, add `{{version}}` in the legend field. #### Example graph diff --git a/ab-testing/README.md b/ab-testing/README.md index 0dd0161..c34a56d 100644 --- a/ab-testing/README.md +++ b/ab-testing/README.md @@ -39,8 +39,8 @@ Before starting, it is recommended to know the basic concept of the ### Deploy Istio -In this example, Istio 1.0.0 is used. To install Istio, follow the -[instructions](https://istio.io/docs/setup/kubernetes/helm-install/) from the +In this example, Istio 1.13.4 is used. To install Istio, follow the +[instructions](https://istio.io/latest/docs/setup/install/helm/) from the Istio website. Automatic sidecar injection should be enabled by default. Then annotate the diff --git a/app/main.go b/app/main.go index f42bee3..45ff974 100644 --- a/app/main.go +++ b/app/main.go @@ -36,7 +36,7 @@ var ( prometheus.CounterOpts{ Name: "http_requests_total", Help: "A counter for requests to the wrapped handler.", - ConstLabels: map[string]string{ + ConstLabels: prometheus.Labels{ "version": version, }, }, @@ -48,7 +48,7 @@ var ( Name: "request_duration_seconds", Help: "A histogram of latencies for requests.", Buckets: []float64{.25, .5, 1, 2.5, 5, 10}, - ConstLabels: map[string]string{ + ConstLabels: prometheus.Labels{ "version": version, }, }, @@ -60,19 +60,18 @@ var ( Name: "response_size_bytes", Help: "A histogram of response sizes for requests.", Buckets: []float64{200, 500, 900, 1500}, - ConstLabels: map[string]string{ + ConstLabels: prometheus.Labels{ "version": version, }, }, []string{"code", "method"}, ) - version string + version = os.Getenv("VERSION") ) func init() { prometheus.MustRegister(inFlightGauge, counter, duration, responseSize) - version = os.Getenv("VERSION") } func main() { diff --git a/blue-green/single-service/README.md b/blue-green/single-service/README.md index d58be45..67cec5f 100644 --- a/blue-green/single-service/README.md +++ b/blue-green/single-service/README.md @@ -37,7 +37,8 @@ deployment "my-app-v2" successfully rolled out # traffic to the first deployment. # If necessary, you can manually test one of the pod by port-forwarding it to -# your local environment. +# your local environment: +$ kubectl port-forward 8080:8080 # Once your are ready, you can switch the traffic to the new version by patching # the service to send traffic to all pods with label version=v2.0.0 diff --git a/grafana-dashboard.json b/grafana-dashboard.json new file mode 100644 index 0000000..a1aef1e --- /dev/null +++ b/grafana-dashboard.json @@ -0,0 +1,148 @@ +{ + "annotations": { + "list": [ + { + "builtIn": 1, + "datasource": { + "type": "grafana", + "uid": "-- Grafana --" + }, + "enable": true, + "hide": true, + "iconColor": "rgba(0, 211, 255, 1)", + "name": "Annotations & Alerts", + "target": { + "limit": 100, + "matchAny": false, + "tags": [], + "type": "dashboard" + }, + "type": "dashboard" + } + ] + }, + "editable": true, + "fiscalYearStartMonth": 0, + "graphTooltip": 0, + "id": 1, + "links": [], + "liveNow": false, + "panels": [ + { + "datasource": { + "type": "prometheus", + "uid": "VqQ98CX7z" + }, + "description": "", + "fieldConfig": { + "defaults": { + "color": { + "mode": "palette-classic" + }, + "custom": { + "axisLabel": "", + "axisPlacement": "auto", + "barAlignment": 0, + "drawStyle": "bars", + "fillOpacity": 10, + "gradientMode": "none", + "hideFrom": { + "legend": false, + "tooltip": false, + "viz": false + }, + "lineInterpolation": "linear", + "lineStyle": { + "fill": "solid" + }, + "lineWidth": 1, + "pointSize": 5, + "scaleDistribution": { + "type": "linear" + }, + "showPoints": "never", + "spanNulls": true, + "stacking": { + "group": "A", + "mode": "none" + }, + "thresholdsStyle": { + "mode": "off" + } + }, + "mappings": [], + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "green", + "value": null + }, + { + "color": "red", + "value": 80 + } + ] + }, + "unit": "short" + }, + "overrides": [] + }, + "gridPos": { + "h": 9, + "w": 12, + "x": 0, + "y": 0 + }, + "id": 2, + "options": { + "legend": { + "calcs": [], + "displayMode": "list", + "placement": "bottom" + }, + "tooltip": { + "mode": "multi", + "sort": "none" + } + }, + "pluginVersion": "8.5.3", + "targets": [ + { + "datasource": { + "type": "prometheus", + "uid": "VqQ98CX7z" + }, + "editorMode": "code", + "exemplar": false, + "expr": "sum(rate(http_requests_total{app=\"my-app\"}[2m])) by (version)", + "format": "time_series", + "instant": false, + "interval": "", + "legendFormat": "{{version}}", + "range": true, + "refId": "A" + } + ], + "title": "Requests Total", + "type": "timeseries" + } + ], + "refresh": "", + "schemaVersion": 36, + "style": "dark", + "tags": [], + "templating": { + "list": [] + }, + "time": { + "from": "now-15m", + "to": "now" + }, + "timepicker": {}, + "timezone": "", + "title": "k8s-deployment-strategies dashboard", + "uid": "WM-nwCX7k", + "version": 3, + "weekStart": "" +} diff --git a/ramped/README.md b/ramped/README.md index 3355bcd..cf996e9 100644 --- a/ramped/README.md +++ b/ramped/README.md @@ -56,7 +56,7 @@ $ kubectl rollout undo deploy my-app # subset of users $ kubectl rollout pause deploy my-app -# Then if you are satisfy with the result, rollout +# Then if you are satisfied with the result, resume rollout $ kubectl rollout resume deploy my-app ``` diff --git a/shadow/README.md b/shadow/README.md index e2b856f..78c32cf 100644 --- a/shadow/README.md +++ b/shadow/README.md @@ -37,8 +37,8 @@ Before starting, it is recommended to know the basic concept of the ### Deploy Istio -In this example, Istio 1.0.0 is used. To install Istio, follow the -[instructions](https://istio.io/docs/setup/kubernetes/helm-install/) from the +In this example, Istio 1.13.4 is used. To install Istio, follow the +[instructions](https://istio.io/latest/docs/setup/install/helm/) from the Istio website. Automatic sidecar injection should be enabled by default. Then annotate the