newshortdemo

This commit is contained in:
Jeffrey Regan 2018-03-27 15:13:56 -07:00
parent 8d3533e8d6
commit fb5ca9df94
13 changed files with 233 additions and 256 deletions

View File

@ -1,77 +1,44 @@
# Overview
# kinflate
[_kubectl apply_]: https://goo.gl/UbCRuf
[Declarative Application Management]: https://goo.gl/T66ZcD
`kinflate` is a command line tool supporting
template-free customization of declarative
configuration targetted to kubernetes.
It's an implementation of ideas described in Brian
Grant's [Declarative Application Management] proposal.
## Design tenets
* __composable__: do one thing, use plain text, work
with pipes, usable in other tools (e.g. helm,
kubernetes-deploy, etc.).
* __simple__: no templating, no logic, no inheritance,
no new API obscuring the k8s API.
* __accountable__: gitops friendly, diff against
declaration in version control, diff against
cluster.
* __k8s style__: recognizable k8s resources,
extensible (openAPI, CRDs),
patching, intended for [_kubectl apply_].
`kinflate` is a command line interface to manage Kubernetes Application configuration.
## Installation
`kinflate` is written in Go and can be installed using `go get`:
<!-- @installKinflate @test -->
```shell
```
go get k8s.io/kubectl/cmd/kinflate
```
After running the above command, `kinflate` should get installed in your `GOPATH/bin` directory.
## Demos
## Usage
This section explains sub-commands of `kinflate` using examples.
### init
`kinflate init` initializes a directory by creating an application manifest file named `Kube-manifest.yaml`. This command should be run in the same directory where application config resides.
```shell
kinflate init
```
### set nameprefix
`kinflate set nameprefix` updates the nameprefix field in the [manifest].
`kinflate inflate` uses the prefix to generate prefixed names for Kubernetes resources.
Examples
```shell
# set nameprefix to 'staging'
kinflate set nameprefix staging
# set nameprefix to 'john`
kinflate set nameprefix john
```
### add
`kinflate add` adds a resource, configmap or secret to the [manifest].
#### examples
```shell
# adds a resource to the manifest
kinflate add resource <path/to/resource-file-or-dir>
# adds a configmap from a literal or file-source to the manifest
kinflate add configmap my-configmap --from-file=my-key=file/path --from-literal=my-literal=12345
# Adds a generic secret to the Manifest (with a specified key)
kinflate add secret generic my-secret --from-file=my-key=file/path --from-literal=my-literal=12345
# Adds a TLS secret to the Manifest (with a specified key)
kinflate add secret tls my-tls-secret --cert=cert/path.cert --key=key/path.key
```
### inflate
`kinflate inflate` generates application configuration by applying
transformations (e.g. name-prefix, label, annotations) specified in the [manifest].
#### examples
```shell
# generate application configuration and output to stdout
kinflate inflate -f <path/to/application/dir>
# generate application configuration and apply it to a Kubernetes cluster
kinflate inflate -f <path/to/application/dir> | kubectl apply -f -
```
## Demos and tutorial
* [Getting Started](getting_started.md)
* [Short demo](shortDemo.md)
* [Longer demo / tutorial](longerDemo/README.md)
* [hello world one-pager](shortDemo.md)
* [hello world detailed, with instances](longerDemo/README.md)
* [mysql](getting_started.md)

View File

@ -1,122 +1,118 @@
# Kinflate: Getting Started
# MySql Example
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:
In this `getting started` guide, we will take an off-the-shelf MySQL configuration for Kubernetes and customize it to suit our production scenario.
In production environment, we want:
- MySQL resource names to be prefixed by 'prod-' to make them distinguishable.
- MySQL resources to have 'env: prod' labels so that we can use label selector to query these.
- MySQL resources to have 'env: prod' labels so that we can use label selector to query these.
- MySQL to use persistent disk for storing data.
## Installation
### Download resources
If you have `kinflate` installed already, then you can skip this step. `kinflate` can be installed using `go get`:
<!-- @installKinflate @test -->
```shell
go get k8s.io/kubectl/cmd/kinflate
```
This fetches kinflate and install `kinflate` executable under `GOPATH/bin` - you will want that on your $PATH.
### Get off-the-shelf MySQL configs for Kubernetes
Download a sample MySQL YAML manifest files:
Download `deployment.yaml`, `service.yaml` and
`secret.yaml`. These are plain k8s resources files one
could add to a k8s cluster to run MySql.
<!-- @makeMySQLDir @test -->
```shell
MYSQL_DIR=$HOME/kinflate_demo/mysql
rm -rf $MYSQL_DIR && mkdir -p $MYSQL_DIR
cd $MYSQL_DIR
```
DEMO_HOME=$HOME/kinflate_demo/mysql
rm -rf $DEMO_HOME && mkdir -p $DEMO_HOME
cd $DEMO_HOME
# Get MySQL configs
for f in service secret deployment ; do \
wget https://raw.githubusercontent.com/kinflate/mysql/master/emptyDir/$f.yaml ; \
wget https://raw.githubusercontent.com/kinflate/mysql/master/emptyDir/$f.yaml ; \
done
```
This downloads YAML files `deployment.yaml`, `service.yaml` and `secret.yaml` which are needed to run MySQL in a Kubernetes cluster.
### Initialization
Now that we have base configuration for MySQL in place, we can begin with customization for production environment. Follow the step below:
### Initialize a manifest
A manifest is needed to group these resources together.
Create one:
<!-- @initApp @test -->
```shell
mkdir -p $MYSQL_DIR/prod
cd $MYSQL_DIR/prod
#initialize the customization
```
mkdir -p $DEMO_HOME/prod
cd $DEMO_HOME/prod
kinflate init
cat Kube-manifest.yaml
```
`Kube-manifest.yaml` should contain:
You should now have a file called `Kube-manifest.yaml`:
<!-- @catMan @test -->
```
apiVersion: manifest.k8s.io/v1alpha1
kind: Manifest
metadata:
name: helloworld
description: helloworld does useful stuff.
namePrefix: some-prefix
# Labels to add to all objects and selectors.
# These labels would also be used to form the selector for apply --prune
# Named differently than “labels” to avoid confusion with metadata for this object
objectLabels:
app: helloworld
objectAnnotations:
note: This is a example annotation
resources:
- deployment.yaml
- service.yaml
# There could also be configmaps in Base, which would make these overlays
configmaps: []
# There could be secrets in Base, if just using a fork/rebase workflow
secrets: []
recursive: true
cat $DEMO_HOME/prod/Kube-manifest.yaml
```
Lets break this down:
- First step create a directory called `prod` and switches to that dir. We will keep all the resources related to production customization in this directory.
- `kinflate init` generates a kinflate manifest file called `Kube-manifest.yaml` that contains metadata about the customizations. You can think of this file as containing instructions which inflate will use to apply to generate the required configuration.
containing something like:
> ```
> apiVersion: manifest.k8s.io/v1alpha1
> kind: Manifest
> metadata:
> name: helloworld
> description: helloworld does useful stuff.
> namePrefix: some-prefix
> # Labels to add to all objects and selectors.
> # These labels would also be used to form the selector for apply --prune
> # Named differently than “labels” to avoid confusion with metadata for this object
> objectLabels:
> app: helloworld
> objectAnnotations:
> note: This is a example annotation
> resources:
> - deployment.yaml
> - service.yaml
> # There could also be configmaps in Base, which would make these overlays
> configmaps: []
> # There could be secrets in Base, if just using a fork/rebase workflow
> secrets: []
> recursive: true
> ```
### Add resources
Lets add resource files that we want to `kinflate` to act on. Steps below add the three resources for MySQL.
Add the resources to the manifest
<!-- @addResources @test -->
```shell
```
cd $DEMO_HOME/prod
cd $MYSQL_DIR/prod
# add the MySQL resources
kinflate add resource ../secret.yaml
kinflate add resource ../service.yaml
kinflate add resource ../deployment.yaml
cat Kube-manifest.yaml
cat Kube-manifest.yaml
```
`Kube-manifest.yaml`'s resources section should contain:
```
apiVersion: manifest.k8s.io/v1alpha1
....
....
resources:
- ../secret.yaml
- ../service.yaml
- ../deployment.yaml
```
> ```
> apiVersion: manifest.k8s.io/v1alpha1
> ....
> resources:
> - ../secret.yaml
> - ../service.yaml
> - ../deployment.yaml
> ```
Now we are ready to apply our first customization.
### NamePrefix Customization
We want MySQL resources to begin with prefix 'prod' in production environment. Follow the steps below:
Arrange for the MySQL resources to begin with prefix
_prod-_ (since they are meant for the _production_
environment):
<!-- @customizeLabel @test -->
```shell
cd $MYSQL_DIR/prod
```
cd $DEMO_HOME/prod
kinflate set nameprefix 'prod-'
@ -125,95 +121,87 @@ cat Kube-manifest.yaml
`Kube-manifest.yaml` should have updated value of namePrefix field:
```
apiVersion: manifest.k8s.io/v1alpha1
.....
.....
namePrefix: prod-
objectAnnotations:
note: This is a example annotation
.....
> ```
> apiVersion: manifest.k8s.io/v1alpha1
> ....
> namePrefix: prod-
> objectAnnotations:
> note: This is a example annotation
This `namePrefix` directive adds _prod-_ to all
resource names.
```
Lets break this down:
- `kinflate set nameprex <prefix>` updates the `namePrefix` directive to `prod` in the manifest file.
- Now if you view the `Kube-manifest.yaml`, you will see `namePrefix` directive updated. Editing the `namePrefix` directive in the file will also achieve the same thing.
At this point you can run `kinflate inflate` to generate name-prefixed configuration as shown below.
Run kinflate:
<!-- @genNamePrefixConfig @test -->
```shell
cd $MYSQL_DIR/prod
# lets generate name-prefixed resources
```
cd $DEMO_HOME/prod
kinflate inflate -f .
```
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:
....
....
```
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. `kinflate` does not have `set label` command to add label, but we can edit `Kube-manifest.yaml` file under `prod` directory and add the production labels under `objectLabels` fields as highlighted below.
We want resources in production environment to have
certain labels so that we can query them by label
selector.
`kinflate` does not have `set label` command to add
label, but we can edit `Kube-manifest.yaml` file under
`prod` directory and add the production labels under
`objectLabels` fields as highlighted below.
<!-- @customizeLabels @test -->
```
cd $MYSQL_DIR/prod
edit Kube-manifest.yaml
# Edit the objectLabels
....
objectLabels:
app: prod
....
cd $DEMO_HOME/prod
sed -i 's/app: helloworld/app: prod/' Kube-manifest.yaml
```
At this point, running `kinflate inflate -f .` will generate MySQL configs with name-prefix 'prod-' and labels `env:prod`.
At this point, running `kinflate inflate -f .` 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. Kinflate lets you apply `patches` to the resources.
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. Kinflate lets you apply `patches` to the
resources.
<!-- @customizeOverlay @test -->
```shell
cd $MYSQL_DIR/prod
```
cd $DEMO_HOME/prod
# create a patch for persistent-disk.yaml
# Create a patch for persistent-disk.yaml
cat <<'EOF' > persistent-disk.yaml
apiVersion: apps/v1beta2 # for versions before 1.9.0 use apps/v1beta2
kind: Deployment
@ -229,15 +217,30 @@ spec:
pdName: mysql-persistent-storage
EOF
# edit the manifest file to add the above patch or run following command
cat <<'EOF' >> $MYSQL_DIR/prod/Kube-manifest.yaml
# Edit the manifest file to add the above patch:
cat <<'EOF' >> $DEMO_HOME/prod/Kube-manifest.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 `Kube-manifest.yaml`. `kinflate inflate` will apply this patch to the deployment resource with the name `mysql` as defined in the patch.
At this point, if you run `kinflate inflate -f .`, it will generate the Kubernetes config for production environement.
- 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 `Kube-manifest.yaml`. `kinflate inflate`
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 -->
```
kinflate inflate -f $DEMO_HOME/prod # | kubectl apply -f -
```

View File

@ -1,4 +1,4 @@
# Kinflate Demo
# Demo: hello world with instances
Goal:
@ -25,4 +25,4 @@ Alternatively, use
__Next:__ [Clone an Example](clone)
__Next:__ [Clone an Example](clone.md)

View File

@ -30,4 +30,4 @@ cluster:
to instantiate the _hello_ service in off-the-shelf form.
__Next:__ [The Base Manifest](manifest)
__Next:__ [The Base Manifest](manifest.md)

View File

@ -16,4 +16,4 @@ to `stdout`:
kinflate inflate -f $BASE
```
__Next:__ [Customize it](customize)
__Next:__ [Customize it](customize.md)

