mirror of
https://github.com/kubernetes-sigs/kustomize.git
synced 2026-09-15 12:18:57 +00:00
Merge pull request #197 from Liujingfang1/master
Change configmapGenerator to configmap.yaml in helloWorld example
This commit is contained in:
@@ -23,10 +23,13 @@ go get github.com/kubernetes-sigs/kustomize
|
|||||||
* [springboot](springboot/README.md) - Create a Spring Boot
|
* [springboot](springboot/README.md) - Create a Spring Boot
|
||||||
application production configuration from scratch.
|
application production configuration from scratch.
|
||||||
|
|
||||||
* [configGeneration](configGeneration.md) -
|
* [combineConfigs](combineConfigs.md) -
|
||||||
Mixing configuration data from different owners
|
Mixing configuration data from different owners
|
||||||
(e.g. devops/SRE and developers).
|
(e.g. devops/SRE and developers).
|
||||||
|
|
||||||
|
* [configGenerations](configGeneration.md) -
|
||||||
|
Rolling update when ConfigMapGenerator changes
|
||||||
|
|
||||||
* [breakfast](breakfast.md) - Customize breakfast for
|
* [breakfast](breakfast.md) - Customize breakfast for
|
||||||
Alice and Bob.
|
Alice and Bob.
|
||||||
|
|
||||||
|
|||||||
298
examples/combineConfigs.md
Normal file
298
examples/combineConfigs.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/README.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 -
|
||||||
|
> ```
|
||||||
@@ -1,298 +1,208 @@
|
|||||||
[overlay]: ../docs/glossary.md#overlay
|
[patch]: ../../docs/glossary.md#patch
|
||||||
[target]: ../docs/glossary.md#target
|
[resource]: ../../docs/glossary.md#resource
|
||||||
|
[variant]: ../../docs/glossary.md#variant
|
||||||
|
|
||||||
# Demo: combining config data from devops and developers
|
## ConfigMap generation and rolling updates
|
||||||
|
|
||||||
Scenario: you have a Java-based server storefront in
|
Kustomize provides two ways of adding ConfigMap in one `kustomization`, either by declaring ConfigMap as a [resource] or declaring ConfigMap from a ConfigMapGenerator. The formats inside `kustomization.yaml` are
|
||||||
production that various internal development teams
|
|
||||||
(signups, checkout, search, etc.) contribute to.
|
|
||||||
|
|
||||||
The server runs in different environments:
|
> ```
|
||||||
_development_, _testing_, _staging_ and _production_,
|
> # declare ConfigMap as a resource
|
||||||
accepting configuration parameters from java property
|
> resources:
|
||||||
files.
|
> - configmap.yaml
|
||||||
|
>
|
||||||
|
> # declare ConfigMap from a ConfigMapGenerator
|
||||||
|
> configMapGenerator:
|
||||||
|
> - name: a-configmap
|
||||||
|
> files:
|
||||||
|
> - configs/configfile
|
||||||
|
> - configs/another_configfile
|
||||||
|
> ```
|
||||||
|
|
||||||
Using one big properties file for each environment is
|
The ConfigMaps declared as [resource] are treated the same way as other resources. Kustomize doesn't append any hash to the ConfigMap name. The ConfigMap declared from a ConfigMapGenerator is treated differently. A hash is appended to the name and any change in the ConfigMap will trigger a rolling update.
|
||||||
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
|
In this demo, the same [hello_world](helloWorld/README.md) is used while the ConfigMap declared as [resources] is replaced by a ConfigMap declared from a ConfigmapGenerator. The change in this ConfigMap will result in a hash change and a rolling update.
|
||||||
values that devops cares about and that developers
|
|
||||||
ignore and
|
|
||||||
1. because the production
|
|
||||||
properties contain sensitive data like production
|
|
||||||
database credentials.
|
|
||||||
|
|
||||||
## Property sharding
|
### Establish base and staging
|
||||||
|
|
||||||
With some study, we notice that the properties are
|
Establish the base with a configMapGenerator
|
||||||
separable into categories.
|
<!-- @establishBase @test -->
|
||||||
|
|
||||||
### 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/README.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)
|
DEMO_HOME=$(mktemp -d)
|
||||||
```
|
|
||||||
|
|
||||||
### Create the base
|
BASE=$DEMO_HOME/base
|
||||||
|
mkdir -p $BASE
|
||||||
|
|
||||||
<!-- kubectl create configmap BOB --dry-run -o yaml --from-file db. -->
|
curl -s -o "$BASE/#1.yaml" "https://raw.githubusercontent.com\
|
||||||
|
/kubernetes-sigs/kustomize\
|
||||||
|
/master/examples/helloWorld\
|
||||||
|
/{deployment,service}.yaml"
|
||||||
|
|
||||||
Make a place to put the base configuration:
|
cat <<'EOF' >$BASE/kustomization.yaml
|
||||||
|
commonLabels:
|
||||||
<!-- @baseDir @test -->
|
app: hello
|
||||||
```
|
resources:
|
||||||
mkdir -p $DEMO_HOME/base
|
- deployment.yaml
|
||||||
```
|
- service.yaml
|
||||||
|
|
||||||
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:
|
configMapGenerator:
|
||||||
- name: my-configmap
|
- name: the-map
|
||||||
files:
|
literals:
|
||||||
- common.properties
|
- altGreeting=Good Morning!
|
||||||
|
- enableRisky="false"
|
||||||
EOF
|
EOF
|
||||||
```
|
```
|
||||||
|
|
||||||
|
Establish the staging with a patch applied to the ConfigMap
|
||||||
### Create and use the overlay for _development_
|
<!-- @establishStaging @test -->
|
||||||
|
|
||||||
Make an abbreviation for the parent of the overlay
|
|
||||||
directories:
|
|
||||||
|
|
||||||
<!-- @overlays @test -->
|
|
||||||
```
|
```
|
||||||
OVERLAYS=$DEMO_HOME/overlays
|
OVERLAYS=$DEMO_HOME/overlays
|
||||||
```
|
mkdir -p $OVERLAYS/staging
|
||||||
|
|
||||||
Create the files that define the _development_ overlay:
|
cat <<'EOF' >$OVERLAYS/staging/kustomization.yaml
|
||||||
|
namePrefix: staging-
|
||||||
<!-- @developmentFiles @test -->
|
commonLabels:
|
||||||
```
|
variant: staging
|
||||||
mkdir -p $OVERLAYS/development
|
org: acmeCorporation
|
||||||
|
commonAnnotations:
|
||||||
cat <<EOF >$OVERLAYS/development/plumbing.properties
|
note: Hello, I am staging!
|
||||||
port=30000
|
|
||||||
EOF
|
|
||||||
|
|
||||||
cat <<EOF >$OVERLAYS/development/secret.properties
|
|
||||||
dbpassword=mothersMaidenName
|
|
||||||
EOF
|
|
||||||
|
|
||||||
cat <<EOF >$OVERLAYS/development/kustomization.yaml
|
|
||||||
bases:
|
bases:
|
||||||
- ../../base
|
- ../../base
|
||||||
namePrefix: dev-
|
patches:
|
||||||
configMapGenerator:
|
- map.yaml
|
||||||
- name: my-configmap
|
EOF
|
||||||
behavior: merge
|
|
||||||
files:
|
cat <<EOF >$OVERLAYS/staging/map.yaml
|
||||||
- plumbing.properties
|
apiVersion: v1
|
||||||
- secret.properties
|
kind: ConfigMap
|
||||||
|
metadata:
|
||||||
|
name: the-map
|
||||||
|
data:
|
||||||
|
altGreeting: "Have a pineapple!"
|
||||||
|
enableRisky: "true"
|
||||||
EOF
|
EOF
|
||||||
```
|
```
|
||||||
|
|
||||||
One can now generate the configMaps for development:
|
### Review
|
||||||
|
|
||||||
<!-- @runDev @test -->
|
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 -->
|
||||||
```
|
```
|
||||||
kustomize build $OVERLAYS/development
|
grep -C 2 configMapKeyRef $BASE/deployment.yaml
|
||||||
```
|
```
|
||||||
|
|
||||||
#### Check the ConfigMap name
|
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 name of the generated `ConfigMap` is visible in this
|
The recommended way to change a deployment's
|
||||||
output.
|
configuration is to
|
||||||
|
|
||||||
The name should be something like `dev-my-configmap-b5m75ck895`:
|
1. create a new configMap with a new name,
|
||||||
|
1. patch the _deployment_, modifying the name value of
|
||||||
|
the appropriate `configMapKeyRef` field.
|
||||||
|
|
||||||
* `"dev-"` comes from the `namePrefix` field,
|
This latter change initiates rolling update to the pods
|
||||||
* `"my-configmap"` comes from the `configMapGenerator/name` field,
|
in the deployment. The older configMap, when no longer
|
||||||
* `"-b5m75ck895"` comes from a deterministic hash that `kustomize`
|
referenced by any other resource, is eventually garbage
|
||||||
computes from the contents of the configMap.
|
collected.
|
||||||
|
|
||||||
The hash suffix is critical. If the configMap content
|
### How this works with kustomize
|
||||||
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
|
The _staging_ [variant] here has a configMap [patch]:
|
||||||
restart to get new data if this YAML is applied to the
|
|
||||||
cluster using a command like
|
|
||||||
|
|
||||||
> ```
|
<!-- @showMapPatch @test -->
|
||||||
> 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 $OVERLAYS/staging/map.yaml
|
||||||
|
|
||||||
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:
|
This patch is by definition a named but not necessarily
|
||||||
|
complete resource spec intended to modify a complete
|
||||||
|
resource spec.
|
||||||
|
|
||||||
<!-- @runProd @test -->
|
The ConfigMap it modifies is declared from a configMapGenerator.
|
||||||
|
|
||||||
|
<!-- @showMapBase @test -->
|
||||||
```
|
```
|
||||||
kustomize build $OVERLAYS/production
|
grep -C 4 configMapGenerator $BASE/kustomization.yaml
|
||||||
```
|
```
|
||||||
|
|
||||||
A CICD process could apply this directly to
|
For a patch to work, the names in the `metadata/name`
|
||||||
the cluser using:
|
fields must match.
|
||||||
|
|
||||||
> ```
|
However, the name values specified in the file are
|
||||||
> kustomize build $OVERLAYS/production | kubectl apply -f -
|
_not_ what gets used in the cluster. By design,
|
||||||
> ```
|
kustomize modifies names of ConfigMaps declared from ConfigMapGenerator. 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
|
||||||
|
```
|
||||||
|
|
||||||
|
See the new greeting:
|
||||||
|
|
||||||
|
```
|
||||||
|
kustomize build $OVERLAYS/staging |\
|
||||||
|
grep -B 2 -A 3 kiwi
|
||||||
|
```
|
||||||
|
|
||||||
|
Run kustomize again to see the new configMap 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); \
|
||||||
|
echo $?
|
||||||
|
```
|
||||||
|
|
||||||
|
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.
|
||||||
|
|||||||
@@ -315,130 +315,3 @@ To deploy, pipe the above commands to kubectl apply:
|
|||||||
> kustomize build $OVERLAYS/production |\
|
> kustomize build $OVERLAYS/production |\
|
||||||
> kubectl apply -f -
|
> 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
|
|
||||||
|
|
||||||
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
|
|
||||||
```
|
|
||||||
|
|
||||||
See the new greeting:
|
|
||||||
|
|
||||||
```
|
|
||||||
kustomize build $OVERLAYS/staging |\
|
|
||||||
grep -B 2 -A 3 kiwi
|
|
||||||
```
|
|
||||||
|
|
||||||
Run kustomize again to see the new configMap 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); \
|
|
||||||
echo $?
|
|
||||||
```
|
|
||||||
|
|
||||||
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.
|
|
||||||
|
|||||||
@@ -6,9 +6,4 @@ commonLabels:
|
|||||||
resources:
|
resources:
|
||||||
- deployment.yaml
|
- deployment.yaml
|
||||||
- service.yaml
|
- service.yaml
|
||||||
|
- configMap.yaml
|
||||||
configMapGenerator:
|
|
||||||
- name: the-map
|
|
||||||
literals:
|
|
||||||
- altGreeting="Good Morning!"
|
|
||||||
- enableRisky="false"
|
|
||||||
|
|||||||
Reference in New Issue
Block a user