kubernetes-deploy 0.25.0 → 0.26.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (37) hide show
  1. checksums.yaml +4 -4
  2. data/.buildkite/pipeline.nightly.yml +0 -9
  3. data/.buildkite/pipeline.yml +0 -9
  4. data/CHANGELOG.md +23 -0
  5. data/CONTRIBUTING.md +164 -0
  6. data/README.md +29 -104
  7. data/dev.yml +3 -3
  8. data/exe/kubernetes-deploy +32 -21
  9. data/exe/kubernetes-render +20 -12
  10. data/exe/kubernetes-restart +5 -1
  11. data/lib/kubernetes-deploy.rb +1 -0
  12. data/lib/kubernetes-deploy/bindings_parser.rb +20 -8
  13. data/lib/kubernetes-deploy/cluster_resource_discovery.rb +1 -1
  14. data/lib/kubernetes-deploy/container_logs.rb +6 -0
  15. data/lib/kubernetes-deploy/deploy_task.rb +85 -44
  16. data/lib/kubernetes-deploy/ejson_secret_provisioner.rb +38 -84
  17. data/lib/kubernetes-deploy/errors.rb +8 -0
  18. data/lib/kubernetes-deploy/kubeclient_builder.rb +52 -20
  19. data/lib/kubernetes-deploy/kubeclient_builder/kube_config.rb +1 -1
  20. data/lib/kubernetes-deploy/kubectl.rb +11 -10
  21. data/lib/kubernetes-deploy/kubernetes_resource.rb +47 -9
  22. data/lib/kubernetes-deploy/kubernetes_resource/custom_resource.rb +1 -1
  23. data/lib/kubernetes-deploy/kubernetes_resource/custom_resource_definition.rb +1 -1
  24. data/lib/kubernetes-deploy/kubernetes_resource/deployment.rb +1 -1
  25. data/lib/kubernetes-deploy/kubernetes_resource/horizontal_pod_autoscaler.rb +12 -4
  26. data/lib/kubernetes-deploy/kubernetes_resource/network_policy.rb +22 -0
  27. data/lib/kubernetes-deploy/kubernetes_resource/pod.rb +2 -0
  28. data/lib/kubernetes-deploy/kubernetes_resource/secret.rb +23 -0
  29. data/lib/kubernetes-deploy/label_selector.rb +42 -0
  30. data/lib/kubernetes-deploy/options_helper.rb +31 -15
  31. data/lib/kubernetes-deploy/remote_logs.rb +6 -1
  32. data/lib/kubernetes-deploy/renderer.rb +5 -1
  33. data/lib/kubernetes-deploy/resource_cache.rb +4 -1
  34. data/lib/kubernetes-deploy/restart_task.rb +22 -10
  35. data/lib/kubernetes-deploy/runner_task.rb +5 -3
  36. data/lib/kubernetes-deploy/version.rb +1 -1
  37. metadata +6 -2
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 2f35ca56d7b0ec844c55ff82157238409f2c21db3a9d83f870a73cc3305ee0b8
4
- data.tar.gz: a9d9e566c21f699e9f066cd5bd505cd9c9ef9466a0180bb7563e9004211a8184
3
+ metadata.gz: 75e707a9039e39eacc8206308b5bd0a8a189480cf389763f3a0667c05c975e9d
4
+ data.tar.gz: d6746729e5889a4b1667385ee9705b61a78ee86d9079d86ccbd38f0f87ddb113
5
5
  SHA512:
6
- metadata.gz: 2c3e2b2a8267d997e7d8859d6238d70f8a052bb423c8526f6e0f0490efe9de97da54ec1de0737f229f2682b04ba0b385ed2cc54caea3cc8276536026abb660cd
7
- data.tar.gz: 98a21af1679cec75a00a6f81981b5a092888113c81f74d03eb967ba07da8b722db06c1394202a2de0fb943df5d784b3e95de15f653682e9c4555a4b595018a45
6
+ metadata.gz: 618d63d8f2b30607e8610348e9383355646b5446cce4941bf326eea9e82641c007a13788ced9f2a6dee0e047638a90215cd3c603913271ddc329ebec34604abe
7
+ data.tar.gz: 6c8cfef5dc1320701046bef897c164703e94a50bf9a44c95b7d3b24016f395297707869e488ce55d8c1920c8f561235433b4029cb58d901070df78ddfd879b14
@@ -1,11 +1,5 @@
1
- shared: &shared
2
- retry:
3
- automatic:
4
- - exit_status: "*"
5
- limit: 1
6
1
  steps:
7
2
  - name: 'Run Test Suite (:kubernetes: 1.13-latest)'
8
- <<: *shared
9
3
  command: bin/ci
10
4
  agents:
11
5
  queue: k8s-ci
