1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
|
# Development Guide
This document is the canonical source of truth for things like supported
toolchain versions for building Kubernetes.
Please submit an [issue] on Github if you
* Notice a requirement that this doc does not capture.
* Find a different doc that specifies requirements (the doc should instead link
here).
Development branch requirements will change over time, but release branch
requirements are frozen.
## Pre submit flight checks
Determine whether your issue or pull request is improving Kubernetes'
architecture or whether it's simply fixing a bug.
If you need a diagram, add it. SEPARATE the description of the problem (e.g. Y
is a critical component that is too slow for an SLA that we care about) from the
solution (e.g. make X faster).
Some of these checks were less common in Kubernetes' earlier days. Now that we
have over 50000 contributors, each issue should be filed with care. No issue
should take more than 5 minutes to check for sanity (even the busiest of
reviewers can spare 5 minutes to review a patch that is thoughtfully justified).
### Is this just a simple bug fix?
Simple bug patches are easy to review since test coverage is submitted with the
patch. Bug fixes don't usually require a lot of extra testing, but please
update the unit tests so they catch the bug!
### Is this an architecture improvement?
Some examples of "Architecture" improvements include:
- Adding a new feature or making a feature more configurable or modular.
- Improving test coverage.
- Decoupling logic or creation of new utilities.
- Making code more resilient (sleeps, backoffs, reducing flakiness, etc.).
These sorts of improvements are easily evaluated, especially when they decrease
lines of code without breaking functionality. That said, please explain exactly
what you are 'cleaning up' in your Pull Request so as not to waste a reviewer's
time.
If you're making code more resilient, include tests that demonstrate the new
resilient behavior. For example: if your patch causes a controller to better
handle inconsistent data, make a mock object which returns incorrect data a few
times and verify the controller's new behaviour.
### Is this a performance improvement?
Performance bug reports MUST include data that demonstrates the bug. Without
data, the issue will be closed. You can measure performance using kubemark,
scheduler_perf, go benchmark tests, or e2e tests on a real cluster with metric
plots.
Examples of how NOT to suggest a performance bug (these lead to a long review
process and waste cycles):
- We *should* be doing X instead of Y because it *might* lead to better
performance.
- Doing X instead of Y would reduce calls to Z.
The above statements have no value to a reviewer because neither is backed by
data. Writing issues like this lands your PR in a no-man's-land and waste your
reviewers' time.
Examples of possible performance improvements include (remember, you MUST
document the improvement with data):
- Improving a caching implementation.
- Reducing calls to functions which are O(n^2)
- Reducing dependence on API server requests.
- Changing the value of default parameters for processes, or making those values
'smarter'.
- Parallelizing a calculation that needs to run on a large set of node/pod
objects.
These issues should always be submitted with (in decreasing order of value):
- A golang Benchmark test.
- A visual depiction of reduced metric load on a cluster (measurable using
metrics/ endpoints and grafana).
- A hand-instrumented timing test (i.e. adding some logs into the controller
manager).
Here are some examples of properly submitted performance issues. If you are new
to kubernetes and thinking about filing a performance optimization, re-read one
or all of these before you get started.
- https://github.com/kubernetes/kubernetes/issues/18266 (apiserver)
- https://github.com/kubernetes/kubernetes/issues/32833 (node)
- https://github.com/kubernetes/kubernetes/issues/31795 (scheduler)
Since performance improvements can be empirically measured, you should follow
the "scientific method" of creating a hypothesis, collecting data, and then
revising your hypothesis. The above issues do this transparently, using figures
and data rather than conjecture. Notice that the problem is analyzed and a
correct solution is created before a single line of code is reviewed.
## Building Kubernetes with Docker
Official releases are built using Docker containers. To build Kubernetes using
Docker please follow [these
instructions](http://releases.k8s.io/HEAD/build/README.md).
## Building Kubernetes on a local OS/shell environment
While building via Docker can be simpler, sometimes it makes sense to
do development on your local workstation or some other shell
environment. The details below outline the hardware and software
requirements for building on Linux, Windows, and macOS.
### Hardware Requirements
Kubernetes is a large project, and compiling it can use a lot of
resources. We recommend the following for any physical or virtual
machine being used for building Kubernetes.
- 8GB of RAM
- 50GB of free disk space
### Preparing Your Local Operating System
Where needed, each piece of required software will have separate
instructions for Linux, Windows, or macOS.
#### Setting Up Windows
If you are running Windows, you will need to use one of two methods
to set up your machine for Kubernetes development. To figure out which
method is the best choice, you will first need to determine which version of
Windows you are running. To do this, press **Windows logo key + R**,
type **winver**, and click **OK**. You may also enter the `ver` command at
the Windows Command Prompt.
1. If you're using Windows 10, Version 2004, Build 19041 or higher,
you can use Windows Subsystem for Linux (WSL) to build
Kubernetes. [Follow these instructions to install WSL2.](https://docs.microsoft.com/en-us/windows/wsl/install-win10)
2. If you're using an earlier version of Windows, then create a Linux
virtual machine with at least 8GB of memory and 60GB of disk space.
Once you have finished setting up your WSL2 installation or Linux VM,
follow the instructions below to configure your system for building
and developing Kubernetes.
#### Setting Up macOS
Since Kubernetes assumes you are using GNU command line tools, you will need to
install those tools on your
system. [Follow these directions to install the tools](https://ryanparman.com/posts/2019/using-gnu-command-line-tools-in-macos-instead-of-freebsd-tools/).
In particular, this command installs the necessary packages:
```sh
brew install coreutils ed findutils gawk gnu-sed gnu-tar grep make jq
```
You will want to include this block or something similar at the end of
your `.bashrc` or shell init script:
```sh
GNUBINS="$(find `brew --prefix`/opt -type d -follow -name gnubin -print)"
for bindir in ${GNUBINS[@]}
do
export PATH=$bindir:$PATH
done
export PATH
```
This ensures that the GNU tools are found first in your path. Note
that shell init scripts work a little differently for
macOS. [This article can help you figure out what changes to make.](https://scriptingosx.com/2017/04/about-bash_profile-and-bashrc-on-macos/)
### Installing Required Software
#### GNU Development Tools
Kubernetes development helper scripts require an up-to-date GNU
development tools environment. The method for installing these tools
varies from system to system.
##### Installing on Linux
All Linux distributions have the GNU tools available. The most popular
distributions and commands used to install these tools are below.
- Debian/Ubuntu
```sh
sudo apt update
sudo apt install build-essential
```
- Fedora/RHEL/CentOS
```sh
sudo yum update
sudo yum groupinstall "Development Tools"
```
- OpenSUSE
```sh
sudo zypper update
sudo zypper install -t pattern devel_C_C++
```
- Arch
```sh
sudo pacman -Sy base-devel
```
Once you have finished, confirm that `gcc` and `make` are installed.
##### Installing on macOS
Some of the build tools were installed when you prepared your system
with the GNU command line tools earlier. However, you will also need
to install the
[Command Line Tools for Xcode](https://developer.apple.com/library/archive/technotes/tn2339/_index.html).
#### Docker
Kubernetes development requires Docker to run certain verifications. To
install Docker in your development environment,
[follow the instructions from the Docker website](https://docs.docker.com/get-docker/).
**Note:** If you are running macOS, make sure that `/usr/local/bin` is
in your `PATH`.
#### rsync
The Kubernetes build system requires that `rsync`, a common file
synchronization and transfer tool, be present in the
development environment. Most modern operating systems come with
`rsync` already installed. If this is not the case, your operating
system's package manager can most likely install the `rsync`
package.
If this fails, check the [rsync download instructions page](https://rsync.samba.org/download.html).
#### jq
Some of the Kubernetes helper scripts require `jq`, a command-line JSON processor, to be
installed in your development environment. The
[jq installation guide](https://stedolan.github.io/jq/download/)
provides detailed instructions for supported platforms.
#### gcloud
If you plan to build remotely or run end-to-end (e2e) tests, you will
need to install the command line interface to the Google Cloud
Platform. [Follow the `gcloud` installation instructions for your operating system.](https://cloud.google.com/sdk/downloads)
#### Go
Kubernetes is written in [Go](http://golang.org). If you don't have a Go
development environment, please follow the instructions in the
[Go Getting Started guide](https://golang.org/doc/install).
Confirm that your `GOPATH` and `GOBIN` environment variables are
correctly set as detailed in
[How to Write Go Code](https://golang.org/doc/code.html) before
proceeding.
**Note:** Building and developing Kubernetes requires a very recent
version of Go. Please install the newest stable version available for
your system. The table below lists the required Go versions for
different versions of Kubernetes.
| Kubernetes | requires Go |
|----------------|-------------|
| 1.0 - 1.2 | 1.4.2 |
| 1.3, 1.4 | 1.6 |
| 1.5, 1.6 | 1.7 - 1.7.5 |
| 1.7 | 1.8.1 |
| 1.8 | 1.8.3 |
| 1.9 | 1.9.1 |
| 1.10 | 1.9.1 |
| 1.11 | 1.10.2 |
| 1.12 | 1.10.4 |
| 1.13 | 1.11.13 |
| 1.14 - 1.16 | 1.12.9 |
| 1.17 - 1.18 | 1.13.15 |
| 1.19 - 1.20 | 1.15.5 |
| 1.21 - 1.22 | 1.16.7 |
| 1.23 | 1.17 |
| 1.24+ | 1.18 |
##### A Note on Changing Go Versions
If you have already compiled Kubernetes but are now trying with a
different version of Go, please refer to the
[SIG Release documentation](https://github.com/kubernetes/sig-release).
#### PyYAML
Some Kubernetes verification tests use [PyYAML](https://pyyaml.org/) and it therefore needs to be installed to successfully run all verification tests in your local environment.
You can use the
[PyYAML documentation](https://pyyaml.org/wiki/PyYAMLDocumentation) to
find the installation instructions for your platform.
**Note:** If you are running macOS, you may need to use the `pip3`
command instead of the `pip` command to install PyYAML.
#### Cloning the Kubernetes Git Repository
You are now ready to clone the Kubernetes git repository. See the [GitHub Workflow](/contributors/guide/github-workflow.md) document from the Contributor Guide for instructions.
#### etcd
To test Kubernetes, you will need to install a recent version of [etcd](https://etcd.io/), a consistent and highly-available key-value store. To install a local version of etcd, run the following command in your Kubernetes working directory.
```sh
./hack/install-etcd.sh
```
This script will instruct you to make a change to your `PATH`. To make
this permanent, add this to your `.bashrc` or login script:
```sh
export PATH="$GOPATH/src/k8s.io/kubernetes/third_party/etcd:${PATH}"
```
Once you have installed all required software, you can proceed to the
[Building Kubernetes](#building-kubernetes) section to test if it all works properly.
## Building Kubernetes
The best way to validate your development environment is to build part of Kubernetes. This allows you to address issues and correct your configuration without waiting for a full build to complete. This section briefly describes various methods for compiling Kubernetes subsystems. For more detailed instructions, see [Building Kubernetes](https://github.com/kubernetes/kubernetes/blob/master/build/README.md) in the official Kubernetes documentation.
To build a specific part of Kubernetes use the `WHAT` environment variable. In `$GOPATH/src/k8s.io/kubernetes/`, the Kubernetes project directory, run the following command:
```sh
make WHAT=cmd/<subsystem>
```
Replace `<subsystem>` with one of the command folders under the `cmd/` directory. For example, to build the `kubectl` CLI, run the following:
```sh
make WHAT=cmd/kubectl
```
If this command succeeds, you will now have an executable at `_output/bin/kubectl` off of your Kubernetes project directory.
To build the entire Kubernetes project, run the following command:
```sh
make all
```
**Note:** You can omit `all` and just run `make`.
The Kubernetes build system defaults to limiting the number of reported Go compiler errors to 10. If you would like to remove this limit, add `GOGCFLAGS="-e"` to your command line. For example:
```sh
make WHAT="cmd/kubectl" GOGCFLAGS="-e"
```
If you need to use debugging inspection tools on your compiled Kubernetes executables, set DBG=1. For example:
```sh
make WHAT="cmd/kubectl" DBG=1
```
To cross-compile Kubernetes for all platforms, run the following command:
```sh
make cross
```
To build binaries for a specific platform, add `KUBE_BUILD_PLATFORMS=<os>/<arch>`. For example:
```sh
make cross KUBE_BUILD_PLATFORMS=windows/amd64
```
## A Quick Start for Testing Kubernetes
Because kubernetes only merges pull requests when unit, integration, and e2e tests are
passing, your development environment needs to run all tests successfully. While this quick start will get you going,
to really understand the testing infrastructure, read the
[Testing Guide](sig-testing/testing.md) and check out the
[SIG Architecture developer guide material](README.md#sig-testing).
Note that all of the commands in this section are run in your
Kubernetes project directory at `$GOPATH/src/k8s.io/kubernetes/`
unless otherwise specified.
**Note:** You can get additional information for many of the commands
mentioned here by running `make help`.
### Presubmission Verification
Presubmission verification provides a battery of checks and tests to
give your pull request the best chance of being accepted. Developers need to run as many verification tests as possible
locally.
You can view a list of all verification tests in `hack/verify-*.sh`
off of your Kubernetes project directory.
To run all presubmission verification tests, use this command:
```sh
make verify
```
If a specific verification test is failing, there could be an update
script to help fix the problem. These are located in
`hack/update-*.sh`. For example, `hack/update-gofmt.sh` makes sure
that all source code files are correctly formatted. This is usually
needed when you add new files to the project.
You can also run all update scripts with this command:
```sh
make update
```
### Unit Tests
Pull requests need to pass all unit tests. To run every unit test, use
this command:
```sh
make test
```
You can also use the `WHAT` option to control which packages and
subsystems are testing and use `GOFLAGS` to change how tests are
run. For example, to run unit tests verbosely against just one
package, use a command like this:
```
make test WHAT=./pkg/apis/core/helper GOFLAGS=-v
```
### Integration Tests
All integration tests need to pass for a pull request to be
accepted. Note that for this stage, in particular, it is important that
[etcd](#etcd) be properly installed. Without it, integration testing
will fail.
To run integration tests, use this command:
```sh
make test-integration
```
To learn more about integration testing, read the
[SIG Testing Integration Tests guide](./sig-testing/integration-tests.md).
### E2E Tests
End-to-end (E2E) tests provide a mechanism to test the end-to-end behavior
of the system. The primary objective of the E2E tests is to ensure
consistent and reliable behavior of the Kubernetes code base,
especially in areas where unit and integration tests are insufficient.
E2E tests build test binaries, spin up a test cluster,
run the tests, and then tear the cluster down.
**Note:** Running all E2E tests takes a *very long time*!
For more information on E2E tests, including methods for saving time
by just running specific tests, read
[End-to-End Testing in Kubernetes](./sig-testing/e2e-tests.md) and the
[getting started guide for `kubetest2`](./sig-testing/e2e-tests-kubetest2.md).
## Dependency management
Kubernetes uses [go modules](https://github.com/golang/go/wiki/Modules) to manage
dependencies.
Developers who need to manage dependencies in the `vendor/` tree should read
the docs on [using go modules to manage dependencies](/contributors/devel/sig-architecture/vendor.md).
## GitHub workflow
To check out code to work on, please refer to [this guide](/contributors/guide/github-workflow.md).
[macOS GNU tools]: https://www.topbug.net/blog/2013/04/14/install-and-use-gnu-command-line-tools-in-mac-os-x
[build/build-image/cross]: https://git.k8s.io/kubernetes/build/build-image/cross
[build/common.sh]: https://git.k8s.io/kubernetes/build/common.sh
[etcd-latest]: https://coreos.com/etcd/docs/latest
[etcd-install]: sig-testing/integration-tests.md#install-etcd-dependency
<!-- https://github.com/coreos/etcd/releases -->
[go-workspace]: https://golang.org/doc/code.html#Workspaces
[issue]: https://github.com/kubernetes/kubernetes/issues
[kubectl user guide]: https://kubernetes.io/docs/user-guide/kubectl
[kubernetes.io]: https://kubernetes.io
[mercurial]: http://mercurial.selenic.com/wiki/Download
|