Fix merge conflicts, plus some more cleanup

This commit is contained in:
lucperkins
2018-07-05 13:50:44 -07:00
539 changed files with 130871 additions and 11057 deletions
-4
View File
@@ -1,4 +0,0 @@
FROM node:6.9.2
EXPOSE 8080
COPY server.js .
CMD node server.js
@@ -95,7 +95,7 @@ You can follow the steps below to configure a Redis cache using data stored in a
1. Create the pod:
```shell
kubectl create -f https://k8s.io/tutorials/configuration/configmap/redis/redis-pod.yaml
kubectl create -f https://k8s.io/docs/tutorials/configuration/configmap/redis/redis-pod.yaml
```
In the example, the config volume is mounted at `/redis-master`.
@@ -1,19 +0,0 @@
apiVersion: apps/v1
kind: Deployment
metadata:
name: nginx-deployment
spec:
selector:
matchLabels:
app: nginx
replicas: 2
template:
metadata:
labels:
app: nginx
spec:
containers:
- name: nginx
image: nginx:1.8 # Update the version of nginx from 1.7.9 to 1.8
ports:
- containerPort: 80
-21
View File
@@ -1,21 +0,0 @@
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
+9 -5
View File
@@ -82,7 +82,7 @@ Use Homebrew to download the `kubectl` command-line tool, which you can
use to interact with Kubernetes clusters:
```shell
brew install kubectl
brew install kubernetes-cli
```
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
@@ -148,7 +148,7 @@ minikube dashboard
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" >}}
{{< codenew language="js" file="minikube/server.js" >}}
Run your application:
@@ -168,7 +168,7 @@ Create a file, also in the `hellonode` folder, named `Dockerfile`. A Dockerfile
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" >}}
{{< codenew language="conf" file="minikube/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
@@ -183,8 +183,10 @@ sure you are using the Minikube Docker daemon:
eval $(minikube docker-env)
```
{{< note >}}
**Note:** Later, when you no longer wish to use the Minikube host, you can undo
this change by running `eval $(minikube docker-env -u)`.
{{< /note >}}
Build your Docker image, using the Minikube Docker daemon (mind the trailing dot):
@@ -204,10 +206,12 @@ 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:
Pod runs a Container based on your `hello-node:v1` Docker image. Set the
`--image-pull-policy` flag to `Never` to always use the local image, rather than
pulling it from your Docker registry (since you haven't pushed it there):
```shell
kubectl run hello-node --image=hello-node:v1 --port=8080
kubectl run hello-node --image=hello-node:v1 --port=8080 --image-pull-policy=Never
```
View the Deployment:
+18 -20
View File
@@ -35,7 +35,7 @@ For more information, see [Pods](/docs/concepts/workloads/pods/pod/).
The simplest Pod definition describes the deployment of a single container. For example, an nginx web server Pod might be defined as:
{{< code file="pod-nginx.yaml" >}}
{{< codenew file="pods/simple-pod.yaml" >}}
A Pod definition is a declaration of a _desired state_. Desired state is a very important concept in the Kubernetes model. Many things present a desired state to the system, and Kubernetes' ensures that the current state matches the desired state. For example, when you create a Pod and declare that the containers in it to be running. If the containers happen not to be running because of a program failure, Kubernetes continues to (re-)create the Pod in order to drive the pod to the desired state. This process continues until you delete the Pod.
@@ -44,10 +44,10 @@ For more information, see [Kubernetes Design Documents and Proposals](https://gi
#### Pod Management
Create a Pod containing an nginx server ([pod-nginx.yaml](/docs/tutorials/pod-nginx.yaml)):
Create a Pod containing an nginx server ([simple-pod.yaml](/examples/pods/simple-pod.yaml)):
```shell
$ kubectl create -f docs/tutorials/pod-nginx.yaml
$ kubectl create -f https://k8s.io/examples/pods/simple-pod.yaml
```
List all Pods:
@@ -85,27 +85,25 @@ In this example you can create a Redis Pod with a named volume, and a volume mou
1. Define a Volume:
```yaml
volumes:
- name: redis-persistent-storage
emptyDir: {}
```
```yaml
volumes:
- name: redis-storage
emptyDir: {}
```
2. Define a Volume mount within a container definition:
1. Define a Volume mount within a container definition:
```yaml
volumeMounts:
   # name must match the volume name defined in volumes
   - name: redis-persistent-storage
# mount path within the container
mountPath: /data/redis
```
```yaml
volumeMounts:
 # name must match the volume name defined in volumes
 - name: redis-storage
# mount path within the container
mountPath: /data/redis
```
Here is an example of Redis Pod definition with a persistent storage volume ([redis.yaml](/examples/pods/storage/redis.yaml)):
Here is an example of Redis Pod definition with a persistent storage volume ([pod-redis.yaml](/docs/tutorials/pod-redis.yaml)):
{{< code file="pod-redis.yaml" >}}
{{< codenew file="pods/storage/redis.yaml" >}}
Where:
+24 -23
View File
@@ -5,6 +5,8 @@ reviewers:
title: Kubernetes 201
---
{{< toc >}}
## Labels, Deployments, Services and Health Checking
If you went through [Kubernetes 101](/docs/tutorials/k8s101/), you learned about kubectl, Pods, Volumes, and multiple containers.
@@ -15,9 +17,6 @@ scaling.
In order for the kubectl usage examples to work, make sure you have an examples directory locally, either from [a release](https://github.com/kubernetes/kubernetes/releases) or [the source](https://github.com/kubernetes/kubernetes).
* TOC
{{< toc >}}
## Labels
@@ -27,29 +26,29 @@ To add a label, add a labels section under metadata in the Pod definition:
```yaml
labels:
app: nginx
env: test
```
For example, here is the nginx Pod definition with labels ([pod-nginx-with-label.yaml](/docs/tutorials/pod-nginx-with-label.yaml)):
For example, here is the nginx Pod definition with labels ([pod-nginx.yaml](/examples/pods/pod-nginx.yaml)):
{{< code file="pod-nginx-with-label.yaml" >}}
{{< codenew file="pods/pod-nginx.yaml" >}}
Create the labeled Pod ([pod-nginx-with-label.yaml](/docs/tutorials/pod-nginx-with-label.yaml)):
Create the labeled Pod:
```shell
kubectl create -f https://k8s.io/docs/tutorials/pod-nginx-with-label.yaml
kubectl create -f https://k8s.io/examples/pods/pod-nginx.yaml
```
List all Pods with the label `app=nginx`:
List all Pods with the label `env=test`:
```shell
kubectl get pods -l app=nginx
kubectl get pods -l env=test
```
Delete the Pod by label:
```shell
kubectl delete pod -l app=nginx
kubectl delete pod -l env=test
```
For more information, see [Labels](/docs/concepts/overview/working-with-objects/labels/).
@@ -66,7 +65,7 @@ A Deployment object defines a Pod creation template (a "cookie-cutter" if you wi
Here is a Deployment that instantiates two nginx Pods:
{{< code file="deployment.yaml" >}}
{{< codenew file="application/deployment.yaml" >}}
### Deployment Management
@@ -74,7 +73,7 @@ Here is a Deployment that instantiates two nginx Pods:
Create an nginx Deployment:
```shell
kubectl create -f https://k8s.io/docs/tutorials/deployment.yaml
kubectl create -f https://k8s.io/examples/application/deployment.yaml
```
List all Deployments:
@@ -92,10 +91,10 @@ kubectl get pods -l app=nginx
Upgrade the nginx container from 1.7.9 to 1.8 by changing the Deployment and calling `apply`. The following config
contains the desired changes:
{{< code file="deployment-update.yaml" >}}
{{< codenew file="application/deployment-update.yaml" >}}
```shell
kubectl apply -f https://k8s.io/docs/tutorials/deployment-update.yaml
kubectl apply -f https://k8s.io/examples/application/deployment-update.yaml
```
Watch the Deployment create Pods with new names and delete the old Pods:
@@ -117,17 +116,17 @@ For more information, such as how to rollback Deployment changes to a previous v
Once you have a replicated set of Pods, you need an abstraction that enables connectivity between the layers of your application. For example, if you have a Deployment managing your backend jobs, you don't want to have to reconfigure your front-ends whenever you re-scale your backends. Likewise, if the Pods in your backends are scheduled (or rescheduled) onto different machines, you can't be required to re-configure your front-ends. In Kubernetes, the service abstraction achieves these goals. A service provides a way to refer to a set of Pods (selected by labels) with a single static IP address. It may also provide load balancing, if supported by the provider.
For example, here is a service that balances across the Pods created in the previous nginx Deployment example ([service.yaml](/docs/tutorials/service.yaml)):
For example, here is a service that balances across the Pods created in the previous nginx Deployment example ([service.yaml](/examples/service/nginx-service.yaml)):
{{< code file="service.yaml" >}}
{{< codenew file="service/nginx-service.yaml" >}}
### Service Management
Create an nginx service ([service.yaml](/docs/tutorials/service.yaml)):
Create an nginx Service:
```shell
kubectl create -f https://k8s.io/docs/tutorials/service.yaml
kubectl create -f https://k8s.io/examples/service/nginx-service.yaml
```
List all services:
@@ -222,13 +221,15 @@ In all cases, if the Kubelet discovers a failure the container is restarted.
The container health checks are configured in the `livenessProbe` section of your container config. There you can also specify an `initialDelaySeconds` that is a grace period from when the container is started to when health checks are performed, to enable your container to perform any necessary initialization.
Here is an example config for a Pod with an HTTP health check ([pod-with-http-healthcheck.yaml](/docs/tutorials/pod-with-http-healthcheck.yaml)):
Here is an example config for a Pod with an HTTP health check
([pod-with-http-healthcheck.yaml](/examples/pods/probe/pod-with-http-healthcheck.yaml)):
{{< code file="pod-with-http-healthcheck.yaml" >}}
{{< codenew file="pods/probe/pod-with-http-healthcheck.yaml" >}}
And here is an example config for a Pod with a TCP Socket health check ([pod-with-tcp-socket-healthcheck.yaml](/docs/tutorials/pod-with-tcp-socket-healthcheck.yaml)):
And here is an example config for a Pod with a TCP Socket health check
([pod-with-tcp-socket-healthcheck.yaml](/examples/pods/probe/pod-with-tcp-socket-healthcheck.yaml)):
{{< code file="pod-with-tcp-socket-healthcheck.yaml" >}}
{{< codenew file="pods/probe/pod-with-tcp-socket-healthcheck.yaml" >}}
For more information about health checking, see [Container Probes](/docs/user-guide/pod-states/#container-probes).
@@ -1,12 +0,0 @@
apiVersion: v1
kind: Pod
metadata:
name: nginx
labels:
app: nginx
spec:
containers:
- name: nginx
image: nginx
ports:
- containerPort: 80
-10
View File
@@ -1,10 +0,0 @@
apiVersion: v1
kind: Pod
metadata:
name: nginx
spec:
containers:
- name: nginx
image: nginx:1.7.9
ports:
- containerPort: 80
-14
View File
@@ -1,14 +0,0 @@
apiVersion: v1
kind: Pod
metadata:
name: redis
spec:
containers:
- name: redis
image: redis
volumeMounts:
- name: redis-persistent-storage
mountPath: /data/redis
volumes:
- name: redis-persistent-storage
emptyDir: {}
@@ -1,20 +0,0 @@
apiVersion: v1
kind: Pod
metadata:
name: pod-with-http-healthcheck
spec:
containers:
- name: nginx
image: nginx
# defines the health checking
livenessProbe:
# an http probe
httpGet:
path: /_status/healthz
port: 80
# length of time to wait for a pod to initialize
# after pod startup, before applying health checking
initialDelaySeconds: 30
timeoutSeconds: 1
ports:
- containerPort: 80
@@ -1,19 +0,0 @@
apiVersion: v1
kind: Pod
metadata:
name: pod-with-tcp-socket-healthcheck
spec:
containers:
- name: redis
image: redis
# defines the health checking
livenessProbe:
# a TCP socket probe
tcpSocket:
port: 6379
# length of time to wait for a pod to initialize
# after pod startup, before applying health checking
initialDelaySeconds: 30
timeoutSeconds: 1
ports:
- containerPort: 6379
-9
View File
@@ -1,9 +0,0 @@
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);
-16
View File
@@ -1,16 +0,0 @@
apiVersion: v1
kind: Service
metadata:
name: nginx-service
spec:
ports:
- port: 8000 # the port that this service should serve on
# the container on each pod to connect to, can be a name
# (e.g. 'www') or a number (e.g. 80)
targetPort: 80
protocol: TCP
# just like the selector in the deployment,
# but this time it identifies the set of pods to load balance
# traffic to.
selector:
app: nginx
@@ -1,17 +0,0 @@
# This is an image with Percona XtraBackup, mysql-client and ncat installed.
FROM debian:jessie
RUN \
echo "deb http://repo.percona.com/apt jessie main" > /etc/apt/sources.list.d/percona.list \
&& echo "deb-src http://repo.percona.com/apt jessie main" >> /etc/apt/sources.list.d/percona.list \
&& apt-key adv --keyserver keys.gnupg.net --recv-keys 8507EFA5
RUN \
apt-get update && apt-get install -y --no-install-recommends \
percona-xtrabackup-24 \
mysql-client \
nmap \
&& rm -rf /var/lib/apt/lists/*
CMD ["bash"]
@@ -60,7 +60,7 @@ example presented in the
It creates a [Headless Service](/docs/concepts/services-networking/service/#headless-services),
`nginx`, to publish the IP addresses of Pods in the StatefulSet, `web`.
{{< code file="web.yaml" >}}
{{< codenew file="application/web/web.yaml" >}}
Download the example above, and save it to a file named `web.yaml`
@@ -283,7 +283,8 @@ web-0
web-1
```
Note, if you instead see 403 Forbidden responses for the above curl command,
{{< note >}}
**Note:** If you instead see 403 Forbidden responses for the above curl command,
you will need to fix the permissions of the directory mounted by the `volumeMounts`
(due to a [bug when using hostPath volumes](https://github.com/kubernetes/kubernetes/issues/2630)) with:
@@ -292,6 +293,7 @@ for i in 0 1; do kubectl exec web-$i -- chmod 755 /usr/share/nginx/html; done
```
before retrying the curl command above.
{{< /note >}}
In one terminal, watch the StatefulSet's Pods.
@@ -927,9 +929,9 @@ terminate all Pods in parallel, and not to wait for Pods to become Running
and Ready or completely terminated prior to launching or terminating another
Pod.
{{< code file="webp.yaml" >}}
{{< codenew file="application/web/web-parallel.yaml" >}}
Download the example above, and save it to a file named `webp.yaml`
Download the example above, and save it to a file named `web-parallel.yaml`
This manifest is identical to the one you downloaded above except that the `.spec.podManagementPolicy`
of the `web` StatefulSet is set to `Parallel`.
@@ -943,7 +945,7 @@ kubectl get po -l app=nginx -w
In another terminal, create the StatefulSet and Service in the manifest.
```shell
kubectl create -f webp.yaml
kubectl create -f web-parallel.yaml
service "nginx" created
statefulset "web" created
```
@@ -7,15 +7,19 @@ weight: 30
---
{{% capture overview %}}
This tutorial shows you how to develop a native cloud [Cassandra](http://cassandra.apache.org/) deployment on Kubernetes. In this instance, a custom Cassandra `SeedProvider` enables Cassandra to discover new Cassandra nodes as they join the cluster.
This tutorial shows you how to develop a native cloud [Cassandra](http://cassandra.apache.org/) deployment on Kubernetes. In this example, a custom Cassandra `SeedProvider` enables Cassandra to discover new Cassandra nodes as they join the cluster.
Deploying stateful distributed applications, like Cassandra, within a clustered environment can be challenging. StatefulSets greatly simplify this process. Please read about [StatefulSets](/docs/concepts/workloads/controllers/statefulset/) for more information about the features used in this tutorial.
It can be challenging to deploy stateful distributed applications like Cassandra within a clustered environment. StatefulSets greatly simplify this process. Please read about [StatefulSets](/docs/concepts/workloads/controllers/statefulset/) for more information about the features used in this tutorial.
**Cassandra Docker**
**Cassandra on Docker**
The Pods use the [`gcr.io/google-samples/cassandra:v13`](https://github.com/kubernetes/examples/blob/master/cassandra/image/Dockerfile)
image from Google's [container registry](https://cloud.google.com/container-registry/docs/).
The docker image above is based on [debian-base](https://github.com/kubernetes/kubernetes/tree/master/build/debian-base) and includes OpenJDK 8. This image includes a standard Cassandra installation from the Apache Debian repo. By using environment variables you can change values that are inserted into `cassandra.yaml`.
The Docker image above is based on [debian-base](https://github.com/kubernetes/kubernetes/tree/master/build/debian-base)
and includes OpenJDK 8.
This image includes a standard Cassandra installation from the Apache Debian repo.
By using environment variables you can change values that are inserted into `cassandra.yaml`.
| ENV VAR | DEFAULT VALUE |
| ------------- |:-------------: |
@@ -38,7 +42,8 @@ To complete this tutorial, you should already have a basic familiarity with [Pod
* [Install and Configure](/docs/tasks/tools/install-kubectl/) the `kubectl` command line
* Download [cassandra-service.yaml](/docs/tutorials/stateful-application/cassandra/cassandra-service.yaml) and [cassandra-statefulset.yaml](/docs/tutorials/stateful-application/cassandra/cassandra-statefulset.yaml)
* Download [cassandra-service.yaml](/examples/application/cassandra/cassandra-service.yaml)
and [cassandra-statefulset.yaml](/examples/application/cassandra/cassandra-statefulset.yaml)
* Have a supported Kubernetes Cluster running
@@ -65,15 +70,15 @@ A Kubernetes [Service](/docs/concepts/services-networking/service/) describes a
The following `Service` is used for DNS lookups between Cassandra Pods and clients within the Kubernetes Cluster.
{{< codenew file="application/cassandra/cassandra-service.yaml" >}}
1. Launch a terminal window in the directory you downloaded the manifest files.
2. Create a `Service` to track all Cassandra StatefulSet Nodes from the `cassandra-service.yaml` file:
1. Create a `Service` to track all Cassandra StatefulSet Nodes from the `cassandra-service.yaml` file:
```bash
kubectl create -f cassandra-service.yaml
kubectl create -f https://k8s.io/examples/application/cassandra/cassandra-service.yaml
```
{{< code file="cassandra/cassandra-service.yaml" >}}
### Validating (optional)
Get the Cassandra `Service`.
@@ -99,15 +104,15 @@ The StatefulSet manifest, included below, creates a Cassandra ring that consists
**Note:** This example uses the default provisioner for Minikube. Please update the following StatefulSet for the cloud you are working with.
{{< /note >}}
{{< codenew file="application/cassandra/cassandra-statefulset.yaml" >}}
1. Update the StatefulSet if necessary.
2. Create the Cassandra StatefulSet from the `cassandra-statefulset.yaml` file:
1. Create the Cassandra StatefulSet from the `cassandra-statefulset.yaml` file:
```bash
kubectl create -f cassandra-statefulset.yaml
kubectl create -f https://k8s.io/examples/application/cassandra/cassandra-statefulset.yaml
```
{{< code file="cassandra/cassandra-statefulset.yaml" >}}
## Validating The Cassandra StatefulSet
1. Get the Cassandra StatefulSet:
@@ -125,7 +130,7 @@ The StatefulSet manifest, included below, creates a Cassandra ring that consists
The StatefulSet resource deploys Pods sequentially.
2. Get the Pods to see the ordered creation status:
1. Get the Pods to see the ordered creation status:
```bash
kubectl get pods -l="app=cassandra"
@@ -204,7 +209,7 @@ Use `kubectl edit` to modify the size of a Cassandra StatefulSet.
The StatefulSet now contains 4 Pods.
3. Get the Cassandra StatefulSet to verify:
1. Get the Cassandra StatefulSet to verify:
```bash
kubectl get statefulset cassandra
@@ -236,7 +241,7 @@ Deleting or scaling a StatefulSet down does not delete the volumes associated wi
&& kubectl delete pvc -l app=cassandra
```
2. Run the following command to delete the Cassandra `Service`.
1. Run the following command to delete the Cassandra `Service`.
```bash
kubectl delete service -l app=cassandra
@@ -245,6 +250,7 @@ Deleting or scaling a StatefulSet down does not delete the volumes associated wi
{{% /capture %}}
{{% capture whatsnext %}}
* Learn how to [Scale a StatefulSet](/docs/tasks/run-application/scale-stateful-set/).
* Learn more about the [KubernetesSeedProvider](https://github.com/kubernetes/examples/blob/master/cassandra/java/src/main/java/io/k8s/cassandra/KubernetesSeedProvider.java)
* See more custom [Seed Provider Configurations](https://git.k8s.io/examples/cassandra/java/README.md)
@@ -1,12 +0,0 @@
apiVersion: v1
kind: Service
metadata:
labels:
app: cassandra
name: cassandra
spec:
clusterIP: None
ports:
- port: 9042
selector:
app: cassandra
@@ -1,100 +0,0 @@
apiVersion: apps/v1
kind: StatefulSet
metadata:
name: cassandra
labels:
app: cassandra
spec:
serviceName: cassandra
replicas: 3
selector:
matchLabels:
app: cassandra
template:
metadata:
labels:
app: cassandra
spec:
terminationGracePeriodSeconds: 1800
containers:
- name: cassandra
image: gcr.io/google-samples/cassandra:v13
imagePullPolicy: Always
ports:
- containerPort: 7000
name: intra-node
- containerPort: 7001
name: tls-intra-node
- containerPort: 7199
name: jmx
- containerPort: 9042
name: cql
resources:
limits:
cpu: "500m"
memory: 1Gi
requests:
cpu: "500m"
memory: 1Gi
securityContext:
capabilities:
add:
- IPC_LOCK
lifecycle:
preStop:
exec:
command:
- /bin/sh
- -c
- nodetool drain
env:
- name: MAX_HEAP_SIZE
value: 512M
- name: HEAP_NEWSIZE
value: 100M
- name: CASSANDRA_SEEDS
value: "cassandra-0.cassandra.default.svc.cluster.local"
- name: CASSANDRA_CLUSTER_NAME
value: "K8Demo"
- name: CASSANDRA_DC
value: "DC1-K8Demo"
- name: CASSANDRA_RACK
value: "Rack1-K8Demo"
- name: POD_IP
valueFrom:
fieldRef:
fieldPath: status.podIP
readinessProbe:
exec:
command:
- /bin/bash
- -c
- /ready-probe.sh
initialDelaySeconds: 15
timeoutSeconds: 5
# These volume mounts are persistent. They are like inline claims,
# but not exactly because the names need to match exactly one of
# the stateful pod volumes.
volumeMounts:
- name: cassandra-data
mountPath: /cassandra_data
# These are converted to volume claims by the controller
# and mounted at the paths mentioned above.
# do not use these in production until ssd GCEPersistentDisk or other ssd pd
volumeClaimTemplates:
- metadata:
name: cassandra-data
spec:
accessModes: [ "ReadWriteOnce" ]
storageClassName: fast
resources:
requests:
storage: 1Gi
---
kind: StorageClass
apiVersion: storage.k8s.io/v1
metadata:
name: fast
provisioner: k8s.io/minikube-hostpath
parameters:
type: pd-ssd
@@ -36,9 +36,9 @@ A [PersistentVolume](/docs/concepts/storage/persistent-volumes/) (PV) is a piece
Download the following configuration files:
1. [mysql-deployment.yaml](/docs/tutorials/stateful-application/mysql-wordpress-persistent-volume/mysql-deployment.yaml)
1. [mysql-deployment.yaml](/examples/application/wordpress/mysql-deployment.yaml)
1. [wordpress-deployment.yaml](/docs/tutorials/stateful-application/mysql-wordpress-persistent-volume/wordpress-deployment.yaml)
1. [wordpress-deployment.yaml](/examples/application/wordpress/wordpress-deployment.yaml)
{{% /capture %}}
@@ -71,13 +71,13 @@ A [Secret](/docs/concepts/configuration/secret/) is an object that stores a piec
1. Create the Secret object from the following command. You will need to replace
`YOUR_PASSWORD` with the password you want to use.
```
```shell
kubectl create secret generic mysql-pass --from-literal=password=YOUR_PASSWORD
```
2. Verify that the Secret exists by running the following command:
```
```shell
kubectl get secrets
```
@@ -96,18 +96,18 @@ A [Secret](/docs/concepts/configuration/secret/) is an object that stores a piec
The following manifest describes a single-instance MySQL Deployment. The MySQL container mounts the PersistentVolume at /var/lib/mysql. The `MYSQL_ROOT_PASSWORD` environment variable sets the database password from the Secret.
{{< code file="mysql-wordpress-persistent-volume/mysql-deployment.yaml" >}}
{{< codenew file="application/wordpress/mysql-deployment.yaml" >}}
1. Deploy MySQL from the `mysql-deployment.yaml` file:
```
kubectl create -f mysql-deployment.yaml
```shell
kubectl create -f https://k8s.io/examples/application/wordpress/mysql-deployment.yaml
```
2. Verify that a PersistentVolume got dynamically provisioned. Note that it can
It can take up to a few minutes for the PVs to be provisioned and bound.
```
```shell
kubectl get pvc
```
@@ -120,11 +120,11 @@ The following manifest describes a single-instance MySQL Deployment. The MySQL c
3. Verify that the Pod is running by running the following command:
```
```shell
kubectl get pods
```
**Note:** It can take up to a few minutes for the Pod's Status to be `RUNNING`.
{{< note >}}**Note:** It can take up to a few minutes for the Pod's Status to be `RUNNING`.{{< /note >}}
The response should be like this:
@@ -137,21 +137,21 @@ The following manifest describes a single-instance MySQL Deployment. The MySQL c
The following manifest describes a single-instance WordPress Deployment and Service. It uses many of the same features like a PVC for persistent storage and a Secret for the password. But it also uses a different setting: `type: LoadBalancer`. This setting exposes WordPress to traffic from outside of the cluster.
{{< code file="mysql-wordpress-persistent-volume/wordpress-deployment.yaml" >}}
{{< codenew file="application/wordpress/wordpress-deployment.yaml" >}}
1. Create a WordPress Service and Deployment from the `wordpress-deployment.yaml` file:
```
kubectl create -f wordpress-deployment.yaml
```shell
kubectl create -f https://k8s.io/examples/wordpress/wordpress-deployment.yaml
```
2. Verify that a PersistentVolume got dynamically provisioned:
```
```shell
kubectl get pvc
```
**Note:** It can take up to a few minutes for the PVs to be provisioned and bound.
{{< note >}}**Note:** It can take up to a few minutes for the PVs to be provisioned and bound.{{< /note >}}
The response should be like this:
@@ -162,7 +162,7 @@ The following manifest describes a single-instance WordPress Deployment and Serv
3. Verify that the Service is running by running the following command:
```
```shell
kubectl get services wordpress
```
@@ -173,15 +173,11 @@ The following manifest describes a single-instance WordPress Deployment and Serv
wordpress 10.0.0.89 <pending> 80:32406/TCP 4m
```
**Note:** Minikube can only expose Services through `NodePort`.
```
The EXTERNAL-IP is always <pending>.
```
{{< note >}}**Note:** Minikube can only expose Services through `NodePort`. The EXTERNAL-IP is always pending.{{< /note >}}
4. Run the following command to get the IP Address for the WordPress Service:
```
```shell
minikube service wordpress --url
```
@@ -207,20 +203,20 @@ The following manifest describes a single-instance WordPress Deployment and Serv
1. Run the following command to delete your Secret:
```
```shell
kubectl delete secret mysql-pass
```
2. Run the following commands to delete all Deployments and Services:
```
```shell
kubectl delete deployment -l app=wordpress
kubectl delete service -l app=wordpress
```
3. Run the following commands to delete the PersistentVolumeClaims. The dynamically provisioned PersistentVolumes will be automatically deleted.
```
```shell
kubectl delete pvc -l app=wordpress
```
@@ -235,4 +231,3 @@ The following manifest describes a single-instance WordPress Deployment and Serv
{{% /capture %}}
@@ -1,65 +0,0 @@
apiVersion: v1
kind: Service
metadata:
name: wordpress-mysql
labels:
app: wordpress
spec:
ports:
- port: 3306
selector:
app: wordpress
tier: mysql
clusterIP: None
---
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: mysql-pv-claim
labels:
app: wordpress
spec:
accessModes:
- ReadWriteOnce
resources:
requests:
storage: 20Gi
---
apiVersion: apps/v1 # for versions before 1.9.0 use apps/v1beta2
kind: Deployment
metadata:
name: wordpress-mysql
labels:
app: wordpress
spec:
selector:
matchLabels:
app: wordpress
tier: mysql
strategy:
type: Recreate
template:
metadata:
labels:
app: wordpress
tier: mysql
spec:
containers:
- image: mysql:5.6
name: mysql
env:
- name: MYSQL_ROOT_PASSWORD
valueFrom:
secretKeyRef:
name: mysql-pass
key: password
ports:
- containerPort: 3306
name: mysql
volumeMounts:
- name: mysql-persistent-storage
mountPath: /var/lib/mysql
volumes:
- name: mysql-persistent-storage
persistentVolumeClaim:
claimName: mysql-pv-claim
@@ -1,67 +0,0 @@
apiVersion: v1
kind: Service
metadata:
name: wordpress
labels:
app: wordpress
spec:
ports:
- port: 80
selector:
app: wordpress
tier: frontend
type: LoadBalancer
---
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: wp-pv-claim
labels:
app: wordpress
spec:
accessModes:
- ReadWriteOnce
resources:
requests:
storage: 20Gi
---
apiVersion: apps/v1 # for versions before 1.9.0 use apps/v1beta2
kind: Deployment
metadata:
name: wordpress
labels:
app: wordpress
spec:
selector:
matchLabels:
app: wordpress
tier: frontend
strategy:
type: Recreate
template:
metadata:
labels:
app: wordpress
tier: frontend
spec:
containers:
- image: wordpress:4.8-apache
name: wordpress
env:
- name: WORDPRESS_DB_HOST
value: wordpress-mysql
- name: WORDPRESS_DB_PASSWORD
valueFrom:
secretKeyRef:
name: mysql-pass
key: password
ports:
- containerPort: 80
name: wordpress
volumeMounts:
- name: wordpress-persistent-storage
mountPath: /var/www/html
volumes:
- name: wordpress-persistent-storage
persistentVolumeClaim:
claimName: wp-pv-claim
@@ -1,47 +0,0 @@
apiVersion: v1
kind: Service
metadata:
name: nginx
labels:
app: nginx
spec:
ports:
- port: 80
name: web
clusterIP: None
selector:
app: nginx
---
apiVersion: apps/v1
kind: StatefulSet
metadata:
name: web
spec:
serviceName: "nginx"
replicas: 2
selector:
matchLabels:
app: nginx
template:
metadata:
labels:
app: nginx
spec:
containers:
- name: nginx
image: k8s.gcr.io/nginx-slim:0.8
ports:
- containerPort: 80
name: web
volumeMounts:
- name: www
mountPath: /usr/share/nginx/html
volumeClaimTemplates:
- metadata:
name: www
spec:
accessModes: [ "ReadWriteOnce" ]
resources:
requests:
storage: 1Gi
@@ -1,47 +0,0 @@
apiVersion: v1
kind: Service
metadata:
name: nginx
labels:
app: nginx
spec:
ports:
- port: 80
name: web
clusterIP: None
selector:
app: nginx
---
apiVersion: apps/v1
kind: StatefulSet
metadata:
name: web
spec:
serviceName: "nginx"
podManagementPolicy: "Parallel"
replicas: 2
selector:
matchLabels:
app: nginx
template:
metadata:
labels:
app: nginx
spec:
containers:
- name: nginx
image: k8s.gcr.io/nginx-slim:0.8
ports:
- containerPort: 80
name: web
volumeMounts:
- name: www
mountPath: /usr/share/nginx/html
volumeClaimTemplates:
- metadata:
name: www
spec:
accessModes: [ "ReadWriteOnce" ]
resources:
requests:
storage: 1Gi
@@ -76,14 +76,14 @@ a [Service](/docs/concepts/services-networking/service/),
a [PodDisruptionBudget](/docs/concepts/workloads/pods/disruptions//#specifying-a-poddisruptionbudget),
and a [StatefulSet](/docs/concepts/workloads/controllers/statefulset/).
{{< code file="zookeeper.yaml" >}}
{{< codenew file="application/zookeeper/zookeeper.yaml" >}}
Open a terminal, and use the
[`kubectl apply`](/docs/reference/generated/kubectl/kubectl-commands/#apply) command to create the
manifest.
```shell
kubectl apply -f https://k8s.io/docs/tutorials/stateful-application/zookeeper.yaml
kubectl apply -f https://k8s.io/examples/application/zookeeper/zookeeper.yaml
```
This creates the `zk-hs` Headless Service, the `zk-cs` Service,
@@ -343,7 +343,7 @@ zk-0 0/1 Terminating 0 11m
Reapply the manifest in `zookeeper.yaml`.
```shell
kubectl apply -f https://k8s.io/docs/tutorials/stateful-application/zookeeper.yaml
kubectl apply -f https://k8s.io/examples/application/zookeeper/zookeeper.yaml
```
This creates the `zk` StatefulSet object, but the other API objects in the manifest are not modified because they already exist.
@@ -792,14 +792,14 @@ For a ZooKeeper server, liveness implies readiness. Therefore, the readiness
probe from the `zookeeper.yaml` manifest is identical to the liveness probe.
```yaml
readinessProbe:
exec:
command:
- sh
- -c
- "zookeeper-ready 2181"
initialDelaySeconds: 15
timeoutSeconds: 5
readinessProbe:
exec:
command:
- sh
- -c
- "zookeeper-ready 2181"
initialDelaySeconds: 15
timeoutSeconds: 5
```
Even though the liveness and readiness probes are identical, it is important
@@ -1065,7 +1065,11 @@ Attempt to drain the node on which `zk-2` is scheduled.
```shell
kubectl drain $(kubectl get pod zk-2 --template {{.spec.nodeName}}) --ignore-daemonsets --force --delete-local-data
```
The output:
```
node "kubernetes-minion-group-i4c4" already cordoned
WARNING: Deleting pods not managed by ReplicationController, ReplicaSet, Job, or DaemonSet: fluentd-cloud-logging-kubernetes-minion-group-i4c4, kube-proxy-kubernetes-minion-group-i4c4; Ignoring DaemonSet-managed pods: node-problem-detector-v0.1-dyrog
pod "heapster-v1.2.0-2604621511-wht1r" deleted
@@ -1079,7 +1083,9 @@ Uncordon the second node to allow `zk-2` to be rescheduled.
```shell
kubectl uncordon kubernetes-minion-group-ixsl
```
```
node "kubernetes-minion-group-ixsl" uncordoned
```
@@ -1089,10 +1095,11 @@ You can use `kubectl drain` in conjunction with `PodDisruptionBudgets` to ensure
{{% capture cleanup %}}
- Use `kubectl uncordon` to uncordon all the nodes in your cluster.
- You will need to delete the persistent storage media for the PersistentVolumes
used in this tutorial. Follow the necessary steps, based on your environment,
storage configuration, and provisioning method, to ensure that all storage is
reclaimed.
{{% /capture %}}
- Use `kubectl uncordon` to uncordon all the nodes in your cluster.
- You will need to delete the persistent storage media for the PersistentVolumes
used in this tutorial. Follow the necessary steps, based on your environment,
storage configuration, and provisioning method, to ensure that all storage is
reclaimed.
{{% /capture %}}
@@ -1,133 +0,0 @@
apiVersion: v1
kind: Service
metadata:
name: zk-hs
labels:
app: zk
spec:
ports:
- port: 2888
name: server
- port: 3888
name: leader-election
clusterIP: None
selector:
app: zk
---
apiVersion: v1
kind: Service
metadata:
name: zk-cs
labels:
app: zk
spec:
ports:
- port: 2181
name: client
selector:
app: zk
---
apiVersion: policy/v1beta1
kind: PodDisruptionBudget
metadata:
name: zk-pdb
spec:
selector:
matchLabels:
app: zk
maxUnavailable: 1
---
apiVersion: apps/v1
kind: StatefulSet
metadata:
name: zk
spec:
selector:
matchLabels:
app: zk
serviceName: zk-hs
replicas: 3
updateStrategy:
type: RollingUpdate
podManagementPolicy: Parallel
template:
metadata:
labels:
app: zk
spec:
affinity:
podAntiAffinity:
requiredDuringSchedulingIgnoredDuringExecution:
- labelSelector:
matchExpressions:
- key: "app"
operator: In
values:
- zk
topologyKey: "kubernetes.io/hostname"
containers:
- name: kubernetes-zookeeper
imagePullPolicy: Always
image: "k8s.gcr.io/kubernetes-zookeeper:1.0-3.4.10"
resources:
requests:
memory: "1Gi"
cpu: "0.5"
ports:
- containerPort: 2181
name: client
- containerPort: 2888
name: server
- containerPort: 3888
name: leader-election
command:
- sh
- -c
- "start-zookeeper \
--servers=3 \
--data_dir=/var/lib/zookeeper/data \
--data_log_dir=/var/lib/zookeeper/data/log \
--conf_dir=/opt/zookeeper/conf \
--client_port=2181 \
--election_port=3888 \
--server_port=2888 \
--tick_time=2000 \
--init_limit=10 \
--sync_limit=5 \
--heap=512M \
--max_client_cnxns=60 \
--snap_retain_count=3 \
--purge_interval=12 \
--max_session_timeout=40000 \
--min_session_timeout=4000 \
--log_level=INFO"
readinessProbe:
exec:
command:
- sh
- -c
- "zookeeper-ready 2181"
initialDelaySeconds: 10
timeoutSeconds: 5
livenessProbe:
exec:
command:
- sh
- -c
- "zookeeper-ready 2181"
initialDelaySeconds: 10
timeoutSeconds: 5
volumeMounts:
- name: datadir
mountPath: /var/lib/zookeeper
securityContext:
runAsUser: 1000
fsGroup: 1000
volumeClaimTemplates:
- metadata:
name: datadir
spec:
accessModes: [ "ReadWriteOnce" ]
resources:
requests:
storage: 10Gi
@@ -1,21 +0,0 @@
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
@@ -28,12 +28,12 @@ This tutorial shows you how to build and deploy a simple, multi-tier web applica
{{< 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)
1. [redis-master-deployment.yaml](/examples/application/guestbook/redis-master-deployment.yaml)
1. [redis-master-service.yaml](/examples/application/guestbook/redis-master-service.yaml)
1. [redis-slave-deployment.yaml](/examples/application/guestbook/redis-slave-deployment.yaml)
1. [redis-slave-service.yaml](/examples/application/guestbook/redis-slave-service.yaml)
1. [frontend-deployment.yaml](/examples/application/guestbook/frontend-deployment.yaml)
1. [frontend-service.yaml](/examples/application/guestbook/frontend-service.yaml)
{{% /capture %}}
@@ -47,27 +47,34 @@ The guestbook application uses Redis to store its data. It writes its data to a
The manifest file, included below, specifies a Deployment controller that runs a single replica Redis master Pod.
{{< codenew file="application/guestbook/redis-master-deployment.yaml" >}}
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" >}}
1. Apply the Redis Master Deployment from the `redis-master-deployment.yaml` file:
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
```
```
kubectl apply -f https://k8s.io/examples/application/guestbook/redis-master-deployment.yaml
```
1. Query the list of Pods to verify that the Redis Master Pod is running:
```shell
kubectl get pods
```
The response should be similar to this:
```shell
NAME READY STATUS RESTARTS AGE
redis-master-1068406935-3lswp 1/1 Running 0 28s
```
1. Run the following command to view the logs from the Redis Master Pod:
```shell
kubectl logs -f POD-NAME
```
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 >}}
@@ -76,29 +83,32 @@ The manifest file, included below, specifies a Deployment controller that runs a
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.
{{< codenew file="application/guestbook/redis-master-service.yaml" >}}
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" >}}
```shell
kubectl apply -f https://k8s.io/examples/application/guestbook/redis-master-service.yaml
```
1. Query the list of Services to verify that the Redis Master Service is running:
```shell
kubectl get service
```
The response should be similar to this:
```shell
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
```
{{< 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
@@ -110,55 +120,55 @@ Deployments scale based off of the configurations set in the manifest file. In t
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.
{{< codenew file="application/guestbook/redis-slave-deployment.yaml" >}}
1. Apply the Redis Slave Deployment from the `redis-slave-deployment.yaml` file:
```
kubectl apply -f redis-slave-deployment.yaml
```
```shell
kubectl apply -f https://k8s.io/examples/application/guestbook/redis-slave-deployment.yaml
```
{{< code file="guestbook/redis-slave-deployment.yaml" >}}
1. Query the list of Pods to verify that the Redis Slave Pods are running:
2. Query the list of Pods to verify that the Redis Slave Pods are running:
```shell
kubectl get pods
```
```
kubectl get pods
```
The response should be similar to this:
The response should be similar to this:
```shell
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
```
```
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.
{{< codenew file="application/guestbook/redis-slave-service.yaml" >}}
1. Apply the Redis Slave Service from the following `redis-slave-service.yaml` file:
```
kubectl apply -f redis-slave-service.yaml
```
```shell
kubectl apply -f https://k8s.io/examples/application/guestbook/redis-slave-service.yaml
```
{{< code file="guestbook/redis-slave-service.yaml" >}}
1. Query the list of Services to verify that the Redis slave service is running:
2. Query the list of Services to verify that the Redis Slave Service is running:
```shell
kubectl get services
```
```
kubectl get services
```
The response should be similar to this:
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
```
```
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
@@ -166,28 +176,28 @@ The guestbook application has a web frontend serving the HTTP requests written i
### Creating the Guestbook Frontend Deployment
1. Apply the frontend Deployment from the following `frontend-deployment.yaml` file:
{{< codenew file="application/guestbook/frontend-deployment.yaml" >}}
```
kubectl apply -f frontend-deployment.yaml
```
1. Apply the frontend Deployment from the `frontend-deployment.yaml` file:
{{< code file="guestbook/frontend-deployment.yaml" >}}
```shell
kubectl apply -f https://k8s.io/examples/application/guestbook/frontend-deployment.yaml
```
2. Query the list of Pods to verify that the three frontend replicas are running:
1. Query the list of Pods to verify that the three frontend replicas are running:
```
kubectl get pods -l app=guestbook -l tier=frontend
```
```shell
kubectl get pods -l app=guestbook -l tier=frontend
```
The response should be similar to this:
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
```
```
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
@@ -199,29 +209,29 @@ If you want guests to be able to access your guestbook, you must configure the f
**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:
{{< codenew file="application/guestbook/frontend-service.yaml" >}}
```
kubectl apply -f frontend-service.yaml
```
{{< code file="guestbook/frontend-service.yaml" >}}
1. Apply the frontend Service from the `frontend-service.yaml` file:
2. Query the list of Services to verify that the frontend Service is running:
```shell
kubectl apply -f https://k8s.io/examples/application/guestbook/frontend-service.yaml
```
```
kubectl get services
```
1. Query the list of Services to verify that the frontend Service is running:
The response should be similar to this:
```shell
kubectl get services
```
```
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
```
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`
@@ -229,17 +239,17 @@ If you deployed this application to Minikube or a local cluster, you need to fin
1. Run the following command to get the IP address for the frontend Service.
```
minikube service frontend --url
```
```shell
minikube service frontend --url
```
The response should be similar to this:
The response should be similar to this:
```
http://192.168.99.100:31323
```
```
http://192.168.99.100:31323
```
2. Copy the IP address, and load the page in your browser to view your guestbook.
1. Copy the IP address, and load the page in your browser to view your guestbook.
### Viewing the Frontend Service via `LoadBalancer`
@@ -247,18 +257,18 @@ If you deployed the `frontend-service.yaml` manifest with type: `LoadBalancer` y
1. Run the following command to get the IP address for the frontend Service.
```
kubectl get service frontend
```
```shell
kubectl get service frontend
```
The response should be similar to this:
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
```
```
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.
1. Copy the external IP address, and load the page in your browser to view your guestbook.
## Scale the Web Frontend
@@ -266,52 +276,52 @@ Scaling up or down is easy because your servers are defined as a Service that us
1. Run the following command to scale up the number of frontend Pods:
```
kubectl scale deployment frontend --replicas=5
```
```shell
kubectl scale deployment frontend --replicas=5
```
2. Query the list of Pods to verify the number of frontend Pods running:
1. Query the list of Pods to verify the number of frontend Pods running:
```
kubectl get pods
```
```shell
kubectl get pods
```
The response should look similar to this:
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
```
```
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:
1. Run the following command to scale down the number of frontend Pods:
```
kubectl scale deployment frontend --replicas=2
```
```shell
kubectl scale deployment frontend --replicas=2
```
4. Query the list of Pods to verify the number of frontend Pods running:
1. Query the list of Pods to verify the number of frontend Pods running:
```
kubectl get pods
```
```shell
kubectl get pods
```
The response should look similar to this:
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
```
```
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 %}}
@@ -320,36 +330,36 @@ Deleting the Deployments and Services also deletes any running Pods. Use labels
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
```
```shell
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:
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
```
```
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:
1. Query the list of Pods to verify that no Pods are running:
```
kubectl get pods
```
The response should be this:
```shell
kubectl get pods
```
The response should be this:
```
No resources found.
```
```
No resources found.
```
{{% /capture %}}
{{% capture whatsnext %}}
@@ -1,38 +0,0 @@
apiVersion: apps/v1 # for versions before 1.9.0 use apps/v1beta2
kind: Deployment
metadata:
name: frontend
labels:
app: guestbook
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
@@ -1,18 +0,0 @@
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
@@ -1,29 +0,0 @@
apiVersion: apps/v1 # for versions before 1.9.0 use apps/v1beta2
kind: Deployment
metadata:
name: redis-master
labels:
app: redis
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
@@ -1,16 +0,0 @@
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
@@ -1,40 +0,0 @@
apiVersion: apps/v1 # for versions before 1.9.0 use apps/v1beta2
kind: Deployment
metadata:
name: redis-slave
labels:
app: redis
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
@@ -1,15 +0,0 @@
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