Merge pull request #379 from monopole/newdemo

A new hello-world demo.
This commit is contained in:
Jeff Regan 2018-03-27 14:15:51 -07:00 committed by GitHub
commit 8d3533e8d6
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
24 changed files with 253 additions and 569 deletions

View File

@ -7,6 +7,7 @@ go_import_path: k8s.io/kubectl
before_install:
- source ./bin/consider-early-travis-exit.sh
- sudo apt-get install tree
- go get -u github.com/golang/lint/golint
- go get -u golang.org/x/tools/cmd/goimports
- go get -u github.com/onsi/ginkgo/ginkgo

View File

@ -1,27 +1,28 @@
# Longer Demo
# Kinflate Demo
* Create a raw set of resources: deployment, service, configMap
Goal:
* Run them on a cluster
1. Clone a simple off-the-shelf example as a base configuration.
1. Customize it.
1. Create two different instances based on the customization.
* Create a manifest referring to them
First install the tool, and define a place to work locally:
* Simple customizations
* Instances
* Git flow
* Editor
<!-- @makeWorkDir @test -->
<!-- @install @test -->
```
TUT_DIR=$HOME/kinflate_demo
/bin/rm -rf $TUT_DIR
mkdir -p $TUT_DIR
TUT_TMP=$TUT_DIR/tmp
mkdir -p $TUT_TMP
go get k8s.io/kubectl/cmd/kinflate
```
<!-- @makeWorkplace @test -->
```
DEMO_HOME=$(mktemp -d)
```
__Next:__ [Make some resources](resources.md)
Alternatively, use
> ```
> DEMO_HOME=~/hello
> ```
__Next:__ [Clone an Example](clone)

View File

@ -1,8 +1,5 @@
resources
base
clone
manifest
identity
customization
instances
lifecycle
customize
overlays
editor

View File

@ -1,50 +0,0 @@
# The base app
These resources work as is. To optionally confirm this,
apply it to your cluster.
<!-- @runKinflate -->
```
kubectl apply -f $TUT_APP
```
<!-- @showResources -->
```
kubectl get deployments
```
Define some functions to query the server directly:
<!-- @funcGetAddress -->
```
function tut_getServiceAddress {
local name=$1
local tm='{{range .spec.ports -}}{{.nodePort}}{{end}}'
local nodePort=$(\
kubectl get -o go-template="$tm" service $name)
echo $($MINIKUBE_HOME/minikube ip):$nodePort
}
function tut_query {
local addr=$(tut_getServiceAddress $1)
curl --fail --silent --max-time 3 $addr/$2
}
```
Query it:
<!-- @query -->
```
tut_query tut-service peach
```
All done. Clear the cluster for the next example.
<!-- @query -->
```
kubectl delete deployment tut-deployment
kubectl delete service tut-service
kubectl delete configmap tut-map
```
__Next:__ [Describe the app with a Manifest](manifest.md)

View File

@ -0,0 +1,33 @@
# Clone
[hello]: https://github.com/monopole/hello
Assume you want to run the [hello] service.
[off-the-shelf config]: https://github.com/kinflate/example-hello
Find an [off-the-shelf config] for it, and clone that
config into a directory called `base`:
<!-- @cloneIt @test -->
```
git clone \
https://github.com/kinflate/example-hello \
$DEMO_HOME/base
```
<!-- @runTree @test -->
```
tree $DEMO_HOME
```
One could immediately apply these resources to a
cluster:
> ```
> kubectl apply -f $DEMO_HOME/base
> ```
to instantiate the _hello_ service in off-the-shelf form.
__Next:__ [The Base Manifest](manifest)

View File

@ -1,70 +0,0 @@
# First order customization
Kinflate offers simple customization directly in the manifest.
This is _first-order_ customization, a simple fork
of `Kube-manifest.yaml`.
## Names
The simplest form of customization is to change
resource names.
In DAM, this is done by adding a
prefix.
Add a _namePrefix_ specification to the manifest:
<!-- @addNamePrefix @test -->
```
cd $TUT_APP
kinflate set nameprefix acme-
```
Run it:
<!-- @runKinflate @test -->
```
kinflate inflate -f $TUT_APP >$TUT_TMP/customized_out
```
Compare to see result:
<!-- @checkDiffs @test -->
```
diff $TUT_TMP/original_out $TUT_TMP/customized_out || true
```
## Labels and annotations
Just add some new fields directly to the manifest:
<!-- @addLabelsAndAnnotations @test -->
```
cat <<'EOF' >>$TUT_APP_MANIFEST
objectLabels:
app: acmehello
org: acme-corporation
objectAnnotations:
note: Generated by a tutorial.
EOF
```
<!-- @runKinflateAgain @test -->
```
kinflate inflate -f $TUT_APP >$TUT_TMP/customized_out
```
<!-- @checkDiffsAgain -->
```
diff $TUT_TMP/original_out $TUT_TMP/customized_out | more
```
At this point, an end user could check the manifest and
its resources into her version control repository.
It becomes her own version of the _app_.
She can capture upgrades (i.e. manifest and resource
changes) by rebasing from the original.
__Next:__ [Instances](instances/README.md)

