Skip to content

Commit 80f74b2

Browse files
authored
Merge pull request #366 from DirectXMan12/book/deps
[book] section on dependencies, update upgrading
2 parents ed3b83c + 6c8fea6 commit 80f74b2

File tree

3 files changed

+205
-0
lines changed

3 files changed

+205
-0
lines changed

docs/book/SUMMARY.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,7 @@
3030
* [Running Tests](beyond_basics/running_tests.md)
3131
* [Generating API Documentation](beyond_basics/generating_documentation.md)
3232
* [Updating Kubebuilder](beyond_basics/upgrading_kubebuilder.md)
33+
* [Dependency Management](beyond_basics/dependencies.md)
3334
* Controllers
3435
* [Controllers For Core Resources](beyond_basics/controllers_for_core_resources.md)
3536
* [Controller Watch Functions](beyond_basics/controller_watches.md)
Lines changed: 178 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,178 @@
1+
# Dependency Management
2+
3+
Kubebuilder uses [dep](https://golang.github.io/dep) to manage dependencies.
4+
Different dependency management tasks can be done using the `dep ensure`
5+
command.
6+
7+
## Adding new dependencies
8+
9+
{% panel style="warning", title="Kubernetes Dependencies" %}
10+
11+
Kubebuilder-generated projects depends on a number of Kubernetes
12+
dependencies internally. Kubebuilder (using the controller-runtime
13+
library) makes sure that the parts of these dependencies that are exposed
14+
in the Kubebuilder API remain stable.
15+
16+
It's recommended not to make use of most of these libraries directly, since
17+
they change frequently in incompatible ways. The `k8s.io/api` repository is
18+
the exception to this, and it's reccomended that you rely on the version that
19+
`kubebuilder` requires, instead of listing it as a direct dependency in
20+
`Gopkg.toml`.
21+
22+
However, if you do add direct dependencies on any of these libraries yourself,
23+
be aware that you may encounter dependency conflicts. See [the problem with
24+
kubernetes libraries](#the-problem-with-kubernetes-libraries) below for more
25+
information.
26+
27+
{% endpanel %}
28+
29+
{% method %}
30+
31+
Dep manages dependency constraints using the `Gopkg.toml` file. You can add
32+
new dependencies by adding new `[[constraint]]` stanzas to that file.
33+
Alternatively, if you're [not using `kubebuilder
34+
update`](./upgrading_kubebuilder.md#by-hand), you can use the `dep ensure -add`
35+
command to add new dependencies to your `Gopkg.toml`.
36+
37+
{% sample lang="bash" %}
38+
```bash
39+
# edit Gopkg.toml OR perform the following:
40+
dep ensure -add github.com/pkg/errors
41+
```
42+
{% endmethod %}
43+
44+
## Updating existing dependencies
45+
46+
{% method %}
47+
48+
Update dependencies for your project to the latest minor and patch versions.
49+
50+
{% sample lang="bash" %}
51+
```bash
52+
dep ensure -update
53+
```
54+
{% endmethod %}
55+
56+
## Repopulating your vendor directory
57+
58+
{% method %}
59+
60+
Dependency source code is stored in the vendor directory. If it ever gets
61+
deleted, you can repopulate it using the exact dependency versions stored in
62+
`Gopkg.lock`.
63+
64+
{% sample lang="bash" %}
65+
```bash
66+
dep ensure
67+
```
68+
{% endmethod %}
69+
70+
## How Kubebuilder's Dependencies Work
71+
72+
{% panel style="warning", title="Under the Hood" %}
73+
74+
The information in this section details how Kubebuilder's dependency graph
75+
works. It's not necessary for day-to-day use of Kubebuilder, but can be useful
76+
if you want to understand how a particular version of Kubebuilder relates to
77+
a particular version of Kubernetes.
78+
79+
{% endpanel %}
80+
81+
### TL;DR
82+
83+
As of Kubebuilder 1.0.2:
84+
85+
* Projects generated with Kubebuilder list a semantic version of
86+
controller-runtime and controller-tools as their only direct
87+
dependencies. All other Kubernetes-related libraries are transative
88+
dependencies.
89+
90+
* controller-runtime and controller-tools each list a specific, identical
91+
set of dependencies on Kubernetes libraries and related libraries.
92+
93+
* Once you've updated your dependencies with `kubebuilder update vendor`,
94+
you'll be able to run `dep ensure` and `dep ensure --update` to safely
95+
update all your dependencies in the future.
96+
97+
* You can depend on controller-runtime to follow [semantic versioning
98+
guarantees](https://semver.org) -- we won't break your code without
99+
introducing a new major version, for both the interfaces in
100+
controller-runtime, and the bits of the kubernetes libraries that
101+
controller-runtime actually exposes.
102+
103+
### The Problem with Kubernetes libraries
104+
105+
The kubernetes project exports a collection of libraries (which we'll call
106+
the **k8s-deps** from now on) that expose common functionality used when
107+
building applications that consume Kubernetes APIs (e.g. clients,
108+
informers, etc). Due to the way Kubrenetes is versioned
109+
(non-semantically), all of these dependencies must closely match --
110+
differing versions can cause strange compilation or runtime errors.
111+
112+
Beyond this, these libraries have their own set of dependencies which are
113+
not always the latest versions, or are occaisionally in-between versions.
114+
115+
Collecting the correct set of dependencies for any given Kubernetes
116+
project can thus be tricky.
117+
118+
### Using Prebaked Manifests (Kubebuilder pre-1.0.2)
119+
120+
Before version 1.0.2, Kubebuilder shipped a pre-baked manifest of the
121+
correct dependencies. When scaffolding out at new project using
122+
`kubebuilder init` (a **kb-project**), it would copy over a `Gopkg.toml`
123+
file containing the exact dependency versions required for the project
124+
(which could then be used by `dep` dependency management tool to actually
125+
fetch the dependencies).
126+
127+
In addition to the Kubernetes dependencies required, this also specified
128+
that all kb-projects use the master branch of the **controller-runtime**
129+
library, which provides the abstractions that Kubebuilder is built upon.
130+
Because controller-runtime wraps and consumes Kubernetes, it *also* needs
131+
specific versions of the k8s-deps, and those version *must* match the ones
132+
listed in the kb-project's Gopkg.toml, otherwise we'd have conflicting
133+
dependencies.
134+
135+
#### The Problem with Prebaked Manifests
136+
137+
Using the master branch as the target version of controller-runtime made
138+
it impossible to make breaking changes to controller-runtime. However,
139+
even when using a specific version of controller-runtime, it's still
140+
difficult to make changes.
141+
142+
Since kb-projects must use an identical set of dependencies to
143+
controller-runtime, any update to the controller-runtime dependencies
144+
(say, to pull in a new feature) would have caused immediate dependency
145+
version conflicts. Effectively, any update to the dependencies had to be
146+
treated as a major version revision, and there would have been no way to
147+
tell the difference between "this release includes breaking API changes"
148+
and "this release simply switches to a newer version of the k8s-deps".
149+
150+
### Transitive Dependencies (Kubebuilder 1.0.2+)
151+
152+
As noted above, any dependency version in kb-projects must match
153+
dependency versions listed in controller-runtime, exactly. Furthermore, it
154+
turns out, by design, the set of k8s-deps used in controller-runtime is
155+
a superset of the set of dependencies actually imported by kb-projects.
156+
157+
Therefore, in kb-projects generated with Kubebuilder 1.0.2+, no
158+
dependencies are listed besides controller-runtime (and controller-tools).
159+
All of the k8s-deps become transitive dependencies, whose versions are
160+
determined when `dep` (the dependency management tool) looks at the
161+
versions required by controller-runtime.
162+
163+
controller-runtime is semantically versioned, so any changes to either the
164+
interfaces in controller-runtime, or the pieces of the k8s-deps that are
165+
exposed as part of those interfaces, means a new major version of
166+
controller-runtime will be released. Any other changes (new features, bug
167+
fixes, updates to k8s-deps which don't break interfaces) yield minor or
168+
patch versions (as per [semver](https://semver.org)), which can easily and
169+
safely be updated to by kb-projects.
170+
171+
#### controller-tools Dependencies
172+
173+
controller-tools is the library used to generate CRD and RBAC manifests
174+
for kb-projects. With Kubebuilder 1.0.2+, it does not directly depend on
175+
controller-runtime, but shares the same set of dependencies. It therefore
176+
must be updated in lockstep with controller-runtime. This is mostly
177+
a concern of the controller-tools/controller-runtime maintainers, and will
178+
not affect users. Like controller-runtime, controller-tools uses semver.

docs/book/beyond_basics/upgrading_kubebuilder.md

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,24 @@ Install the latest version of kubebuilder from [releases page](https://github.co
66

77
## Update Existing Project's Dependencies
88

9+
{% panel style="warning", title="Kubebuilder 1.0.1 and earlier" %}
10+
11+
Before following the instructions below, make sure to update Kubebuilder
12+
to 1.0.2+, update your dependency file to the latest version by using
13+
`kubebuilder update vendor` (see
14+
[below](#updating-to-new-major-versions)). See the [dependencies
15+
guide](./dependencies.md) for more information on why this is necessary.
16+
17+
{% endpanel %}
18+
19+
You can update dependencies to minor and patch versions using
20+
[dep](https://golang.github.io/dep/), as you would any other dependency in
21+
your project. See [the dependencies
22+
guide](./dependencies.md#updating-existing-dependencies) for more
23+
information.
24+
25+
### Updating to New Major Versions
26+
927
{% method %}
1028

1129
Update your project's dependencies to the latest version of the libraries used by kubebuilder. This
@@ -20,4 +38,12 @@ kubebuilder update vendor
2038
```
2139
{% endmethod %}
2240

41+
#### By Hand
2342

43+
You can also update your project by hand. Simply edit `Gopkg.toml` to
44+
point to a new version of the dependencies listed under the `# DO NOT
45+
MODIFY BELOW THIS LINE.` line, making sure that
46+
`sigs.k8s.io/controller-tools` and `sigs.k8s.io/controller-runtime` always
47+
have the same version listed. You should then remove the marker line to
48+
indicate that you've updated dependencies by hand, and don't want them
49+
overridden.

0 commit comments

Comments
 (0)