Convert site to Hugo (#8316)
This commit converts content and layout to use Hugo.
This commit is contained in:
committed by
k8s-ci-robot
parent
7745f0e0c5
commit
7f3b633aa0
@@ -0,0 +1,4 @@
|
||||
FROM node:6.9.2
|
||||
EXPOSE 8080
|
||||
COPY server.js .
|
||||
CMD node server.js
|
||||
@@ -0,0 +1,5 @@
|
||||
---
|
||||
title: "Stateless Applications"
|
||||
weight: 90
|
||||
---
|
||||
|
||||
@@ -0,0 +1,21 @@
|
||||
apiVersion: apps/v1
|
||||
kind: Deployment
|
||||
metadata:
|
||||
name: nginx-deployment
|
||||
spec:
|
||||
selector:
|
||||
matchLabels:
|
||||
app: nginx
|
||||
replicas: 2 # tells deployment to run 2 pods matching the template
|
||||
template: # create pods using pod definition in this template
|
||||
metadata:
|
||||
# unlike pod-nginx.yaml, the name is not included in the meta data as a unique name is
|
||||
# generated from the deployment name
|
||||
labels:
|
||||
app: nginx
|
||||
spec:
|
||||
containers:
|
||||
- name: nginx
|
||||
image: nginx:1.7.9
|
||||
ports:
|
||||
- containerPort: 80
|
||||
@@ -0,0 +1,161 @@
|
||||
---
|
||||
title: Exposing an External IP Address to Access an Application in a Cluster
|
||||
content_template: templates/tutorial
|
||||
---
|
||||
|
||||
{{% capture overview %}}
|
||||
|
||||
This page shows how to create a Kubernetes Service object that exposes an
|
||||
external IP address.
|
||||
|
||||
{{% /capture %}}
|
||||
|
||||
|
||||
{{% capture prerequisites %}}
|
||||
|
||||
* Install [kubectl](/docs/tasks/tools/install-kubectl/).
|
||||
|
||||
* Use a cloud provider like Google Kubernetes Engine or Amazon Web Services to
|
||||
create a Kubernetes cluster. This tutorial creates an
|
||||
[external load balancer](/docs/tasks/access-application-cluster/create-external-load-balancer/),
|
||||
which requires a cloud provider.
|
||||
|
||||
* Configure `kubectl` to communicate with your Kubernetes API server. For
|
||||
instructions, see the documentation for your cloud provider.
|
||||
|
||||
{{% /capture %}}
|
||||
|
||||
|
||||
{{% capture objectives %}}
|
||||
|
||||
* Run five instances of a Hello World application.
|
||||
* Create a Service object that exposes an external IP address.
|
||||
* Use the Service object to access the running application.
|
||||
|
||||
{{% /capture %}}
|
||||
|
||||
|
||||
{{% capture lessoncontent %}}
|
||||
|
||||
## Creating a service for an application running in five pods
|
||||
|
||||
1. Run a Hello World application in your cluster:
|
||||
|
||||
kubectl run hello-world --replicas=5 --labels="run=load-balancer-example" --image=gcr.io/google-samples/node-hello:1.0 --port=8080
|
||||
|
||||
The preceding command creates a
|
||||
[Deployment](/docs/concepts/workloads/controllers/deployment/)
|
||||
object and an associated
|
||||
[ReplicaSet](/docs/concepts/workloads/controllers/replicaset/)
|
||||
object. The ReplicaSet has five
|
||||
[Pods](/docs/concepts/workloads/pods/pod/),
|
||||
each of which runs the Hello World application.
|
||||
|
||||
1. Display information about the Deployment:
|
||||
|
||||
kubectl get deployments hello-world
|
||||
kubectl describe deployments hello-world
|
||||
|
||||
1. Display information about your ReplicaSet objects:
|
||||
|
||||
kubectl get replicasets
|
||||
kubectl describe replicasets
|
||||
|
||||
1. Create a Service object that exposes the deployment:
|
||||
|
||||
kubectl expose deployment hello-world --type=LoadBalancer --name=my-service
|
||||
|
||||
1. Display information about the Service:
|
||||
|
||||
kubectl get services my-service
|
||||
|
||||
The output is similar to this:
|
||||
|
||||
NAME CLUSTER-IP EXTERNAL-IP PORT(S) AGE
|
||||
my-service 10.3.245.137 104.198.205.71 8080/TCP 54s
|
||||
|
||||
Note: If the external IP address is shown as \<pending\>, wait for a minute
|
||||
and enter the same command again.
|
||||
|
||||
1. Display detailed information about the Service:
|
||||
|
||||
kubectl describe services my-service
|
||||
|
||||
The output is similar to this:
|
||||
|
||||
Name: my-service
|
||||
Namespace: default
|
||||
Labels: run=load-balancer-example
|
||||
Annotations: <none>
|
||||
Selector: run=load-balancer-example
|
||||
Type: LoadBalancer
|
||||
IP: 10.3.245.137
|
||||
LoadBalancer Ingress: 104.198.205.71
|
||||
Port: <unset> 8080/TCP
|
||||
NodePort: <unset> 32377/TCP
|
||||
Endpoints: 10.0.0.6:8080,10.0.1.6:8080,10.0.1.7:8080 + 2 more...
|
||||
Session Affinity: None
|
||||
Events: <none>
|
||||
|
||||
Make a note of the external IP address (`LoadBalancer Ingress`) exposed by
|
||||
your service. In this example, the external IP address is 104.198.205.71.
|
||||
Also note the value of `Port` and `NodePort`. In this example, the `Port`
|
||||
is 8080 and the `NodePort` is 32377.
|
||||
|
||||
1. In the preceding output, you can see that the service has several endpoints:
|
||||
10.0.0.6:8080,10.0.1.6:8080,10.0.1.7:8080 + 2 more. These are internal
|
||||
addresses of the pods that are running the Hello World application. To
|
||||
verify these are pod addresses, enter this command:
|
||||
|
||||
kubectl get pods --output=wide
|
||||
|
||||
The output is similar to this:
|
||||
|
||||
NAME ... IP NODE
|
||||
hello-world-2895499144-1jaz9 ... 10.0.1.6 gke-cluster-1-default-pool-e0b8d269-1afc
|
||||
hello-world-2895499144-2e5uh ... 10.0.1.8 gke-cluster-1-default-pool-e0b8d269-1afc
|
||||
hello-world-2895499144-9m4h1 ... 10.0.0.6 gke-cluster-1-default-pool-e0b8d269-5v7a
|
||||
hello-world-2895499144-o4z13 ... 10.0.1.7 gke-cluster-1-default-pool-e0b8d269-1afc
|
||||
hello-world-2895499144-segjf ... 10.0.2.5 gke-cluster-1-default-pool-e0b8d269-cpuc
|
||||
|
||||
1. Use the external IP address (`LoadBalancer Ingress`) to access the Hello
|
||||
World application:
|
||||
|
||||
curl http://<external-ip>:<port>
|
||||
|
||||
where `<external-ip>` is the external IP address (`LoadBalancer Ingress`)
|
||||
of your Service, and `<port>` is the value of `Port` in your Service
|
||||
description.
|
||||
If you are using minikube, typing `minikube service my-service` will
|
||||
automatically open the Hello World application in a browser.
|
||||
|
||||
The response to a successful request is a hello message:
|
||||
|
||||
Hello Kubernetes!
|
||||
|
||||
{{% /capture %}}
|
||||
|
||||
|
||||
{{% capture cleanup %}}
|
||||
|
||||
To delete the Service, enter this command:
|
||||
|
||||
kubectl delete services my-service
|
||||
|
||||
To delete the Deployment, the ReplicaSet, and the Pods that are running
|
||||
the Hello World application, enter this command:
|
||||
|
||||
kubectl delete deployment hello-world
|
||||
|
||||
{{% /capture %}}
|
||||
|
||||
|
||||
{{% capture whatsnext %}}
|
||||
|
||||
Learn more about
|
||||
[connecting applications with services](/docs/concepts/services-networking/connect-applications-service/).
|
||||
{{% /capture %}}
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -0,0 +1,304 @@
|
||||
---
|
||||
title: "Example: Deploying PHP Guestbook application with Redis"
|
||||
reviewers:
|
||||
- ahmetb
|
||||
content_template: templates/tutorial
|
||||
---
|
||||
|
||||
{{% capture overview %}}
|
||||
This tutorial shows you how to build and deploy a simple, multi-tier web application using Kubernetes and [Docker](https://www.docker.com/). This example consists of the following components:
|
||||
|
||||
* A single-instance [Redis](https://redis.io/) master to store guestbook entries
|
||||
* Multiple replicated Redis instances to serve reads
|
||||
* Multiple web frontend instances
|
||||
|
||||
{{% /capture %}}
|
||||
|
||||
{{% capture objectives %}}
|
||||
* Start up a Redis master.
|
||||
* Start up Redis slaves.
|
||||
* Start up the guestbook frontend.
|
||||
* Expose and view the Frontend Service.
|
||||
* Clean up.
|
||||
{{% /capture %}}
|
||||
|
||||
{{% capture prerequisites %}}
|
||||
|
||||
{{< include "task-tutorial-prereqs.md" >}} {{< version-check >}}
|
||||
Download the following configuration files:
|
||||
|
||||
1. [redis-master-deployment.yaml](/docs/tutorials/stateless-application/guestbook/redis-master-deployment.yaml)
|
||||
1. [redis-master-service.yaml](/docs/tutorials/stateless-application/guestbook/redis-master-service.yaml)
|
||||
1. [redis-slave-deployment.yaml](/docs/tutorials/stateless-application/guestbook/redis-slave-deployment.yaml)
|
||||
1. [redis-slave-service.yaml](/docs/tutorials/stateless-application/guestbook/redis-slave-service.yaml)
|
||||
1. [frontend-deployment.yaml](/docs/tutorials/stateless-application/guestbook/frontend-deployment.yaml)
|
||||
1. [frontend-service.yaml](/docs/tutorials/stateless-application/guestbook/frontend-service.yaml)
|
||||
|
||||
{{% /capture %}}
|
||||
|
||||
{{% capture lessoncontent %}}
|
||||
|
||||
## Start up the Redis Master
|
||||
|
||||
The guestbook application uses Redis to store its data. It writes its data to a Redis master instance and reads data from multiple Redis slave instances.
|
||||
|
||||
### Creating the Redis Master Deployment
|
||||
|
||||
The manifest file, included below, specifies a Deployment controller that runs a single replica Redis master Pod.
|
||||
|
||||
1. Launch a terminal window in the directory you downloaded the manifest files.
|
||||
2. Apply the Redis Master Deployment from the `redis-master-deployment.yaml` file:
|
||||
|
||||
kubectl apply -f redis-master-deployment.yaml
|
||||
|
||||
{{< code file="guestbook/redis-master-deployment.yaml" >}}
|
||||
|
||||
3. Query the list of Pods to verify that the Redis Master Pod is running:
|
||||
|
||||
kubectl get pods
|
||||
|
||||
The response should be similar to this:
|
||||
|
||||
NAME READY STATUS RESTARTS AGE
|
||||
redis-master-1068406935-3lswp 1/1 Running 0 28s
|
||||
|
||||
4. Run the following command to view the logs from the Redis Master Pod:
|
||||
|
||||
kubectl logs -f POD-NAME
|
||||
|
||||
{{< note >}}
|
||||
**Note:** Replace POD-NAME with the name of your Pod.
|
||||
{{< /note >}}
|
||||
|
||||
### Creating the Redis Master Service
|
||||
|
||||
The guestbook applications needs to communicate to the Redis master to write its data. You need to apply a [Service](/docs/concepts/services-networking/service/) to proxy the traffic to the Redis master Pod. A Service defines a policy to access the Pods.
|
||||
|
||||
1. Apply the Redis Master Service from the following `redis-master-service.yaml` file:
|
||||
|
||||
kubectl apply -f redis-master-service.yaml
|
||||
|
||||
{{< code file="guestbook/redis-master-service.yaml" >}}
|
||||
|
||||
{{< note >}}
|
||||
**Note:** This manifest file creates a Service named `redis-master` with a set of labels that match the labels previously defined, so the Service routes network traffic to the Redis master Pod.
|
||||
{{< /note >}}
|
||||
|
||||
2. Query the list of Services to verify that the Redis Master Service is running:
|
||||
|
||||
kubectl get service
|
||||
|
||||
The response should be similar to this:
|
||||
|
||||
NAME CLUSTER-IP EXTERNAL-IP PORT(S) AGE
|
||||
kubernetes 10.0.0.1 <none> 443/TCP 1m
|
||||
redis-master 10.0.0.151 <none> 6379/TCP 8s
|
||||
|
||||
## Start up the Redis Slaves
|
||||
|
||||
Although the Redis master is a single pod, you can make it highly available to meet traffic demands by adding replica Redis slaves.
|
||||
|
||||
### Creating the Redis Slave Deployment
|
||||
|
||||
Deployments scale based off of the configurations set in the manifest file. In this case, the Deployment object specifies two replicas.
|
||||
|
||||
If there are not any replicas running, this Deployment would start the two replicas on your container cluster. Conversely, if there are more than two replicas are running, it would scale down until two replicas are running.
|
||||
|
||||
1. Apply the Redis Slave Deployment from the `redis-slave-deployment.yaml` file:
|
||||
|
||||
kubectl apply -f redis-slave-deployment.yaml
|
||||
|
||||
{{< code file="guestbook/redis-slave-deployment.yaml" >}}
|
||||
|
||||
2. Query the list of Pods to verify that the Redis Slave Pods are running:
|
||||
|
||||
kubectl get pods
|
||||
|
||||
The response should be similar to this:
|
||||
|
||||
NAME READY STATUS RESTARTS AGE
|
||||
redis-master-1068406935-3lswp 1/1 Running 0 1m
|
||||
redis-slave-2005841000-fpvqc 0/1 ContainerCreating 0 6s
|
||||
redis-slave-2005841000-phfv9 0/1 ContainerCreating 0 6s
|
||||
|
||||
### Creating the Redis Slave Service
|
||||
|
||||
The guestbook application needs to communicate to Redis slaves to read data. To make the Redis slaves discoverable, you need to set up a Service. A Service provides transparent load balancing to a set of Pods.
|
||||
|
||||
1. Apply the Redis Slave Service from the following `redis-slave-service.yaml` file:
|
||||
|
||||
kubectl apply -f redis-slave-service.yaml
|
||||
|
||||
{{< code file="guestbook/redis-slave-service.yaml" >}}
|
||||
|
||||
2. Query the list of Services to verify that the Redis Slave Service is running:
|
||||
|
||||
kubectl get services
|
||||
|
||||
The response should be similar to this:
|
||||
|
||||
NAME CLUSTER-IP EXTERNAL-IP PORT(S) AGE
|
||||
kubernetes 10.0.0.1 <none> 443/TCP 2m
|
||||
redis-master 10.0.0.151 <none> 6379/TCP 1m
|
||||
redis-slave 10.0.0.223 <none> 6379/TCP 6s
|
||||
|
||||
## Set up and Expose the Guestbook Frontend
|
||||
|
||||
The guestbook application has a web frontend serving the HTTP requests written in PHP. It is configured to connect to the `redis-master` Service for write requests and the `redis-slave` service for Read requests.
|
||||
|
||||
### Creating the Guestbook Frontend Deployment
|
||||
|
||||
1. Apply the frontend Deployment from the following `frontend-deployment.yaml` file:
|
||||
|
||||
kubectl apply -f frontend-deployment.yaml
|
||||
|
||||
{{< code file="guestbook/frontend-deployment.yaml" >}}
|
||||
|
||||
2. Query the list of Pods to verify that the three frontend replicas are running:
|
||||
|
||||
kubectl get pods -l app=guestbook -l tier=frontend
|
||||
|
||||
The response should be similar to this:
|
||||
|
||||
NAME READY STATUS RESTARTS AGE
|
||||
frontend-3823415956-dsvc5 1/1 Running 0 54s
|
||||
frontend-3823415956-k22zn 1/1 Running 0 54s
|
||||
frontend-3823415956-w9gbt 1/1 Running 0 54s
|
||||
|
||||
### Creating the Frontend Service
|
||||
|
||||
The `redis-slave` and `redis-master` Services you applied are only accessible within the container cluster because the default type for a Service is [ClusterIP](/docs/concepts/services-networking/service/#publishing-services---service-types). `ClusterIP` provides a single IP address for the set of Pods the Service is pointing to. This IP address is accessible only within the cluster.
|
||||
|
||||
If you want guests to be able to access your guestbook, you must configure the frontend Service to be externally visible, so a client can request the Service from outside the container cluster. Minikube can only expose Services through `NodePort`.
|
||||
|
||||
{{< note >}}
|
||||
**Note:** Some cloud providers, like Google Compute Engine or Google Kubernetes Engine, support external load balancers. If your cloud provider supports load balancers and you want to use it, simply delete or comment out `type: NodePort`, and uncomment `type: LoadBalancer`.
|
||||
{{< /note >}}
|
||||
|
||||
1. Apply the frontend Service from the following `frontend-service.yaml` file:
|
||||
|
||||
kubectl apply -f frontend-service.yaml
|
||||
|
||||
{{< code file="guestbook/frontend-service.yaml" >}}
|
||||
|
||||
2. Query the list of Services to verify that the frontend Service is running:
|
||||
|
||||
kubectl get services
|
||||
|
||||
The response should be similar to this:
|
||||
|
||||
NAME CLUSTER-IP EXTERNAL-IP PORT(S) AGE
|
||||
frontend 10.0.0.112 <none> 80:31323/TCP 6s
|
||||
kubernetes 10.0.0.1 <none> 443/TCP 4m
|
||||
redis-master 10.0.0.151 <none> 6379/TCP 2m
|
||||
redis-slave 10.0.0.223 <none> 6379/TCP 1m
|
||||
|
||||
### Viewing the Frontend Service via `NodePort`
|
||||
|
||||
If you deployed this application to Minikube or a local cluster, you need to find the IP address to view your Guestbook.
|
||||
|
||||
1. Run the following command to get the IP address for the frontend Service.
|
||||
|
||||
minikube service frontend --url
|
||||
|
||||
The response should be similar to this:
|
||||
|
||||
http://192.168.99.100:31323
|
||||
|
||||
2. Copy the IP address, and load the page in your browser to view your guestbook.
|
||||
|
||||
### Viewing the Frontend Service via `LoadBalancer`
|
||||
|
||||
If you deployed the `frontend-service.yaml` manifest with type: `LoadBalancer` you need to find the IP address to view your Guestbook.
|
||||
|
||||
1. Run the following command to get the IP address for the frontend Service.
|
||||
|
||||
kubectl get service frontend
|
||||
|
||||
The response should be similar to this:
|
||||
|
||||
NAME CLUSTER-IP EXTERNAL-IP PORT(S) AGE
|
||||
frontend 10.51.242.136 109.197.92.229 80:32372/TCP 1m
|
||||
|
||||
2. Copy the External IP address, and load the page in your browser to view your guestbook.
|
||||
|
||||
## Scale the Web Frontend
|
||||
|
||||
Scaling up or down is easy because your servers are defined as a Service that uses a Deployment controller.
|
||||
|
||||
1. Run the following command to scale up the number of frontend Pods:
|
||||
|
||||
kubectl scale deployment frontend --replicas=5
|
||||
|
||||
2. Query the list of Pods to verify the number of frontend Pods running:
|
||||
|
||||
kubectl get pods
|
||||
|
||||
The response should look similar to this:
|
||||
|
||||
NAME READY STATUS RESTARTS AGE
|
||||
frontend-3823415956-70qj5 1/1 Running 0 5s
|
||||
frontend-3823415956-dsvc5 1/1 Running 0 54m
|
||||
frontend-3823415956-k22zn 1/1 Running 0 54m
|
||||
frontend-3823415956-w9gbt 1/1 Running 0 54m
|
||||
frontend-3823415956-x2pld 1/1 Running 0 5s
|
||||
redis-master-1068406935-3lswp 1/1 Running 0 56m
|
||||
redis-slave-2005841000-fpvqc 1/1 Running 0 55m
|
||||
redis-slave-2005841000-phfv9 1/1 Running 0 55m
|
||||
|
||||
3. Run the following command to scale down the number of frontend Pods:
|
||||
|
||||
kubectl scale deployment frontend --replicas=2
|
||||
|
||||
4. Query the list of Pods to verify the number of frontend Pods running:
|
||||
|
||||
kubectl get pods
|
||||
|
||||
The response should look similar to this:
|
||||
|
||||
NAME READY STATUS RESTARTS AGE
|
||||
frontend-3823415956-k22zn 1/1 Running 0 1h
|
||||
frontend-3823415956-w9gbt 1/1 Running 0 1h
|
||||
redis-master-1068406935-3lswp 1/1 Running 0 1h
|
||||
redis-slave-2005841000-fpvqc 1/1 Running 0 1h
|
||||
redis-slave-2005841000-phfv9 1/1 Running 0 1h
|
||||
|
||||
{{% /capture %}}
|
||||
|
||||
{{% capture cleanup %}}
|
||||
Deleting the Deployments and Services also deletes any running Pods. Use labels to delete multiple resources with one command.
|
||||
|
||||
1. Run the following commands to delete all Pods, Deployments, and Services.
|
||||
|
||||
kubectl delete deployment -l app=redis
|
||||
kubectl delete service -l app=redis
|
||||
kubectl delete deployment -l app=guestbook
|
||||
kubectl delete service -l app=guestbook
|
||||
|
||||
The responses should be:
|
||||
|
||||
deployment "redis-master" deleted
|
||||
deployment "redis-slave" deleted
|
||||
service "redis-master" deleted
|
||||
service "redis-slave" deleted
|
||||
deployment "frontend" deleted
|
||||
service "frontend" deleted
|
||||
|
||||
2. Query the list of Pods to verify that no Pods are running:
|
||||
|
||||
kubectl get pods
|
||||
|
||||
The response should be this:
|
||||
|
||||
No resources found.
|
||||
|
||||
{{% /capture %}}
|
||||
|
||||
{{% capture whatsnext %}}
|
||||
* Complete the [Kubernetes Basics](/docs/tutorials/kubernetes-basics/) Interactive Tutorials
|
||||
* Use Kubernetes to create a blog using [Persistent Volumes for MySQL and Wordpress](/docs/tutorials/stateful-application/mysql-wordpress-persistent-volume/#visit-your-new-wordpress-blog)
|
||||
* Read more about [connecting applications](/docs/concepts/services-networking/connect-applications-service/)
|
||||
* Read more about [Managing Resources](/docs/concepts/cluster-administration/manage-deployment/#using-labels-effectively)
|
||||
{{% /capture %}}
|
||||
|
||||
|
||||
@@ -0,0 +1,36 @@
|
||||
apiVersion: apps/v1 # for versions before 1.9.0 use apps/v1beta2
|
||||
kind: Deployment
|
||||
metadata:
|
||||
name: frontend
|
||||
spec:
|
||||
selector:
|
||||
matchLabels:
|
||||
app: guestbook
|
||||
tier: frontend
|
||||
replicas: 3
|
||||
template:
|
||||
metadata:
|
||||
labels:
|
||||
app: guestbook
|
||||
tier: frontend
|
||||
spec:
|
||||
containers:
|
||||
- name: php-redis
|
||||
image: gcr.io/google-samples/gb-frontend:v4
|
||||
resources:
|
||||
requests:
|
||||
cpu: 100m
|
||||
memory: 100Mi
|
||||
env:
|
||||
- name: GET_HOSTS_FROM
|
||||
value: dns
|
||||
# Using `GET_HOSTS_FROM=dns` requires your cluster to
|
||||
# provide a dns service. As of Kubernetes 1.3, DNS is a built-in
|
||||
# service launched automatically. However, if the cluster you are using
|
||||
# does not have a built-in DNS service, you can instead
|
||||
# access an environment variable to find the master
|
||||
# service's host. To do so, comment out the 'value: dns' line above, and
|
||||
# uncomment the line below:
|
||||
# value: env
|
||||
ports:
|
||||
- containerPort: 80
|
||||
@@ -0,0 +1,18 @@
|
||||
apiVersion: v1
|
||||
kind: Service
|
||||
metadata:
|
||||
name: frontend
|
||||
labels:
|
||||
app: guestbook
|
||||
tier: frontend
|
||||
spec:
|
||||
# comment or delete the following line if you want to use a LoadBalancer
|
||||
type: NodePort
|
||||
# if your cluster supports it, uncomment the following to automatically create
|
||||
# an external load-balanced IP for the frontend service.
|
||||
# type: LoadBalancer
|
||||
ports:
|
||||
- port: 80
|
||||
selector:
|
||||
app: guestbook
|
||||
tier: frontend
|
||||
+27
@@ -0,0 +1,27 @@
|
||||
apiVersion: apps/v1 # for versions before 1.9.0 use apps/v1beta2
|
||||
kind: Deployment
|
||||
metadata:
|
||||
name: redis-master
|
||||
spec:
|
||||
selector:
|
||||
matchLabels:
|
||||
app: redis
|
||||
role: master
|
||||
tier: backend
|
||||
replicas: 1
|
||||
template:
|
||||
metadata:
|
||||
labels:
|
||||
app: redis
|
||||
role: master
|
||||
tier: backend
|
||||
spec:
|
||||
containers:
|
||||
- name: master
|
||||
image: k8s.gcr.io/redis:e2e # or just image: redis
|
||||
resources:
|
||||
requests:
|
||||
cpu: 100m
|
||||
memory: 100Mi
|
||||
ports:
|
||||
- containerPort: 6379
|
||||
@@ -0,0 +1,16 @@
|
||||
apiVersion: v1
|
||||
kind: Service
|
||||
metadata:
|
||||
name: redis-master
|
||||
labels:
|
||||
app: redis
|
||||
role: master
|
||||
tier: backend
|
||||
spec:
|
||||
ports:
|
||||
- port: 6379
|
||||
targetPort: 6379
|
||||
selector:
|
||||
app: redis
|
||||
role: master
|
||||
tier: backend
|
||||
@@ -0,0 +1,38 @@
|
||||
apiVersion: apps/v1 # for versions before 1.9.0 use apps/v1beta2
|
||||
kind: Deployment
|
||||
metadata:
|
||||
name: redis-slave
|
||||
spec:
|
||||
selector:
|
||||
matchLabels:
|
||||
app: redis
|
||||
role: slave
|
||||
tier: backend
|
||||
replicas: 2
|
||||
template:
|
||||
metadata:
|
||||
labels:
|
||||
app: redis
|
||||
role: slave
|
||||
tier: backend
|
||||
spec:
|
||||
containers:
|
||||
- name: slave
|
||||
image: gcr.io/google_samples/gb-redisslave:v1
|
||||
resources:
|
||||
requests:
|
||||
cpu: 100m
|
||||
memory: 100Mi
|
||||
env:
|
||||
- name: GET_HOSTS_FROM
|
||||
value: dns
|
||||
# Using `GET_HOSTS_FROM=dns` requires your cluster to
|
||||
# provide a dns service. As of Kubernetes 1.3, DNS is a built-in
|
||||
# service launched automatically. However, if the cluster you are using
|
||||
# does not have a built-in DNS service, you can instead
|
||||
# access an environment variable to find the master
|
||||
# service's host. To do so, comment out the 'value: dns' line above, and
|
||||
# uncomment the line below:
|
||||
# value: env
|
||||
ports:
|
||||
- containerPort: 6379
|
||||
@@ -0,0 +1,15 @@
|
||||
apiVersion: v1
|
||||
kind: Service
|
||||
metadata:
|
||||
name: redis-slave
|
||||
labels:
|
||||
app: redis
|
||||
role: slave
|
||||
tier: backend
|
||||
spec:
|
||||
ports:
|
||||
- port: 6379
|
||||
selector:
|
||||
app: redis
|
||||
role: slave
|
||||
tier: backend
|
||||
@@ -0,0 +1,427 @@
|
||||
---
|
||||
title: Hello Minikube
|
||||
content_template: templates/tutorial
|
||||
---
|
||||
|
||||
{{% 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.
|
||||
|
||||
* [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 %}}
|
||||
|
||||
|
||||
@@ -0,0 +1,9 @@
|
||||
var http = require('http');
|
||||
|
||||
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);
|
||||
Reference in New Issue
Block a user