kubernetes-deploy 0.8.0 → 0.8.1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/README.md +220 -52
- data/exe/kubernetes-deploy +0 -1
- data/kubernetes-deploy.gemspec +1 -0
- data/lib/kubernetes-deploy.rb +2 -0
- data/lib/kubernetes-deploy/kubernetes_resource.rb +19 -0
- data/lib/kubernetes-deploy/resource_watcher.rb +2 -0
- data/lib/kubernetes-deploy/runner.rb +12 -2
- data/lib/kubernetes-deploy/statsd.rb +22 -0
- data/lib/kubernetes-deploy/version.rb +1 -1
- data/screenshots/migrate-logs.png +0 -0
- data/screenshots/missing-secret-fail.png +0 -0
- data/screenshots/success.png +0 -0
- data/screenshots/test-output.png +0 -0
- metadata +21 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 0a6a0a8232035518d42b8dd709c236df5ee436bb
|
4
|
+
data.tar.gz: b1e8c26dc53fe92a2e22bec894badc46c2e292f4
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: d94033e6774153f24ddbee8fa6e560636ba091cbc3e5a6ac24cab07dc2ac0ed2132d1ce6d5a5a60529e2d309e2589bf42e24c55893a7b48aa034d042afdfcb74
|
7
|
+
data.tar.gz: ef4456ba9e4303a70af71dbf36f63c5a4a4b24c31fa556b34f968dcc59e543c51fe937e4a084b85c4fb659033e8711125d98e637909fa92e89259fbc5a426367
|
data/README.md
CHANGED
@@ -1,46 +1,143 @@
|
|
1
|
-
#
|
1
|
+
# kubernetes-deploy [![Build status](https://badge.buildkite.com/0f2d4956d49fbc795f9c17b0a741a6aa9ea532738e5f872ac8.svg?branch=master)](https://buildkite.com/shopify/kubernetes-deploy-gem)
|
2
2
|
|
3
|
-
|
3
|
+
`kubernetes-deploy` is a command line tool that helps you ship changes to a Kubernetes namespace and understand the result. At Shopify, we use it within our much-beloved, open-source [Shipit](https://github.com/Shopify/shipit-engine#kubernetes) deployment app.
|
4
4
|
|
5
|
-
|
5
|
+
Why not just use the standard `kubectl apply` mechanism to deploy? It is indeed a fantastic tool; `kubernetes-deploy` uses it under the hood! However, it leaves its users with some burning questions: _What just happened?_ _Did it work?_
|
6
6
|
|
7
|
-
|
7
|
+
Especially in a CI/CD environment, we need a clear, actionable pass/fail result for each deploy. Providing this was the foundational goal of `kubernetes-deploy`, which has grown to support the following core features:
|
8
8
|
|
9
|
-
|
9
|
+
:eyes: Watches the changes you requested to make sure they roll out successfully.
|
10
10
|
|
11
|
-
|
12
|
-
|
13
|
-
|
11
|
+
:interrobang: Provides debug information for changes that failed.
|
12
|
+
|
13
|
+
:1234: Predeploys certain types of resources (e.g. ConfigMap, PersistentVolumeClaim) to make sure the latest version will be available when resources that might consume them (e.g. Deployment) are deployed.
|
14
|
+
|
15
|
+
:closed_lock_with_key: [Creates Kubernetes secrets from encrypted EJSON](#deploying-kubernetes-secrets-from-ejson), which you can safely commit to your repository
|
16
|
+
|
17
|
+
:running: [Runs tasks at the beginning of the deploy](#deploy-time-tasks) using bare pods (example use case: Rails migrations)
|
18
|
+
|
19
|
+
This repo also includes related tools for [running tasks](#kubernetes-run) and [restarting deployments](#kubernetes-restart).
|
20
|
+
|
21
|
+
![success](screenshots/success.png)
|
22
|
+
|
23
|
+
|
24
|
+
|
25
|
+
![missing-secret-fail](screenshots/missing-secret-fail.png)
|
26
|
+
|
27
|
+
|
28
|
+
|
29
|
+
--------
|
30
|
+
|
31
|
+
|
32
|
+
|
33
|
+
## Table of contents
|
34
|
+
|
35
|
+
**KUBERNETES-DEPLOY**
|
36
|
+
* [Prerequisites](#prerequisites)
|
37
|
+
* [Installation](#installation)
|
38
|
+
* [Usage](#usage)
|
39
|
+
* [Using templates and variables](#using-templates-and-variables)
|
40
|
+
* [Running tasks at the beginning of a deploy](#running-tasks-at-the-beginning-of-a-deploy)
|
41
|
+
* [Deploying Kubernetes secrets (from EJSON)](#deploying-kubernetes-secrets-from-ejson)
|
42
|
+
|
43
|
+
**KUBERNETES-RESTART**
|
44
|
+
* [Usage](#usage-1)
|
45
|
+
|
46
|
+
**KUBERNETES-RUN**
|
47
|
+
* [Prerequisites](#prerequisites-1)
|
48
|
+
* [Usage](#usage-2)
|
49
|
+
|
50
|
+
**DEVELOPMENT**
|
51
|
+
* [Setup](#setup)
|
52
|
+
* [Running the test suite locally](#running-the-test-suite-locally)
|
53
|
+
* [Releasing a new version (Shopify employees)](#releasing-a-new-version-shopify-employees)
|
54
|
+
* [CI (Shopify employees)](#ci-shopify-employees)
|
55
|
+
* [CI (External contributors)](#ci-external-contributors)
|
56
|
+
|
57
|
+
**CONTRIBUTING**
|
58
|
+
* [Contributing](#contributing)
|
59
|
+
* [License](#license)
|
60
|
+
|
61
|
+
|
62
|
+
----------
|
63
|
+
|
64
|
+
|
65
|
+
|
66
|
+
## Prerequisites
|
14
67
|
|
15
|
-
|
68
|
+
* Your cluster must be running Kubernetes v1.6.0 or higher
|
69
|
+
* Each app must have a deploy directory containing its Kubernetes templates (see [Templates](#templates))
|
70
|
+
* You must remove the` kubectl.kubernetes.io/last-applied-configuration` annotation from any resources in the namespace that are not included in your deploy directory. This annotation is added automatically when you create resources with `kubectl apply`. `kubernetes-deploy` will prune any resources that have this annotation and are not in the deploy directory.**
|
71
|
+
* Each app managed by `kubernetes-deploy` must have its own exclusive Kubernetes namespace.**
|
72
|
+
|
73
|
+
|
74
|
+
**This requirement can be bypassed with the `--no-prune` option, but it is not recommended.
|
75
|
+
|
76
|
+
## Installation
|
77
|
+
|
78
|
+
1. [Install kubectl](https://kubernetes.io/docs/tasks/tools/install-kubectl/#install-kubectl-binary-via-curl) (requires v1.6.0 or higher) and make sure it is available in your $PATH
|
79
|
+
2. Set up your [kubeconfig file](https://kubernetes.io/docs/tasks/access-application-cluster/authenticate-across-clusters-kubeconfig/) for access to your cluster(s).
|
80
|
+
3. `gem install kubernetes-deploy`
|
16
81
|
|
17
|
-
$ bundle
|
18
82
|
|
19
|
-
Or install it yourself as:
|
20
83
|
|
21
|
-
$ gem install kubernetes-deploy
|
22
84
|
|
23
85
|
## Usage
|
24
86
|
|
25
|
-
`kubernetes-deploy <app's namespace> <kube context
|
87
|
+
`kubernetes-deploy <app's namespace> <kube context>`
|
26
88
|
|
27
|
-
|
89
|
+
*Environment variables:*
|
28
90
|
|
29
|
-
|
30
|
-
|
31
|
-
-
|
32
|
-
|
33
|
-
- `ENV['ENVIRONMENT']` must be set to use the default template path (`config/deploy/$ENVIRONMENT`) in the absence of the `--template-dir=DIR` option
|
91
|
+
- `$REVISION` **(required)**: the SHA of the commit you are deploying. Will be exposed to your ERB templates as `current_sha`.
|
92
|
+
- `$KUBECONFIG` **(required)**: points to a valid kubeconfig file that includes the context you want to deploy to
|
93
|
+
- `$ENVIRONMENT`: used to set the deploy directory to `config/deploy/$ENVIRONMENT`. You can use the `--template-dir=DIR` option instead if you prefer (**one or the other is required**).
|
94
|
+
- `$GOOGLE_APPLICATION_CREDENTIALS`: points to the credentials for an authenticated service account (required if your kubeconfig `user`'s auth provider is GCP)
|
34
95
|
|
35
|
-
The tool also provides a task for restarting all of the pods in one or more deployments.
|
36
|
-
It triggers the restart by touching the `RESTARTED_AT` environment variable in the deployment's podSpec.
|
37
|
-
The rollout strategy defined for each deployment will be respected by the restart.
|
38
96
|
|
39
|
-
|
97
|
+
*Options:*
|
98
|
+
|
99
|
+
- `--bindings=BINDINGS`: Makes additional variables available to your ERB templates. For example, `kubernetes-deploy my-app cluster1 --bindings=color=blue,size=large` will expose `color` and `size`.
|
100
|
+
- `--verbose-log-prefix`: Prefixes each log line with `[#{context}][#{namespace}][#{severity}][#{datetime}]` instead of just `[#{severity}][#{datetime}]`. Useful if you're running multiple concurrent deploys in Shipit.
|
101
|
+
- `--allow-protected-ns`: Enables you to deploy to `default`, `kube-system` or `kube-public` if you really know what you're doing. Must be used with `--no-prune` (pruning a protected namespace cannot be enabled).
|
102
|
+
- `--no-prune`: Skips pruning of resources that are no longer in your Kubernetes template set. Not recommended, as it allows your namespace to accumulate cruft that is not reflected in your deploy directory.
|
103
|
+
- `--skip-wait`: Verifies the result of predeployed resources only. Declares success immediately after the bulk `kubectl apply` operation. Not recommended, as it skips a huge part of the value of this tool.
|
104
|
+
|
105
|
+
|
106
|
+
|
107
|
+
|
108
|
+
|
109
|
+
### Using templates and variables
|
110
|
+
|
111
|
+
Each app's templates are expected to be stored in a single directory. If this is not the case, you can create a directory containing symlinks to the templates. The recommended location for app's deploy directory is `{app root}/config/deploy/{env}`, but this is completely configurable.
|
112
|
+
|
113
|
+
All templates must be YAML formatted. You can also use ERB. The following local variables will be available to your ERB templates by default:
|
114
|
+
|
115
|
+
* `current_sha`: The value of `$REVISION`
|
116
|
+
* `deployment_id`: A randomly generated identifier for the deploy. Useful for creating unique names for task-runner pods (e.g. a pod that runs rails migrations at the beginning of deploys).
|
117
|
+
|
118
|
+
You can add additional variables using the `--bindings=BINDINGS` option. For example, `kubernetes-deploy my-app cluster1 --bindings=color=blue,size=large` will expose `color` and `size` in your templates.
|
119
|
+
|
120
|
+
|
121
|
+
|
122
|
+
### Running tasks at the beginning of a deploy
|
123
|
+
|
124
|
+
To run a task in your cluster at the beginning of every deploy, simply include a `Pod` template in your deploy directory. `kubernetes-deploy` will first deploy any `ConfigMap` and `PersistentVolumeClaim` resources in your template set, followed by any such pods. If the command run by one of these pods fails (i.e. exits with a non-zero status), the overall deploy will fail at this step (no other resources will be deployed).
|
125
|
+
|
126
|
+
*Requirements:*
|
127
|
+
|
128
|
+
* The pod's name should include `<%= deployment_id %>` to ensure that a unique name will be used on every deploy (the deploy will fail if a pod with the same name already exists).
|
129
|
+
* The pod's `spec.restartPolicy` must be set to `Never` so that it will be run exactly once. We'll fail the deploy if that run exits with a non-zero status.
|
130
|
+
* The pod's `spec.activeDeadlineSeconds` should be set to a reasonable value for the performed task (not required, but highly recommended)
|
131
|
+
|
132
|
+
A simple example can be found in the test fixtures: test/fixtures/hello-cloud/unmanaged-pod.yml.erb.
|
133
|
+
|
134
|
+
The logs of all pods run in this way will be printed inline.
|
135
|
+
|
136
|
+
![migrate-logs](screenshots/migrate-logs.png)
|
40
137
|
|
41
|
-
`kubernetes-restart <kube namespace> <kube context> --deployments=web,jobs`
|
42
138
|
|
43
|
-
|
139
|
+
|
140
|
+
### Deploying Kubernetes secrets (from EJSON)
|
44
141
|
|
45
142
|
**Note: If you're a Shopify employee using our cloud platform, this setup has already been done for you. Please consult the CloudPlatform User Guide for usage instructions.**
|
46
143
|
|
@@ -91,59 +188,130 @@ Since their data is only base64 encoded, Kubernetes secrets should not be commit
|
|
91
188
|
}
|
92
189
|
```
|
93
190
|
|
94
|
-
### Running one off tasks
|
95
191
|
|
96
|
-
To trigger a one-off job such as a rake task _outside_ of a deploy, use the following command:
|
97
192
|
|
98
|
-
|
193
|
+
# kubernetes-restart
|
194
|
+
|
195
|
+
`kubernetes-restart` is a tool for restarting all of the pods in one or more deployments. It triggers the restart by touching the `RESTARTED_AT` environment variable in the deployment's podSpec. The rollout strategy defined for each deployment will be respected by the restart.
|
196
|
+
|
197
|
+
|
198
|
+
|
199
|
+
## Usage
|
200
|
+
|
201
|
+
The following command will restart all pods in the `web` and `jobs` deployments:
|
202
|
+
|
203
|
+
`kubernetes-restart <kube namespace> <kube context> --deployments=web,jobs`
|
204
|
+
|
205
|
+
|
99
206
|
|
100
|
-
|
207
|
+
# kubernetes-run
|
101
208
|
|
102
|
-
|
209
|
+
`kubernetes-run` is a tool for triggering a one-off job, such as a rake task, _outside_ of a deploy.
|
103
210
|
|
104
|
-
The [`PodTemplate`](https://kubernetes.io/docs/api-reference/v1.6/#podtemplate-v1-core) object should have a field `template` containing a `Pod` specification which does not include the `apiVersion` or `kind` parameters. An example is provided in this repo in `test/fixtures/hello-cloud/template-runner.yml`.
|
105
211
|
|
106
|
-
#### Providing multiple different task-runner configurations
|
107
212
|
|
108
|
-
|
213
|
+
## Prerequisites
|
109
214
|
|
110
|
-
|
215
|
+
* You've already deployed a [`PodTemplate`](https://kubernetes.io/docs/api-reference/v1.6/#podtemplate-v1-core) object with field `template` containing a `Pod` specification that does not include the `apiVersion` or `kind` parameters. An example is provided in this repo in `test/fixtures/hello-cloud/template-runner.yml`.
|
216
|
+
* The `Pod` specification in that template has a container named `task-runner`.
|
111
217
|
|
112
|
-
|
218
|
+
Based on this specification `kubernetes-run` will create a new pod with the entrypoint of the `task-runner ` container overridden with the supplied arguments.
|
113
219
|
|
114
220
|
|
115
|
-
## Development
|
116
221
|
|
117
|
-
|
222
|
+
## Usage
|
223
|
+
|
224
|
+
`kubernetes-run <kube namespace> <kube context> <arguments> --entrypoint=/bin/bash`
|
225
|
+
|
226
|
+
*Options:*
|
227
|
+
|
228
|
+
* `--template=TEMPLATE`: Specifies the name of the PodTemplate to use (default is `task-runner-template` if this option is not set).
|
229
|
+
* `--env-vars=ENV_VARS`: Accepts a comma separated list of environment variables to be added to the pod template. For example, `--env-vars="ENV=VAL,ENV2=VAL2"` will make `ENV` and `ENV2` available to the container.
|
230
|
+
|
231
|
+
|
118
232
|
|
119
|
-
To run the tests:
|
120
233
|
|
121
|
-
|
122
|
-
|
123
|
-
|
124
|
-
|
234
|
+
|
235
|
+
# Development
|
236
|
+
|
237
|
+
## Setup
|
238
|
+
|
239
|
+
1. [Install kubectl version 1.6.0 or higher](https://kubernetes.io/docs/user-guide/prereqs/) and make sure it is in your path
|
240
|
+
2. [Install minikube](https://kubernetes.io/docs/getting-started-guides/minikube/#installation) (required to run the test suite)
|
241
|
+
3. Check out the repo
|
242
|
+
4. Run `bin/setup` to install dependencies
|
125
243
|
|
126
244
|
To install this gem onto your local machine, run `bundle exec rake install`.
|
127
245
|
|
128
|
-
To release a new version:
|
129
246
|
|
130
|
-
* Update the version number in `version.rb`
|
131
|
-
* Tag the version with `git tag vx.y.z && git push --tags`
|
132
|
-
* A Shopify employee can use the [Shipit Stack](https://shipit.shopify.io/shopify/kubernetes-deploy/rubygems) to build the `.gem` file and upload to [rubygems.org](https://rubygems.org/gems/kubernetes-deploy).
|
133
247
|
|
134
|
-
##
|
248
|
+
## Running the test suite locally
|
249
|
+
|
250
|
+
1. Start [minikube](https://kubernetes.io/docs/getting-started-guides/minikube/#installation) (`minikube start [options]`)
|
251
|
+
2. Make sure you have a context named "minikube" in your kubeconfig. Minikube adds this context for you when you run `minikube start`; please do not rename it. You can check for it using `kubectl config get-contexts`.
|
252
|
+
3. Run `bundle exec rake test`
|
253
|
+
|
254
|
+
|
135
255
|
|
136
|
-
|
137
|
-
|
256
|
+
To see the full-color output of a specific integration test, you can use `PRINT_LOGS=1 bundle exec ruby -I test test/integration/kubernetes_deploy_test.rb -n/test_name/`.
|
257
|
+
|
258
|
+
|
259
|
+
|
260
|
+
![test-output](screenshots/test-output.png)
|
261
|
+
|
262
|
+
|
263
|
+
|
264
|
+
## Releasing a new version (Shopify employees)
|
265
|
+
|
266
|
+
1. Update the version number in `version.rb` and commit that change alone to master.
|
267
|
+
2. Tag the version with `git tag vx.y.z && git push --tags`
|
268
|
+
3. Use the [Shipit Stack](https://shipit.shopify.io/shopify/kubernetes-deploy/rubygems) to build the `.gem` file and upload to [rubygems.org](https://rubygems.org/gems/kubernetes-deploy).
|
269
|
+
|
270
|
+
If Shipit fails with `You need to create the v0.7.9 tag first.` even though you're sure you've already pushed that tag, go to `Settings` > `Resynchronize this stack` > `Clear git cache`.
|
271
|
+
|
272
|
+
|
273
|
+
|
274
|
+
## CI (Shopify employees)
|
275
|
+
|
276
|
+
Buildkite will build branches as you're working on them, but as soon as you create a PR it will stop building new commits from that branch because we disabled PR builds for security reasons. You can manually trigger the PR build from the [Buildkite UI](https://buildkite.com/shopify/kubernetes-deploy-gem) (just specify the branch; SHA is not required).
|
138
277
|
|
139
278
|
<img width="464" alt="screen shot 2017-02-21 at 10 55 33" src="https://cloud.githubusercontent.com/assets/522155/23172610/52771a3a-f824-11e6-8c8e-3d59c45e7ff8.png">
|
140
279
|
|
141
280
|
|
142
|
-
## Contributing
|
143
281
|
|
144
|
-
|
282
|
+
## CI (External contributors)
|
283
|
+
|
284
|
+
Please make sure you run the tests locally before submitting your PR (see [Running the test suite locally](#running-the-test-suite-locally)). A Shopify employee will trigger CI for you after reviewing your PR.
|
285
|
+
|
286
|
+
|
287
|
+
|
288
|
+
# Contributing
|
289
|
+
|
290
|
+
Bug reports and pull requests are welcome on GitHub at https://github.com/Shopify/kubernetes-deploy.
|
291
|
+
|
292
|
+
Contributions to help us support additional resource types or increase the sophistication of our success heuristics for an existing type are especially encouraged! (See tips below)
|
293
|
+
|
294
|
+
|
295
|
+
|
296
|
+
### Contributing a new resource type
|
297
|
+
|
298
|
+
The list of fully supported types is effectively the list of classes found in `lib/kubernetes-deploy/kubernetes_resource/`.
|
299
|
+
|
300
|
+
This gem uses subclasses of `KubernetesResource` to implement custom success/failure detection logic for each resource type. If no subclass exists for a type you're deploying, the gem simply assumes `kubectl apply` succeeded (and prints a warning about this assumption). We're always looking to support more types! Here are the basic steps for contributing a new one:
|
301
|
+
|
302
|
+
1. Create a the file for your type in `lib/kubernetes-deploy/kubernetes_resource/`
|
303
|
+
2. Create a new class that inherits from `KubernetesResource`. Minimally, it should implement the following methods:
|
304
|
+
* `sync` -- gather/update the data you'll need to determine `deploy_succeeded?` and `deploy_failed?`
|
305
|
+
* `deploy_succeeded?`
|
306
|
+
* `deploy_failed?`
|
307
|
+
* `exists?`
|
308
|
+
3. Adjust the `TIMEOUT` constant to an appropriate value for this type.
|
309
|
+
4. Add the a basic example of the type to the hello-cloud [fixture set](https://github.com/Shopify/kubernetes-deploy/tree/master/test/fixtures/hello-cloud) and appropriate assertions to `#assert_all_up` in [`hello_cloud.rb`](https://github.com/Shopify/kubernetes-deploy/blob/master/test/helpers/fixture_sets/hello_cloud.rb). This will get you coverage in several existing tests, such as `test_full_hello_cloud_set_deploy_succeeds`.
|
310
|
+
5. Add tests for any edge cases you foresee.
|
311
|
+
|
312
|
+
|
145
313
|
|
146
314
|
|
147
|
-
|
315
|
+
# License
|
148
316
|
|
149
317
|
The gem is available as open source under the terms of the [MIT License](http://opensource.org/licenses/MIT).
|
data/exe/kubernetes-deploy
CHANGED
data/kubernetes-deploy.gemspec
CHANGED
@@ -25,6 +25,7 @@ Gem::Specification.new do |spec|
|
|
25
25
|
spec.add_dependency "googleauth", ">= 0.5"
|
26
26
|
spec.add_dependency "ejson", "1.0.1"
|
27
27
|
spec.add_dependency "colorize", "~> 0.8"
|
28
|
+
spec.add_dependency "statsd-instrument", "~> 2.1"
|
28
29
|
|
29
30
|
spec.add_development_dependency "bundler"
|
30
31
|
spec.add_development_dependency "rake", "~> 10.0"
|
data/lib/kubernetes-deploy.rb
CHANGED
@@ -54,6 +54,7 @@ module KubernetesDeploy
|
|
54
54
|
@context = context
|
55
55
|
@logger = logger
|
56
56
|
@definition = definition
|
57
|
+
@statsd_report_done = false
|
57
58
|
end
|
58
59
|
|
59
60
|
def id
|
@@ -184,6 +185,24 @@ module KubernetesDeploy
|
|
184
185
|
@kubectl ||= Kubectl.new(namespace: @namespace, context: @context, logger: @logger, log_failure_by_default: false)
|
185
186
|
end
|
186
187
|
|
188
|
+
def report_status_to_statsd(watch_time)
|
189
|
+
unless @statsd_report_done
|
190
|
+
status = if deploy_failed?
|
191
|
+
"failure"
|
192
|
+
elsif deploy_timed_out?
|
193
|
+
"timeout"
|
194
|
+
elsif deploy_succeeded?
|
195
|
+
"success"
|
196
|
+
else
|
197
|
+
"unknown"
|
198
|
+
end
|
199
|
+
tags = %W(namespace:#{namespace} resource:#{id} type:#{type} sha:#{ENV['REVISION']} status:#{status})
|
200
|
+
::StatsD.measure('resource.duration', watch_time * 1000, tags: tags)
|
201
|
+
::StatsD.increment('resource.status', 1, tags: tags)
|
202
|
+
@statsd_report_done = true
|
203
|
+
end
|
204
|
+
end
|
205
|
+
|
187
206
|
class Event
|
188
207
|
EVENT_SEPARATOR = "ENDEVENT--BEGINEVENT"
|
189
208
|
FIELD_SEPARATOR = "ENDFIELD--BEGINFIELD"
|
@@ -39,6 +39,8 @@ module KubernetesDeploy
|
|
39
39
|
private
|
40
40
|
|
41
41
|
def report_what_just_happened(resources, watch_time)
|
42
|
+
resources.each { |r| r.report_status_to_statsd(watch_time) }
|
43
|
+
|
42
44
|
new_successes, new_failures = resources.partition(&:deploy_succeeded?)
|
43
45
|
new_failures.each do |resource|
|
44
46
|
if resource.deploy_failed?
|
@@ -79,6 +79,7 @@ module KubernetesDeploy
|
|
79
79
|
end
|
80
80
|
|
81
81
|
def run(verify_result: true, allow_protected_ns: false, prune: true)
|
82
|
+
start = Time.now.utc
|
82
83
|
@logger.reset
|
83
84
|
|
84
85
|
@logger.phase_heading("Initializing deploy")
|
@@ -104,7 +105,9 @@ module KubernetesDeploy
|
|
104
105
|
|
105
106
|
if deploy_has_priority_resources?(resources)
|
106
107
|
@logger.phase_heading("Predeploying priority resources")
|
107
|
-
|
108
|
+
::StatsD.measure('duration.priority_resources', tags: statsd_tags) do
|
109
|
+
predeploy_priority_resources(resources)
|
110
|
+
end
|
108
111
|
end
|
109
112
|
|
110
113
|
@logger.phase_heading("Deploying all resources")
|
@@ -113,7 +116,9 @@ module KubernetesDeploy
|
|
113
116
|
end
|
114
117
|
|
115
118
|
if verify_result
|
116
|
-
|
119
|
+
::StatsD.measure('duration.normal_resources', tags: statsd_tags) do
|
120
|
+
deploy_resources(resources, prune: prune, verify: true)
|
121
|
+
end
|
117
122
|
record_statuses(resources)
|
118
123
|
success = resources.all?(&:deploy_succeeded?)
|
119
124
|
else
|
@@ -131,6 +136,7 @@ module KubernetesDeploy
|
|
131
136
|
success = false
|
132
137
|
ensure
|
133
138
|
@logger.print_summary(success)
|
139
|
+
::StatsD.measure('duration.total', (Time.now.utc - start) * 1000.0, tags: statsd_tags)
|
134
140
|
success
|
135
141
|
end
|
136
142
|
|
@@ -433,5 +439,9 @@ module KubernetesDeploy
|
|
433
439
|
def kubectl
|
434
440
|
@kubectl ||= Kubectl.new(namespace: @namespace, context: @context, logger: @logger, log_failure_by_default: true)
|
435
441
|
end
|
442
|
+
|
443
|
+
def statsd_tags
|
444
|
+
%W(namespace:#{@namespace} sha:#{@current_sha})
|
445
|
+
end
|
436
446
|
end
|
437
447
|
end
|
@@ -0,0 +1,22 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
require 'statsd-instrument'
|
3
|
+
require 'logger'
|
4
|
+
|
5
|
+
module KubernetesDeploy
|
6
|
+
class StatsD
|
7
|
+
def self.build
|
8
|
+
::StatsD.default_sample_rate = 1.0
|
9
|
+
::StatsD.prefix = "KubernetesDeploy"
|
10
|
+
|
11
|
+
if ENV['STATSD_DEV'].present?
|
12
|
+
::StatsD.backend = ::StatsD::Instrument::Backends::LoggerBackend.new(Logger.new($stderr))
|
13
|
+
elsif ENV['STATSD_ADDR'].present?
|
14
|
+
statsd_impl = ENV['STATSD_IMPLEMENTATION'].empty? ? "datadog" : ENV['STATSD_IMPLEMENTATION']
|
15
|
+
::StatsD.backend = ::StatsD::Instrument::Backends::UDPBackend.new(ENV['STATSD_ADDR'], statsd_impl)
|
16
|
+
else
|
17
|
+
::StatsD.backend = ::StatsD::Instrument::Backends::NullBackend.new
|
18
|
+
end
|
19
|
+
::StatsD.backend
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: kubernetes-deploy
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.8.
|
4
|
+
version: 0.8.1
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Katrina Verey
|
@@ -9,7 +9,7 @@ authors:
|
|
9
9
|
autorequire:
|
10
10
|
bindir: exe
|
11
11
|
cert_chain: []
|
12
|
-
date: 2017-07-
|
12
|
+
date: 2017-07-11 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: activesupport
|
@@ -81,6 +81,20 @@ dependencies:
|
|
81
81
|
- - "~>"
|
82
82
|
- !ruby/object:Gem::Version
|
83
83
|
version: '0.8'
|
84
|
+
- !ruby/object:Gem::Dependency
|
85
|
+
name: statsd-instrument
|
86
|
+
requirement: !ruby/object:Gem::Requirement
|
87
|
+
requirements:
|
88
|
+
- - "~>"
|
89
|
+
- !ruby/object:Gem::Version
|
90
|
+
version: '2.1'
|
91
|
+
type: :runtime
|
92
|
+
prerelease: false
|
93
|
+
version_requirements: !ruby/object:Gem::Requirement
|
94
|
+
requirements:
|
95
|
+
- - "~>"
|
96
|
+
- !ruby/object:Gem::Version
|
97
|
+
version: '2.1'
|
84
98
|
- !ruby/object:Gem::Dependency
|
85
99
|
name: bundler
|
86
100
|
requirement: !ruby/object:Gem::Requirement
|
@@ -212,7 +226,12 @@ files:
|
|
212
226
|
- lib/kubernetes-deploy/restart_task.rb
|
213
227
|
- lib/kubernetes-deploy/runner.rb
|
214
228
|
- lib/kubernetes-deploy/runner_task.rb
|
229
|
+
- lib/kubernetes-deploy/statsd.rb
|
215
230
|
- lib/kubernetes-deploy/version.rb
|
231
|
+
- screenshots/migrate-logs.png
|
232
|
+
- screenshots/missing-secret-fail.png
|
233
|
+
- screenshots/success.png
|
234
|
+
- screenshots/test-output.png
|
216
235
|
homepage: https://github.com/Shopify/kubernetes-deploy
|
217
236
|
licenses:
|
218
237
|
- MIT
|