442 lines
12 KiB
Markdown
442 lines
12 KiB
Markdown
|
---
|
||
|
title: Hello Minikube
|
||
|
content_template: templates/tutorial
|
||
|
weight: 5
|
||
|
---
|
||
|
|
||
|
{{% 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.
|
||
|
|
||
|
{{% /capture %}}
|
||
|
|
||
|
{{% capture objectives %}}
|
||
|
|
||
|
* Run a hello world Node.js application.
|
||
|
* Deploy the application to Minikube.
|
||
|
* View application logs.
|
||
|
* Update the application image.
|
||
|
|
||
|
|
||
|
{{% /capture %}}
|
||
|
|
||
|
{{% capture prerequisites %}}
|
||
|
|
||
|
* For OS X, you need [Homebrew](https://brew.sh) to install the `xhyve` driver.
|
||
|
|
||
|
{{< note >}}
|
||
|
**Note:** If you see the following Homebrew error when you run `brew update` after you update your computer to MacOS 10.13:
|
||
|
|
||
|
```
|
||
|
Error: /usr/local is not writable. You should change the ownership
|
||
|
and permissions of /usr/local back to your user account:
|
||
|
sudo chown -R $(whoami) /usr/local
|
||
|
```
|
||
|
You can resolve the issue by reinstalling Homebrew:
|
||
|
```
|
||
|
/usr/bin/ruby -e "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/master/install)"
|
||
|
```
|
||
|
{{< /note >}}
|
||
|
|
||
|
* [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/).
|
||
|
|
||
|
|
||
|
{{% /capture %}}
|
||
|
|
||
|
{{% 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
|
||
|
```
|
||
|
|
||
|
Use Homebrew to download the `kubectl` command-line tool, which you can
|
||
|
use to interact with Kubernetes clusters:
|
||
|
|
||
|
```shell
|
||
|
brew install kubectl
|
||
|
```
|
||
|
|
||
|
Determine whether you can access sites like [https://cloud.google.com/container-registry/](https://cloud.google.com/container-registry/) directly without a proxy, by opening a new terminal and using
|
||
|
|
||
|
```shell
|
||
|
curl --proxy "" https://cloud.google.com/container-registry/
|
||
|
```
|
||
|
|
||
|
Make sure that the Docker daemon is started. You can determine if docker is running by using a command such as:
|
||
|
|
||
|
```shell
|
||
|
docker images
|
||
|
```
|
||
|
|
||
|
If NO proxy is required, start the Minikube cluster:
|
||
|
|
||
|
```shell
|
||
|
minikube start --vm-driver=xhyve
|
||
|
```
|
||
|
If a proxy server is required, use the following method to start Minikube cluster with proxy setting:
|
||
|
|
||
|
```shell
|
||
|
minikube start --vm-driver=xhyve --docker-env HTTP_PROXY=http://your-http-proxy-host:your-http-proxy-port --docker-env HTTPS_PROXY=http(s)://your-https-proxy-host:your-https-proxy-port
|
||
|
```
|
||
|
|
||
|
The `--vm-driver=xhyve` flag specifies that you are using Docker for Mac. The
|
||
|
default VM driver is VirtualBox.
|
||
|
|
||
|
Note if `minikube start --vm-driver=xhyve` is unsuccessful due to the error:
|
||
|
```
|
||
|
Error creating machine: Error in driver during machine creation: Could not convert the UUID to MAC address: exit status 1
|
||
|
```
|
||
|
|
||
|
Then the following may resolve the `minikube start --vm-driver=xhyve` issue:
|
||
|
```
|
||
|
rm -rf ~/.minikube
|
||
|
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
|
||
|
```
|
||
|
|
||
|
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
|
||
|
```
|
||
|
|
||
|
Open the Kubernetes dashboard in a browser:
|
||
|
|
||
|
```shell
|
||
|
minikube dashboard
|
||
|
```
|
||
|
|
||
|
## 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`:
|
||
|
|
||
|
{{< code language="js" file="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.
|
||
|
|
||
|
{{< code language="conf" file="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 starts 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 (mind the trailing dot):
|
||
|
|
||
|
```shell
|
||
|
docker build -t hello-node:v1 .
|
||
|
```
|
||
|
|
||
|
Now the Minikube VM can run the image you built.
|
||
|
|
||
|
## Create a Deployment
|
||
|
|
||
|
A Kubernetes [*Pod*](/docs/concepts/workloads/pods/pod/) 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/concepts/workloads/controllers/deployment/) 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/concepts/services-networking/service/).
|
||
|
|
||
|
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 (mind the trailing dot):
|
||
|
|
||
|
```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
|
||
|
```
|
||
|
|
||
|
## Enable addons
|
||
|
|
||
|
Minikube has a set of built-in addons that can be enabled, disabled and opened in the local Kubernetes environment.
|
||
|
|
||
|
First list the currently supported addons:
|
||
|
|
||
|
```shell
|
||
|
minikube addons list
|
||
|
```
|
||
|
|
||
|
Output:
|
||
|
|
||
|
```shell
|
||
|
- storage-provisioner: enabled
|
||
|
- kube-dns: enabled
|
||
|
- registry: disabled
|
||
|
- registry-creds: disabled
|
||
|
- addon-manager: enabled
|
||
|
- dashboard: disabled
|
||
|
- default-storageclass: enabled
|
||
|
- coredns: disabled
|
||
|
- heapster: disabled
|
||
|
- efk: disabled
|
||
|
- ingress: disabled
|
||
|
```
|
||
|
|
||
|
Minikube must be running for these commands to take effect. To enable `heapster` addon, for example:
|
||
|
|
||
|
```shell
|
||
|
minikube addons enable heapster
|
||
|
```
|
||
|
|
||
|
Output:
|
||
|
|
||
|
```shell
|
||
|
heapster was successfully enabled
|
||
|
```
|
||
|
|
||
|
View the Pod and Service you just created:
|
||
|
|
||
|
```shell
|
||
|
kubectl get po,svc -n kube-system
|
||
|
```
|
||
|
|
||
|
Output:
|
||
|
|
||
|
```shell
|
||
|
NAME READY STATUS RESTARTS AGE
|
||
|
po/heapster-zbwzv 1/1 Running 0 2m
|
||
|
po/influxdb-grafana-gtht9 2/2 Running 0 2m
|
||
|
|
||
|
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
|
||
|
svc/heapster NodePort 10.0.0.52 <none> 80:31655/TCP 2m
|
||
|
svc/monitoring-grafana NodePort 10.0.0.33 <none> 80:30002/TCP 2m
|
||
|
svc/monitoring-influxdb ClusterIP 10.0.0.43 <none> 8083/TCP,8086/TCP 2m
|
||
|
```
|
||
|
|
||
|
Open the endpoint to interacting with heapster in a browser:
|
||
|
|
||
|
```shell
|
||
|
minikube addons open heapster
|
||
|
```
|
||
|
|
||
|
Output:
|
||
|
|
||
|
```shell
|
||
|
Opening kubernetes service kube-system/monitoring-grafana in default browser...
|
||
|
```
|
||
|
|
||
|
## 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, force removal of the Docker images created:
|
||
|
|
||
|
```shell
|
||
|
docker rmi hello-node:v1 hello-node:v2 -f
|
||
|
```
|
||
|
|
||
|
Optionally, stop the Minikube VM:
|
||
|
|
||
|
```shell
|
||
|
minikube stop
|
||
|
eval $(minikube docker-env -u)
|
||
|
```
|
||
|
|
||
|
Optionally, delete the Minikube VM:
|
||
|
|
||
|
```shell
|
||
|
minikube delete
|
||
|
```
|
||
|
|
||
|
{{% /capture %}}
|
||
|
|
||
|
|
||
|
{{% capture whatsnext %}}
|
||
|
|
||
|
* Learn more about [Deployment objects](/docs/concepts/workloads/controllers/deployment/).
|
||
|
* Learn more about [Deploying applications](/docs/user-guide/deploying-applications/).
|
||
|
* Learn more about [Service objects](/docs/concepts/services-networking/service/).
|
||
|
|
||
|
{{% /capture %}}
|
||
|
|
||
|
|