View File

@ -0,0 +1,18 @@
# Customize
A first customization step could be to change the _app label_
applied to all resources:
<!-- @manifest @test -->
```
sed -i 's/app: hello/app: my-hello/' \
$BASE/Kube-manifest.yaml
```
See the effect:
<!-- @manifest @test -->
```
kinflate inflate -f $BASE | grep -C 3 app:
```
__Next:__ [Overlays](overlays)

View File

@ -1,19 +1,17 @@
# Edit tool
> _kinflate is a text editor / linter!_
Kinflate's basic function is to read manifests and resources to create new YAML.
It also offers some basic manifest file operations.
It also offers some basic manifest file operations, to let one
change a manifest file safely without using a general editor.
Make a new workspace:
<!-- @workspace @test -->
```
TUT_EDITS=$TUT_TMP/edits
/bin/rm -rf $TUT_EDITS
mkdir -p $TUT_EDITS
pushd $TUT_EDITS
rm -rf $DEMO_HOME/edits
mkdir -p $DEMO_HOME/edits
pushd $DEMO_HOME/edits
```
Create a manifest:
@ -37,7 +35,7 @@ cat <<EOF >configMap.yaml
apiVersion: v1
kind: ConfigMap
metadata:
name: tut-map
name: the-map
data:
altGreeting: "Good Morning!"
enableRisky: "false"

View File

@ -1,36 +0,0 @@
# Identity transformation
Run it
<!-- @noCustomization @test -->
```
kinflate inflate -f $TUT_APP >$TUT_TMP/original_out
```
kinflate expects to find `Kube-manifest.yaml` in `$TUT_APP`.
The above command discovers the resources, processes them,
and emits the result to `stdout`.
<!-- @showOutput -->
```
more $TUT_TMP/original_out
```
As the app now stands, this command spits out
_unmodified resources_.
The output could be piped directly to kubectl:
> ```
> kinflate inflate -f $TUT_APP | kubectl apply -f -
> ```
The resulting change to the cluster would be no
different than using kubectl directly:
> ```
> kubectl apply -f $TUT_APP
> ```
__Next:__ [Customization](customization.md)

View File

@ -1,28 +0,0 @@
# Instances
_Instances_ of a cluster app represent a common configuration problem.
Their configuration is mostly the same.
We'd like to focus on managing _differences_.
The DAM approach is to create _overlays_.
An overlay is just a sub-directory with another manifest file,
and optionally more (or fewer) resources.
## Example
Create a _staging_ and _production_ instance.
* The greetings from the _hello world_ web servers will differ.
* _Staging_ enables a risky feature (for testing).
* _Production_ has a higher replica count.
<!-- @makePatchDirectories @test -->
```
mkdir -p $TUT_APP/staging
mkdir -p $TUT_APP/production
```
__Next:__ [Staging](staging.md)

View File

@ -1,66 +0,0 @@
# Compare them
Before running kinflate on the two different instance
directories, review the directory
structure:
<!-- @listFiles @test -->
```
find $TUT_APP
```
<!-- @compareKinflateOutput -->
```
diff \
<(kinflate inflate -f $TUT_APP/staging) \
<(kinflate inflate -f $TUT_APP/production) |\
more
```
Look at the output individually:
<!-- @runKinflateStaging @test -->
```
kinflate inflate -f $TUT_APP/staging
```
<!-- @runKinflateProduction @test -->
```
kinflate inflate -f $TUT_APP/production
```
Deploy them:
<!-- @deployStaging -->
```
kinflate inflate -f $TUT_APP/staging |\
kubectl apply -f -
```
<!-- @deployProduction -->
```
kinflate inflate -f $TUT_APP/production |\
kubectl apply -f -
```
<!-- @getAll -->
```
kubectl get all
```
Delete the resources:
<!-- @deleteStaging -->
```
kubectl delete configmap staging-acme-tut-map
kubectl delete service staging-acme-tut-service
kubectl delete deployment staging-acme-tut-deployment
```
<!-- @deleteProduction -->
```
kinflate inflate -f $TUT_APP/production |\
kubectl delete -f -
```
__Next:__ [Lifecycle](../lifecycle.md)

View File