@@ -13,7 +7,6 @@ steps:
13
7
  LOGGING_LEVEL: 4
14
8
  KUBERNETES_VERSION: v1.13-latest
15
9
  - name: 'Run Test Suite (:kubernetes: 1.12-latest)'
16
- <<: *shared
17
10
  command: bin/ci
18
11
  agents:
19
12
  queue: k8s-ci
@@ -21,7 +14,6 @@ steps:
21
14
  LOGGING_LEVEL: 4
22
15
  KUBERNETES_VERSION: v1.12-latest
23
16
  - name: 'Run Test Suite (:kubernetes: 1.11-latest)'
24
- <<: *shared
25
17
  command: bin/ci
26
18
  agents:
27
19
  queue: k8s-ci
@@ -29,7 +21,6 @@ steps:
29
21
  LOGGING_LEVEL: 4
30
22
  KUBERNETES_VERSION: v1.11-latest
31
23
  - name: 'Run Test Suite (:kubernetes: 1.10-latest)'
32
- <<: *shared
33
24
  command: bin/ci
34
25
  agents:
35
26
  queue: minikube-ci
@@ -1,11 +1,5 @@
1
- shared: &shared
2
- retry:
3
- automatic:
4
- - exit_status: "*"
5
- limit: 1
6
1
  steps:
7
2
  - name: 'Run Test Suite (:kubernetes: 1.13-latest)'
8
- <<: *shared
9
3
  command: bin/ci
10
4
  agents:
11
5
  queue: k8s-ci
@@ -13,7 +7,6 @@ steps:
13
7
  LOGGING_LEVEL: 4
14
8
  KUBERNETES_VERSION: v1.13-latest
15
9
  - name: 'Run Test Suite (:kubernetes: 1.12-latest)'
16
- <<: *shared
17
10
  command: bin/ci
18
11
  agents:
19
12
  queue: k8s-ci
@@ -21,7 +14,6 @@ steps:
21
14
  LOGGING_LEVEL: 4
22
15
  KUBERNETES_VERSION: v1.12-latest
23
16
  - name: 'Run Test Suite (:kubernetes: 1.11-latest)'
24
- <<: *shared
25
17
  command: bin/ci
26
18
  agents:
27
19
  queue: k8s-ci
@@ -29,7 +21,6 @@ steps:
29
21
  LOGGING_LEVEL: 4
30
22
  KUBERNETES_VERSION: v1.11-latest
31
23
  - name: 'Run Test Suite (:kubernetes: 1.10-latest)'
32
- <<: *shared
33
24
  command: bin/ci
34
25
  agents:
35
26
  queue: minikube-ci