View File

@ -13,4 +13,4 @@ mkdir -p $OVERLAYS/staging
mkdir -p $OVERLAYS/production
```
__Next:__ [Staging](staging)
__Next:__ [Staging](staging/manifest.md)

View File

@ -1,14 +1,16 @@
# Compare them
# Compare overlays
[original]: https://github.com/kinflate/example-hello
`DEMO_HOME` now contains a _base_ directory - your
slightly customized clone of the [original]
configuration, and an _overlays_ directory, that
contains all one needs to create a _staging_ and
_production_ instance in a cluster.
`DEMO_HOME` now contains:
Review the directory structure:
- a _base_ directory - your slightly customized clone of the [original]
configuration, and
- an _overlays_ directory, containing the manifests and patches required to
create distinct _staging_ and _production_ instance in a cluster.
Review the directory structure and differences:
<!-- @listFiles @test -->
```
@ -23,4 +25,4 @@ diff \
more
```
__Next:__ [Deploy](deploy)
__Next:__ [Deploy](deploy.md)

View File

@ -23,3 +23,5 @@ To deploy, pipe the above commands to kubectl apply:
> kinflate inflate -f $OVERLAYS/production |\
> kubectl apply -f -
> ```
__Next:__ [Editting](../editor.md)

View File

@ -24,4 +24,4 @@ patches:
EOF
```
__Next:__ [Production Patch](patch)
__Next:__ [Production Patch](patch.md)

View File

@ -15,4 +15,4 @@ spec:
EOF
```
__Next:__ [Compare](../compare)
__Next:__ [Compare](../compare.md)