@ -1,46 +0,0 @@
# Production Instance
Again, different name prefix and labels. This time patch the deployment to
increase the replica count.
<!-- @makeProductionManifest @test -->
```
cat <<'EOF' >$TUT_APP/production/Kube-manifest.yaml
apiVersion: manifest.k8s.io/v1alpha1
kind: Package
metadata:
name: makes-production-tuthello
description: Tuthello configured for production
namePrefix: production-
objectLabels:
instance: production
org: acmeCorporation
objectAnnotations:
note: Hello, I am production!
bases:
- ..
patches:
- deployment.yaml
EOF
```
<!-- @productionDeployment @test -->
```
cat <<EOF >$TUT_APP/production/deployment.yaml
apiVersion: apps/v1beta1
kind: Deployment
metadata:
name: tut-deployment
spec:
replicas: 6
EOF
```
__Next:__ [Compare](compare.md)

View File

@ -1,53 +0,0 @@
# Staging Instance
In the staging subdirectory, define a shorter manifest,
with a new name prefix, and some different labels.
<!-- @makeStagingManifest @test -->
```
cat <<'EOF' >$TUT_APP/staging/Kube-manifest.yaml
apiVersion: manifest.k8s.io/v1alpha1
kind: Package
metadata:
name: makes-staging-tuthello
description: Tuthello configured for staging
namePrefix: staging-
objectLabels:
instance: staging
org: acmeCorporation
objectAnnotations:
note: Hello, I am staging!
bases:
- ..
patches:
- map.yaml
EOF
```
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 >$TUT_APP/staging/map.yaml
apiVersion: v1
kind: ConfigMap
metadata:
name: tut-map
data:
altGreeting: "Have a pineapple!"
enableRisky: "true"
EOF
```
__Next:__ [Production](production.md)

View File

@ -1,15 +0,0 @@
# Lifecycle
<!-- @listFiles @test -->
```
find $TUT_APP
```
TODO: Show edits required to roll staging out to
production, find a bug and rollback. It's all git
operations and re-applications of _kinflate | kubectl_.
TODO: Demo fork/rebase flow of getting an upgrade,
e.g. new container images in the manifest.
__Next:__ [Editor](editor.md)

View File

@ -1,80 +1,19 @@
# Manifest
# Base Manifest
Add a manifest, to turn a directory of resources into a kinflate
application.
The `base` directory has a _manifest_:
A manifest is always called
> `Kube-manifest.yaml`
<!-- @defineManifest @test -->
<!-- @manifest @test -->
```
export TUT_APP_MANIFEST=$TUT_APP/Kube-manifest.yaml
BASE=$DEMO_HOME/base
more $BASE/Kube-manifest.yaml
```
<!-- @makeManifest @test -->
Run kinflate on the base to emit customized resources
to `stdout`:
<!-- @manifest @test -->
```
cat <<'EOF' >$TUT_APP_MANIFEST
apiVersion: manifest.k8s.io/v1alpha1
kind: Package
metadata:
name: tuthello
description: Tuthello offers greetings as a service.
keywords: [hospitality, kubernetes]
appVersion: 0.1.0
home: https://github.com/kinflate/tuthello
sources:
- https://github.com/kinflate/tuthello
icon: https://www.pexels.com/photo/some-icon.png
maintainers:
- name: Miles Mackentunnel
email: milesmackentunnel@gmail.com
github: milesmackentunnel
resources:
- deployment.yaml
- configMap.yaml
- service.yaml
EOF
kinflate inflate -f $BASE
```
### K8s API fields
[k8s API style]: https://kubernetes.io/docs/concepts/overview/working-with-objects/kubernetes-objects/#required-fields
The manifest follows [k8s API style], defining
* _apiVersion_ - which version of the k8s API is known to work
with this object
* _kind_ - the object type
* _metadata_ - data that helps uniquely identify the
object, e.g. a name.
### The Usual Suspects
The manifest has the fields one would expect:
_description_, _version_, _home page_, _maintainers_, etc.
### Resources field
This is a _manifest_, it must list the cargo.
## Save a copy
Before going any further, save a copy of the manifest:
<!-- @copyManifest @test -->
```
export TUT_ORG_MANIFEST=$TUT_TMP/original-manifest.yaml
cp $TUT_APP_MANIFEST $TUT_ORG_MANIFEST
```
__Next:__ [Identity transformation](identity.md)
__Next:__ [Customize it](customize)

View File

@ -0,0 +1,16 @@
# Overlays
Create a _staging_ and _production_ overlay:
* _Staging_ enables a risky feature not enabled in production.
* _Production_ has a higher replica count.
* Greetings from these instances will differ from each other.
<!-- @overlayDirectories @test -->
```
OVERLAYS=$DEMO_HOME/overlays
mkdir -p $OVERLAYS/staging
mkdir -p $OVERLAYS/production
```
__Next:__ [Staging](staging)

View File

@ -0,0 +1,26 @@
# Compare them
[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.
Review the directory structure:
<!-- @listFiles @test -->
```
tree $DEMO_HOME
```
<!-- @compareOutput -->
```
diff \
<(kinflate inflate -f $OVERLAYS/staging) \
<(kinflate inflate -f $OVERLAYS/production) |\
more
```
__Next:__ [Deploy](deploy)

View File

@ -0,0 +1,25 @@
# Deploy
The individual resource sets are:
<!-- @runKinflateStaging @test -->
```
kinflate inflate -f $OVERLAYS/staging
```
<!-- @runKinflateProduction @test -->
```
kinflate inflate -f $OVERLAYS/production
```
To deploy, pipe the above commands to kubectl apply:
> ```
> kinflate inflate -f $OVERLAYS/staging |\
> kubectl apply -f -
> ```
> ```
> kinflate inflate -f $OVERLAYS/production |\
> kubectl apply -f -
> ```

View File

@ -0,0 +1,27 @@
# Production Manifest
In the production directory, make a manifest
with a different name prefix and labels.
<!-- @makeProductionManifest @test -->
```
cat <<EOF >$OVERLAYS/production/Kube-manifest.yaml
apiVersion: manifest.k8s.io/v1alpha1
kind: Package
metadata:
name: makes-production-tuthello
description: hello configured for production
namePrefix: production-
objectLabels:
instance: production
org: acmeCorporation
objectAnnotations:
note: Hello, I am production!
bases:
- ../../base
patches:
- deployment.yaml
EOF
```
__Next:__ [Production Patch](patch)

View File

@ -0,0 +1,18 @@
# 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: 6
EOF
```
__Next:__ [Compare](../compare)

