From ec745a86f48330d1dbf23d1713bf56eddd1a045c Mon Sep 17 00:00:00 2001 From: Sunil Arora Date: Tue, 13 Feb 2018 14:37:18 -0800 Subject: [PATCH] kinflate: improved README and added getting-started --- cmd/kinflate/README.md | 91 ++++++++---- cmd/kinflate/getting_started.md | 243 ++++++++++++++++++++++++++++++++ 2 files changed, 308 insertions(+), 26 deletions(-) create mode 100644 cmd/kinflate/getting_started.md diff --git a/cmd/kinflate/README.md b/cmd/kinflate/README.md index 7f26e1d7f..518b91913 100644 --- a/cmd/kinflate/README.md +++ b/cmd/kinflate/README.md @@ -1,38 +1,77 @@ -# kinflate +# Overview -`kinflate` is a kubernetes cluster configuration -utility. - -It reads a cluster app definition from a -directory of YAML files, and creates new YAML suitable -for directly piping to `kubectl apply`. - - -## Declarative Application Management - -kinflate is a a prototype of ideas discussed in the -[Declarative Application -Management (DAM) proposal](https://goo.gl/T66ZcD). - -DAM encourages one to use literal kubernetes resource -declarations to configure a cluster. DAM understands -new declarations to modify resources, rather than -achieving modification via templates or configuration -languages. - -DAM facilitates coupling cluster state changes to version -control commits. It encourages forking a configuration, -customizing it, and occasionally rebasing to capture -upgrades from the original configuration. +`kinflate` is a command line interface to manage Kubernetes Application configuration. ## Installation +`kinflate` is written in Go and can be installed using `go get`: + +```shell +go get -u k8s.io/kubectl/cmd/kinflate ``` -go get k8s.io/kubectl/cmd/kinflate + +After running the above command, `kinflate` should get installed in your `GOPATH/bin` directory. + +## 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 + +# 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 + +# generate application configuration and apply it to a Kubernetes cluster +kinflate inflate -f | kubectl apply -f - +``` + + ## Demos and tutorial + * [Getting Started](getting_started.md) * [Short demo](shortDemo.md) * [Longer demo / tutorial](longerDemo/README.md) diff --git a/cmd/kinflate/getting_started.md b/cmd/kinflate/getting_started.md new file mode 100644 index 000000000..e32a0bf64 --- /dev/null +++ b/cmd/kinflate/getting_started.md @@ -0,0 +1,243 @@ +# Kinflate: Getting Started + +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 to use persistent disk for storing data. + +## Installation + +If you have `kinflate` installed already, then you can skip this step. `kinflate` can be installed using `go get`: + + +```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: + + +```shell +MYSQL_DIR=$HOME/kinflate_demo/mysql +rm -rf $MYSQL_DIR && mkdir -p $MYSQL_DIR +cd $MYSQL_DIR + +# Get MySQL configs +for f in service secret deployment ; do \ + 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: + + +```shell +mkdir -p $MYSQL_DIR/prod +cd $MYSQL_DIR/prod + +#initialize the customization +kinflate init + +cat Kube-manifest.yaml +``` + +`Kube-manifest.yaml` should contain: + +``` +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 + +``` + +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. + +### Add resources + +Lets add resource files that we want to `kinflate` to act on. Steps below add the three resources for MySQL. + + +```shell + +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 +``` + +`Kube-manifest.yaml`'s resources section should contain: + +``` +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: + + +```shell + +cd $MYSQL_DIR/prod + +kinflate set nameprefix 'prod-' + +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 +..... + + +``` + +Lets break this down: +- `kinflate set nameprex ` 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. + + +```shell +cd $MYSQL_DIR/prod + +# lets generate name-prefixed resources +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: + .... + .... + +``` + + +### 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. + +``` +cd $MYSQL_DIR/prod + +edit Kube-manifest.yaml + +# Edit the objectLabels +.... +objectLabels: + app: 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. + + +```shell +cd $MYSQL_DIR/prod + +# 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 +metadata: + name: mysql +spec: + template: + spec: + volumes: + - name: mysql-persistent-storage + emptyDir: null + gcePersistentDisk: + 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 +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.