data/CHANGELOG.md CHANGED
@@ -1,3 +1,26 @@
1
+ ## next
2
+
3
+ ## 0.26.0
4
+
5
+ *Enhancements*
6
+ - Add support for NetworkPolicies ([#422](https://github.com/Shopify/kubernetes-deploy/pull/422))
7
+ - Setting the REVISION environment variable is now optional ([#429](https://github.com/Shopify/kubernetes-deploy/pull/429))
8
+ - Defaults KUBECONFIG to `~/.kube/config` ([#429](https://github.com/Shopify/kubernetes-deploy/pull/429))
9
+ - Uses `TASK_ID` environment variable as the `deployment_id` when rendering resource templates for better [Shipit](https://github.com/Shopify/shipit) integration. ([#430](https://github.com/Shopify/kubernetes-deploy/pull/430))
10
+ - Arguments to `--bindings` will now be deep merged. ([#419](https://github.com/Shopify/kubernetes-deploy/pull/419))
11
+ - `kubernetes-deploy` and `kubernetes-render` now support reading templates from STDIN. ([#415](https://github.com/Shopify/kubernetes-deploy/pull/415))
12
+ - Support for specifying a `--selector`, a label with which all deployed resources are expected to have, and by which prunable resources will be filtered. This permits sharing a namespace with resources managed by third-parties, including other kubernetes-deploy deployments. ([#439](https://github.com/Shopify/kubernetes-deploy/pull/439))
13
+ - Lists of resources printed during deployments will now be sorted alphabetically. ([#441](https://github.com/Shopify/kubernetes-deploy/pull/441))
14
+ - Bare / unmanaged pods run as pre-deployment tasks will now stream logs if there is only one of them. ([#436](https://github.com/Shopify/kubernetes-deploy/pull/436))
15
+
16
+ *Features*
17
+
18
+ - **[Breaking change]** Support for deploying Secrets from templates ([#424](https://github.com/Shopify/kubernetes-deploy/pull/424)). Non-ejson secrets are now fully supported and therefore **subject to pruning like any other resource**. As a result:
19
+ * If you previously manually `kubectl apply`'d secrets that are not passed to kubernetes-deploy, your first deploy using this version is going to delete them.
20
+ * If you previously passed secrets manifests to kubernetes-deploy and they are no longer in the set you pass to the first deploy using this version, it will delete them.
21
+ * To identify potentially affected secrets in your cluster, run: `kubectl get secrets -o jsonpath='{ range .items[*] }{.metadata.namespace}{ "\t" }{.metadata.name}{ "\t" }{.metadata.annotations}{ "\n" }{ end }' --context=$YOUR_CONTEXT_HERE --all-namespaces | grep -v "kubernetes-deploy.shopify.io/ejson-secret" | grep "last-applied" | cut -f 1,2`. To exclude a secret from kubernetes-deploy (and kubectl apply) management, remove the last-applied annotation `kubectl annotate secret $SECRET_NAME kubectl.kubernetes.io/last-applied-configuration-`.
22
+ * The secret `ejson-keys` will never be pruned by kubernetes-deploy. Instead, it will fail the deploy at the validation stage (unless `--no-prune` is set). ([#447](https://github.com/Shopify/kubernetes-deploy/pull/447))
23
+
1
24
  ## 0.25.0
2
25
 
3
26
  *Features*
data/CONTRIBUTING.md ADDED
@@ -0,0 +1,164 @@
1
+ # Contributing to kubernetes-deploy
2
+
3
+ :+1::tada: First off, thanks for taking the time to contribute! :tada::+1:
4
+
5
+ The following is a set of guidelines for contributing to kubernetes-deploy. Please take a moment to read through them before submitting your first PR.
6
+
7
+
8
+ #### Table Of Contents
9
+
10
+ [Code of Conduct](#code-of-conduct)
11
+
12
+ [What should I know before I get started?](#what-should-i-know-before-i-get-started)
13
+ * [High-level design decisions](#high-level-design-decisions)
14
+ * [Feature acceptance policies](#feature-acceptance-policies)
15
+ * [Adding a new resource type](#contributing-a-new-resource-type)
16
+
17
+ [Development](#development)
18
+ * [Setup](#setup)
19
+ * [Running the test suite locally](#running-the-test-suite-locally)
20
+ * [Releasing a new version (Shopify employees)](#releasing-a-new-version-shopify-employees)
21
+ * [CI (External contributors)](#ci-external-contributors)
22
+ ## Code of Conduct
23
+
24
+ This project and everyone participating in it are governed by the [Code of Conduct](https://github.com/Shopify/kubernetes-deploy/blob/master/CODE_OF_CONDUCT.md).
25
+ By participating, you are expected to uphold this code. Please report unacceptable
26
+ behavior to [kubernetes-deploy@shopify.com](mailto:kubernetes-deploy@shopify.com).
27
+
28
+ ## Maintainers
29
+
30
+ This project is currently under the stewardship of the Production Platform group at Shopify.
31
+ The two primary maintainers are @knverey and @dturn. Approval from at least one primary maintainer is
32
+ required for all significant feature proposals and code architecture changes. In general,
33
+ two people must approve all non-trivial PRs.
34
+
35
+ ## What should I know before I get started?
36
+
37
+ ### High-level design decisions
38
+
39
+ **Logging**
40
+
41
+ Since we are primarily a CLI tool, logging is our entire user interface. Please think carefully about the information you log. Is it clear? Is it logged at the right time? Is it helpful?
42
+
43
+ In particular, we need to ensure that every mutation we’ve done to the cluster is clearly described (and is something the operator wanted us to do!).
44
+
45
+ We handle Kubernetes secrets, so it is critical that changes do not cause the contents of any secrets in the template set to be logged.
46
+
47
+ **Project architecture**
48
+
49
+ The main interface of this project is our four tasks: `DeployTask`, `RestartTask`, `RunnerTask`, and `RenderTask`. The code in these classes should be high-level abstractions, with implementation details encapsulated in other classes. The public interface of these tasks is a `run` method (and a `run!` equivalent), the body of which should read like a set of phases and steps.
50
+
51
+ An important design principle of the tasks is that they should try to fail fast before touching the cluster if they will not succeed overall. Part of how we achieve this is by separating each task into phases, where the first phase simply gathers information and runs validations to determine what needs to be done and whether that will be able to succeed. In practice, this is the “Initializing <task>” phase for all tasks, plus the “Checking initial resource statuses” phase for DeployTask. Our users should be able to assume that these initial phases never modify their clusters.
52
+
53
+ **Thread safety**
54
+
55
+ This tool must be able to run concurrent deploys to different targets safely, including when used as a library. Each of those deploys will internally also use parallelism via ruby threads, as do our integration tests. This means all of our code must be thread-safe. Notably, our code must not modify the global namespace (e.g. environment variables, classes, class variables or constants), and all gems we depend on must also be thread-safe.
56
+
57
+ _Note_: Local tests do not run in parallel by default. To enable it, use `PARALLELIZE_ME=1 PARALLELISM=$NUM_THREADS`. Unit tests never run in parallel because they use mocha, which is not thread-safe (mocha cannot be used in integration tests).
58
+
59
+ **Performance and the sync cycle**
60
+
61
+ DeployTask must remain performant when given several hundred resources at a time, generating 1000+ pods. This means only `sync` methods can make calls to the Kubernetes API server during result verification. This both limits the number of API calls made and ensures a consistent view of the world within each polling cycle.
62
+
63
+
64
+
65
+ ### Feature acceptance policies
66
+
67
+ **Our mission**
68
+
69
+ This project's mission is to make it easy to ship changes to a Kubernetes namespace and understand the result. Features that introduce new classes of responsibility to the tool are not usually accepted.
70
+
71
+ Deploys can be a very tempting place to cram features. Imagine a proposed feature actually fits better elsewhere—where might that be? (Examples: validator in CI, custom controller, initializer, pre-processing step in the CD pipeline, or even Kubernetes core)
72
+
73
+ **Global resources**
74
+
75
+ This project is intended to manage a namespace (or a label-delimited subsection of one). It does not officially support non-namespaced resources. In practice, we do model custom resource definitions specifically, because it helps us better handle custom resources (which typically are namespaced). However, our intent is to keep this the only exception to the rule.
76
+
77
+ **Template rendering**
78
+
79
+ The basic ERB renderer included with the tool is intended as a convenience feature for a better out-of-the box experience. Providing complex rendering capabilities is outside the scope of this project's mission, and enhancements in this area may be rejected.
80
+
81
+ **Composability**
82
+
83
+ This project strives to be composable with other tools in the ecosystem, such as renderers and validators. The deploy task must work with any Kubernetes templates provided to it, no matter how they were generated.
84
+
85
+ **Universality**
86
+
87
+ This project is open-source. Features tied to any specific organization (including Shopify) will be rejected.
88
+
89
+
90
+ ### Contributing a new resource type
91
+
92
+ The list of fully supported types is effectively the list of classes found in `lib/kubernetes-deploy/kubernetes_resource/`.
93
+
94
+ 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:
95
+
96
+ 1. Create a file for your type in `lib/kubernetes-deploy/kubernetes_resource/`
97
+ 2. Create a new class that inherits from `KubernetesResource`. Minimally, it should implement the following methods:
98
+ * `sync` -- Gather the data you'll need to determine `deploy_succeeded?` and `deploy_failed?`. The superclass's implementation fetches the corresponding resource, parses it and stores it in `@instance_data`. You can define your own implementation if you need something else.
99
+ * `deploy_succeeded?`
100
+ * `deploy_failed?`
101
+ 3. Adjust the `TIMEOUT` constant to an appropriate value for this type.
102
+ 4. Add the new class to list of resources in
103
+ [`deploy_task.rb`](https://github.com/Shopify/kubernetes-deploy/blob/master/lib/kubernetes-deploy/deploy_task.rb#L8)
104
+ 5. Add the new resource to the [prune whitelist](https://github.com/Shopify/kubernetes-deploy/blob/master/lib/kubernetes-deploy/deploy_task.rb#L81)
105
+ 6. Add 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`.
106
+ 7. Add tests for any edge cases you foresee.
107
+
108
+ # Development
109
+
110
+ ## Setup
111
+
112
+ If you work for Shopify, just run `dev up`, but otherwise:
113
+
114
+ 1. [Install kubectl version 1.10.0 or higher](https://kubernetes.io/docs/user-guide/prereqs/) and make sure it is in your path
115
+ 2. [Install minikube](https://kubernetes.io/docs/getting-started-guides/minikube/#installation) (required to run the test suite)
116
+ 3. Check out the repo
117
+ 4. Run `bin/setup` to install dependencies
118
+
119
+ To install this gem onto your local machine, run `bundle exec rake install`.
120
+
121
+
122
+
123
+ ## Running the test suite locally
124
+
125
+ Using minikube:
126
+
127
+ 1. Start [minikube](https://kubernetes.io/docs/getting-started-guides/minikube/#installation) (`minikube start [options]`).
128
+ 2. Make sure you have a context named "minikube" in your kubeconfig. Minikube adds this context for you when you run `minikube start`. You can check for it using `kubectl config get-contexts`.
129
+ 3. Run `bundle exec rake test` (or `dev test` if you work for Shopify).
130
+
131
+ Using another local cluster:
132
+
133
+ 1. Start your cluster.
134
+ 2. Put the name of the context you want to use in a file named `.local-context` in the root of this project. For example: `echo "dind" > .local-context`.
135
+ 3. Run `bundle exec rake test` (or `dev test` if you work for Shopify).
136
+
137
+ To make StatsD log what it would have emitted, run a test with `STATSD_DEV=1`.
138
+
139
+ To see the full-color output of a specific integration test, you can use `PRINT_LOGS=1`. For example: `PRINT_LOGS=1 bundle exec ruby -I test test/integration/kubernetes_deploy_test.rb -n/test_name/`.
140
+
141
+
142
+ ![test-output](screenshots/test-output.png)
143
+
144
+
145
+ ## Releasing a new version (Shopify employees)
146
+
147
+ 1. Make sure all merged PRs are reflected in the changelog before creating the commit for the new version.
148
+ 2. Update the version number in `version.rb` and commit that change with message "Version x.y.z". Don't push yet or you'll confuse Shipit.
149
+ 3. Tag the version with `git tag vx.y.z -a -m "Version x.y.z"`
150
+ 4. Push both your bump commit and its tag simultaneously with `git push origin master --follow-tags` (note that you can set `git config --global push.followTags true` to turn this flag on by default)
151
+ 5. 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).
152
+
153
+ If you push your commit and the tag separately, Shipit usually fails with `You need to create the v0.7.9 tag first.`. To make it find your tag, go to `Settings` > `Resynchronize this stack` > `Clear git cache`.
154
+
155
+
156
+ ## CI (External contributors)
157
+
158
+ Please make sure you run the tests locally before submitting your PR (see [Running the test suite locally](#running-the-test-suite-locally)). After reviewing your PR, a Shopify employee will trigger CI for you.
159
+
160
+ #### Employees: Triggering CI for a contributed PR
161
+
162
+ Go to the [kubernetes-deploy-gem pipeline](https://buildkite.com/shopify/kubernetes-deploy-gem) and click "New Build". Use branch `external_contrib_ci` and the specific sha of the commit you want to build. Add `BUILDKITE_REFSPEC="refs/pull/${PR_NUM}/head"` in the Environment Variables section. Since CI is only visible to Shopify employees, you will need to provide any failing tests and output to the the contributor.
163
+
164
+ <img width="350" alt="build external contrib PR" src="https://screenshot.click/2017-11-07--163728_7ovek-wrpwq.png">
data/README.md CHANGED
@@ -55,12 +55,6 @@ This repo also includes related tools for [running tasks](#kubernetes-run) and [
55
55
  * [Prerequisites](#prerequisites-2)
56
56
  * [Usage](#usage-3)
57
57
 
58
- **DEVELOPMENT**
59
- * [Setup](#setup)
60
- * [Running the test suite locally](#running-the-test-suite-locally)
61
- * [Releasing a new version (Shopify employees)](#releasing-a-new-version-shopify-employees)
62
- * [CI (External contributors)](#ci-external-contributors)
63
-
64
58
  **CONTRIBUTING**
65
59
  * [Contributing](#contributing)
66
60
  * [Code of Conduct](#code-of-conduct)
@@ -76,14 +70,10 @@ This repo also includes related tools for [running tasks](#kubernetes-run) and [
76
70
  * Ruby 2.3+
77
71
  * Your cluster must be running Kubernetes v1.10.0 or higher<sup>1</sup>
78
72
  * Each app must have a deploy directory containing its Kubernetes templates (see [Templates](#using-templates-and-variables))
79
- * 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.<sup>2</sup>
80
- * Each app managed by `kubernetes-deploy` must have its own exclusive Kubernetes namespace.
81
73
 
82
74
  <sup>1</sup> We run integration tests against these Kubernetes versions. You can find our
83
75
  offical compatibility chart below.
84
76
 
85
- <sup>2</sup> This requirement can be bypassed with the `--no-prune` option, but it is not recommended.
86
-
87
77
  | Kubernetes version | Last officially supported in gem version |
88
78
  | :----------------: | :-------------------: |
89
79
  | 1.5 | 0.11.2 |
@@ -106,8 +96,9 @@ offical compatibility chart below.
106
96
 
107
97
  *Environment variables:*
108
98
 
109
- - `$REVISION` **(required)**: the SHA of the commit you are deploying. Will be exposed to your ERB templates as `current_sha`.
110
- - `$KUBECONFIG` **(required)**: points to one or multiple valid kubeconfig files that include the context you want to deploy to. File names are separated by colon for Linux and Mac, and semi-colon for Windows.
99
+ - `$REVISION`: the SHA of the commit you are deploying. Will be exposed to your ERB templates as `current_sha`.
100
+ - `$KUBECONFIG`: points to one or multiple valid kubeconfig files that include the context you want to deploy to. File names are separated by colon for Linux and Mac, and semi-colon for Windows. If ommitted, will use the Kubernetes default of `~/.kube/config`.
101
+ - `$TASK_ID`: used as the ID of the deployment for resource naming.
111
102
  - `$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**).
112
103
  - `$GOOGLE_APPLICATION_CREDENTIALS`: points to the credentials for an authenticated service account (required if your kubeconfig `user`'s auth provider is GCP)
113
104
 
@@ -116,12 +107,20 @@ offical compatibility chart below.
116
107
 
117
108
  Refer to `kubernetes-deploy --help` for the authoritative set of options.
118
109
 
119
- - `--template-dir=DIR`: Used to set the deploy directory. Set `$ENVIRONMENT` instead to use `config/deploy/$ENVIRONMENT`.
110
+ - `--template-dir=DIR`: Used to set the deploy directory. Set `$ENVIRONMENT` instead to use `config/deploy/$ENVIRONMENT`. This flag also supports reading from STDIN. You can do this by using `--template-dir=-`. Example: `cat templates_from_stdin/*.yml | kubernetes-deploy ns ctx --template-dir=-`.
120
111
  - `--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`.
121
112
  - `--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.
122
113
  - `--max-watch-seconds=seconds`: Raise a timeout error if it takes longer than _seconds_ for any
123
114
  resource to deploy.
115
+ - `--selector`: Instructs kubernetes-deploy to only prune resources which match the specified label selector, such as `environment=staging`. If you use this option, all resource templates must specify matching labels. See [Sharing a namespace](#sharing-a-namespace) below.
116
+
117
+ ### Sharing a namespace
124
118
 
119
+ By default, kubernetes-deploy will prune any resources in the target namespace which have the `kubectl.kubernetes.io/last-applied-configuration` annotation and are not a result of the current deployment process, on the assumption that there is a one-to-one relationship between application deployment and namespace, and that a deployment provisions all relevant resources in the namespace.
120
+
121
+ If you need to, you may specify `--no-prune` to disable all pruning behaviour, but this is not recommended.
122
+
123
+ If you need to share a namespace with resources which are managed by other tools or indeed other kubernetes-deploy deployments, you can supply the `--selector` option, such that only resources with labels matching the selector are considered for pruning.
125
124
 
126
125
  ### Using templates and variables
127
126
 
@@ -130,7 +129,7 @@ Each app's templates are expected to be stored in a single directory. If this is
130
129
  All templates must be YAML formatted. You can also use ERB. The following local variables will be available to your ERB templates by default:
131
130
 
132
131
  * `current_sha`: The value of `$REVISION`
133
- * `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).
132
+ * `deployment_id`: The value of `$TASK_ID`, or in its absence, 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).
134
133
 
135
134
  You can add additional variables using the `--bindings=BINDINGS` option which can be formated as comma separated string, JSON string or path to a JSON or YAML file. Complex JSON or YAML data will be converted to a Hash for use in templates. To load a file the argument should include the relative file path prefixed with an `@` sign. An argument error will be raised if the string argument cannot be parsed, the referenced file does not include a valid extension (`.json`, `.yaml` or `.yml`) or the referenced file does not exist.
136
135
 
@@ -256,7 +255,7 @@ To run a task in your cluster at the beginning of every deploy, simply include a
256
255
 
257
256
  A simple example can be found in the test fixtures: test/fixtures/hello-cloud/unmanaged-pod.yml.erb.
258
257
 
259
- The logs of all pods run in this way will be printed inline.
258
+ The logs of all pods run in this way will be printed inline. If there is only one pod, the logs will be streamed in real-time. If there are multiple, they will be fetched when the pod terminates.
260
259
 
261
260
  ![migrate-logs](screenshots/migrate-logs.png)
262
261
 
@@ -271,6 +270,7 @@ Since their data is only base64 encoded, Kubernetes secrets should not be commit
271
270
  1. Install the ejson gem: `gem install ejson`
272
271
  2. Generate a new keypair: `ejson keygen` (prints the keypair to stdout)
273
272
  3. Create a Kubernetes secret in your target namespace with the new keypair: `kubectl create secret generic ejson-keys --from-literal=YOUR_PUBLIC_KEY=YOUR_PRIVATE_KEY --namespace=TARGET_NAMESPACE`
273
+ >Warning: Do *not* use `apply` to create the `ejson-keys` secret. kubernetes-deploy will fail if `ejson-keys` is prunable. This safeguard is to protect against the accidental deletion of your private keys.
274
274
  4. (optional but highly recommended) Back up the keypair somewhere secure, such as a password manager, for disaster recovery purposes.
275
275
  5. In your template directory (alongside your Kubernetes templates), create `secrets.ejson` with the format shown below. The `_type` key should have the value “kubernetes.io/tls” for TLS secrets and “Opaque” for all others. The `data` key must be a json object, but its keys and values can be whatever you need.
276
276
 
@@ -299,6 +299,7 @@ Since their data is only base64 encoded, Kubernetes secrets should not be commit
299
299
  7. Commit the encrypted file and deploy as usual. The deploy will create secrets from the data in the `kubernetes_secrets` key.
300
300
 
301
301
  **Note**: Since leading underscores in ejson keys are used to skip encryption of the associated value, `kubernetes-deploy` will strip these leading underscores when it creates the keys for the Kubernetes secret data. For example, given the ejson data below, the `monitoring-token` secret will have keys `api-token` and `property` (_not_ `_property`):
302
+
302
303
  ```json
303
304
  {
304
305
  "_public_key": "YOUR_PUBLIC_KEY",
@@ -313,6 +314,8 @@ Since their data is only base64 encoded, Kubernetes secrets should not be commit
313
314
  }
314
315
  ```
315
316
 
317
+ **A warning about using EJSON secrets with `--selector`**: when using EJSON to generate `Secret` resources and specifying a `--selector` for deployment, the labels from the selector are automatically added to the `Secret`. If _the same_ EJSON file is deployed to the same namespace using different selectors, this will cause the resource to thrash - even if the contents of the secret were the same, the resource has different labels on each deploy.
318
+
316
319
  ### Deploying custom resources
317
320
 
318
321
  By default, kubernetes-deploy does not check the status of custom resources; it simply assumes that they deployed successfully. In order to meaningfully monitor the rollout of custom resources, kubernetes-deploy supports configuring pass/fail conditions using annotations on CustomResourceDefinitions (CRDs).
@@ -435,6 +438,13 @@ With this done, you can use the following command to restart all of them:
435
438
 
436
439
  `kubernetes-restart <kube namespace> <kube context>`
437
440
 
441
+ *Options:*
442
+
443
+ Refer to `kubernetes-restart --help` for the authoritative set of options.
444
+
445
+ - `--selector`: Only restarts Deployments which match the specified Kubernetes resource selector.
446
+ - `--deployments`: Restart specific Deployment resources by name.
447
+
438
448
  # kubernetes-run
439
449
 
440
450
  `kubernetes-run` is a tool for triggering a one-off job, such as a rake task, _outside_ of a deploy.
@@ -490,102 +500,17 @@ kubernetes-render --template-dir=./path/to/template/dir this-template.yaml.erb t
490
500
 
491
501
  *Options:*
492
502
 
493
- - `--template-dir=DIR`: Used to set the directory to interpret template names relative to. This is often the same directory passed as `--template-dir` when running `kubernetes-deploy` to actually deploy templates. Set `$ENVIRONMENT` instead to use `config/deploy/$ENVIRONMENT`.
503
+ - `--template-dir=DIR`: Used to set the directory to interpret template names relative to. This is often the same directory passed as `--template-dir` when running `kubernetes-deploy` to actually deploy templates. Set `$ENVIRONMENT` instead to use `config/deploy/$ENVIRONMENT`. This flag also supports reading from STDIN. You can do this by using `--template-dir=-`.
494
504
  - `--bindings=BINDINGS`: Makes additional variables available to your ERB templates. For example, `kubernetes-render --bindings=color=blue,size=large some-template.yaml.erb` will expose `color` and `size` to `some-template.yaml.erb`.
495
505
 
496
506
 
497
- # Development
498
-
499
- ## Setup
500
-
501
- If you work for Shopify, just run `dev up`, but otherwise:
502
-
503
- 1. [Install kubectl version 1.10.0 or higher](https://kubernetes.io/docs/user-guide/prereqs/) and make sure it is in your path
504
- 2. [Install minikube](https://kubernetes.io/docs/getting-started-guides/minikube/#installation) (required to run the test suite)
505
- 3. Check out the repo
506
- 4. Run `bin/setup` to install dependencies
507
-
508
- To install this gem onto your local machine, run `bundle exec rake install`.
509
-
510
-
511
-
512
- ## Running the test suite locally
513
-
514
- Using minikube:
515
-
516
- 1. Start [minikube](https://kubernetes.io/docs/getting-started-guides/minikube/#installation) (`minikube start [options]`).
517
- 2. Make sure you have a context named "minikube" in your kubeconfig. Minikube adds this context for you when you run `minikube start`. You can check for it using `kubectl config get-contexts`.
518
- 3. Run `bundle exec rake test` (or `dev test` if you work for Shopify).
519
-
520
- Using another local cluster:
521
-
522
- 1. Start your cluster.
523
- 2. Put the name of the context you want to use in a file named `.local-context` in the root of this project. For example: `echo "dind" > .local-context`.
524
- 3. Run `bundle exec rake test` (or `dev test` if you work for Shopify).
525
-
526
- To make StatsD log what it would have emitted, run a test with `STATSD_DEV=1`.
527
-
528
- To see the full-color output of a specific integration test, you can use `PRINT_LOGS=1`. For example: `PRINT_LOGS=1 bundle exec ruby -I test test/integration/kubernetes_deploy_test.rb -n/test_name/`.
529
-
530
-
531
-
532
-
533
- ![test-output](screenshots/test-output.png)
534
-
535
-
536
-
537
- ## Releasing a new version (Shopify employees)
538
-
539
- 1. Make sure all merged PRs are reflected in the changelog before creating the commit for the new version.
540
- 2. Update the version number in `version.rb` and commit that change with message "Version x.y.z". Don't push yet or you'll confuse Shipit.
541
- 3. Tag the version with `git tag vx.y.z -a -m "Version x.y.z"`
542
- 4. Push both your bump commit and its tag simultaneously with `git push origin master --follow-tags` (note that you can set `git config --global push.followTags true` to turn this flag on by default)
543
- 5. 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).
544
-
545
- If you push your commit and the tag separately, Shipit usually fails with `You need to create the v0.7.9 tag first.`. To make it find your tag, go to `Settings` > `Resynchronize this stack` > `Clear git cache`.
546
-
547
-
548
- ## CI (External contributors)
549
-
550
- Please make sure you run the tests locally before submitting your PR (see [Running the test suite locally](#running-the-test-suite-locally)). After reviewing your PR, a Shopify employee will trigger CI for you.
551
-
552
- #### Employees: Triggering CI for a contributed PR
553
-
554
- Go to the [kubernetes-deploy-gem pipeline](https://buildkite.com/shopify/kubernetes-deploy-gem) and click "New Build". Use branch `external_contrib_ci` and the specific sha of the commit you want to build. Add `BUILDKITE_REFSPEC="refs/pull/${PR_NUM}/head"` in the Environment Variables section.
555
-
556
- <img width="350" alt="build external contrib PR" src="https://screenshot.click/2017-11-07--163728_7ovek-wrpwq.png">
557
-
558
507
  # Contributing
559
508
 
560
- Bug reports and pull requests are welcome on GitHub at https://github.com/Shopify/kubernetes-deploy.
561
-
562
- 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)
563
-
564
- ## Feature acceptance guidelines
565
-
566
- - This project's mission is to make it easy to ship changes to a Kubernetes namespace and understand the result. Features that introduce new classes of responsibility to the tool are not usually accepted.
567
- - Deploys can be a very tempting place to cram features. Imagine a proposed feature actually fits better elsewhere—where might that be? (Examples: validator in CI, custom controller, initializer, pre-processing step in the CD pipeline, or even Kubernetes core)
568
- - The basic ERB renderer included with the tool is intended as a convenience feature for a better out-of-the box experience. Providing complex rendering capabilities is out of scope of this project's mission, and enhancements in this area may be rejected.
569
- - The deploy command does not officially support non-namespaced resource types.
570
- - This project strives to be composable with other tools in the ecosystem, such as renderers and validators. The deploy command must work with any Kubernetes templates provided to it, no matter how they were generated.
571
- - This project is open-source. Features tied to any specific organization (including Shopify) will be rejected.
572
- - The deploy command must remain performant when given several hundred resources at a time, generating 1000+ pods. (Technical note: This means only `sync` methods can make calls to the Kuberentes API server during result verification. This both limits the number of API calls made and ensures a consistent view of the world within each polling cycle.)
573
- - This tool must be able to run concurrent deploys to different targets safely, including when used as a library.
574
-
575
- ## Contributing a new resource type
576
-
577
- The list of fully supported types is effectively the list of classes found in `lib/kubernetes-deploy/kubernetes_resource/`.
509
+ We :heart: contributors! To make it easier for you and us we've written a
510
+ [Contributing Guide](https://github.com/Shopify/kubernetes-deploy/blob/master/CONTRIBUTING.md)
578
511
 
579
- 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:
580
512
 
581
- 1. Create a the file for your type in `lib/kubernetes-deploy/kubernetes_resource/`
582
- 2. Create a new class that inherits from `KubernetesResource`. Minimally, it should implement the following methods:
583
- * `sync` -- Gather the data you'll need to determine `deploy_succeeded?` and `deploy_failed?`. The superclass's implementation fetches the corresponding resource, parses it and stores it in `@instance_data`. You can define your own implementation if you need something else.
584
- * `deploy_succeeded?`
585
- * `deploy_failed?`
586
- 3. Adjust the `TIMEOUT` constant to an appropriate value for this type.
587
- 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`.
588
- 5. Add tests for any edge cases you foresee.
513
+ You can also reach out to us on our slack channel, #krane, at https://kubernetes.slack.com. All are welcome!
589
514
 
590
515
  ## Code of Conduct
591
516
  Everyone is expected to follow our [Code of Conduct](https://github.com/Shopify/kubernetes-deploy/blob/master/CODE_OF_CONDUCT.md).