From 86b76fffba2bb41570acb783a0e6141373de0220 Mon Sep 17 00:00:00 2001
From: Bill Prin <waprin@google.com>
Date: Mon, 12 Dec 2016 22:36:19 -0800
Subject: [PATCH] Minikube Quickstart

---
 _data/tutorials.yml                           |   1 +
 .../stateless-application/Dockerfile          |   4 +
 .../stateless-application/hello-minikube.md   | 305 ++++++++++++++++++
 .../tutorials/stateless-application/server.js |   7 +
 4 files changed, 317 insertions(+)
 create mode 100644 docs/tutorials/stateless-application/Dockerfile
 create mode 100644 docs/tutorials/stateless-application/hello-minikube.md
 create mode 100644 docs/tutorials/stateless-application/server.js

diff --git a/_data/tutorials.yml b/_data/tutorials.yml
index a4ff243bfb..08e8b0b46a 100644
--- a/_data/tutorials.yml
+++ b/_data/tutorials.yml
@@ -31,6 +31,7 @@ toc:
     - docs/tutorials/kubernetes-basics/update-interactive.html
 - title: Stateless Applications
   section:
+  - docs/tutorials/stateless-application/hello-minikube.md
   - docs/tutorials/stateless-application/run-stateless-application-deployment.md
   - docs/tutorials/stateless-application/expose-external-ip-address-service.md
   - docs/tutorials/stateless-application/expose-external-ip-address.md