View File

@ -23,4 +23,4 @@ patches:
- map.yaml
EOF
```
__Next:__ [Staging Patch](patch)
__Next:__ [Staging Patch](patch.md)

View File

@ -18,4 +18,4 @@ data:
EOF
```
__Next:__ [Production Manifest](../production)
__Next:__ [Production Manifest](../production/manifest.md)

View File

@ -1,4 +1,4 @@
# Short Demo
# Demo: hello world
Prerequisites: [Go](https://golang.org/), [git](https://git-scm.com),
a `PATH` containing `$GOPATH/bin`, [kubectl] set up
@ -6,28 +6,31 @@ to talk to a cluster.
[kubectl]: https://kubernetes.io/docs/user-guide/kubectl-overview/
The following clones an app, customizes the resources in
the app with a name prefix, then pipes the resulting
YAML directly to a cluster via [kubectl].
Steps:
<!-- @makeWorkDir @test -->
1. Clone an off-the-shelf example configuration.
1. Customizes the resources in it with a name prefix.
1. Apply the result to a cluster via [kubectl].
First make a place to work:
<!-- @makeDemoDir @test -->
```
TUT_DIR=$HOME/kinflate_demo
/bin/rm -rf $TUT_DIR
mkdir -p $TUT_DIR
DEMO_HOME=$(mktemp -d)
```
Download the app:
[example-hello]: https://github.com/kinflate/example-hello
Clone an example configuration ([example-hello]):
<!-- @downloadTutorialHelloApp @test -->
<!-- @cloneExample @test -->
```
cd $TUT_DIR
git clone https://github.com/kinflate/tuthello
cd tuthello
cd $DEMO_HOME
git clone https://github.com/kinflate/example-hello
cd example-hello
```
Customize the base application by specifying a prefix that will be applied to
all resource names:
Customize the base application by specifying a prefix
that will be applied to all resource names:
<!-- @customizeApp @test -->
```
@ -48,16 +51,16 @@ Confirm that the prefix appears in the output:
kinflate inflate -f . | grep --context=3 acme-
```
Optionally apply to a cluster:
Optionally apply the modified configuration to a cluster:
<!-- @applyToCluster -->
```
kinflate inflate -f . | kubectl apply -f -
```
This fork of the app repository could be committed to a private repo. Rebase as
desired.
This fork of [example-hello] could be commited to a
private repo, and evolve independently of its upstream.
## Longer demo / tutorial
One could rebase from upstream as desired.
See [longerDemo](longerDemo/README.md).
__Next:__ [hello world (with instances)](longerDemo/README.md).