mirror of
https://github.com/kubernetes-sigs/kustomize.git
synced 2026-05-22 06:47:00 +00:00
Copying cmd/kustomize
This commit is contained in:
36
CONTRIBUTING.md
Normal file
36
CONTRIBUTING.md
Normal file
@@ -0,0 +1,36 @@
|
||||
# Contributing guidelines
|
||||
|
||||
[Contributor License Agreement]: https://git.k8s.io/community/CLA.md
|
||||
[github workflow guide]: https://github.com/kubernetes/community/blob/master/contributors/guide/github-workflow.md
|
||||
[CNCF code of conduct]: https://github.com/cncf/foundation/blob/master/code-of-conduct.md
|
||||
|
||||
## Contributing a Patch
|
||||
|
||||
1. Kubernetes projects require contributors to sign the
|
||||
[Contributor License Agreement] before pull requests
|
||||
can be considered.
|
||||
1. Submit an issue describing your proposed change to
|
||||
the repo in question.
|
||||
1. The [repo owners](OWNERS) will respond to your issue
|
||||
promptly.
|
||||
1. Fork the repo, develop and test your code.
|
||||
See the [github workflow guide].
|
||||
1. For _new features_, provide a markdown-based demo following
|
||||
the pattern established in the [demos](demos) directory.
|
||||
Run `bin/pre-commit.sh` to test your demo.
|
||||
1. Submit a pull request.
|
||||
|
||||
## Community, discussion, contribution, and support
|
||||
|
||||
Learn how to engage with the Kubernetes community on
|
||||
the [community page](http://kubernetes.io/community/).
|
||||
|
||||
You can reach the maintainers of this project at:
|
||||
|
||||
- [Slack](http://slack.k8s.io/)
|
||||
- [Mailing List](https://groups.google.com/forum/#!forum/kubernetes-kustomize)
|
||||
|
||||
## Code of conduct
|
||||
|
||||
Participation in the Kubernetes community is governed
|
||||
by the [CNCF code of conduct].
|
||||
201
LICENSE
Normal file
201
LICENSE
Normal file
@@ -0,0 +1,201 @@
|
||||
Apache License
|
||||
Version 2.0, January 2004
|
||||
http://www.apache.org/licenses/
|
||||
|
||||
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
|
||||
|
||||
1. Definitions.
|
||||
|
||||
"License" shall mean the terms and conditions for use, reproduction,
|
||||
and distribution as defined by Sections 1 through 9 of this document.
|
||||
|
||||
"Licensor" shall mean the copyright owner or entity authorized by
|
||||
the copyright owner that is granting the License.
|
||||
|
||||
"Legal Entity" shall mean the union of the acting entity and all
|
||||
other entities that control, are controlled by, or are under common
|
||||
control with that entity. For the purposes of this definition,
|
||||
"control" means (i) the power, direct or indirect, to cause the
|
||||
direction or management of such entity, whether by contract or
|
||||
otherwise, or (ii) ownership of fifty percent (50%) or more of the
|
||||
outstanding shares, or (iii) beneficial ownership of such entity.
|
||||
|
||||
"You" (or "Your") shall mean an individual or Legal Entity
|
||||
exercising permissions granted by this License.
|
||||
|
||||
"Source" form shall mean the preferred form for making modifications,
|
||||
including but not limited to software source code, documentation
|
||||
source, and configuration files.
|
||||
|
||||
"Object" form shall mean any form resulting from mechanical
|
||||
transformation or translation of a Source form, including but
|
||||
not limited to compiled object code, generated documentation,
|
||||
and conversions to other media types.
|
||||
|
||||
"Work" shall mean the work of authorship, whether in Source or
|
||||
Object form, made available under the License, as indicated by a
|
||||
copyright notice that is included in or attached to the work
|
||||
(an example is provided in the Appendix below).
|
||||
|
||||
"Derivative Works" shall mean any work, whether in Source or Object
|
||||
form, that is based on (or derived from) the Work and for which the
|
||||
editorial revisions, annotations, elaborations, or other modifications
|
||||
represent, as a whole, an original work of authorship. For the purposes
|
||||
of this License, Derivative Works shall not include works that remain
|
||||
separable from, or merely link (or bind by name) to the interfaces of,
|
||||
the Work and Derivative Works thereof.
|
||||
|
||||
"Contribution" shall mean any work of authorship, including
|
||||
the original version of the Work and any modifications or additions
|
||||
to that Work or Derivative Works thereof, that is intentionally
|
||||
submitted to Licensor for inclusion in the Work by the copyright owner
|
||||
or by an individual or Legal Entity authorized to submit on behalf of
|
||||
the copyright owner. For the purposes of this definition, "submitted"
|
||||
means any form of electronic, verbal, or written communication sent
|
||||
to the Licensor or its representatives, including but not limited to
|
||||
communication on electronic mailing lists, source code control systems,
|
||||
and issue tracking systems that are managed by, or on behalf of, the
|
||||
Licensor for the purpose of discussing and improving the Work, but
|
||||
excluding communication that is conspicuously marked or otherwise
|
||||
designated in writing by the copyright owner as "Not a Contribution."
|
||||
|
||||
"Contributor" shall mean Licensor and any individual or Legal Entity
|
||||
on behalf of whom a Contribution has been received by Licensor and
|
||||
subsequently incorporated within the Work.
|
||||
|
||||
2. Grant of Copyright License. Subject to the terms and conditions of
|
||||
this License, each Contributor hereby grants to You a perpetual,
|
||||
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
|
||||
copyright license to reproduce, prepare Derivative Works of,
|
||||
publicly display, publicly perform, sublicense, and distribute the
|
||||
Work and such Derivative Works in Source or Object form.
|
||||
|
||||
3. Grant of Patent License. Subject to the terms and conditions of
|
||||
this License, each Contributor hereby grants to You a perpetual,
|
||||
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
|
||||
(except as stated in this section) patent license to make, have made,
|
||||
use, offer to sell, sell, import, and otherwise transfer the Work,
|
||||
where such license applies only to those patent claims licensable
|
||||
by such Contributor that are necessarily infringed by their
|
||||
Contribution(s) alone or by combination of their Contribution(s)
|
||||
with the Work to which such Contribution(s) was submitted. If You
|
||||
institute patent litigation against any entity (including a
|
||||
cross-claim or counterclaim in a lawsuit) alleging that the Work
|
||||
or a Contribution incorporated within the Work constitutes direct
|
||||
or contributory patent infringement, then any patent licenses
|
||||
granted to You under this License for that Work shall terminate
|
||||
as of the date such litigation is filed.
|
||||
|
||||
4. Redistribution. You may reproduce and distribute copies of the
|
||||
Work or Derivative Works thereof in any medium, with or without
|
||||
modifications, and in Source or Object form, provided that You
|
||||
meet the following conditions:
|
||||
|
||||
(a) You must give any other recipients of the Work or
|
||||
Derivative Works a copy of this License; and
|
||||
|
||||
(b) You must cause any modified files to carry prominent notices
|
||||
stating that You changed the files; and
|
||||
|
||||
(c) You must retain, in the Source form of any Derivative Works
|
||||
that You distribute, all copyright, patent, trademark, and
|
||||
attribution notices from the Source form of the Work,
|
||||
excluding those notices that do not pertain to any part of
|
||||
the Derivative Works; and
|
||||
|
||||
(d) If the Work includes a "NOTICE" text file as part of its
|
||||
distribution, then any Derivative Works that You distribute must
|
||||
include a readable copy of the attribution notices contained
|
||||
within such NOTICE file, excluding those notices that do not
|
||||
pertain to any part of the Derivative Works, in at least one
|
||||
of the following places: within a NOTICE text file distributed
|
||||
as part of the Derivative Works; within the Source form or
|
||||
documentation, if provided along with the Derivative Works; or,
|
||||
within a display generated by the Derivative Works, if and
|
||||
wherever such third-party notices normally appear. The contents
|
||||
of the NOTICE file are for informational purposes only and
|
||||
do not modify the License. You may add Your own attribution
|
||||
notices within Derivative Works that You distribute, alongside
|
||||
or as an addendum to the NOTICE text from the Work, provided
|
||||
that such additional attribution notices cannot be construed
|
||||
as modifying the License.
|
||||
|
||||
You may add Your own copyright statement to Your modifications and
|
||||
may provide additional or different license terms and conditions
|
||||
for use, reproduction, or distribution of Your modifications, or
|
||||
for any such Derivative Works as a whole, provided Your use,
|
||||
reproduction, and distribution of the Work otherwise complies with
|
||||
the conditions stated in this License.
|
||||
|
||||
5. Submission of Contributions. Unless You explicitly state otherwise,
|
||||
any Contribution intentionally submitted for inclusion in the Work
|
||||
by You to the Licensor shall be under the terms and conditions of
|
||||
this License, without any additional terms or conditions.
|
||||
Notwithstanding the above, nothing herein shall supersede or modify
|
||||
the terms of any separate license agreement you may have executed
|
||||
with Licensor regarding such Contributions.
|
||||
|
||||
6. Trademarks. This License does not grant permission to use the trade
|
||||
names, trademarks, service marks, or product names of the Licensor,
|
||||
except as required for reasonable and customary use in describing the
|
||||
origin of the Work and reproducing the content of the NOTICE file.
|
||||
|
||||
7. Disclaimer of Warranty. Unless required by applicable law or
|
||||
agreed to in writing, Licensor provides the Work (and each
|
||||
Contributor provides its Contributions) on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
|
||||
implied, including, without limitation, any warranties or conditions
|
||||
of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
|
||||
PARTICULAR PURPOSE. You are solely responsible for determining the
|
||||
appropriateness of using or redistributing the Work and assume any
|
||||
risks associated with Your exercise of permissions under this License.
|
||||
|
||||
8. Limitation of Liability. In no event and under no legal theory,
|
||||
whether in tort (including negligence), contract, or otherwise,
|
||||
unless required by applicable law (such as deliberate and grossly
|
||||
negligent acts) or agreed to in writing, shall any Contributor be
|
||||
liable to You for damages, including any direct, indirect, special,
|
||||
incidental, or consequential damages of any character arising as a
|
||||
result of this License or out of the use or inability to use the
|
||||
Work (including but not limited to damages for loss of goodwill,
|
||||
work stoppage, computer failure or malfunction, or any and all
|
||||
other commercial damages or losses), even if such Contributor
|
||||
has been advised of the possibility of such damages.
|
||||
|
||||
9. Accepting Warranty or Additional Liability. While redistributing
|
||||
the Work or Derivative Works thereof, You may choose to offer,
|
||||
and charge a fee for, acceptance of support, warranty, indemnity,
|
||||
or other liability obligations and/or rights consistent with this
|
||||
License. However, in accepting such obligations, You may act only
|
||||
on Your own behalf and on Your sole responsibility, not on behalf
|
||||
of any other Contributor, and only if You agree to indemnify,
|
||||
defend, and hold each Contributor harmless for any liability
|
||||
incurred by, or claims asserted against, such Contributor by reason
|
||||
of your accepting any such warranty or additional liability.
|
||||
|
||||
END OF TERMS AND CONDITIONS
|
||||
|
||||
APPENDIX: How to apply the Apache License to your work.
|
||||
|
||||
To apply the Apache License to your work, attach the following
|
||||
boilerplate notice, with the fields enclosed by brackets "{}"
|
||||
replaced with your own identifying information. (Don't include
|
||||
the brackets!) The text should be enclosed in the appropriate
|
||||
comment syntax for the file format. We also recommend that a
|
||||
file or class name and description of purpose be included on the
|
||||
same "printed page" as the copyright notice for easier
|
||||
identification within third-party archives.
|
||||
|
||||
Copyright {yyyy} {name of copyright owner}
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
4
OWNERS
Normal file
4
OWNERS
Normal file
@@ -0,0 +1,4 @@
|
||||
# See https://github.com/kubernetes/community/blob/master/community-membership.md
|
||||
approvers:
|
||||
- kustomize-admins
|
||||
- kustomize-maintainers
|
||||
12
OWNERS_ALIASES
Normal file
12
OWNERS_ALIASES
Normal file
@@ -0,0 +1,12 @@
|
||||
aliases:
|
||||
kustomize-admins:
|
||||
- grodrigues3
|
||||
- monopole
|
||||
- pwittrock
|
||||
kustomize-maintainers:
|
||||
- droot
|
||||
- justinsb
|
||||
- liujingfang1
|
||||
- mengqiy
|
||||
- monopole
|
||||
- pwittrock
|
||||
64
README.md
Normal file
64
README.md
Normal file
@@ -0,0 +1,64 @@
|
||||
# kustomize
|
||||
|
||||
[applied]: docs/glossary.md#apply
|
||||
[base]: docs/glossary.md#base
|
||||
[declarative configuration]: docs/glossary.md#declarative-application-management
|
||||
[demo]: demos/README.md
|
||||
[demos]: demos/README.md
|
||||
[imageBase]: docs/base.jpg
|
||||
[imageOverlay]: docs/overlay.jpg
|
||||
[kubernetes style]: docs/glossary.md#kubernetes-style-object
|
||||
[kustomization]: docs/glossary.md#kustomization
|
||||
[overlay]: docs/glossary.md#overlay
|
||||
[resources]: docs/glossary.md#resource
|
||||
[sig-cli]: https://github.com/kubernetes/community/blob/master/sig-cli/README.md
|
||||
[workflows]: docs/workflows.md
|
||||
|
||||
`kustomize` is a command line tool supporting
|
||||
template-free customization of YAML (or JSON) objects
|
||||
that conform to the [kubernetes style]. If your
|
||||
objects have a `kind` and a `metadata` field,
|
||||
`kustomize` can patch them to support configuration
|
||||
sharing and re-use.
|
||||
|
||||
For more details, try a [demo].
|
||||
|
||||
## Installation
|
||||
|
||||
This assumes [Go](https://golang.org/) (v1.10.1 or higher)
|
||||
is installed and your `PATH` contains `$GOPATH/bin`:
|
||||
|
||||
<!-- @installkustomize @test -->
|
||||
```
|
||||
go get k8s.io/kubectl/cmd/kustomize
|
||||
```
|
||||
|
||||
## Usage
|
||||
|
||||
#### 1) Make a base
|
||||
|
||||
A [base] configuration is a [kustomization] file listing a set of
|
||||
k8s [resources] - deployments, services, configmaps,
|
||||
secrets that serve some common purpose.
|
||||
|
||||
![base image][imageBase]
|
||||
|
||||
#### 2) Customize it with overlays
|
||||
|
||||
An [overlay] customizes your base along different dimensions
|
||||
for different purposes or different teams, e.g. for
|
||||
_development, staging and production_.
|
||||
|
||||
![overlay image][imageOverlay]
|
||||
|
||||
#### 3) Run kustomize
|
||||
|
||||
Run `kustomize` on your overlay. The result
|
||||
is printed to `stdout` as a set of complete
|
||||
resources, ready to be [applied] to a cluster.
|
||||
See the [demos].
|
||||
|
||||
|
||||
## About
|
||||
|
||||
This project sponsored by [sig-cli].
|
||||
29
build/.goreleaser.yml
Normal file
29
build/.goreleaser.yml
Normal file
@@ -0,0 +1,29 @@
|
||||
# This is an example goreleaser.yaml file with some sane defaults.
|
||||
# Make sure to check the documentation at http://goreleaser.com
|
||||
project_name: kustomize
|
||||
builds:
|
||||
- main: ./cmd/kustomize
|
||||
binary: kustomize
|
||||
ldflags: -s -X k8s.io/kubectl/cmd/kustomize/version.kustomizeVersion={{.Version}} -X k8s.io/kubectl/cmd/kustomize/version.gitCommit={{.Commit}} -X k8s.io/kubectl/cmd/kustomize/version.buildDate={{.Date}}
|
||||
goos:
|
||||
- darwin
|
||||
- linux
|
||||
- windows
|
||||
env:
|
||||
- CGO_ENABLED=0
|
||||
archive:
|
||||
wrap_in_directory: true
|
||||
checksum:
|
||||
name_template: 'checksums.txt'
|
||||
snapshot:
|
||||
name_template: "{{ .Tag }}-next"
|
||||
changelog:
|
||||
sort: asc
|
||||
filters:
|
||||
exclude:
|
||||
- '^docs:'
|
||||
- '^test:'
|
||||
release:
|
||||
github:
|
||||
owner: droot
|
||||
name: kubectl
|
||||
16
build/README.md
Normal file
16
build/README.md
Normal file
@@ -0,0 +1,16 @@
|
||||
## Steps to run build locally
|
||||
|
||||
Install container-builder-local from github and define GOOS, GOARCH, OUTPUT env
|
||||
variables and run following command
|
||||
|
||||
```sh
|
||||
container-builder-local --config=cmd/kustomize/build/cloudbuild_local.yaml --dryrun=false --substitutions=_GOOS=$GOOS,_GOARCH=$GOARCH --write-workspace=$OUTPUT .
|
||||
```
|
||||
|
||||
## Steps to submit build to Google container builder
|
||||
|
||||
You need to be at the repo level to be able to run the following command
|
||||
|
||||
```
|
||||
gcloud container builds submit . --config=cmd/kustomize/build/cloudbuild.yaml --substitutions=_GOOS=$GOOS,_GOARCH=$GOARCH
|
||||
```
|
||||
42
build/build.sh
Executable file
42
build/build.sh
Executable file
@@ -0,0 +1,42 @@
|
||||
#!/bin/bash
|
||||
#
|
||||
# Copyright 2018 The Kubernetes Authors.
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||
# you may not use this file except in compliance with the License.
|
||||
# You may obtain a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS,
|
||||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
||||
|
||||
set -e
|
||||
set -x
|
||||
|
||||
# Google Container Builder automatically checks out all the code under the /workspace directory,
|
||||
# but we actually want it to under the correct expected package in the GOPATH (/go)
|
||||
# - Create the directory to host the code that matches the expected GOPATH package locations
|
||||
# - Use /go as the default GOPATH because this is what the image uses
|
||||
# - Link our current directory (containing the source code) to the package location in the GOPATH
|
||||
|
||||
export PKG=k8s.io
|
||||
export REPO=kubectl
|
||||
export CMD=kustomize
|
||||
|
||||
GO_PKG_OWNER=$GOPATH/src/$PKG
|
||||
GO_PKG_PATH=$GO_PKG_OWNER/$REPO
|
||||
|
||||
mkdir -p $GO_PKG_OWNER
|
||||
ln -s $(pwd) $GO_PKG_PATH
|
||||
|
||||
# When invoked in container builder, this script runs under /workspace which is
|
||||
# not under $GOPATH, so we need to `cd` to repo under GOPATH for it to build
|
||||
cd $GO_PKG_PATH
|
||||
|
||||
/goreleaser release --config=cmd/$CMD/build/.goreleaser.yml --debug --rm-dist
|
||||
# --skip-validate
|
||||
# --snapshot --skip-publish
|
||||
25
build/cloudbuild.yaml
Normal file
25
build/cloudbuild.yaml
Normal file
@@ -0,0 +1,25 @@
|
||||
# Copyright 2018 The Kubernetes Authors.
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||
# you may not use this file except in compliance with the License.
|
||||
# You may obtain a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS,
|
||||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
||||
|
||||
# TODO(droot): add instructions for running in production.
|
||||
steps:
|
||||
- name: "ubuntu"
|
||||
args: ["mkdir", "-p", "/workspace/_output"]
|
||||
- name: "gcr.io/kustomize-199618/golang_with_goreleaser:1.10-stretch"
|
||||
args: ["bash", "cmd/kustomize/build/build.sh"]
|
||||
secretEnv: ['GITHUB_TOKEN']
|
||||
secrets:
|
||||
- kmsKeyName: projects/kustomize-199618/locations/global/keyRings/github-tokens/cryptoKeys/gh-release-token
|
||||
secretEnv:
|
||||
GITHUB_TOKEN: CiQAyrREbPgXJOeT7M3t+WlxkhXwlMPudixBeiyWTjmLOMLqdK4SUQA0W+xUmDJKAhyfHCcwqSEzUn9OwKC7XAYcmwe0CCKTCbPbDgmioDK24q3LVapndXNvnnHvCjhOJNEr1o+P1DCF+LlzYV2YL8lP09rrKrslPg==
|
||||
32
build/cloudbuild_local.yaml
Normal file
32
build/cloudbuild_local.yaml
Normal file
@@ -0,0 +1,32 @@
|
||||
# Copyright 2018 The Kubernetes Authors.
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||
# you may not use this file except in compliance with the License.
|
||||
# You may obtain a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS,
|
||||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
||||
|
||||
# Instructions to run locally:
|
||||
# Download google container builder: https://github.com/kubernetes-sigs/container-builder-local
|
||||
# Set you GOOS and GOARCH vars to match your system
|
||||
# Set OUTPUT to the location to write the directory containing the tar.gz
|
||||
# $ container-builder-local --config=build/cloudbuild_local.yaml --dryrun=false \
|
||||
# --substitutions=_GOOS=$GOOS,_GOARCH=$GOARCH --write-workspace=$OUTPUT .
|
||||
# Release tar will be in $OUTPUT
|
||||
|
||||
steps:
|
||||
- name: "ubuntu"
|
||||
args: ["mkdir", "-p", "/workspace/_output"]
|
||||
- name: "gcr.io/kustomize-199618/golang_with_goreleaser:1.10-stretch"
|
||||
args: ["bash", "cmd/kustomize/build/build.sh"]
|
||||
secretEnv: ['GITHUB_TOKEN']
|
||||
secrets:
|
||||
- kmsKeyName: projects/kustomize-199618/locations/global/keyRings/github-tokens/cryptoKeys/gh-release-token
|
||||
secretEnv:
|
||||
GITHUB_TOKEN: CiQAyrREbPgXJOeT7M3t+WlxkhXwlMPudixBeiyWTjmLOMLqdK4SUQA0W+xUmDJKAhyfHCcwqSEzUn9OwKC7XAYcmwe0CCKTCbPbDgmioDK24q3LVapndXNvnnHvCjhOJNEr1o+P1DCF+LlzYV2YL8lP09rrKrslPg==
|
||||
6
code-of-conduct.md
Normal file
6
code-of-conduct.md
Normal file
@@ -0,0 +1,6 @@
|
||||
[Kubernetes Community Code of Conduct]: https://git.k8s.io/community/code-of-conduct.md
|
||||
|
||||
# Code of Conduct
|
||||
|
||||
This project has adopted the
|
||||
[Kubernetes Community Code of Conduct].
|
||||
24
demos/README.md
Normal file
24
demos/README.md
Normal file
@@ -0,0 +1,24 @@
|
||||
# Demos
|
||||
|
||||
These demos assume that `kustomize` is on your `$PATH`.
|
||||
They are covered by pre-submit tests.
|
||||
|
||||
* [hello world](helloWorld.md) - Deploy multiple
|
||||
(differently configured) variants of a simple Hello
|
||||
World server.
|
||||
|
||||
* [LDAP](ldap.md) - Deploy multiple
|
||||
(differently configured) variants of a LDAP server.
|
||||
|
||||
* [mySql](mySql.md) - Create a MySQL production
|
||||
configuration from scratch.
|
||||
|
||||
* [springboot](springboot.md) - Create a Spring Boot
|
||||
application production configuration from scratch.
|
||||
|
||||
* [configGeneration](configGeneration.md) -
|
||||
Mixing configuration data from different owners
|
||||
(e.g. devops/SRE and developers).
|
||||
|
||||
* [breakfast](breakfast.md) - Customize breakfast for
|
||||
Alice and Bob.
|
||||
124
demos/breakfast.md
Normal file
124
demos/breakfast.md
Normal file
@@ -0,0 +1,124 @@
|
||||
[kubernetes API object style]: https://kubernetes.io/docs/concepts/overview/working-with-objects/kubernetes-objects/#required-fields
|
||||
[variant]: ../docs/glossary.md#variant
|
||||
|
||||
# Demo: configure breakfast
|
||||
|
||||
|
||||
Define a place to work:
|
||||
|
||||
<!-- @makeWorkplace @test -->
|
||||
```
|
||||
DEMO_HOME=$(mktemp -d)
|
||||
```
|
||||
|
||||
Make a place to put the base breakfast configuration:
|
||||
|
||||
<!-- @baseDir @test -->
|
||||
```
|
||||
mkdir -p $DEMO_HOME/breakfast/base
|
||||
```
|
||||
|
||||
Make a `kustomization` to define what goes into
|
||||
breakfast. This breakfast has coffee and pancakes:
|
||||
|
||||
<!-- @baseKustomization @test -->
|
||||
```
|
||||
cat <<EOF >$DEMO_HOME/breakfast/base/kustomization.yaml
|
||||
resources:
|
||||
- coffee.yaml
|
||||
- pancakes.yaml
|
||||
EOF
|
||||
```
|
||||
|
||||
Here's a _coffee_ type. Give it a `kind` and `metdata/name` field
|
||||
to conform to [kubernetes API object style]; no other
|
||||
file or definition is needed:
|
||||
|
||||
<!-- @coffee @test -->
|
||||
```
|
||||
cat <<EOF >$DEMO_HOME/breakfast/base/coffee.yaml
|
||||
kind: Coffee
|
||||
metadata:
|
||||
name: morningCup
|
||||
temperature: lukewarm
|
||||
data:
|
||||
greeting: "Good Morning!"
|
||||
EOF
|
||||
```
|
||||
|
||||
The `name` field merely distinguishes this instance of
|
||||
coffee from others (if there were any).
|
||||
|
||||
Likewise, define _pancakes_:
|
||||
<!-- @pancakes @test -->
|
||||
```
|
||||
cat <<EOF >$DEMO_HOME/breakfast/base/pancakes.yaml
|
||||
kind: Pancakes
|
||||
metadata:
|
||||
name: comfort
|
||||
stacksize: 3
|
||||
topping: none
|
||||
EOF
|
||||
```
|
||||
|
||||
Make a custom [variant] of breakfast for Alice, who
|
||||
likes her coffee hot:
|
||||
|
||||
<!-- @aliceOverlay @test -->
|
||||
```
|
||||
mkdir -p $DEMO_HOME/breakfast/overlays/alice
|
||||
|
||||
cat <<EOF >$DEMO_HOME/breakfast/overlays/alice/kustomization.yaml
|
||||
commonLabels:
|
||||
who: alice
|
||||
bases:
|
||||
- ../../base
|
||||
patches:
|
||||
- temperature.yaml
|
||||
EOF
|
||||
|
||||
cat <<EOF >$DEMO_HOME/breakfast/overlays/alice/temperature.yaml
|
||||
kind: Coffee
|
||||
metadata:
|
||||
name: morningCup
|
||||
temperature: hot!
|
||||
EOF
|
||||
```
|
||||
|
||||
And likewise a [variant] for Bob, who wants _five_ pancakes, with strawberries:
|
||||
|
||||
<!-- @bobOverlay @test -->
|
||||
```
|
||||
mkdir -p $DEMO_HOME/breakfast/overlays/bob
|
||||
|
||||
cat <<EOF >$DEMO_HOME/breakfast/overlays/bob/kustomization.yaml
|
||||
commonLabels:
|
||||
who: bob
|
||||
bases:
|
||||
- ../../base
|
||||
patches:
|
||||
- topping.yaml
|
||||
EOF
|
||||
|
||||
cat <<EOF >$DEMO_HOME/breakfast/overlays/bob/topping.yaml
|
||||
kind: Pancakes
|
||||
metadata:
|
||||
name: comfort
|
||||
stacksize: 5
|
||||
topping: strawberries
|
||||
EOF
|
||||
```
|
||||
|
||||
One can now generate the configs for Alice’s breakfast:
|
||||
|
||||
<!-- @generateAlice @test -->
|
||||
```
|
||||
kustomize build $DEMO_HOME/breakfast/overlays/alice
|
||||
```
|
||||
|
||||
Likewise for Bob:
|
||||
|
||||
<!-- @generateBob @test -->
|
||||
```
|
||||
kustomize build $DEMO_HOME/breakfast/overlays/bob
|
||||
```
|
||||
298
demos/configGeneration.md
Normal file
298
demos/configGeneration.md
Normal file
@@ -0,0 +1,298 @@
|
||||
[overlay]: ../docs/glossary.md#overlay
|
||||
[target]: ../docs/glossary.md#target
|
||||
|
||||
# Demo: combining config data from devops and developers
|
||||
|
||||
Scenario: you have a Java-based server storefront in
|
||||
production that various internal development teams
|
||||
(signups, checkout, search, etc.) contribute to.
|
||||
|
||||
The server runs in different environments:
|
||||
_development_, _testing_, _staging_ and _production_,
|
||||
accepting configuration parameters from java property
|
||||
files.
|
||||
|
||||
Using one big properties file for each environment is
|
||||
difficult to manage. The files change frequently, and
|
||||
have to be changed by devops exclusively because
|
||||
|
||||
1. the files must at least partially agree on certain
|
||||
values that devops cares about and that developers
|
||||
ignore and
|
||||
1. because the production
|
||||
properties contain sensitive data like production
|
||||
database credentials.
|
||||
|
||||
## Property sharding
|
||||
|
||||
With some study, we notice that the properties are
|
||||
separable into categories.
|
||||
|
||||
### Common properties
|
||||
|
||||
E.g. internationalization data, static data like
|
||||
physical constants, location of external services, etc.
|
||||
|
||||
_Things that are the same regardless of environment._
|
||||
|
||||
Only one set of values is needed.
|
||||
|
||||
Place them in a file called
|
||||
|
||||
* `common.properties`
|
||||
|
||||
(relative location defined below).
|
||||
|
||||
### Plumbing properties
|
||||
|
||||
E.g. serving location of static content (HTML, CSS,
|
||||
javascript), location of product and customer database
|
||||
tables, ports expected by load balancers, log sinks,
|
||||
etc.
|
||||
|
||||
_The different values for these properties are
|
||||
precisely what sets the environments apart._
|
||||
|
||||
Devops or SRE will want full control over the values
|
||||
used in production. Testing will have fixed
|
||||
databases supporting testing. Developers will want
|
||||
to do whatever they want to try scenarios under
|
||||
development.
|
||||
|
||||
Places these values in
|
||||
|
||||
* `development/plumbing.properties`
|
||||
* `staging/plumbing.properties`
|
||||
* `production/plumbing.properties`
|
||||
|
||||
|
||||
### Secret properties
|
||||
|
||||
E.g. location of actual user tables, database
|
||||
credentials, decryption keys, etc.
|
||||
|
||||
_Things that are a subset of devops controls, that
|
||||
nobody else has (or should want) access to._
|
||||
|
||||
Places these values in
|
||||
|
||||
* `development/secret.properties`
|
||||
* `staging/secret.properties`
|
||||
* `production/secret.properties`
|
||||
|
||||
[kubernetes secret]: https://kubernetes.io/docs/tasks/inject-data-application/distribute-credentials-secure/
|
||||
|
||||
and control access to them with (for example) unix file
|
||||
owner and mode bits, or better yet, put them in
|
||||
a server dedicated to storing password protected
|
||||
secrets, and use a field called `secretGenerator`
|
||||
in your _kustomization_ to create a kubernetes
|
||||
secret holding them (not covering that here).
|
||||
|
||||
<!--
|
||||
secretGenerator:
|
||||
- name: app-tls
|
||||
commands:
|
||||
tls.crt: "cat tls.cert"
|
||||
tls.key: "cat tls.key"
|
||||
type: "kubernetes.io/tls"
|
||||
EOF
|
||||
-->
|
||||
|
||||
## A mixin approach to management
|
||||
|
||||
The way to create _n_ cluster environments that share
|
||||
some common information is to create _n_ overlays of a
|
||||
common base.
|
||||
|
||||
For the rest of this example, we'll do _n==2_, just
|
||||
_development_ and _production_, since adding more
|
||||
environments follows the same pattern.
|
||||
|
||||
A cluster environment is created by
|
||||
running `kustomize build` on a [target] that happens to
|
||||
be an [overlay].
|
||||
|
||||
[helloworld]: helloworld.md
|
||||
|
||||
The following example will do that, but will focus on
|
||||
configMap construction, and not worry about how to
|
||||
connect the configMaps to deployments (that is covered
|
||||
in the [helloworld] example).
|
||||
|
||||
|
||||
All files - including the shared property files
|
||||
discussed above - will be created in a directory tree
|
||||
that is consistent with the base vs overlay file layout
|
||||
defined in the [helloworld] demo.
|
||||
|
||||
It will all live in this work directory:
|
||||
|
||||
<!-- @makeWorkplace @test -->
|
||||
```
|
||||
DEMO_HOME=$(mktemp -d)
|
||||
```
|
||||
|
||||
### Create the base
|
||||
|
||||
<!-- kubectl create configmap BOB --dry-run -o yaml --from-file db. -->
|
||||
|
||||
Make a place to put the base configuration:
|
||||
|
||||
<!-- @baseDir @test -->
|
||||
```
|
||||
mkdir -p $DEMO_HOME/base
|
||||
```
|
||||
|
||||
Make the data for the base. This direction by
|
||||
definition should hold resources common to all
|
||||
environments. Here we're only defining a java
|
||||
properties file, and a `kustomization` file that
|
||||
references it.
|
||||
|
||||
<!-- @baseKustomization @test -->
|
||||
```
|
||||
cat <<EOF >$DEMO_HOME/base/common.properties
|
||||
color=blue
|
||||
height=10m
|
||||
EOF
|
||||
|
||||
cat <<EOF >$DEMO_HOME/base/kustomization.yaml
|
||||
configMapGenerator:
|
||||
- name: my-configmap
|
||||
files:
|
||||
- common.properties
|
||||
EOF
|
||||
```
|
||||
|
||||
|
||||
### Create and use the overlay for _development_
|
||||
|
||||
Make an abbreviation for the parent of the overlay
|
||||
directories:
|
||||
|
||||
<!-- @overlays @test -->
|
||||
```
|
||||
OVERLAYS=$DEMO_HOME/overlays
|
||||
```
|
||||
|
||||
Create the files that define the _development_ overlay:
|
||||
|
||||
<!-- @developmentFiles @test -->
|
||||
```
|
||||
mkdir -p $OVERLAYS/development
|
||||
|
||||
cat <<EOF >$OVERLAYS/development/plumbing.properties
|
||||
port=30000
|
||||
EOF
|
||||
|
||||
cat <<EOF >$OVERLAYS/development/secret.properties
|
||||
dbpassword=mothersMaidenName
|
||||
EOF
|
||||
|
||||
cat <<EOF >$OVERLAYS/development/kustomization.yaml
|
||||
bases:
|
||||
- ../../base
|
||||
namePrefix: dev-
|
||||
configMapGenerator:
|
||||
- name: my-configmap
|
||||
behavior: merge
|
||||
files:
|
||||
- plumbing.properties
|
||||
- secret.properties
|
||||
EOF
|
||||
```
|
||||
|
||||
One can now generate the configMaps for development:
|
||||
|
||||
<!-- @runDev @test -->
|
||||
```
|
||||
kustomize build $OVERLAYS/development
|
||||
```
|
||||
|
||||
#### Check the ConfigMap name
|
||||
|
||||
The name of the generated `ConfigMap` is visible in this
|
||||
output.
|
||||
|
||||
The name should be something like `dev-my-configmap-b5m75ck895`:
|
||||
|
||||
* `"dev-"` comes from the `namePrefix` field,
|
||||
* `"my-configmap"` comes from the `configMapGenerator/name` field,
|
||||
* `"-b5m75ck895"` comes from a deterministic hash that `kustomize`
|
||||
computes from the contents of the configMap.
|
||||
|
||||
The hash suffix is critical. If the configMap content
|
||||
changes, so does the configMap name, along with all
|
||||
references to that name that appear in the YAML output
|
||||
from `kustomize`.
|
||||
|
||||
The name change means deployments will do a rolling
|
||||
restart to get new data if this YAML is applied to the
|
||||
cluster using a command like
|
||||
|
||||
> ```
|
||||
> kustomize build $OVERLAYS/development | kubectl apply -f -
|
||||
> ```
|
||||
|
||||
A deployment has no means to automatically know when or
|
||||
if a configMap in use by the deployment changes.
|
||||
|
||||
If one changes a configMap without changing its name
|
||||
and all references to that name, one must imperatively
|
||||
restart the cluster to pick up the change.
|
||||
|
||||
The best practice is to treat configMaps as immutable.
|
||||
|
||||
Instead of editing configMaps, modify your declarative
|
||||
specification of the cluster's desired state to
|
||||
point deployments to _new_ configMaps with _new_ names.
|
||||
`kustomize` makes this easy with its
|
||||
`configMapGenerator` directive and associated naming
|
||||
controls. A GC process in the k8s master eventually
|
||||
deletes unused configMaps.
|
||||
|
||||
|
||||
### Create and use the overlay for _production_
|
||||
|
||||
Next, create the files for the _production_ overlay:
|
||||
|
||||
|
||||
<!-- @productionFiles @test -->
|
||||
```
|
||||
mkdir -p $OVERLAYS/production
|
||||
|
||||
cat <<EOF >$OVERLAYS/production/plumbing.properties
|
||||
port=8080
|
||||
EOF
|
||||
|
||||
cat <<EOF >$OVERLAYS/production/secret.properties
|
||||
dbpassword=thisShouldProbablyBeInASecretInstead
|
||||
EOF
|
||||
|
||||
cat <<EOF >$OVERLAYS/production/kustomization.yaml
|
||||
bases:
|
||||
- ../../base
|
||||
namePrefix: prod-
|
||||
configMapGenerator:
|
||||
- name: my-configmap
|
||||
behavior: merge
|
||||
files:
|
||||
- plumbing.properties
|
||||
- secret.properties
|
||||
EOF
|
||||
```
|
||||
|
||||
One can now generate the configMaps for production:
|
||||
|
||||
<!-- @runProd @test -->
|
||||
```
|
||||
kustomize build $OVERLAYS/production
|
||||
```
|
||||
|
||||
A CICD process could apply this directly to
|
||||
the cluser using:
|
||||
|
||||
> ```
|
||||
> kustomize build $OVERLAYS/production | kubectl apply -f -
|
||||
> ```
|
||||
7
demos/data/helloWorld/configMap.yaml
Normal file
7
demos/data/helloWorld/configMap.yaml
Normal file
@@ -0,0 +1,7 @@
|
||||
apiVersion: v1
|
||||
kind: ConfigMap
|
||||
metadata:
|
||||
name: the-map
|
||||
data:
|
||||
altGreeting: "Good Morning!"
|
||||
enableRisky: "false"
|
||||
30
demos/data/helloWorld/deployment.yaml
Normal file
30
demos/data/helloWorld/deployment.yaml
Normal file
@@ -0,0 +1,30 @@
|
||||
apiVersion: apps/v1
|
||||
kind: Deployment
|
||||
metadata:
|
||||
name: the-deployment
|
||||
spec:
|
||||
replicas: 3
|
||||
template:
|
||||
metadata:
|
||||
labels:
|
||||
deployment: hello
|
||||
spec:
|
||||
containers:
|
||||
- name: the-container
|
||||
image: monopole/hello:1
|
||||
command: ["/hello",
|
||||
"--port=8080",
|
||||
"--enableRiskyFeature=$(ENABLE_RISKY)"]
|
||||
ports:
|
||||
- containerPort: 8080
|
||||
env:
|
||||
- name: ALT_GREETING
|
||||
valueFrom:
|
||||
configMapKeyRef:
|
||||
name: the-map
|
||||
key: altGreeting
|
||||
- name: ENABLE_RISKY
|
||||
valueFrom:
|
||||
configMapKeyRef:
|
||||
name: the-map
|
||||
key: enableRisky
|
||||
9
demos/data/helloWorld/kustomization.yaml
Normal file
9
demos/data/helloWorld/kustomization.yaml
Normal file
@@ -0,0 +1,9 @@
|
||||
# Example configuration for the webserver
|
||||
# at https://github.com/monopole/hello
|
||||
commonLabels:
|
||||
app: hello
|
||||
|
||||
resources:
|
||||
- deployment.yaml
|
||||
- configMap.yaml
|
||||
- service.yaml
|
||||
12
demos/data/helloWorld/service.yaml
Normal file
12
demos/data/helloWorld/service.yaml
Normal file
@@ -0,0 +1,12 @@
|
||||
kind: Service
|
||||
apiVersion: v1
|
||||
metadata:
|
||||
name: the-service
|
||||
spec:
|
||||
selector:
|
||||
deployment: hello
|
||||
type: LoadBalancer
|
||||
ports:
|
||||
- protocol: TCP
|
||||
port: 8666
|
||||
targetPort: 8080
|
||||
46
demos/data/ldap/base/deployment.yaml
Normal file
46
demos/data/ldap/base/deployment.yaml
Normal file
@@ -0,0 +1,46 @@
|
||||
apiVersion: apps/v1beta2
|
||||
kind: Deployment
|
||||
metadata:
|
||||
name: ldap
|
||||
labels:
|
||||
app: ldap
|
||||
spec:
|
||||
replicas: 1
|
||||
selector:
|
||||
matchLabels:
|
||||
app: ldap
|
||||
template:
|
||||
metadata:
|
||||
labels:
|
||||
app: ldap
|
||||
spec:
|
||||
containers:
|
||||
- name: ldap
|
||||
image: osixia/openldap:1.1.11
|
||||
args: ["--copy-service"]
|
||||
volumeMounts:
|
||||
- name: ldap-data
|
||||
mountPath: /var/lib/ldap
|
||||
- name: ldap-config
|
||||
mountPath: /etc/ldap/slapd.d
|
||||
- name: ldap-certs
|
||||
mountPath: /container/service/slapd/assets/certs
|
||||
- name: configmap-volume
|
||||
mountPath: /container/environment/01-custom
|
||||
- name: container-run
|
||||
mountPath: /container/run
|
||||
ports:
|
||||
- containerPort: 389
|
||||
name: openldap
|
||||
volumes:
|
||||
- name: ldap-data
|
||||
emptyDir: {}
|
||||
- name: ldap-config
|
||||
emptyDir: {}
|
||||
- name: ldap-certs
|
||||
emptyDir: {}
|
||||
- name: "configmap-volume"
|
||||
configMap:
|
||||
name: "ldap-configmap"
|
||||
- name: container-run
|
||||
emptyDir: {}
|
||||
61
demos/data/ldap/base/env.startup.txt
Normal file
61
demos/data/ldap/base/env.startup.txt
Normal file
@@ -0,0 +1,61 @@
|
||||
# This is the default image startup configuration file
|
||||
# this file define environment variables used during the container **first start** in **startup files**.
|
||||
|
||||
# This file is deleted right after startup files are processed for the first time,
|
||||
# after that all these values will not be available in the container environment.
|
||||
# This helps to keep your container configuration secret.
|
||||
# more information : https://github.com/osixia/docker-light-baseimage
|
||||
|
||||
# Required and used for new ldap server only
|
||||
LDAP_ORGANISATION: Example Inc.
|
||||
LDAP_DOMAIN: example.org
|
||||
LDAP_BASE_DN: #if empty automatically set from LDAP_DOMAIN
|
||||
|
||||
LDAP_ADMIN_PASSWORD: admin
|
||||
LDAP_CONFIG_PASSWORD: config
|
||||
|
||||
LDAP_READONLY_USER: false
|
||||
LDAP_READONLY_USER_USERNAME: readonly
|
||||
LDAP_READONLY_USER_PASSWORD: readonly
|
||||
|
||||
LDAP_RFC2307BIS_SCHEMA: false
|
||||
|
||||
# Backend
|
||||
LDAP_BACKEND: hdb
|
||||
|
||||
# Tls
|
||||
LDAP_TLS: true
|
||||
LDAP_TLS_CRT_FILENAME: ldap.crt
|
||||
LDAP_TLS_KEY_FILENAME: ldap.key
|
||||
LDAP_TLS_CA_CRT_FILENAME: ca.crt
|
||||
|
||||
LDAP_TLS_ENFORCE: false
|
||||
LDAP_TLS_CIPHER_SUITE: SECURE256:+SECURE128:-VERS-TLS-ALL:+VERS-TLS1.2:-RSA:-DHE-DSS:-CAMELLIA-128-CBC:-CAMELLIA-256-CBC
|
||||
LDAP_TLS_VERIFY_CLIENT: demand
|
||||
|
||||
# Replication
|
||||
LDAP_REPLICATION: false
|
||||
# variables $LDAP_BASE_DN, $LDAP_ADMIN_PASSWORD, $LDAP_CONFIG_PASSWORD
|
||||
# are automaticaly replaced at run time
|
||||
|
||||
# if you want to add replication to an existing ldap
|
||||
# adapt LDAP_REPLICATION_CONFIG_SYNCPROV and LDAP_REPLICATION_DB_SYNCPROV to your configuration
|
||||
# avoid using $LDAP_BASE_DN, $LDAP_ADMIN_PASSWORD and $LDAP_CONFIG_PASSWORD variables
|
||||
LDAP_REPLICATION_CONFIG_SYNCPROV: binddn="cn=admin,cn=config" bindmethod=simple credentials=$LDAP_CONFIG_PASSWORD searchbase="cn=config" type=refreshAndPersist retry="60 +" timeout=1 starttls=critical
|
||||
LDAP_REPLICATION_DB_SYNCPROV: binddn="cn=admin,$LDAP_BASE_DN" bindmethod=simple credentials=$LDAP_ADMIN_PASSWORD searchbase="$LDAP_BASE_DN" type=refreshAndPersist interval=00:00:00:10 retry="60 +" timeout=1 starttls=critical
|
||||
LDAP_REPLICATION_HOSTS:
|
||||
- ldap://ldap.example.org # The order must be the same on all ldap servers
|
||||
- ldap://ldap2.example.org
|
||||
|
||||
|
||||
# Do not change the ldap config
|
||||
# - If set to true with an existing database, config will remain unchanged. Image tls and replication config will not be run.
|
||||
# The container can be started with LDAP_ADMIN_PASSWORD and LDAP_CONFIG_PASSWORD empty or filled with fake data.
|
||||
# - If set to true when bootstrapping a new database, bootstap ldif and schema will not be added and tls and replication config will not be run.
|
||||
KEEP_EXISTING_CONFIG: false
|
||||
|
||||
# Remove config after setup
|
||||
LDAP_REMOVE_CONFIG_AFTER_SETUP: true
|
||||
|
||||
# ssl-helper environment variables prefix
|
||||
LDAP_SSL_HELPER_PREFIX: ldap # ssl-helper first search config from LDAP_SSL_HELPER_* variables, before SSL_HELPER_* variables.
|
||||
7
demos/data/ldap/base/kustomization.yaml
Normal file
7
demos/data/ldap/base/kustomization.yaml
Normal file
@@ -0,0 +1,7 @@
|
||||
resources:
|
||||
- deployment.yaml
|
||||
- service.yaml
|
||||
configMapGenerator:
|
||||
- name: ldap-configmap
|
||||
files:
|
||||
- env.startup.txt
|
||||
11
demos/data/ldap/base/service.yaml
Normal file
11
demos/data/ldap/base/service.yaml
Normal file
@@ -0,0 +1,11 @@
|
||||
apiVersion: v1
|
||||
kind: Service
|
||||
metadata:
|
||||
labels:
|
||||
app: ldap
|
||||
name: ldap-service
|
||||
spec:
|
||||
ports:
|
||||
- port: 389
|
||||
selector:
|
||||
app: ldap
|
||||
102
demos/data/ldap/base/tests/test.sh
Executable file
102
demos/data/ldap/base/tests/test.sh
Executable file
@@ -0,0 +1,102 @@
|
||||
#!/bin/bash
|
||||
# Copyright 2018 The Kubernetes Authors.
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||
# you may not use this file except in compliance with the License.
|
||||
# You may obtain a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS,
|
||||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
||||
#
|
||||
# ----------------------------------------------------
|
||||
#
|
||||
# This script tests the ldap kustomization demo
|
||||
# against a real cluster.
|
||||
#
|
||||
# - deploy a ldap server by the output of kustomize
|
||||
# - add a user
|
||||
# - query a user
|
||||
# - delete a user
|
||||
#
|
||||
# This script is a test that (passes|fails) if exit
|
||||
# code is (0|1).
|
||||
|
||||
set -x
|
||||
|
||||
function exit_with {
|
||||
local msg=$1
|
||||
echo >&2 ${msg}
|
||||
exit 1
|
||||
}
|
||||
|
||||
# make sure kustomize and kubectl are available
|
||||
command -v kustomize >/dev/null 2>&1 || \
|
||||
{ exit_with "Require kustomize but it's not installed. Aborting."; }
|
||||
command -v kubectl >/dev/null 2>&1 || \
|
||||
{ exit_with "Require kubectl but it's not installed. Aborting."; }
|
||||
|
||||
# set namespace to default
|
||||
kubectl config set-context $(kubectl config current-context) --namespace=default
|
||||
|
||||
echo Kustomizing \"$1\"
|
||||
ls $1
|
||||
kustomize build $1 > generatedResources.yaml
|
||||
[[ $? -eq 0 ]] || { exit_with "Failed to kustomize build"; }
|
||||
cat generatedResources.yaml
|
||||
kubectl apply -f generatedResources.yaml
|
||||
[[ $? -eq 0 ]] || { exit_with "Failed to run kubectl apply"; }
|
||||
sleep 20
|
||||
|
||||
# get the pod and namespace
|
||||
pod=$(kubectl get pods -l app=ldap -o jsonpath='{.items[0].metadata.name}')
|
||||
namespace=$(kubectl get pods -l app=ldap -o jsonpath='{.items[0].metadata.namespace}')
|
||||
container="ldap"
|
||||
[[ -z ${pod} ]] && { exit_with "Pod is not started successfully"; }
|
||||
[[ -z ${namespace} ]] && { exit_with "Couldn't get namespace for Pod ${pod}"; }
|
||||
|
||||
# create a user ldif file locally
|
||||
ldiffile="user.ldif"
|
||||
cat <<EOF >$ldiffile
|
||||
dn: cn=The Postmaster,dc=example,dc=org
|
||||
objectClass: organizationalRole
|
||||
cn: The Postmaster
|
||||
EOF
|
||||
[[ -f ${ldiffile} ]] || { exit_with "Failed to create ldif file locally"; }
|
||||
|
||||
# add a user
|
||||
pod_ldiffile="/tmp/user.ldif"
|
||||
kubectl cp $ldiffile ${namespace}/${pod}:${pod_ldiffile} || \
|
||||
{ exit_with "Failed to copy ldif file to Pod ${pod}"; }
|
||||
|
||||
kubectl exec ${pod} -c ${container} -- \
|
||||
ldapadd -x -H ldap://localhost -D "cn=admin,dc=example,dc=org" -w admin \
|
||||
-f ${pod_ldiffile} || { exit_with "Failed to add a user"; }
|
||||
|
||||
# query the added user
|
||||
r=$(kubectl exec ${pod} -c ${container} -- \
|
||||
ldapsearch -x -H ldap://localhost -b dc=example,dc=org \
|
||||
-D "cn=admin,dc=example,dc=org" -w admin)
|
||||
|
||||
user_count=$(echo ${r} | grep "cn: The Postmaster" | wc -l)
|
||||
[[ ${user_count} -eq 0 ]] && { exit_with "Couldn't find the new added user"; }
|
||||
|
||||
# delete the added user
|
||||
kubectl exec ${pod} -c ${container} -- \
|
||||
ldapdelete -v -x -H ldap://localhost "cn=The Postmaster,dc=example,dc=org" \
|
||||
-D "cn=admin,dc=example,dc=org" -w admin || \
|
||||
{ exit_with "Failed to delete the user"; }
|
||||
|
||||
r=$(kubectl exec ${pod} -c ${container} -- \
|
||||
ldapsearch -x -H ldap://localhost -b dc=example,dc=org \
|
||||
-D "cn=admin,dc=example,dc=org" -w admin)
|
||||
user_count=$(echo ${r} | grep "cn: The Postmaster" | wc -l)
|
||||
[[ ${user_count} -ne 0 ]] && { exit_with "The user hasn't been deleted."; }
|
||||
|
||||
# kubectl delete
|
||||
kubectl delete -f generatedResources.yaml
|
||||
rm $ldiffile
|
||||
13
demos/data/ldap/overlays/production/deployment.yaml
Normal file
13
demos/data/ldap/overlays/production/deployment.yaml
Normal file
@@ -0,0 +1,13 @@
|
||||
apiVersion: apps/v1beta2
|
||||
kind: Deployment
|
||||
metadata:
|
||||
name: ldap
|
||||
spec:
|
||||
replicas: 6
|
||||
template:
|
||||
spec:
|
||||
volumes:
|
||||
- name: ldap-data
|
||||
emptyDir: null
|
||||
gcePersistentDisk:
|
||||
pdName: ldap-persistent-storage
|
||||
5
demos/data/ldap/overlays/production/kustomization.yaml
Normal file
5
demos/data/ldap/overlays/production/kustomization.yaml
Normal file
@@ -0,0 +1,5 @@
|
||||
bases:
|
||||
- ../../base
|
||||
patches:
|
||||
- deployment.yaml
|
||||
namePrefix: production-
|
||||
2
demos/data/ldap/overlays/staging/config.env
Normal file
2
demos/data/ldap/overlays/staging/config.env
Normal file
@@ -0,0 +1,2 @@
|
||||
DB_USERNAME=admin
|
||||
DB_PASSWORD=somepw
|
||||
7
demos/data/ldap/overlays/staging/deployment.yaml
Normal file
7
demos/data/ldap/overlays/staging/deployment.yaml
Normal file
@@ -0,0 +1,7 @@
|
||||
|
||||
apiVersion: apps/v1beta2
|
||||
kind: Deployment
|
||||
metadata:
|
||||
name: ldap
|
||||
spec:
|
||||
replicas: 2
|
||||
9
demos/data/ldap/overlays/staging/kustomization.yaml
Normal file
9
demos/data/ldap/overlays/staging/kustomization.yaml
Normal file
@@ -0,0 +1,9 @@
|
||||
bases:
|
||||
- ../../base
|
||||
patches:
|
||||
- deployment.yaml
|
||||
nameprefix: staging-
|
||||
configMapGenerator:
|
||||
- name: env-config
|
||||
files:
|
||||
- config.env
|
||||
35
demos/data/mySql/deployment.yaml
Normal file
35
demos/data/mySql/deployment.yaml
Normal file
@@ -0,0 +1,35 @@
|
||||
apiVersion: apps/v1beta2 # for versions before 1.9.0 use apps/v1beta2
|
||||
kind: Deployment
|
||||
metadata:
|
||||
name: mysql
|
||||
labels:
|
||||
app: mysql
|
||||
spec:
|
||||
selector:
|
||||
matchLabels:
|
||||
app: mysql
|
||||
strategy:
|
||||
type: Recreate
|
||||
template:
|
||||
metadata:
|
||||
labels:
|
||||
app: mysql
|
||||
spec:
|
||||
containers:
|
||||
- image: mysql:5.6
|
||||
name: mysql
|
||||
env:
|
||||
- name: MYSQL_ROOT_PASSWORD
|
||||
valueFrom:
|
||||
secretKeyRef:
|
||||
name: mysql-pass
|
||||
key: password
|
||||
ports:
|
||||
- containerPort: 3306
|
||||
name: mysql
|
||||
volumeMounts:
|
||||
- name: mysql-persistent-storage
|
||||
mountPath: /var/lib/mysql
|
||||
volumes:
|
||||
- name: mysql-persistent-storage
|
||||
emptyDir: {}
|
||||
9
demos/data/mySql/secret.yaml
Normal file
9
demos/data/mySql/secret.yaml
Normal file
@@ -0,0 +1,9 @@
|
||||
apiVersion: v1
|
||||
kind: Secret
|
||||
metadata:
|
||||
creationTimestamp: null
|
||||
name: mysql-pass-d2gtcm2t2k
|
||||
type: Opaque
|
||||
data:
|
||||
# Default password is "admin".
|
||||
password: YWRtaW4=
|
||||
11
demos/data/mySql/service.yaml
Normal file
11
demos/data/mySql/service.yaml
Normal file
@@ -0,0 +1,11 @@
|
||||
apiVersion: v1
|
||||
kind: Service
|
||||
metadata:
|
||||
name: mysql
|
||||
labels:
|
||||
app: mysql
|
||||
spec:
|
||||
ports:
|
||||
- port: 3306
|
||||
selector:
|
||||
app: mysql
|
||||
27
demos/data/springboot/base/deployment.yaml
Normal file
27
demos/data/springboot/base/deployment.yaml
Normal file
@@ -0,0 +1,27 @@
|
||||
apiVersion: apps/v1beta2
|
||||
kind: Deployment
|
||||
metadata:
|
||||
name: sbdemo
|
||||
labels:
|
||||
app: sbdemo
|
||||
spec:
|
||||
selector:
|
||||
matchLabels:
|
||||
app: sbdemo
|
||||
template:
|
||||
metadata:
|
||||
labels:
|
||||
app: sbdemo
|
||||
spec:
|
||||
containers:
|
||||
- name: sbdemo
|
||||
image: jingfang/sbdemo
|
||||
ports:
|
||||
- containerPort: 8080
|
||||
volumeMounts:
|
||||
- name: demo-config
|
||||
mountPath: /config
|
||||
volumes:
|
||||
- name: "demo-config"
|
||||
configMap:
|
||||
name: "demo-configmap"
|
||||
12
demos/data/springboot/base/service.yaml
Normal file
12
demos/data/springboot/base/service.yaml
Normal file
@@ -0,0 +1,12 @@
|
||||
apiVersion: v1
|
||||
kind: Service
|
||||
metadata:
|
||||
name: sbdemo
|
||||
labels:
|
||||
app: sbdemo
|
||||
spec:
|
||||
ports:
|
||||
- port: 8080
|
||||
selector:
|
||||
app: sbdemo
|
||||
type: LoadBalancer
|
||||
@@ -0,0 +1,5 @@
|
||||
app.name=Staging Kinflate Demo
|
||||
spring.jpa.hibernate.ddl-auto=update
|
||||
spring.datasource.url=jdbc:mysql://<production_db_ip>:3306/db_example
|
||||
spring.datasource.username=root
|
||||
spring.datasource.password=admin
|
||||
@@ -0,0 +1,22 @@
|
||||
apiVersion: apps/v1beta2
|
||||
kind: Deployment
|
||||
metadata:
|
||||
name: sbdemo
|
||||
spec:
|
||||
replicas: 2
|
||||
template:
|
||||
spec:
|
||||
containers:
|
||||
- name: sbdemo
|
||||
livenessProbe:
|
||||
httpGet:
|
||||
path: /actuator/health
|
||||
port: 8080
|
||||
initialDelaySeconds: 10
|
||||
periodSeconds: 3
|
||||
readinessProbe:
|
||||
initialDelaySeconds: 20
|
||||
periodSeconds: 10
|
||||
httpGet:
|
||||
path: /actuator/info
|
||||
port: 8080
|
||||
@@ -0,0 +1,7 @@
|
||||
bases:
|
||||
- ../../base
|
||||
patches:
|
||||
- patch.yaml
|
||||
- healthcheck_patch.yaml
|
||||
- memorylimit_patch.yaml
|
||||
namePrefix: production-
|
||||
@@ -0,0 +1,20 @@
|
||||
apiVersion: apps/v1beta2
|
||||
kind: Deployment
|
||||
metadata:
|
||||
name: sbdemo
|
||||
spec:
|
||||
replicas: 2
|
||||
template:
|
||||
spec:
|
||||
containers:
|
||||
- name: sbdemo
|
||||
resources:
|
||||
limits:
|
||||
memory: 1250Mi
|
||||
requests:
|
||||
memory: 1250Mi
|
||||
env:
|
||||
- name: MEM_TOTAL_MB
|
||||
valueFrom:
|
||||
resourceFieldRef:
|
||||
resource: limits.memory
|
||||
13
demos/data/springboot/overlays/production/patch.yaml
Normal file
13
demos/data/springboot/overlays/production/patch.yaml
Normal file
@@ -0,0 +1,13 @@
|
||||
apiVersion: v1
|
||||
kind: ConfigMap
|
||||
metadata:
|
||||
name: demo-configmap
|
||||
data:
|
||||
application.properties: |
|
||||
app.name=Staging Kinflate Demo
|
||||
spring.jpa.hibernate.ddl-auto=update
|
||||
spring.datasource.url=jdbc:mysql://<production_db_ip>:3306/db_example
|
||||
spring.datasource.username=root
|
||||
spring.datasource.password=admin
|
||||
server.tomcat.max-threads=20
|
||||
server.tomcat.min-spare-threads=3
|
||||
@@ -0,0 +1,5 @@
|
||||
app.name=Staging Kinflate Demo
|
||||
spring.jpa.hibernate.ddl-auto=update
|
||||
spring.datasource.url=jdbc:mysql://<staging_db_ip>:3306/db_example
|
||||
spring.datasource.username=root
|
||||
spring.datasource.password=admin
|
||||
11
demos/data/springboot/overlays/staging/kustomization.yaml
Normal file
11
demos/data/springboot/overlays/staging/kustomization.yaml
Normal file
@@ -0,0 +1,11 @@
|
||||
bases:
|
||||
- ../../base
|
||||
namePrefix: staging-
|
||||
configMapGenerator:
|
||||
- name: demo-configmap
|
||||
behavior: merge
|
||||
files:
|
||||
- application.properties
|
||||
literals:
|
||||
- foo=bar
|
||||
env: staging.env
|
||||
1
demos/data/springboot/overlays/staging/staging.env
Normal file
1
demos/data/springboot/overlays/staging/staging.env
Normal file
@@ -0,0 +1 @@
|
||||
staging
|
||||
432
demos/helloWorld.md
Normal file
432
demos/helloWorld.md
Normal file
@@ -0,0 +1,432 @@
|
||||
[base]: ../docs/glossary.md#base
|
||||
[config]: https://github.com/kinflate/example-hello
|
||||
[gitops]: ../docs/glossary.md#gitops
|
||||
[hello]: https://github.com/monopole/hello
|
||||
[kustomization]: ../docs/glossary.md#kustomization
|
||||
[original]: https://github.com/kinflate/example-hello
|
||||
[overlay]: ../docs/glossary.md#overlay
|
||||
[overlays]: ../docs/glossary.md#overlay
|
||||
[variant]: ../docs/glossary.md#variant
|
||||
[variants]: ../docs/glossary.md#variant
|
||||
|
||||
# Demo: hello world with variants
|
||||
|
||||
Steps:
|
||||
|
||||
1. Clone an existing configuration as a [base].
|
||||
1. Customize it.
|
||||
1. Create two different [overlays] (_staging_ and _production_)
|
||||
from the customized base.
|
||||
1. Run kustomize and kubectl to deploy staging and production.
|
||||
|
||||
First define a place to work:
|
||||
|
||||
<!-- @makeWorkplace @test -->
|
||||
```
|
||||
DEMO_HOME=$(mktemp -d)
|
||||
```
|
||||
|
||||
Alternatively, use
|
||||
|
||||
> ```
|
||||
> DEMO_HOME=~/hello
|
||||
> ```
|
||||
|
||||
## Establish the base
|
||||
|
||||
Let's run the [hello] service.
|
||||
|
||||
To use [overlays] to create [variants], we must
|
||||
first establish a common [base].
|
||||
|
||||
To keep this document shorter, the base resources are
|
||||
off in a supplemental data directory rather than
|
||||
declared here as HERE documents. Download them:
|
||||
|
||||
<!-- @downloadBase @test -->
|
||||
```
|
||||
BASE=$DEMO_HOME/base
|
||||
mkdir -p $BASE
|
||||
|
||||
resources="https://raw.githubusercontent.com/kubernetes/kubectl\
|
||||
/master/cmd/kustomize/demos/data/helloWorld\
|
||||
/{configMap,deployment,kustomization,service}.yaml"
|
||||
|
||||
curl -s $resources -o "$BASE/#1.yaml"
|
||||
```
|
||||
|
||||
Look at the directory:
|
||||
|
||||
<!-- @runTree @test -->
|
||||
```
|
||||
tree $DEMO_HOME
|
||||
```
|
||||
|
||||
Expect something like:
|
||||
|
||||
> ```
|
||||
> /tmp/tmp.IyYQQlHaJP
|
||||
> └── base
|
||||
> ├── configMap.yaml
|
||||
> ├── deployment.yaml
|
||||
> ├── kustomization.yaml
|
||||
> └── service.yaml
|
||||
> ```
|
||||
|
||||
|
||||
One could immediately apply these resources to a
|
||||
cluster:
|
||||
|
||||
> ```
|
||||
> kubectl apply -f $DEMO_HOME/base
|
||||
> ```
|
||||
|
||||
to instantiate the _hello_ service. `kubectl`
|
||||
would only recognize the resource files.
|
||||
|
||||
### The Base Kustomization
|
||||
|
||||
The `base` directory has a [kustomization] file:
|
||||
|
||||
<!-- @showKustomization @test -->
|
||||
```
|
||||
more $BASE/kustomization.yaml
|
||||
```
|
||||
|
||||
Optionally, run `kustomize` on the base to emit
|
||||
customized resources to `stdout`:
|
||||
|
||||
<!-- @buildBase @test -->
|
||||
```
|
||||
kustomize build $BASE
|
||||
```
|
||||
|
||||
### Customize the base
|
||||
|
||||
A first customization step could be to change the _app
|
||||
label_ applied to all resources:
|
||||
|
||||
<!-- @addLabel @test -->
|
||||
```
|
||||
sed -i 's/app: hello/app: my-hello/' \
|
||||
$BASE/kustomization.yaml
|
||||
```
|
||||
|
||||
See the effect:
|
||||
<!-- @checkLabel @test -->
|
||||
```
|
||||
kustomize build $BASE | grep -C 3 app:
|
||||
```
|
||||
|
||||
## Create Overlays
|
||||
|
||||
Create a _staging_ and _production_ [overlay]:
|
||||
|
||||
* _Staging_ enables a risky feature not enabled in production.
|
||||
* _Production_ has a higher replica count.
|
||||
* Web server greetings from these cluster
|
||||
[variants] will differ from each other.
|
||||
|
||||
<!-- @overlayDirectories @test -->
|
||||
```
|
||||
OVERLAYS=$DEMO_HOME/overlays
|
||||
mkdir -p $OVERLAYS/staging
|
||||
mkdir -p $OVERLAYS/production
|
||||
```
|
||||
|
||||
#### Staging Kustomization
|
||||
|
||||
In the `staging` directory, make a kustomization
|
||||
defining a new name prefix, and some different labels.
|
||||
|
||||
<!-- @makeStagingKustomization @test -->
|
||||
```
|
||||
cat <<'EOF' >$OVERLAYS/staging/kustomization.yaml
|
||||
namePrefix: staging-
|
||||
commonLabels:
|
||||
variant: staging
|
||||
org: acmeCorporation
|
||||
commonAnnotations:
|
||||
note: Hello, I am staging!
|
||||
bases:
|
||||
- ../../base
|
||||
patches:
|
||||
- map.yaml
|
||||
EOF
|
||||
```
|
||||
|
||||
#### Staging Patch
|
||||
|
||||
Add a configMap customization to change the server
|
||||
greeting from _Good Morning!_ to _Have a pineapple!_
|
||||
|
||||
Also, enable the _risky_ flag.
|
||||
|
||||
<!-- @stagingMap @test -->
|
||||
```
|
||||
cat <<EOF >$OVERLAYS/staging/map.yaml
|
||||
apiVersion: v1
|
||||
kind: ConfigMap
|
||||
metadata:
|
||||
name: the-map
|
||||
data:
|
||||
altGreeting: "Have a pineapple!"
|
||||
enableRisky: "true"
|
||||
EOF
|
||||
```
|
||||
|
||||
#### Production Kustomization
|
||||
|
||||
In the production directory, make a kustomization
|
||||
with a different name prefix and labels.
|
||||
|
||||
<!-- @makeProductionKustomization @test -->
|
||||
```
|
||||
cat <<EOF >$OVERLAYS/production/kustomization.yaml
|
||||
namePrefix: production-
|
||||
commonLabels:
|
||||
variant: production
|
||||
org: acmeCorporation
|
||||
commonAnnotations:
|
||||
note: Hello, I am production!
|
||||
bases:
|
||||
- ../../base
|
||||
patches:
|
||||
- deployment.yaml
|
||||
EOF
|
||||
```
|
||||
|
||||
|
||||
#### Production Patch
|
||||
|
||||
Make a production patch that increases the replica
|
||||
count (because production takes more traffic).
|
||||
|
||||
<!-- @productionDeployment @test -->
|
||||
```
|
||||
cat <<EOF >$OVERLAYS/production/deployment.yaml
|
||||
apiVersion: apps/v1
|
||||
kind: Deployment
|
||||
metadata:
|
||||
name: the-deployment
|
||||
spec:
|
||||
replicas: 10
|
||||
EOF
|
||||
```
|
||||
|
||||
## Compare overlays
|
||||
|
||||
|
||||
`DEMO_HOME` now contains:
|
||||
|
||||
- a _base_ directory - a slightly customized clone
|
||||
of the original configuration, and
|
||||
|
||||
- an _overlays_ directory, containing the kustomizations
|
||||
and patches required to create distinct _staging_
|
||||
and _production_ [variants] in a cluster.
|
||||
|
||||
Review the directory structure and differences:
|
||||
|
||||
<!-- @listFiles @test -->
|
||||
```
|
||||
tree $DEMO_HOME
|
||||
```
|
||||
|
||||
Expecting something like:
|
||||
|
||||
> ```
|
||||
> /tmp/tmp.IyYQQlHaJP1
|
||||
> ├── base
|
||||
> │ ├── configMap.yaml
|
||||
> │ ├── deployment.yaml
|
||||
> │ ├── kustomization.yaml
|
||||
> │ └── service.yaml
|
||||
> └── overlays
|
||||
> ├── production
|
||||
> │ ├── deployment.yaml
|
||||
> │ └── kustomization.yaml
|
||||
> └── staging
|
||||
> ├── kustomization.yaml
|
||||
> └── map.yaml
|
||||
> ```
|
||||
|
||||
Compare the output directly
|
||||
to see how _staging_ and _production_ differ:
|
||||
|
||||
<!-- @compareOutput -->
|
||||
```
|
||||
diff \
|
||||
<(kustomize build $OVERLAYS/staging) \
|
||||
<(kustomize build $OVERLAYS/production) |\
|
||||
more
|
||||
```
|
||||
|
||||
The first part of the difference output should look
|
||||
something like
|
||||
|
||||
> ```diff
|
||||
> < altGreeting: Have a pineapple!
|
||||
> < enableRisky: "true"
|
||||
> ---
|
||||
> > altGreeting: Good Morning!
|
||||
> > enableRisky: "false"
|
||||
> 8c8
|
||||
> < note: Hello, I am staging!
|
||||
> ---
|
||||
> > note: Hello, I am production!
|
||||
> 11c11
|
||||
> < variant: staging
|
||||
> ---
|
||||
> > variant: production
|
||||
> 13c13
|
||||
> (...truncated)
|
||||
> ```
|
||||
|
||||
|
||||
## Deploy
|
||||
|
||||
The individual resource sets are:
|
||||
|
||||
<!-- @buildStaging @test -->
|
||||
```
|
||||
kustomize build $OVERLAYS/staging
|
||||
```
|
||||
|
||||
<!-- @buildProduction @test -->
|
||||
```
|
||||
kustomize build $OVERLAYS/production
|
||||
```
|
||||
|
||||
To deploy, pipe the above commands to kubectl apply:
|
||||
|
||||
> ```
|
||||
> kustomize build $OVERLAYS/staging |\
|
||||
> kubectl apply -f -
|
||||
> ```
|
||||
|
||||
> ```
|
||||
> kustomize build $OVERLAYS/production |\
|
||||
> kubectl apply -f -
|
||||
> ```
|
||||
|
||||
## Rolling updates
|
||||
|
||||
### Review
|
||||
|
||||
The _hello-world_ deployment running in this cluster is
|
||||
configured with data from a configMap.
|
||||
|
||||
The deployment refers to this map by name:
|
||||
|
||||
|
||||
<!-- @showDeployment @test -->
|
||||
```
|
||||
grep -C 2 configMapKeyRef $DEMO_HOME/base/deployment.yaml
|
||||
```
|
||||
|
||||
Changing the data held by a live configMap in a cluster
|
||||
is considered bad practice. Deployments have no means
|
||||
to know that the configMaps they refer to have
|
||||
changed, so such updates have no effect.
|
||||
|
||||
The recommended way to change a deployment's
|
||||
configuration is to
|
||||
|
||||
1. create a new configMap with a new name,
|
||||
1. patch the _deployment_, modifying the name value of
|
||||
the appropriate `configMapKeyRef` field.
|
||||
|
||||
This latter change initiates rolling update to the pods
|
||||
in the deployment. The older configMap, when no longer
|
||||
referenced by any other resource, is eventually garbage
|
||||
collected.
|
||||
|
||||
### How this works with kustomize
|
||||
|
||||
[patch]: ../docs/glossary.md#patch
|
||||
|
||||
The _staging_ [variant] here has a configMap [patch]:
|
||||
|
||||
<!-- @showMapPatch @test -->
|
||||
```
|
||||
cat $OVERLAYS/staging/map.yaml
|
||||
```
|
||||
|
||||
This patch is by definition a named but not necessarily
|
||||
complete resource spec intended to modify a complete
|
||||
resource spec.
|
||||
|
||||
The resource it modifies is here:
|
||||
|
||||
<!-- @showMapBase @test -->
|
||||
```
|
||||
cat $DEMO_HOME/base/configMap.yaml
|
||||
```
|
||||
|
||||
For a patch to work, the names in the `metadata/name`
|
||||
fields must match.
|
||||
|
||||
However, the name values specified in the file are
|
||||
_not_ what gets used in the cluster. By design,
|
||||
kustomize modifies these names. To see the names
|
||||
ultimately used in the cluster, just run kustomize:
|
||||
|
||||
<!-- @grepStagingName @test -->
|
||||
```
|
||||
kustomize build $OVERLAYS/staging |\
|
||||
grep -B 8 -A 1 staging-the-map
|
||||
```
|
||||
|
||||
The configMap name is prefixed by _staging-_, per the
|
||||
`namePrefix` field in
|
||||
`$OVERLAYS/staging/kustomization.yaml`.
|
||||
|
||||
The suffix to the configMap name is generated from a
|
||||
hash of the maps content - in this case the name suffix
|
||||
is _hhhhkfmgmk_:
|
||||
|
||||
<!-- @grepStagingHash @test -->
|
||||
```
|
||||
kustomize build $OVERLAYS/staging | grep hhhhkfmgmk
|
||||
```
|
||||
|
||||
Now modify the map patch, to change the greeting
|
||||
the server will use:
|
||||
|
||||
<!-- @changeMap @test -->
|
||||
```
|
||||
sed -i 's/pineapple/kiwi/' $OVERLAYS/staging/map.yaml
|
||||
```
|
||||
|
||||
Run kustomize again to see the new names:
|
||||
|
||||
<!-- @grepStagingName @test -->
|
||||
```
|
||||
kustomize build $OVERLAYS/staging |\
|
||||
grep -B 8 -A 1 staging-the-map
|
||||
```
|
||||
|
||||
Confirm that the change in configMap content resulted
|
||||
in three new names ending in _khk45ktkd9_ - one in the
|
||||
configMap name itself, and two in the deployment that
|
||||
uses the map:
|
||||
|
||||
<!-- @countHashes @test -->
|
||||
```
|
||||
test 3 == \
|
||||
$(kustomize build $OVERLAYS/staging | grep khk45ktkd9 | wc -l)
|
||||
```
|
||||
|
||||
Applying these resources to the cluster will result in
|
||||
a rolling update of the deployments pods, retargetting
|
||||
them from the _hhhhkfmgmk_ maps to the _khk45ktkd9_
|
||||
maps. The system will later garbage collect the
|
||||
unused maps.
|
||||
|
||||
## Rollback
|
||||
|
||||
To rollback, one would undo whatever edits were made to
|
||||
the configuation in source control, then rerun kustomize
|
||||
on the reverted configuration and apply it to the
|
||||
cluster.
|
||||
284
demos/ldap.md
Normal file
284
demos/ldap.md
Normal file
@@ -0,0 +1,284 @@
|
||||
[base]: ../docs/glossary.md#base
|
||||
[gitops]: ../docs/glossary.md#gitops
|
||||
[kustomization]: ../docs/glossary.md#kustomization
|
||||
[overlay]: ../docs/glossary.md#overlay
|
||||
[overlays]: ../docs/glossary.md#overlay
|
||||
[variant]: ../docs/glossary.md#variant
|
||||
[variants]: ../docs/glossary.md#variant
|
||||
|
||||
# Demo: LDAP with variants
|
||||
|
||||
Steps:
|
||||
|
||||
1. Clone an existing configuration as a [base].
|
||||
1. Customize it.
|
||||
1. Create two different [overlays] (_staging_ and _production_)
|
||||
from the customized base.
|
||||
1. Run kustomize and kubectl to deploy staging and production.
|
||||
|
||||
First define a place to work:
|
||||
|
||||
<!-- @makeWorkplace @test -->
|
||||
```
|
||||
DEMO_HOME=$(mktemp -d)
|
||||
```
|
||||
|
||||
Alternatively, use
|
||||
|
||||
> ```
|
||||
> DEMO_HOME=~/ldap
|
||||
> ```
|
||||
|
||||
## Establish the base
|
||||
|
||||
To use [overlays] to create [variants], we must
|
||||
first establish a common [base].
|
||||
|
||||
To keep this document shorter, the base resources are
|
||||
off in a supplemental data directory rather than
|
||||
declared here as HERE documents. Download them:
|
||||
|
||||
<!-- @downloadBase @test -->
|
||||
```
|
||||
BASE=$DEMO_HOME/base
|
||||
mkdir -p $BASE
|
||||
|
||||
resources="https://raw.githubusercontent.com/kubernetes/kubectl\
|
||||
/master/cmd/kustomize/demos/data/ldap/base\
|
||||
/{deployment.yaml,kustomization.yaml,service.yaml,env.startup.txt}"
|
||||
|
||||
curl -s $resources -o "$BASE/#1"
|
||||
```
|
||||
|
||||
Look at the directory:
|
||||
|
||||
<!-- @runTree @test -->
|
||||
```
|
||||
tree $DEMO_HOME
|
||||
```
|
||||
|
||||
Expect something like:
|
||||
|
||||
> ```
|
||||
> /tmp/tmp.IyYQQlHaJP
|
||||
> └── base
|
||||
> ├── deployment.yaml
|
||||
> ├── env.startup.txt
|
||||
> ├── kustomization.yaml
|
||||
> └── service.yaml
|
||||
> ```
|
||||
|
||||
|
||||
One could immediately apply these resources to a
|
||||
cluster:
|
||||
|
||||
> ```
|
||||
> kubectl apply -f $DEMO_HOME/base
|
||||
> ```
|
||||
|
||||
to instantiate the _ldap_ service. `kubectl`
|
||||
would only recognize the resource files.
|
||||
|
||||
### The Base Kustomization
|
||||
|
||||
The `base` directory has a [kustomization] file:
|
||||
|
||||
<!-- @showKustomization @test -->
|
||||
```
|
||||
more $BASE/kustomization.yaml
|
||||
```
|
||||
|
||||
Optionally, run `kustomize` on the base to emit
|
||||
customized resources to `stdout`:
|
||||
|
||||
<!-- @buildBase @test -->
|
||||
```
|
||||
kustomize build $BASE
|
||||
```
|
||||
|
||||
### Customize the base
|
||||
|
||||
A first customization step could be to set the name prefix to all resources:
|
||||
|
||||
<!-- @namePrefix @test -->
|
||||
```
|
||||
cd $BASE
|
||||
kustomize edit set nameprefix "my-"
|
||||
```
|
||||
|
||||
See the effect:
|
||||
<!-- @checkNameprefix @test -->
|
||||
```
|
||||
kustomize build $BASE | grep -C 3 "my-"
|
||||
```
|
||||
|
||||
## Create Overlays
|
||||
|
||||
Create a _staging_ and _production_ [overlay]:
|
||||
|
||||
* _Staging_ adds a configMap.
|
||||
* _Production_ has a higher replica count and a persistent disk.
|
||||
* [variants] will differ from each other.
|
||||
|
||||
<!-- @overlayDirectories @test -->
|
||||
```
|
||||
OVERLAYS=$DEMO_HOME/overlays
|
||||
mkdir -p $OVERLAYS/staging
|
||||
mkdir -p $OVERLAYS/production
|
||||
```
|
||||
|
||||
#### Staging Kustomization
|
||||
|
||||
Download the staging customization and patch.
|
||||
<!-- @downloadStagingKustomization @test -->
|
||||
```
|
||||
resources="https://raw.githubusercontent.com/kubernetes/kubectl\
|
||||
/master/cmd/kustomize/demos/data/ldap/overlays/staging\
|
||||
/{config.env,deployment.yaml,kustomization.yaml}"
|
||||
|
||||
curl -s $resources -o "$OVERLAYS/staging/#1"
|
||||
```
|
||||
The staging customization adds a configMap.
|
||||
> ```cat $OVERLAYS/staging/kustomization.yaml
|
||||
> (...truncated)
|
||||
> configMapGenerator:
|
||||
> - name: env-config
|
||||
> files:
|
||||
> - config.env
|
||||
> ```
|
||||
as well as 2 replica
|
||||
> ```cat $OVERLAYS/staging/deployment.yaml
|
||||
> apiVersion: apps/v1beta2
|
||||
> kind: Deployment
|
||||
> metadata:
|
||||
> name: ldap
|
||||
> spec:
|
||||
> replicas: 2
|
||||
> ```
|
||||
|
||||
#### Production Kustomization
|
||||
|
||||
Download the production customization and patch.
|
||||
<!-- @downloadProductionKustomization @test -->
|
||||
```
|
||||
resources="https://raw.githubusercontent.com/kubernetes/kubectl\
|
||||
/master/cmd/kustomize/demos/data/ldap/overlays/production\
|
||||
/{deployment.yaml,kustomization.yaml}"
|
||||
|
||||
curl -s $resources -o "$OVERLAYS/production/#1"
|
||||
```
|
||||
|
||||
The production customization adds 6 replica as well as a consistent disk.
|
||||
> ```cat $OVERLAYS/production/deployment.yaml
|
||||
> apiVersion: apps/v1beta2
|
||||
> kind: Deployment
|
||||
> metadata:
|
||||
> name: ldap
|
||||
> spec:
|
||||
> replicas: 6
|
||||
> template:
|
||||
> spec:
|
||||
> volumes:
|
||||
> - name: ldap-data
|
||||
> emptyDir: null
|
||||
> gcePersistentDisk:
|
||||
> pdName: ldap-persistent-storage
|
||||
> ```
|
||||
|
||||
## Compare overlays
|
||||
|
||||
|
||||
`DEMO_HOME` now contains:
|
||||
|
||||
- a _base_ directory - a slightly customized clone
|
||||
of the original configuration, and
|
||||
|
||||
- an _overlays_ directory, containing the kustomizations
|
||||
and patches required to create distinct _staging_
|
||||
and _production_ [variants] in a cluster.
|
||||
|
||||
Review the directory structure and differences:
|
||||
|
||||
<!-- @listFiles @test -->
|
||||
```
|
||||
tree $DEMO_HOME
|
||||
```
|
||||
|
||||
Expecting something like:
|
||||
|
||||
> ```
|
||||
> /tmp/tmp.IyYQQlHaJP1
|
||||
> ├── base
|
||||
> │ ├── deployment.yaml
|
||||
> │ ├── env.startup.txt
|
||||
> │ ├── kustomization.yaml
|
||||
> │ └── service.yaml
|
||||
> └── overlays
|
||||
> ├── production
|
||||
> │ ├── deployment.yaml
|
||||
> │ └── kustomization.yaml
|
||||
> └── staging
|
||||
> ├── config.env
|
||||
> ├── deployment.yaml
|
||||
> └── kustomization.yaml
|
||||
> ```
|
||||
|
||||
Compare the output directly
|
||||
to see how _staging_ and _production_ differ:
|
||||
|
||||
<!-- @compareOutput -->
|
||||
```
|
||||
diff \
|
||||
<(kustomize build $OVERLAYS/staging) \
|
||||
<(kustomize build $OVERLAYS/production) |\
|
||||
more
|
||||
```
|
||||
|
||||
The difference output should look something like
|
||||
|
||||
> ```diff
|
||||
> (...truncated)
|
||||
> < name: staging-my-ldap-configmap-kftftt474h
|
||||
> ---
|
||||
> > name: production-my-ldap-configmap-k27f7hkg4f
|
||||
> 85c75
|
||||
> < name: staging-my-ldap-service
|
||||
> ---
|
||||
> > name: production-my-ldap-service
|
||||
> 97c87
|
||||
> < name: staging-my-ldap
|
||||
> ---
|
||||
> > name: production-my-ldap
|
||||
> 99c89
|
||||
> < replicas: 2
|
||||
> ---
|
||||
> > replicas: 6
|
||||
> (...truncated)
|
||||
> ```
|
||||
|
||||
|
||||
## Deploy
|
||||
|
||||
The individual resource sets are:
|
||||
|
||||
<!-- @buildStaging @test -->
|
||||
```
|
||||
kustomize build $OVERLAYS/staging
|
||||
```
|
||||
|
||||
<!-- @buildProduction @test -->
|
||||
```
|
||||
kustomize build $OVERLAYS/production
|
||||
```
|
||||
|
||||
To deploy, pipe the above commands to kubectl apply:
|
||||
|
||||
> ```
|
||||
> kustomize build $OVERLAYS/staging |\
|
||||
> kubectl apply -f -
|
||||
> ```
|
||||
|
||||
> ```
|
||||
> kustomize build $OVERLAYS/production |\
|
||||
> kubectl apply -f -
|
||||
> ```
|
||||
203
demos/mySql.md
Normal file
203
demos/mySql.md
Normal file
@@ -0,0 +1,203 @@
|
||||
# Demo: MySql
|
||||
|
||||
This example takes some off-the-shelf k8s resources
|
||||
designed for MySQL, and customizes them to suit a
|
||||
production scenario.
|
||||
|
||||
In the production environment we want:
|
||||
|
||||
- MySQL resource names to be prefixed by 'prod-'.
|
||||
- MySQL resources to have 'env: prod' labels.
|
||||
- MySQL to use persistent disk for storing data.
|
||||
|
||||
First make a place to work:
|
||||
<!-- @makeDemoHome @test -->
|
||||
```
|
||||
DEMO_HOME=$(mktemp -d)
|
||||
```
|
||||
|
||||
### Download resources
|
||||
|
||||
To keep this document shorter, the base resources
|
||||
needed to run MySql on a k8s cluster are off in a
|
||||
supplemental data directory rather than declared here
|
||||
as HERE documents.
|
||||
|
||||
Download them:
|
||||
|
||||
<!-- @downloadResources @test -->
|
||||
```
|
||||
curl -s -o "$DEMO_HOME/#1.yaml" \
|
||||
"https://raw.githubusercontent.com/kubernetes/kubectl\
|
||||
/master/cmd/kustomize/demos/data/mySql\
|
||||
/{deployment,secret,service}.yaml"
|
||||
```
|
||||
|
||||
### Initialize kustomization.yaml
|
||||
|
||||
The `kustomize` program gets its instructions from
|
||||
a file called `kustomization.yaml`.
|
||||
|
||||
Start this file:
|
||||
|
||||
<!-- @kustomizeYaml @test -->
|
||||
```
|
||||
touch $DEMO_HOME/kustomization.yaml
|
||||
```
|
||||
|
||||
### Add the resources
|
||||
|
||||
<!-- @addResources @test -->
|
||||
```
|
||||
cd $DEMO_HOME
|
||||
|
||||
kustomize edit add resource secret.yaml
|
||||
kustomize edit add resource service.yaml
|
||||
kustomize edit add resource deployment.yaml
|
||||
|
||||
cat kustomization.yaml
|
||||
```
|
||||
|
||||
`kustomization.yaml`'s resources section should contain:
|
||||
|
||||
> ```
|
||||
> resources:
|
||||
> - secret.yaml
|
||||
> - service.yaml
|
||||
> - deployment.yaml
|
||||
> ```
|
||||
|
||||
### Name Customization
|
||||
|
||||
Arrange for the MySQL resources to begin with prefix
|
||||
_prod-_ (since they are meant for the _production_
|
||||
environment):
|
||||
|
||||
<!-- @customizeLabel @test -->
|
||||
```
|
||||
cd $DEMO_HOME
|
||||
|
||||
kustomize edit set nameprefix 'prod-'
|
||||
|
||||
cat kustomization.yaml
|
||||
```
|
||||
|
||||
`kustomization.yaml` should have updated value of namePrefix field:
|
||||
|
||||
> ```
|
||||
> namePrefix: prod-
|
||||
> ```
|
||||
|
||||
This `namePrefix` directive adds _prod-_ to all
|
||||
resource names.
|
||||
|
||||
<!-- @genNamePrefixConfig @test -->
|
||||
```
|
||||
kustomize build $DEMO_HOME
|
||||
```
|
||||
|
||||
The output should contain:
|
||||
|
||||
> ```
|
||||
> apiVersion: v1
|
||||
> data:
|
||||
> password: YWRtaW4=
|
||||
> kind: Secret
|
||||
> metadata:
|
||||
> ....
|
||||
> name: prod-mysql-pass-d2gtcm2t2k
|
||||
> ---
|
||||
> apiVersion: v1
|
||||
> kind: Service
|
||||
> metadata:
|
||||
> ....
|
||||
> name: prod-mysql
|
||||
> spec:
|
||||
> ....
|
||||
> ---
|
||||
> apiVersion: apps/v1beta2
|
||||
> kind: Deployment
|
||||
> metadata:
|
||||
> ....
|
||||
> name: prod-mysql
|
||||
> spec:
|
||||
> selector:
|
||||
> ....
|
||||
> ```
|
||||
|
||||
### Label Customization
|
||||
|
||||
We want resources in production environment to have
|
||||
certain labels so that we can query them by label
|
||||
selector.
|
||||
|
||||
`kustomize` does not have `edit set label` command to add
|
||||
a label, but one can always edit `kustomization.yaml` directly:
|
||||
|
||||
<!-- @customizeLabels @test -->
|
||||
```
|
||||
sed -i 's/app: helloworld/app: prod/' \
|
||||
$DEMO_HOME/kustomization.yaml
|
||||
```
|
||||
|
||||
At this point, running `kustomize build` will
|
||||
generate MySQL configs with name-prefix 'prod-' and
|
||||
labels `env:prod`.
|
||||
|
||||
### Storage customization
|
||||
|
||||
Off the shelf MySQL uses `emptyDir` type volume, which
|
||||
gets wiped away if the MySQL Pod is recreated, and that
|
||||
is certainly not desirable for production
|
||||
environment. So we want to use Persistent Disk in
|
||||
production. kustomize lets you apply `patches` to the
|
||||
resources.
|
||||
|
||||
<!-- @createPatchFile @test -->
|
||||
```
|
||||
cat <<'EOF' > $DEMO_HOME/persistent-disk.yaml
|
||||
apiVersion: apps/v1beta2 # for versions before 1.9.0 use apps/v1beta2
|
||||
kind: Deployment
|
||||
metadata:
|
||||
name: mysql
|
||||
spec:
|
||||
template:
|
||||
spec:
|
||||
volumes:
|
||||
- name: mysql-persistent-storage
|
||||
emptyDir: null
|
||||
gcePersistentDisk:
|
||||
pdName: mysql-persistent-storage
|
||||
EOF
|
||||
```
|
||||
|
||||
Add the patch file to `kustomization.yaml`:
|
||||
|
||||
<!-- @specifyPatch @test -->
|
||||
```
|
||||
cat <<'EOF' >> $DEMO_HOME/kustomization.yaml
|
||||
patches:
|
||||
- persistent-disk.yaml
|
||||
EOF
|
||||
```
|
||||
|
||||
Lets break this down:
|
||||
|
||||
- In the first step, we created a YAML file named
|
||||
`persistent-disk.yaml` to patch the resource defined
|
||||
in deployment.yaml
|
||||
|
||||
- Then we added `persistent-disk.yaml` to list of
|
||||
`patches` in `kustomization.yaml`. `kustomize build`
|
||||
will apply this patch to the deployment resource with
|
||||
the name `mysql` as defined in the patch.
|
||||
|
||||
|
||||
The output of the following command can now be applied
|
||||
to the cluster (i.e. piped to `kubectl apply`) to
|
||||
create the production environment.
|
||||
|
||||
<!-- @finalInflation @test -->
|
||||
```
|
||||
kustomize build $DEMO_HOME # | kubectl apply -f -
|
||||
```
|
||||
306
demos/springboot.md
Normal file
306
demos/springboot.md
Normal file
@@ -0,0 +1,306 @@
|
||||
# Demo: SpringBoot
|
||||
|
||||
In this tutorial, you will learn - how to use `kustomize` to customize a basic Spring Boot application's
|
||||
k8s configuration for production use cases.
|
||||
|
||||
In the production environment we want to customize the following:
|
||||
|
||||
- add application specific configuration for this Spring Boot application
|
||||
- configure prod DB access configuration
|
||||
- resource names to be prefixed by 'prod-'.
|
||||
- resources to have 'env: prod' labels.
|
||||
- JVM memory to be properly set.
|
||||
- health check and readiness check.
|
||||
|
||||
First make a place to work:
|
||||
<!-- @makeDemoHome @test -->
|
||||
```
|
||||
DEMO_HOME=$(mktemp -d)
|
||||
```
|
||||
|
||||
### Download resources
|
||||
|
||||
To keep this document shorter, the base resources
|
||||
needed to run springboot on a k8s cluster are off in a
|
||||
supplemental data directory rather than declared here
|
||||
as HERE documents.
|
||||
|
||||
Download them:
|
||||
|
||||
<!-- @downloadResources @test -->
|
||||
```
|
||||
CONTENT="https://raw.githubusercontent.com/kubernetes/kubectl\
|
||||
/master/cmd/kustomize/demos/data/springboot"
|
||||
|
||||
curl -s -o "$DEMO_HOME/#1.yaml" \
|
||||
"$CONTENT/base/{deployment,service}.yaml"
|
||||
```
|
||||
|
||||
### Initialize kustomization.yaml
|
||||
|
||||
The `kustomize` program gets its instructions from
|
||||
a file called `kustomization.yaml`.
|
||||
|
||||
Start this file:
|
||||
|
||||
<!-- @kustomizeYaml @test -->
|
||||
```
|
||||
touch $DEMO_HOME/kustomization.yaml
|
||||
```
|
||||
|
||||
### Add the resources
|
||||
|
||||
<!-- @addResources @test -->
|
||||
```
|
||||
cd $DEMO_HOME
|
||||
|
||||
kustomize edit add resource service.yaml
|
||||
kustomize edit add resource deployment.yaml
|
||||
|
||||
cat kustomization.yaml
|
||||
```
|
||||
|
||||
`kustomization.yaml`'s resources section should contain:
|
||||
|
||||
> ```
|
||||
> resources:
|
||||
> - service.yaml
|
||||
> - deployment.yaml
|
||||
> ```
|
||||
|
||||
### Add configMap generator
|
||||
|
||||
<!-- @addConfigMap @test -->
|
||||
```
|
||||
echo "app.name=Kustomize Demo" >$DEMO_HOME/application.properties
|
||||
|
||||
kustomize edit add configmap demo-configmap \
|
||||
--from-file application.properties
|
||||
|
||||
cat kustomization.yaml
|
||||
```
|
||||
|
||||
`kustomization.yaml`'s configMapGenerator section should contain:
|
||||
|
||||
> ```
|
||||
> configMapGenerator:
|
||||
> - files:
|
||||
> - application.properties
|
||||
> name: demo-configmap
|
||||
> ```
|
||||
|
||||
### Customize configMap
|
||||
|
||||
We want to add database credentials for the prod environment. In general, these credentials can be put into the file `application.properties`.
|
||||
However, for some cases, we want to keep the credentials in a different file and keep application specific configs in `application.properties`.
|
||||
With this clear separation, the credentials and application specific things can be managed and maintained flexibly by different teams.
|
||||
For example, application developers only tune the application configs in `application.properties` and operation teams or SREs
|
||||
only care about the credentials.
|
||||
|
||||
For Spring Boot application, we can set an active profile through the environment variable `spring.profiles.active`. Then
|
||||
the application will pick up an extra `application-<profile>.properties` file. With this, we can customize the configMap in two
|
||||
steps. Add an environment variable through the patch and add a file to the configMap.
|
||||
|
||||
<!-- @customizeConfigMap @test -->
|
||||
```
|
||||
cat <<EOF >$DEMO_HOME/patch.yaml
|
||||
apiVersion: apps/v1beta2
|
||||
kind: Deployment
|
||||
metadata:
|
||||
name: sbdemo
|
||||
spec:
|
||||
template:
|
||||
spec:
|
||||
containers:
|
||||
- name: sbdemo
|
||||
env:
|
||||
- name: spring.profiles.active
|
||||
value: prod
|
||||
EOF
|
||||
|
||||
kustomize edit add patch patch.yaml
|
||||
|
||||
cat <<EOF >$DEMO_HOME/application-prod.properties
|
||||
spring.jpa.hibernate.ddl-auto=update
|
||||
spring.datasource.url=jdbc:mysql://<prod_database_host>:3306/db_example
|
||||
spring.datasource.username=root
|
||||
spring.datasource.password=admin
|
||||
EOF
|
||||
|
||||
kustomize edit add configmap \
|
||||
demo-configmap --from-file application-prod.properties
|
||||
|
||||
cat kustomization.yaml
|
||||
```
|
||||
|
||||
`kustomization.yaml`'s configMapGenerator section should contain:
|
||||
> ```
|
||||
> configMapGenerator:
|
||||
> - files:
|
||||
> - application.properties
|
||||
> - application-prod.properties
|
||||
> name: demo-configmap
|
||||
> ```
|
||||
|
||||
### Name Customization
|
||||
|
||||
Arrange for the resources to begin with prefix
|
||||
_prod-_ (since they are meant for the _production_
|
||||
environment):
|
||||
|
||||
<!-- @customizeLabel @test -->
|
||||
```
|
||||
cd $DEMO_HOME
|
||||
kustomize edit set nameprefix 'prod-'
|
||||
```
|
||||
|
||||
`kustomization.yaml` should have updated value of namePrefix field:
|
||||
|
||||
> ```
|
||||
> namePrefix: prod-
|
||||
> ```
|
||||
|
||||
This `namePrefix` directive adds _prod-_ to all
|
||||
resource names, as can be seen by building the
|
||||
resources:
|
||||
|
||||
<!-- @build1 @test -->
|
||||
```
|
||||
kustomize build $DEMO_HOME | grep prod-
|
||||
```
|
||||
|
||||
### Label Customization
|
||||
|
||||
We want resources in production environment to have
|
||||
certain labels so that we can query them by label
|
||||
selector.
|
||||
|
||||
`kustomize` does not have `edit set label` command to
|
||||
add a label, but one can always edit
|
||||
`kustomization.yaml` directly:
|
||||
|
||||
<!-- @customizeLabels @test -->
|
||||
```
|
||||
cat <<EOF >>$DEMO_HOME/kustomization.yaml
|
||||
commonLabels:
|
||||
env: prod
|
||||
EOF
|
||||
```
|
||||
|
||||
Confirm that the resources now all have names prefixed
|
||||
by `prod-` and the label tuple `env:prod`:
|
||||
|
||||
<!-- @build2 @test -->
|
||||
```
|
||||
kustomize build $DEMO_HOME | grep -C 3 env
|
||||
```
|
||||
|
||||
### Download Patch for JVM memory
|
||||
|
||||
When a Spring Boot application is deployed in a k8s cluster, the JVM is running inside a container. We want to set memory limit for the container and make sure
|
||||
the JVM is aware of that limit. In K8s deployment, we can set the resource limits for containers and inject these limits to
|
||||
some environment variables by downward API. When the container starts to run, it can pick up the environment variables and
|
||||
set JVM options accordingly.
|
||||
|
||||
Download the patch `memorylimit_patch.yaml`. It contains the memory limits setup.
|
||||
|
||||
<!-- @downloadPatch @test -->
|
||||
```
|
||||
curl -s -o "$DEMO_HOME/#1.yaml" \
|
||||
"$CONTENT/overlays/production/{memorylimit_patch}.yaml"
|
||||
|
||||
cat $DEMO_HOME/memorylimit_patch.yaml
|
||||
```
|
||||
|
||||
The output contains
|
||||
|
||||
> ```
|
||||
> apiVersion: apps/v1beta2
|
||||
> kind: Deployment
|
||||
> metadata:
|
||||
> name: sbdemo
|
||||
> spec:
|
||||
> template:
|
||||
> spec:
|
||||
> containers:
|
||||
> - name: sbdemo
|
||||
> resources:
|
||||
> limits:
|
||||
> memory: 1250Mi
|
||||
> requests:
|
||||
> memory: 1250Mi
|
||||
> env:
|
||||
> - name: MEM_TOTAL_MB
|
||||
> valueFrom:
|
||||
> resourceFieldRef:
|
||||
> resource: limits.memory
|
||||
> ```
|
||||
|
||||
### Download Patch for health check
|
||||
We also want to add liveness check and readiness check in the production environment. Spring Boot application
|
||||
has end points such as `/actuator/health` for this. We can customize the k8s deployment resource to talk to Spring Boot end point.
|
||||
|
||||
Download the patch `healthcheck_patch.yaml`. It contains the liveness probes and readyness probes.
|
||||
|
||||
<!-- @downloadPatch @test -->
|
||||
```
|
||||
curl -s -o "$DEMO_HOME/#1.yaml" \
|
||||
"$CONTENT/overlays/production/{healthcheck_patch}.yaml"
|
||||
|
||||
cat $DEMO_HOME/healthcheck_patch.yaml
|
||||
```
|
||||
|
||||
The output contains
|
||||
|
||||
> ```
|
||||
> apiVersion: apps/v1beta2
|
||||
> kind: Deployment
|
||||
> metadata:
|
||||
> name: sbdemo
|
||||
> spec:
|
||||
> template:
|
||||
> spec:
|
||||
> containers:
|
||||
> - name: sbdemo
|
||||
> livenessProbe:
|
||||
> httpGet:
|
||||
> path: /actuator/health
|
||||
> port: 8080
|
||||
> initialDelaySeconds: 10
|
||||
> periodSeconds: 3
|
||||
> readinessProbe:
|
||||
> initialDelaySeconds: 20
|
||||
> periodSeconds: 10
|
||||
> httpGet:
|
||||
> path: /actuator/info
|
||||
> port: 8080
|
||||
> ```
|
||||
|
||||
### Add patches
|
||||
|
||||
Add these patches to the kustomization:
|
||||
|
||||
<!-- @addPatch @test -->
|
||||
```
|
||||
cd $DEMO_HOME
|
||||
kustomize edit add patch memorylimit_patch.yaml
|
||||
kustomize edit add patch healthcheck_patch.yaml
|
||||
```
|
||||
|
||||
`kustomization.yaml` should have patches field:
|
||||
|
||||
> ```
|
||||
> patches:
|
||||
> - patch.yaml
|
||||
> - memorylimit_patch.yaml
|
||||
> - healthcheck_patch.yaml
|
||||
> ```
|
||||
|
||||
The output of the following command can now be applied
|
||||
to the cluster (i.e. piped to `kubectl apply`) to
|
||||
create the production environment.
|
||||
|
||||
<!-- @finalBuild @test -->
|
||||
```
|
||||
kustomize build $DEMO_HOME # | kubectl apply -f -
|
||||
```
|
||||
BIN
docs/base.jpg
Normal file
BIN
docs/base.jpg
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 39 KiB |
318
docs/glossary.md
Normal file
318
docs/glossary.md
Normal file
@@ -0,0 +1,318 @@
|
||||
# Glossary
|
||||
|
||||
[DAM]: #declarative-application-management
|
||||
[JSON]: https://www.json.org/
|
||||
[Resource]: #resource
|
||||
[YAML]: http://www.yaml.org/start.html
|
||||
[application]: #application
|
||||
[apply]: #apply
|
||||
[apt]: https://en.wikipedia.org/wiki/APT_(Debian)
|
||||
[base]: #base
|
||||
[bases]: #base
|
||||
[bespoke]: #bespoke-configuration
|
||||
[gitops]: #gitops
|
||||
[k8s]: #kubernetes
|
||||
[kubernetes]: #kubernetes
|
||||
[kustomize]: #kustomize
|
||||
[kustomization]: #kustomization
|
||||
[off-the-shelf]: #off-the-shelf
|
||||
[overlay]: #overlay
|
||||
[overlays]: #overlay
|
||||
[patch]: #patch
|
||||
[patches]: #patch
|
||||
[proposal]: https://github.com/kubernetes/community/pull/1629
|
||||
[rebase]: https://git-scm.com/docs/git-rebase
|
||||
[resource]: #resource
|
||||
[resources]: #resource
|
||||
[rpm]: https://en.wikipedia.org/wiki/Rpm_(software)
|
||||
[target]: #target
|
||||
[variant]: #variant
|
||||
[variants]: #variant
|
||||
[workflow]: workflows.md
|
||||
|
||||
## application
|
||||
|
||||
An _application_ is a group of k8s resources related by
|
||||
some common purpose, e.g. a load balancer in front of a
|
||||
webserver backed by a database.
|
||||
[Resource] labelling, naming and metadata schemes have
|
||||
historically served to group resources together for
|
||||
collective operations like _list_ and _remove_.
|
||||
|
||||
This [proposal] describes a new k8s resource called
|
||||
_application_ to more formally describe this idea and
|
||||
provide support for application-level operations and
|
||||
dashboards.
|
||||
|
||||
[kustomize] configures k8s resources, and the proposed
|
||||
application resource is just another resource.
|
||||
|
||||
|
||||
## apply
|
||||
|
||||
The verb _apply_ in the context of k8s refers to a
|
||||
kubectl command and an in-progress [API
|
||||
endpoint](https://goo.gl/UbCRuf) for mutating a
|
||||
cluster.
|
||||
|
||||
One _applies_ a statement of what one wants to a
|
||||
cluster in the form of a complete resource list.
|
||||
|
||||
The cluster merges this with the previously applied
|
||||
state and the actual state to arrive at a new desired
|
||||
state, which the cluster's reconcilation loop attempts
|
||||
to create. This is the foundation of level-based state
|
||||
management in k8s.
|
||||
|
||||
## base
|
||||
|
||||
A _base_ is a [target] that some [overlay] modifies.
|
||||
|
||||
Any target, including an overlay, can be a base to
|
||||
another target.
|
||||
|
||||
A base has no knowledge of the overlays that refer to it.
|
||||
|
||||
A base is usable in isolation, i.e. one should
|
||||
be able to [apply] a base to a cluster directly.
|
||||
|
||||
For simple [gitops] management, a base configuration
|
||||
could be the _sole content of a git repository
|
||||
dedicated to that purpose_. Same with [overlays].
|
||||
Changes in a repo could generate a build, test and
|
||||
deploy cycle.
|
||||
|
||||
Some of the demos for [kustomize] will break from this
|
||||
idiom and store all demo config files in directories
|
||||
_next_ to the `kustomize` code so that the code and
|
||||
demos can be more easily maintained by the same group
|
||||
of people.
|
||||
|
||||
## bespoke configuration
|
||||
|
||||
A _bespoke_ configuration is a [kustomization] and some
|
||||
[resources] created and maintained internally by some
|
||||
organization for their own purposes.
|
||||
|
||||
The [workflow] associated with a _bespoke_ config is
|
||||
simpler than the workflow associated with an
|
||||
[off-the-shelf] config, because there's no notion of
|
||||
periodically capturing someone else's upgrades to the
|
||||
[off-the-shelf] config.
|
||||
|
||||
## declarative application management
|
||||
|
||||
_Declarative Application Management_ (DAM) is a [set of
|
||||
ideas](https://goo.gl/T66ZcD) aiming to ease management
|
||||
of k8s clusters.
|
||||
|
||||
* Works with any configuration, be it bespoke,
|
||||
off-the-shelf, stateless, stateful, etc.
|
||||
* Supports common customizations, and creation of
|
||||
[variants] (dev vs. staging vs. production).
|
||||
* Exposes and teaches native k8s APIs, rather than
|
||||
hiding them.
|
||||
* No friction integration with version control to
|
||||
support reviews and audit trails.
|
||||
* Composable with other tools in a unix sense.
|
||||
* Eschews crossing the line into templating, domain
|
||||
specific languages, etc., frustrating the other
|
||||
goals.
|
||||
|
||||
## gitops
|
||||
|
||||
Devops or CICD workflows that use a git repository as a
|
||||
single source of truth and take action (e.g., build,
|
||||
test or deploy) when that truth changes.
|
||||
|
||||
## kustomization
|
||||
|
||||
A _kustomization_ is a file called `kustomization.yaml` that
|
||||
describes a configuration consumable by [kustomize].
|
||||
|
||||
|
||||
Here's an [example](kustomization.yaml).
|
||||
|
||||
A kustomization contains fields falling into these categories:
|
||||
|
||||
* Immediate customization declarations, e.g.
|
||||
_namePrefix_, _commonLabels_, etc.
|
||||
* Resource _generators_ for configmaps and secrets.
|
||||
* References to _external files_ in these categories:
|
||||
* [resources] - completely specified k8s API objects,
|
||||
e.g. `deployment.yaml`, `configmap.yaml`, etc.
|
||||
* [patches] - _partial_ resources that modify full
|
||||
resources defined in a [base]
|
||||
(only meaningful in an [overlay]).
|
||||
* [bases] - path to a directory containing
|
||||
a [kustomization] (only meaningful in an [overlay]).
|
||||
* (_TBD_) Standard k8s API kind-version fields.
|
||||
|
||||
## kubernetes
|
||||
|
||||
[Kubernetes](https://kubernetes.io) is an open-source
|
||||
system for automating deployment, scaling, and
|
||||
management of containerized applications.
|
||||
|
||||
It's often abbreviated as _k8s_.
|
||||
|
||||
## kubernetes-style object
|
||||
|
||||
[fields required]: https://kubernetes.io/docs/concepts/overview/working-with-objects/kubernetes-objects/#required-fields
|
||||
|
||||
An object, expressed in a YAML or JSON file, with the
|
||||
[fields required] by kubernetes. Basically just a
|
||||
`kind` field to identify the type, a `metadata/name`
|
||||
field to identify the variant, and an `apiVersion`
|
||||
field to identify the version (if there's more than one
|
||||
version).
|
||||
|
||||
## kustomize
|
||||
|
||||
_kustomize_ is a command line tool supporting template-free
|
||||
customization of declarative configuration targetted to
|
||||
k8s-style objects.
|
||||
|
||||
_Targetted to k8s means_ that kustomize may need some
|
||||
limited understanding of API resources, k8s concepts
|
||||
like names, labels, namespaces, etc. and the semantics
|
||||
of resource patching.
|
||||
|
||||
kustomize is an implementation of [DAM].
|
||||
|
||||
|
||||
## off-the-shelf configuration
|
||||
|
||||
An _off-the-shelf_ configuration is a kustomization and
|
||||
resources intentionally published somewhere for others
|
||||
to use.
|
||||
|
||||
E.g. one might create a github repository like this:
|
||||
|
||||
> ```
|
||||
> github.com/username/someapp/
|
||||
> kustomization.yaml
|
||||
> deployment.yaml
|
||||
> configmap.yaml
|
||||
> README.md
|
||||
> ```
|
||||
|
||||
Someone could then _fork_ this repo (on github) and
|
||||
_clone_ their fork to their local disk for
|
||||
customization.
|
||||
|
||||
This clone could act as a [base] for the user's
|
||||
own [overlays] to do further customization.
|
||||
|
||||
## overlay
|
||||
|
||||
An _overlay_ is a [target] that modifies (and thus
|
||||
depends on) another target.
|
||||
|
||||
The [kustomization] in an overlay refers to (via file
|
||||
path, URI or other method) _some other kustomization_,
|
||||
known as its [base].
|
||||
|
||||
An overlay is unusable without its base.
|
||||
|
||||
An overlay supports the typical notion of a
|
||||
_development_, _QA_, _staging_ and _production_
|
||||
environment variants.
|
||||
|
||||
The configuration of these environments is specified in
|
||||
individual overlays (one per environment) that all
|
||||
refer to a common base that holds common configuration.
|
||||
One configures the cluster like this:
|
||||
|
||||
> ```
|
||||
> kustomize build someapp/overlays/staging |\
|
||||
> kubectl apply -f -
|
||||
>
|
||||
> kustomize build someapp/overlays/production |\
|
||||
> kubectl apply -f -
|
||||
> ```
|
||||
|
||||
Usage of the base is implicit (the overlay's kustomization
|
||||
points to the base).
|
||||
|
||||
An overlay may act as a base to another overlay.
|
||||
|
||||
## package
|
||||
|
||||
The word _package_ has no meaning in kustomize, as
|
||||
kustomize is not to be confused with a package
|
||||
management tool in the tradition of, say, [apt] or
|
||||
[rpm].
|
||||
|
||||
## patch
|
||||
|
||||
A _patch_ is a partially defined k8s resource with a
|
||||
name that must match a resource already known per
|
||||
traversal rules built into [kustomize].
|
||||
|
||||
_Patch_ is a field in the kustomization, distinct from
|
||||
resources, because a patch file looks like a resource
|
||||
file, but has different semantics. A patch depends on
|
||||
(modifies) a resource, whereas a resource has no
|
||||
dependencies. Since any resource file can be used as a
|
||||
patch, one cannot reliably distinguish a resource from
|
||||
a patch just by looking at the file's [YAML].
|
||||
|
||||
## resource
|
||||
|
||||
A _resource_, in the context of kustomize, is a path to
|
||||
a [YAML] or [JSON] file that completely defines a
|
||||
functional k8s API object, like a deployment or a
|
||||
configmap.
|
||||
|
||||
More generally, a resource can be any correct YAML file
|
||||
that [defines an object](https://kubernetes.io/docs/concepts/overview/working-with-objects/kubernetes-objects/#required-fields)
|
||||
with a `kind` and a `metadata/name` field.
|
||||
|
||||
|
||||
A _resource_ in the content of a REST-ful API is the
|
||||
target of an HTTP operation like _GET_, _PUT_ or
|
||||
_POST_. k8s offers a RESTful API surface to interact
|
||||
with clients.
|
||||
|
||||
|
||||
## sub-target / sub-application / sub-package
|
||||
|
||||
A _sub-whatever_ is not a thing. There are only
|
||||
[bases] and [overlays].
|
||||
|
||||
## target
|
||||
|
||||
The _target_ is the argument to `kustomize build`, e.g.:
|
||||
|
||||
> ```
|
||||
> kustomize build $target
|
||||
> ```
|
||||
|
||||
`$target` must be a path to a directory that
|
||||
immediately contains a file called
|
||||
`kustomization.yaml` (i.e. a [kustomization]).
|
||||
|
||||
The target contains, or refers to, all the information
|
||||
needed to create customized resources to send to the
|
||||
[apply] operation.
|
||||
|
||||
A target is a [base] or an [overlay].
|
||||
|
||||
## variant
|
||||
|
||||
A _variant_ is the outcome, in a cluster, of applying
|
||||
an [overlay] to a [base].
|
||||
|
||||
> E.g., a _staging_ and _production_ overlay both modify some
|
||||
> common base to create distinct variants.
|
||||
>
|
||||
> The _staging_ variant is the set of resources
|
||||
> exposed to quality assurance testing, or to some
|
||||
> external users who'd like to see what the next
|
||||
> version of production will look like.
|
||||
>
|
||||
> The _production_ variant is the set of resources
|
||||
> exposed to production traffic, and thus may employ
|
||||
> deployments with a large number of replicas and higher
|
||||
> cpu and memory requests.
|
||||
115
docs/kustomization.yaml
Normal file
115
docs/kustomization.yaml
Normal file
@@ -0,0 +1,115 @@
|
||||
# Copyright 2018 The Kubernetes Authors.
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||
# you may not use this file except in compliance with the License.
|
||||
# You may obtain a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS,
|
||||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
||||
#
|
||||
# ----------------------------------------------------
|
||||
# Example kustomization.yaml content.
|
||||
#
|
||||
# This file declares the customization provided by
|
||||
# the kustomize program.
|
||||
#
|
||||
# Since customization is, by definition, _custom_,
|
||||
# there are no sensible default values for the fields
|
||||
# in this file.
|
||||
#
|
||||
# The field values used below are merely examples, not
|
||||
# to be copied literally. The values won't work if
|
||||
# they happen to be references to external files that
|
||||
# don't exist.
|
||||
#
|
||||
# In practice, fields with no value should simply be
|
||||
# omitted from kustomize.yaml to reduce the content
|
||||
# visible in configuration reviews.
|
||||
# ----------------------------------------------------
|
||||
|
||||
|
||||
# Value of this field is prepended to the
|
||||
# names of all resources, e.g. a deployment named
|
||||
# "wordpress" becomes "alices-wordpress".
|
||||
namePrefix: alices-
|
||||
|
||||
# Labels to add to all resources and selectors.
|
||||
commonLabels:
|
||||
someName: someValue
|
||||
owner: alice
|
||||
app: bingo
|
||||
|
||||
# Annotations (non-identifying metadata)
|
||||
# to add to all resources. Like labels,
|
||||
# these are key value pairs.
|
||||
commonAnnotations:
|
||||
oncallPager: 800-555-1212
|
||||
|
||||
# Each entry in this list must resolve to an existing
|
||||
# resource definition in YAML. These are the resource
|
||||
# files that kustomize reads, modifies and emits as a
|
||||
# YAML string, with resources separated by document
|
||||
# markers ("---").
|
||||
resources:
|
||||
- some-service.yaml
|
||||
- ../some-dir/some-deployment.yaml
|
||||
|
||||
# Each entry in this list results in the creation of
|
||||
# one ConfigMap resource (it's a generator of n maps).
|
||||
# The example below creates a ConfigMap with the
|
||||
# names and contents of the given files.
|
||||
configMapGenerator:
|
||||
- name: myJavaServerProps
|
||||
files:
|
||||
- application.properties
|
||||
- more.properties
|
||||
|
||||
# Each entry in this list results in the creation of
|
||||
# one Secret resource (it's a generator of n secrets).
|
||||
# A command can do anything to get a secret,
|
||||
# e.g. prompt the user directly, start a webserver to
|
||||
# initate an oauth dance, etc.
|
||||
secretGenerator:
|
||||
- name: app-tls
|
||||
commands:
|
||||
tls.crt: "cat secret/tls.cert"
|
||||
tls.key: "cat secret/tls.key"
|
||||
type: "kubernetes.io/tls"
|
||||
|
||||
# Each entry in this list should resolve to a directory
|
||||
# containing a kustomization file, else the
|
||||
# customization fails.
|
||||
#
|
||||
# The presence of this field means this file (the file
|
||||
# you a reading) is an _overlay_ that further
|
||||
# customizes information coming from these _bases_.
|
||||
#
|
||||
# Typical use case: a dev, staging and production
|
||||
# environment that are mostly identical but differing
|
||||
# crucial ways (image tags, a few server arguments,
|
||||
# etc. that differ from the common base).
|
||||
bases:
|
||||
- ../../base
|
||||
|
||||
# Each entry in this list should resolve to
|
||||
# a partial or complete resource definition file.
|
||||
#
|
||||
# The names in these (possibly partial) resource files
|
||||
# must match names already loaded via the `resources`
|
||||
# field or via `resources` loaded transitively via the
|
||||
# `bases` entries. These entries are used to _patch_
|
||||
# (modify) the known resources.
|
||||
#
|
||||
# Small patches that do one thing are best, e.g. modify
|
||||
# a memory request/limit, change an env var in a
|
||||
# ConfigMap, etc. Small patches are easy to review and
|
||||
# easy to mix together in overlays.
|
||||
patches:
|
||||
- service_port_8888.yaml
|
||||
- deployment_increase_replicas.yaml
|
||||
- deployment_increase_memory.yaml
|
||||
BIN
docs/overlay.jpg
Normal file
BIN
docs/overlay.jpg
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 44 KiB |
BIN
docs/workflowBespoke.jpg
Normal file
BIN
docs/workflowBespoke.jpg
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 36 KiB |
BIN
docs/workflowOts.jpg
Normal file
BIN
docs/workflowOts.jpg
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 43 KiB |
127
docs/workflows.md
Normal file
127
docs/workflows.md
Normal file
@@ -0,0 +1,127 @@
|
||||
[OTS]: glossary.md#off-the-shelf
|
||||
[apply]: glossary.md#apply
|
||||
[applying]: glossary.md#apply
|
||||
[base]: glossary.md#base
|
||||
[fork]: https://guides.github.com/activities/forking/
|
||||
[variants]: glossary.md#variant
|
||||
[kustomization]: glossary.md#kustomization
|
||||
[off-the-shelf]: glossary.md#off-the-shelf
|
||||
[overlays]: glossary.md#overlay
|
||||
[patch]: glossary.md#patch
|
||||
[patches]: glossary.md#patch
|
||||
[rebase]: https://git-scm.com/docs/git-rebase
|
||||
[resources]: glossary.md#resources
|
||||
[workflowBespoke]: workflowBespoke.jpg
|
||||
[workflowOts]: workflowOts.jpg
|
||||
|
||||
# workflows
|
||||
|
||||
A _workflow_ is the sequence of steps one takes to
|
||||
use and maintain a configuration.
|
||||
|
||||
## Bespoke configuration
|
||||
|
||||
In this workflow, all configuration files are owned by
|
||||
the user. No content is incorporated from version
|
||||
control repositories owned by others.
|
||||
|
||||
![bespoke config workflow image][workflowBespoke]
|
||||
|
||||
#### 1) create a directory in version control
|
||||
|
||||
> ```
|
||||
> git init ~/ldap
|
||||
> ```
|
||||
|
||||
#### 2) create a [base]
|
||||
|
||||
> ```
|
||||
> mkdir -p ~/ldap/base
|
||||
> ```
|
||||
|
||||
In this directory, create and commit a [kustomization]
|
||||
file and a set of [resources].
|
||||
|
||||
#### 3) create [overlays]
|
||||
|
||||
> ```
|
||||
> mkdir -p ~/ldap/overlays/staging
|
||||
> mkdir -p ~/ldap/overlays/production
|
||||
> ```
|
||||
|
||||
Each of these directories needs a [kustomization]
|
||||
file and one or more [patches].
|
||||
|
||||
The _staging_ directory might get a patch
|
||||
that turns on an experiment flag in a configmap.
|
||||
|
||||
The _production_ directory might get a patch
|
||||
that increases the replica count in a deployment
|
||||
specified in the base.
|
||||
|
||||
#### 4) bring up [variants]
|
||||
|
||||
Run kustomize, and pipe the output to [apply].
|
||||
|
||||
> ```
|
||||
> kustomize ~/ldap/overlays/staging | kubectl apply -f -
|
||||
> kustomize ~/ldap/overlays/production | kubectl apply -f -
|
||||
> ```
|
||||
|
||||
|
||||
## Off-the-shelf configuration
|
||||
|
||||
In this workflow, all files are owned by the user and
|
||||
maintained in a repository under their control, but
|
||||
they are based on an [off-the-shelf] configuration that
|
||||
is periodically consulted for updates.
|
||||
|
||||
|
||||
![off-the-shelf config workflow image][workflowOts]
|
||||
|
||||
#### 1) find and [fork] an [OTS] config
|
||||
|
||||
#### 2) clone it as your [base]
|
||||
|
||||
The [base] directory is maintained in a repo whose
|
||||
upstream is an [OTS] configuration, in this case
|
||||
https://github.com/kinflate/ldap.
|
||||
|
||||
> ```
|
||||
> mkdir ~/ldap
|
||||
> git clone https://github.com/$USER/ldap ~/ldap/base
|
||||
> cd ~/ldap/base
|
||||
> git remote add upstream git@github.com:kustomize/ldap
|
||||
> ```
|
||||
|
||||
#### 3) create [overlays]
|
||||
|
||||
As in the bespoke case above, create and populate
|
||||
an _overlays_ directory.
|
||||
|
||||
The [overlays] are siblings to each other and to the
|
||||
[base] they depend on.
|
||||
|
||||
> ```
|
||||
> mkdir -p ~/ldap/overlays/staging
|
||||
> mkdir -p ~/ldap/overlays/production
|
||||
> ```
|
||||
|
||||
|
||||
#### 4) bring up [variants]
|
||||
|
||||
> ```
|
||||
> kustomize ~/ldap/overlays/staging | kubectl apply -f -
|
||||
> kustomize ~/ldap/overlays/production | kubectl apply -f -
|
||||
> ```
|
||||
|
||||
#### 5) (optionally) capture changes from upstream
|
||||
|
||||
The user can optionally [rebase] their [base] to
|
||||
capture changes made in the upstream repository.
|
||||
|
||||
> ```
|
||||
> cd ~/ldap/base
|
||||
> git fetch upstream
|
||||
> git rebase upstream/master
|
||||
> ```
|
||||
34
kustomize.go
Normal file
34
kustomize.go
Normal file
@@ -0,0 +1,34 @@
|
||||
/*
|
||||
Copyright 2017 The Kubernetes Authors.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
package main
|
||||
|
||||
import (
|
||||
"os"
|
||||
|
||||
"github.com/golang/glog"
|
||||
|
||||
"k8s.io/kubectl/pkg/kustomize/commands"
|
||||
)
|
||||
|
||||
func main() {
|
||||
defer glog.Flush()
|
||||
|
||||
if err := commands.NewDefaultCommand().Execute(); err != nil {
|
||||
os.Exit(1)
|
||||
}
|
||||
os.Exit(0)
|
||||
}
|
||||
46
test/main.sh
Executable file
46
test/main.sh
Executable file
@@ -0,0 +1,46 @@
|
||||
#!/bin/bash
|
||||
|
||||
# Copyright 2018 The Kubernetes Authors.
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||
# you may not use this file except in compliance with the License.
|
||||
# You may obtain a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS,
|
||||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
||||
|
||||
function exit_with {
|
||||
local msg=$1
|
||||
echo >&2 ${msg}
|
||||
exit 1
|
||||
}
|
||||
|
||||
base_dir="$( cd "$(dirname "$0")/../../.." && pwd )"
|
||||
cd "$base_dir" || {
|
||||
echo "Cannot cd to '$base_dir'. Aborting." >&2
|
||||
exit 1
|
||||
}
|
||||
|
||||
# Install kustomize to $GOPATH/bin and export PATH
|
||||
go install ./cmd/kustomize || { exit_with "Failed to install kustomize"; }
|
||||
export PATH=$GOPATH/bin:$PATH
|
||||
|
||||
home=`pwd`
|
||||
example_dir="./cmd/kustomize/demos/data/ldap/base"
|
||||
if [ ! -d ${example_dir} ]; then
|
||||
exit_with "directory ${example_dir} doesn't exist"
|
||||
fi
|
||||
|
||||
if [ -x "${example_dir}/tests/test.sh" ]; then
|
||||
${example_dir}/tests/test.sh ${example_dir}
|
||||
if [ $? -eq 0 ]; then
|
||||
echo "testing ${example_dir} passed."
|
||||
else
|
||||
exit_with "testing ${example_dir} failed."
|
||||
fi
|
||||
fi
|
||||
67
version/version.go
Normal file
67
version/version.go
Normal file
@@ -0,0 +1,67 @@
|
||||
/*
|
||||
Copyright 2018 The Kubernetes Authors.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
package version
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"io"
|
||||
|
||||
"github.com/spf13/cobra"
|
||||
)
|
||||
|
||||
var (
|
||||
kustomizeVersion = "unknown"
|
||||
goos = "unknown"
|
||||
goarch = "unknown"
|
||||
gitCommit = "$Format:%H$" // sha1 from git, output of $(git rev-parse HEAD)
|
||||
|
||||
buildDate = "1970-01-01T00:00:00Z" // build date in ISO8601 format, output of $(date -u +'%Y-%m-%dT%H:%M:%SZ')
|
||||
)
|
||||
|
||||
type Version struct {
|
||||
KustomizeVersion string `json:"kustomizeVersion"`
|
||||
GitCommit string `json:"gitCommit"`
|
||||
BuildDate string `json:"buildDate"`
|
||||
GoOs string `json:"goOs"`
|
||||
GoArch string `json:"goArch"`
|
||||
}
|
||||
|
||||
func GetVersion() Version {
|
||||
return Version{
|
||||
kustomizeVersion,
|
||||
gitCommit,
|
||||
buildDate,
|
||||
goos,
|
||||
goarch,
|
||||
}
|
||||
}
|
||||
|
||||
func (v Version) Print(w io.Writer) {
|
||||
fmt.Fprintf(w, "Version: %+v\n", v)
|
||||
}
|
||||
|
||||
// NewCmdVersion makes version command.
|
||||
func NewCmdVersion(w io.Writer) *cobra.Command {
|
||||
return &cobra.Command{
|
||||
Use: "version",
|
||||
Short: "Prints the kustomize version",
|
||||
Example: `kustomize version`,
|
||||
Run: func(cmd *cobra.Command, args []string) {
|
||||
GetVersion().Print(w)
|
||||
},
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user