2015-07-14 00:13:09 +00:00
|
|
|
<!-- BEGIN MUNGE: UNVERSIONED_WARNING -->
|
|
|
|
|
2016-06-10 23:46:46 +00:00
|
|
|
<!-- BEGIN STRIP_FOR_RELEASE -->
|
|
|
|
|
2016-07-15 09:44:58 +00:00
|
|
|
<img src="http://kubernetes.io/kubernetes/img/warning.png" alt="WARNING"
|
2016-06-10 23:46:46 +00:00
|
|
|
width="25" height="25">
|
2016-07-15 09:44:58 +00:00
|
|
|
<img src="http://kubernetes.io/kubernetes/img/warning.png" alt="WARNING"
|
2016-06-10 23:46:46 +00:00
|
|
|
width="25" height="25">
|
2016-07-15 09:44:58 +00:00
|
|
|
<img src="http://kubernetes.io/kubernetes/img/warning.png" alt="WARNING"
|
2016-06-10 23:46:46 +00:00
|
|
|
width="25" height="25">
|
2016-07-15 09:44:58 +00:00
|
|
|
<img src="http://kubernetes.io/kubernetes/img/warning.png" alt="WARNING"
|
2016-06-10 23:46:46 +00:00
|
|
|
width="25" height="25">
|
2016-07-15 09:44:58 +00:00
|
|
|
<img src="http://kubernetes.io/kubernetes/img/warning.png" alt="WARNING"
|
2016-06-10 23:46:46 +00:00
|
|
|
width="25" height="25">
|
|
|
|
|
|
|
|
<h2>PLEASE NOTE: This document applies to the HEAD of the source tree</h2>
|
|
|
|
|
|
|
|
If you are using a released version of Kubernetes, you should
|
|
|
|
refer to the docs that go with that version.
|
|
|
|
|
|
|
|
<!-- TAG RELEASE_LINK, added by the munger automatically -->
|
|
|
|
<strong>
|
|
|
|
The latest release of this document can be found
|
2016-09-01 21:40:55 +00:00
|
|
|
[here](http://releases.k8s.io/release-1.4/examples/meteor/README.md).
|
2016-06-10 23:46:46 +00:00
|
|
|
|
|
|
|
Documentation for other releases can be found at
|
|
|
|
[releases.k8s.io](http://releases.k8s.io).
|
|
|
|
</strong>
|
|
|
|
--
|
|
|
|
|
|
|
|
<!-- END STRIP_FOR_RELEASE -->
|
2015-07-14 00:13:09 +00:00
|
|
|
|
|
|
|
<!-- END MUNGE: UNVERSIONED_WARNING -->
|
2016-07-13 14:06:24 +00:00
|
|
|
Meteor on Kubernetes
|
|
|
|
====================
|
2015-04-17 11:24:53 +00:00
|
|
|
|
2015-05-07 17:14:51 +00:00
|
|
|
This example shows you how to package and run a
|
|
|
|
[Meteor](https://www.meteor.com/) app on Kubernetes.
|
2015-04-17 11:24:53 +00:00
|
|
|
|
2015-06-10 22:27:53 +00:00
|
|
|
Get started on Google Compute Engine
|
|
|
|
------------------------------------
|
|
|
|
|
|
|
|
Meteor uses MongoDB, and we will use the `GCEPersistentDisk` type of
|
|
|
|
volume for persistent storage. Therefore, this example is only
|
|
|
|
applicable to [Google Compute
|
|
|
|
Engine](https://cloud.google.com/compute/). Take a look at the
|
2015-07-14 16:37:37 +00:00
|
|
|
[volumes documentation](../../docs/user-guide/volumes.md) for other options.
|
2015-06-10 22:27:53 +00:00
|
|
|
|
|
|
|
First, if you have not already done so:
|
|
|
|
|
|
|
|
1. [Create](https://cloud.google.com/compute/docs/quickstart) a
|
|
|
|
[Google Cloud Platform](https://cloud.google.com/) project.
|
|
|
|
2. [Enable
|
|
|
|
billing](https://developers.google.com/console/help/new/#billing).
|
|
|
|
3. Install the [gcloud SDK](https://cloud.google.com/sdk/).
|
|
|
|
|
|
|
|
Authenticate with gcloud and set the gcloud default project name to
|
|
|
|
point to the project you want to use for your Kubernetes cluster:
|
|
|
|
|
2015-07-20 16:40:32 +00:00
|
|
|
```sh
|
2015-06-10 22:27:53 +00:00
|
|
|
gcloud auth login
|
|
|
|
gcloud config set project <project-name>
|
|
|
|
```
|
|
|
|
|
|
|
|
Next, start up a Kubernetes cluster:
|
2015-07-17 02:01:02 +00:00
|
|
|
|
2015-07-20 16:40:32 +00:00
|
|
|
```sh
|
2015-06-10 22:27:53 +00:00
|
|
|
wget -q -O - https://get.k8s.io | bash
|
|
|
|
```
|
|
|
|
|
2015-06-26 19:13:43 +00:00
|
|
|
Please see the [Google Compute Engine getting started
|
|
|
|
guide](../../docs/getting-started-guides/gce.md) for full
|
2015-06-10 22:27:53 +00:00
|
|
|
details and other options for starting a cluster.
|
|
|
|
|
2015-05-07 17:14:51 +00:00
|
|
|
Build a container for your Meteor app
|
|
|
|
-------------------------------------
|
2015-04-17 11:24:53 +00:00
|
|
|
|
2015-05-07 17:14:51 +00:00
|
|
|
To be able to run your Meteor app on Kubernetes you need to build a
|
|
|
|
Docker container for it first. To do that you need to install
|
|
|
|
[Docker](https://www.docker.com) Once you have that you need to add 2
|
|
|
|
files to your existing Meteor project `Dockerfile` and
|
|
|
|
`.dockerignore`.
|
|
|
|
|
|
|
|
`Dockerfile` should contain the below lines. You should replace the
|
|
|
|
`ROOT_URL` with the actual hostname of your app.
|
2015-07-17 02:01:02 +00:00
|
|
|
|
2015-05-07 17:14:51 +00:00
|
|
|
```
|
|
|
|
FROM chees/meteor-kubernetes
|
|
|
|
ENV ROOT_URL http://myawesomeapp.com
|
|
|
|
```
|
|
|
|
|
|
|
|
The `.dockerignore` file should contain the below lines. This tells
|
|
|
|
Docker to ignore the files on those directories when it's building
|
|
|
|
your container.
|
2015-07-17 02:01:02 +00:00
|
|
|
|
2015-05-07 17:14:51 +00:00
|
|
|
```
|
|
|
|
.meteor/local
|
|
|
|
packages/*/.build*
|
|
|
|
```
|
|
|
|
|
|
|
|
You can see an example meteor project already set up at:
|
|
|
|
[meteor-gke-example](https://github.com/Q42/meteor-gke-example). Feel
|
|
|
|
free to use this app for this example.
|
|
|
|
|
|
|
|
> Note: The next step will not work if you have added mobile platforms
|
|
|
|
> to your meteor project. Check with `meteor list-platforms`
|
|
|
|
|
|
|
|
Now you can build your container by running this in
|
|
|
|
your Meteor project directory:
|
2015-07-17 02:01:02 +00:00
|
|
|
|
2015-05-07 17:14:51 +00:00
|
|
|
```
|
|
|
|
docker build -t my-meteor .
|
|
|
|
```
|
|
|
|
|
|
|
|
Pushing to a registry
|
|
|
|
---------------------
|
|
|
|
|
|
|
|
For the [Docker Hub](https://hub.docker.com/), tag your app image with
|
|
|
|
your username and push to the Hub with the below commands. Replace
|
|
|
|
`<username>` with your Hub username.
|
2015-07-17 02:01:02 +00:00
|
|
|
|
2015-05-07 17:14:51 +00:00
|
|
|
```
|
|
|
|
docker tag my-meteor <username>/my-meteor
|
|
|
|
docker push <username>/my-meteor
|
|
|
|
```
|
|
|
|
|
|
|
|
For [Google Container
|
|
|
|
Registry](https://cloud.google.com/tools/container-registry/), tag
|
|
|
|
your app image with your project ID, and push to GCR. Replace
|
|
|
|
`<project>` with your project ID.
|
2015-07-17 02:01:02 +00:00
|
|
|
|
2015-05-07 17:14:51 +00:00
|
|
|
```
|
|
|
|
docker tag my-meteor gcr.io/<project>/my-meteor
|
2015-06-18 19:18:53 +00:00
|
|
|
gcloud docker push gcr.io/<project>/my-meteor
|
2015-05-07 17:14:51 +00:00
|
|
|
```
|
2015-04-17 11:24:53 +00:00
|
|
|
|
|
|
|
Running
|
|
|
|
-------
|
|
|
|
|
2015-05-07 17:14:51 +00:00
|
|
|
Now that you have containerized your Meteor app it's time to set up
|
2015-06-10 22:27:53 +00:00
|
|
|
your cluster. Edit [`meteor-controller.json`](meteor-controller.json)
|
|
|
|
and make sure the `image:` points to the container you just pushed to
|
|
|
|
the Docker Hub or GCR.
|
2015-04-17 11:24:53 +00:00
|
|
|
|
2015-08-09 18:18:06 +00:00
|
|
|
We will need to provide MongoDB a persistent Kubernetes volume to
|
2015-07-14 16:37:37 +00:00
|
|
|
store its data. See the [volumes documentation](../../docs/user-guide/volumes.md) for
|
2015-06-10 22:27:53 +00:00
|
|
|
options. We're going to use Google Compute Engine persistent
|
2015-05-07 17:14:51 +00:00
|
|
|
disks. Create the MongoDB disk by running:
|
2015-07-17 02:01:02 +00:00
|
|
|
|
2015-05-07 17:14:51 +00:00
|
|
|
```
|
|
|
|
gcloud compute disks create --size=200GB mongo-disk
|
|
|
|
```
|
2015-04-17 11:24:53 +00:00
|
|
|
|
|
|
|
Now you can start Mongo using that disk:
|
2015-07-17 02:01:02 +00:00
|
|
|
|
2015-05-07 17:14:51 +00:00
|
|
|
```
|
2015-07-16 00:20:39 +00:00
|
|
|
kubectl create -f examples/meteor/mongo-pod.json
|
|
|
|
kubectl create -f examples/meteor/mongo-service.json
|
2015-05-07 17:14:51 +00:00
|
|
|
```
|
|
|
|
|
|
|
|
Wait until Mongo is started completely and then start up your Meteor app:
|
2015-07-17 02:01:02 +00:00
|
|
|
|
2015-05-07 17:14:51 +00:00
|
|
|
```
|
2015-07-16 00:20:39 +00:00
|
|
|
kubectl create -f examples/meteor/meteor-service.json
|
2015-07-16 21:41:51 +00:00
|
|
|
kubectl create -f examples/meteor/meteor-controller.json
|
2015-05-07 17:14:51 +00:00
|
|
|
```
|
|
|
|
|
2015-06-10 21:54:33 +00:00
|
|
|
Note that [`meteor-service.json`](meteor-service.json) creates a load balancer, so
|
2015-05-07 17:14:51 +00:00
|
|
|
your app should be available through the IP of that load balancer once
|
2015-07-16 21:41:51 +00:00
|
|
|
the Meteor pods are started. We also created the service before creating the rc to
|
|
|
|
aid the scheduler in placing pods, as the scheduler ranks pod placement according to
|
|
|
|
service anti-affinity (among other things). You can find the IP of your load balancer
|
2015-05-07 17:14:51 +00:00
|
|
|
by running:
|
2015-07-17 02:01:02 +00:00
|
|
|
|
2015-05-07 17:14:51 +00:00
|
|
|
```
|
2015-07-16 21:41:51 +00:00
|
|
|
kubectl get service meteor --template="{{range .status.loadBalancer.ingress}} {{.ip}} {{end}}"
|
2015-05-07 17:14:51 +00:00
|
|
|
```
|
|
|
|
|
|
|
|
You will have to open up port 80 if it's not open yet in your
|
2015-06-26 19:13:43 +00:00
|
|
|
environment. On Google Compute Engine, you may run the below command.
|
2015-07-17 02:01:02 +00:00
|
|
|
|
2015-05-07 17:14:51 +00:00
|
|
|
```
|
2016-05-05 20:41:49 +00:00
|
|
|
gcloud compute firewall-rules create meteor-80 --allow=tcp:80 --target-tags kubernetes-node
|
2015-05-07 17:14:51 +00:00
|
|
|
```
|
|
|
|
|
|
|
|
What is going on?
|
|
|
|
-----------------
|
|
|
|
|
|
|
|
Firstly, the `FROM chees/meteor-kubernetes` line in your `Dockerfile`
|
|
|
|
specifies the base image for your Meteor app. The code for that image
|
|
|
|
is located in the `dockerbase/` subdirectory. Open up the `Dockerfile`
|
|
|
|
to get an insight of what happens during the `docker build` step. The
|
|
|
|
image is based on the Node.js official image. It then installs Meteor
|
|
|
|
and copies in your apps' code. The last line specifies what happens
|
|
|
|
when your app container is run.
|
2015-07-17 02:01:02 +00:00
|
|
|
|
2015-07-20 16:40:32 +00:00
|
|
|
```sh
|
2015-05-07 17:14:51 +00:00
|
|
|
ENTRYPOINT MONGO_URL=mongodb://$MONGO_SERVICE_HOST:$MONGO_SERVICE_PORT /usr/local/bin/node main.js
|
|
|
|
```
|
|
|
|
|
|
|
|
Here we can see the MongoDB host and port information being passed
|
|
|
|
into the Meteor app. The `MONGO_SERVICE...` environment variables are
|
|
|
|
set by Kubernetes, and point to the service named `mongo` specified in
|
2015-05-24 07:15:58 +00:00
|
|
|
[`mongo-service.json`](mongo-service.json). See the [environment
|
2015-07-14 16:37:37 +00:00
|
|
|
documentation](../../docs/user-guide/container-environment.md) for more details.
|
2015-05-07 17:14:51 +00:00
|
|
|
|
|
|
|
As you may know, Meteor uses long lasting connections, and requires
|
|
|
|
_sticky sessions_. With Kubernetes you can scale out your app easily
|
2015-06-10 22:27:53 +00:00
|
|
|
with session affinity. The
|
|
|
|
[`meteor-service.json`](meteor-service.json) file contains
|
2015-05-07 17:14:51 +00:00
|
|
|
`"sessionAffinity": "ClientIP"`, which provides this for us. See the
|
|
|
|
[service
|
2015-07-14 16:37:37 +00:00
|
|
|
documentation](../../docs/user-guide/services.md#virtual-ips-and-service-proxies) for
|
2015-06-10 22:27:53 +00:00
|
|
|
more information.
|
2015-05-07 17:14:51 +00:00
|
|
|
|
|
|
|
As mentioned above, the mongo container uses a volume which is mapped
|
2015-06-05 15:35:17 +00:00
|
|
|
to a persistent disk by Kubernetes. In [`mongo-pod.json`](mongo-pod.json) the container
|
2015-05-07 17:14:51 +00:00
|
|
|
section specifies the volume:
|
2015-07-17 02:01:02 +00:00
|
|
|
|
2015-07-20 16:40:32 +00:00
|
|
|
```json
|
|
|
|
{
|
2015-05-07 17:14:51 +00:00
|
|
|
"volumeMounts": [
|
|
|
|
{
|
|
|
|
"name": "mongo-disk",
|
|
|
|
"mountPath": "/data/db"
|
|
|
|
}
|
|
|
|
```
|
|
|
|
|
|
|
|
The name `mongo-disk` refers to the volume specified outside the
|
|
|
|
container section:
|
2015-07-17 02:01:02 +00:00
|
|
|
|
2015-07-20 16:40:32 +00:00
|
|
|
```json
|
|
|
|
{
|
2015-05-07 17:14:51 +00:00
|
|
|
"volumes": [
|
|
|
|
{
|
|
|
|
"name": "mongo-disk",
|
|
|
|
"gcePersistentDisk": {
|
|
|
|
"pdName": "mongo-disk",
|
|
|
|
"fsType": "ext4"
|
|
|
|
}
|
|
|
|
}
|
|
|
|
],
|
|
|
|
```
|
2015-05-14 22:12:45 +00:00
|
|
|
|
|
|
|
|
2015-07-14 00:13:09 +00:00
|
|
|
<!-- BEGIN MUNGE: GENERATED_ANALYTICS -->
|
2015-05-14 22:12:45 +00:00
|
|
|
[![Analytics](https://kubernetes-site.appspot.com/UA-36037335-10/GitHub/examples/meteor/README.md?pixel)]()
|
2015-07-14 00:13:09 +00:00
|
|
|
<!-- END MUNGE: GENERATED_ANALYTICS -->
|