View File

@ -0,0 +1,26 @@
# Staging Manifest
In the `staging` directory, make a manifest
defining a new name prefix, and some different labels.
<!-- @makeStagingManifest @test -->
```
cat <<'EOF' >$OVERLAYS/staging/Kube-manifest.yaml
apiVersion: manifest.k8s.io/v1alpha1
kind: Package
metadata:
name: makes-staging-hello
description: hello configured for staging
namePrefix: staging-
objectLabels:
instance: staging
org: acmeCorporation
objectAnnotations:
note: Hello, I am staging!
bases:
- ../../base
patches:
- map.yaml
EOF
```
__Next:__ [Staging Patch](patch)

View File

@ -0,0 +1,21 @@
# 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
```
__Next:__ [Production Manifest](../production)

View File

@ -1,99 +0,0 @@
# Resources
Make three resource files. The resources have name
fields with these values:
* tut-deployment
* tut-map
* tut-service
_tut-_ just stands for _tutorial_.
<!-- @mkAppDir @test -->
```
TUT_APP=$TUT_DIR/tuthello
/bin/rm -rf $TUT_APP
mkdir -p $TUT_APP
```
<!-- @writeDeploymentYaml @test -->
```
cat <<EOF >$TUT_APP/deployment.yaml
apiVersion: apps/v1beta1
kind: Deployment
metadata:
name: tut-deployment
spec:
replicas: 3
template:
metadata:
labels:
deployment: tuthello
spec:
containers:
- name: tut-container
image: monopole/tuthello:1
command: ["/tuthello",
"--port=8080",
"--enableRiskyFeature=\$(ENABLE_RISKY)"]
ports:
- containerPort: 8080
env:
- name: ALT_GREETING
valueFrom:
configMapKeyRef:
name: tut-map
key: altGreeting
- name: ENABLE_RISKY
valueFrom:
configMapKeyRef:
name: tut-map
key: enableRisky
EOF
```
This deployment takes some parameters from a map:
<!-- @writeMapYaml @test -->
```
cat <<EOF >$TUT_APP/configMap.yaml
apiVersion: v1
kind: ConfigMap
metadata:
name: tut-map
data:
altGreeting: "Good Morning!"
enableRisky: "false"
EOF
```
A named label selector (a service) is used to
query the deployment.
<!-- @writeServiceYaml @test -->
```
cat <<EOF >$TUT_APP/service.yaml
kind: Service
apiVersion: v1
metadata:
name: tut-service
spec:
selector:
deployment: tuthello
type: LoadBalancer
ports:
- protocol: TCP
port: 8666
targetPort: 8080
EOF
```
Review the app definition so far:
<!-- @listFiles @test -->
```
find $TUT_APP
```
__Next:__ [Confirm base operation](base.md)