diff --git a/docs/tutorials/stateless-application/Dockerfile b/docs/tutorials/stateless-application/Dockerfile
new file mode 100644
index 0000000000..34b1f40f52
--- /dev/null
+++ b/docs/tutorials/stateless-application/Dockerfile
@@ -0,0 +1,4 @@
+FROM node:6.9.2
+EXPOSE 8080
+COPY server.js .
+CMD node server.js
diff --git a/docs/tutorials/stateless-application/hello-minikube.md b/docs/tutorials/stateless-application/hello-minikube.md
new file mode 100644
index 0000000000..dad7158ac3
--- /dev/null
+++ b/docs/tutorials/stateless-application/hello-minikube.md
@@ -0,0 +1,305 @@
+{% capture overview %}
+
+The goal of this tutorial is for you to turn a simple Hello World Node.js app
+into an application running on Kubernetes. The tutorial shows you how to
+take code that you have developed on your machine, turn it into a Docker
+container image and then run that image on [Minikube](/docs/getting-started-guides/minikube).
+Minikube provides a simple way of running Kubernetes on your local machine for free.
+
+{% endcapture %}
+
+{% capture objectives %}
+
+* Run a hello world Node.js application.
+* Deploy the application to Minikube.
+* View application logs.
+* Update the application image.
+
+
+{% endcapture %}
+
+{% capture prerequisites %}
+
+* For OS X, you need [Homebrew](https://brew.sh) to install the `xhyve`
+driver.
+
+* [NodeJS](https://nodejs.org/en/) is required to run the sample application.
+
+* Install Docker. On OS X, we recommend
+[Docker for Mac](https://docs.docker.com/engine/installation/mac/).
+
+
+{% endcapture %}
+
+{% capture lessoncontent %}
+
+### Create a Minikube cluster
+
+This tutorial uses [Minikube](https://github.com/kubernetes/minikube) to
+create a local cluster. This tutorial also assumes you are using
+[Docker for Mac](https://docs.docker.com/engine/installation/mac/)
+on OS X. If you are on a different platform like Linux, or using VirtualBox
+instead of Docker for Mac, the instructions to install Minikube may be
+slightly different. For general Minikube installation instructions, see
+the [Minikube installation guide](docs/getting-started-guides/minikube/).
+
+Use `curl` to download and install the latest Minikube release:
+
+```shell
+curl -Lo minikube https://storage.googleapis.com/minikube/releases/latest/minikube-darwin-amd64 && chmod +x minikube && sudo mv minikube /usr/local/bin/
+```
+
+Use Homebrew to install the xhyve driver and set its permissions:
+
+```shell
+brew install docker-machine-driver-xhyve
+sudo chown root:wheel $(brew --prefix)/opt/docker-machine-driver-xhyve/bin/docker-machine-driver-xhyve
+sudo chmod u+s $(brew --prefix)/opt/docker-machine-driver-xhyve/bin/docker-machine-driver-xhyve
+```
+
+Download the latest version of the `kubectl` command-line tool, which you can
+use to interact with Kubernetes clusters:
+
+```shell
+curl -LO https://storage.googleapis.com/kubernetes-release/release/$(curl -s https://storage.googleapis.com/kubernetes-release/release/stable.txt)/bin/darwin/amd64/kubectl
+chmod +x ./kubectl
+sudo mv ./kubectl /usr/local/bin/kubectl
+```
+
+Start the Minikube cluster:
+
+```shell
+minikube start --vm-driver=xhyve
+```
+
+The `--vm-driver=xyhve` flag specifies that you are using Docker for Mac. The
+default VM driver is VirtualBox.
+
+Now set the Minikube context. The context is what determines which cluster
+`kubectl` is interacting with. You can see all your available contexts in the
+`~/.kube/config` file.
+
+```shell
+kubectl config use-context minikube
+```
+
+Verify that `kubectl` is configured to communicate with your cluster:
+
+```shell
+kubectl cluster-info
+```
+
+### Create your Node.js application
+
+The next step is to write the application. Save this code in a folder named `hellonode`
+with the filename `server.js`:
+
+{% include code.html language="js" file="server.js" ghlink="docs/tutorials/stateless-application/server.js" %}
+
+Run your application:
+
+```shell
+node server.js
+```
+
+You should be able to see your "Hello World!" message at http://localhost:8080/.
+
+Stop the running Node.js server by pressing **Ctrl-C**.
+
+The next step is to package your application in a Docker container.
+
+### Create a Docker container image
+
+Create a file, also in the `hellonode` folder, named `Dockerfile`. A Dockerfile describes
+the image that you want to build. You can build a Docker container image by extending an
+existing image. The image in this tutorial extends an existing Node.js image.
+
+{% include code.html language="conf" file="Dockerfile" ghlink="/docs/tutorials/stateless-application/Dockerfile" %}
+
+This recipe for the Docker image starts from the official Node.js LTS image
+found in the Docker registry, exposes port 8080, copies your `server.js` file
+to the image and start the Node.js server.
+
+Because this tutorial uses Minikube, instead of pushing your Docker image to a
+registry, you can simply build the image using the same Docker host as
+the Minikube VM, so that the images are automatically present. To do so, make
+sure you are using the Minikube Docker daemon:
+
+```shell
+eval $(minikube docker-env)
+```
+
+**Note:** Later, when you no longer wish to use the Minikube host, you can undo
+this change by running `eval $(minikube docker-env) -u`.
+
+Build your Docker image, using the Minikube Docker daemon:
+
+```shell
+docker build -t hello-node:v1 .
+```
+
+Now the Minikube VM can run the image you built.
+
+### Create a Deployment
+
+A Kubernetes [*Pod*](/docs/user-guide/pods/) is a group of one or more Containers,
+tied together for the purposes of administration and networking. The Pod in this
+tutorial has only one Container. A Kubernetes
+[*Deployment*](/docs/user-guide/deployments) checks on the health of your
+Pod and restarts the Pod's Container if it terminates. Deployments are the
+recommended way to manage the creation and scaling of Pods.
+
+Use the `kubectl run` command to create a Deployment that manages a Pod. The
+Pod runs a Container based on your `hello-node:v1` Docker image:
+
+```shell
+kubectl run hello-node --image=hello-node:v1 --port=8080
+```
+
+View the Deployment:
+
+
+```shell
+kubectl get deployments
+```
+
+Output:
+
+
+```shell
+NAME         DESIRED   CURRENT   UP-TO-DATE   AVAILABLE   AGE
+hello-node   1         1         1            1           3m
+```
+
+View the Pod:
+
+
+```shell
+kubectl get pods
+```
+
+Output:
+
+
+```shell
+NAME                         READY     STATUS    RESTARTS   AGE
+hello-node-714049816-ztzrb   1/1       Running   0          6m
+```
+
+View cluster events:
+
+```shell
+kubectl get events
+```
+
+View the `kubectl` configuration:
+
+```shell
+kubectl config view
+```
+
+For more information about `kubectl`commands, see the
+[kubectl overview](/docs/user-guide/kubectl-overview/).
+
+### Create a Service
+
+By default, the Pod is only accessible by its internal IP address within the
+Kubernetes cluster. To make the `hello-node` Container accessible from outside the
+Kubernetes virtual network, you have to expose the Pod as a
+Kubernetes [*Service*](/docs/user-guide/services/).
+
+From your development machine, you can expose the Pod to the public internet
+using the `kubectl expose` command:
+
+```shell
+kubectl expose deployment hello-node --type=LoadBalancer
+```
+
+View the Service you just created:
+
+```shell
+kubectl get services
+```
+
+Output:
+
+```shell
+NAME         CLUSTER-IP   EXTERNAL-IP   PORT(S)    AGE
+hello-node   10.0.0.71    <pending>     8080/TCP   6m
+kubernetes   10.0.0.1     <none>        443/TCP    14d
+```
+
+The `--type=LoadBalancer` flag indicates that you want to expose your Service
+outside of the cluster. On cloud providers that support load balancers,
+an external IP address would be provisioned to access the Service. On Minikube,
+the `LoadBalancer` type makes the Service accessible through the `minikube service`
+command.
+
+```shell
+minikube service hello-node
+```
+
+This automatically opens up a browser window using a local IP address that
+serves your app and shows the "Hello World" message.
+
+Assuming you've sent requests to your new web service using the browser or curl,
+you should now be able to see some logs:
+
+```shell
+kubectl logs <POD-NAME>
+```
+
+### Update your app
+
+Edit your `server.js` file to return a new message:
+
+```javascript
+response.end('Hello World Again!');
+
+```
+
+Build a new version of your image:
+
+```shell
+docker build -t hello-node:v2 .
+```
+
+Update the image of your Deployment:
+
+```shell
+kubectl set image deployment/hello-node hello-node=hello-node:v2
+```
+
+Run your app again to view the new message:
+
+```shell
+minikube service hello-node
+```
+
+### Clean up
+
+Now you can clean up the resources you created in your cluster:
+
+```shell
+kubectl delete service hello-node
+kubectl delete deployment hello-node
+```
+
+Optionally, stop Minikube:
+
+```shell
+minikube stop
+```
+
+{% endcapture %}
+
+
+{% capture whatsnext %}
+
+* Learn more about [Deployment objects](/docs/user-guide/deployments/).
+* Learn more about [Deploying applications](http://localhost:4000/docs/user-guide/deploying-applications/).
+* Learn more about [Service objects](/docs/user-guide/services/).
+
+{% endcapture %}
+
+{% include templates/tutorial.md %}
diff --git a/docs/tutorials/stateless-application/server.js b/docs/tutorials/stateless-application/server.js
new file mode 100644
index 0000000000..4a31299886
--- /dev/null
+++ b/docs/tutorials/stateless-application/server.js
@@ -0,0 +1,7 @@
+var handleRequest = function(request, response) {
+  console.log('Received request for URL: ' + request.url);
+  response.writeHead(200);
+  response.end('Hello World!');
+};
+var www = http.createServer(handleRequest);
+www.listen(8080);