Polishing MySQL / WordPress Tutorial (#65)
* Polishing MySQL / WordPress Tutorial * Readability Edits and Initial Comments from Ahmet * Fix typo * Update README.md * Update README.md * Revisions from Ahmet's Comments PRs [#66](https://github.com/kubernetes/examples/pull/66) and [#67](https://github.com/kubernetes/examples/pull/67) update the manifest files with the new way to create the Secret. * Prereq links * Update mysql-deployment.yaml * Update wordpress-deployment.yaml
This commit is contained in:
parent
37e8f218c6
commit
f676e4d40a
|
@ -4,367 +4,194 @@
|
||||||
> https://kubernetes.io/docs/tutorials/stateful-application/mysql-wordpress-persistent-volume/.
|
> https://kubernetes.io/docs/tutorials/stateful-application/mysql-wordpress-persistent-volume/.
|
||||||
> Otherwise some of the URLs will not work properly.
|
> Otherwise some of the URLs will not work properly.
|
||||||
|
|
||||||
# Persistent Installation of MySQL and WordPress on Kubernetes
|
# Using Persistent Volumes with MySQL and WordPress
|
||||||
<!-- EXCLUDE_FROM_DOCS END -->
|
<!-- EXCLUDE_FROM_DOCS END -->
|
||||||
|
|
||||||
This example describes how to run a persistent installation of
|
{% capture overview %}
|
||||||
[WordPress](https://wordpress.org/) and
|
This tutorial shows you how to deploy a WordPress site and a MySQL database using Minikube. Both applications use PersistentVolumes and PersistentVolumeClaims to store data.
|
||||||
[MySQL](https://www.mysql.com/) on Kubernetes. We'll use the
|
|
||||||
[mysql](https://registry.hub.docker.com/_/mysql/) and
|
|
||||||
[wordpress](https://registry.hub.docker.com/_/wordpress/) official
|
|
||||||
[Docker](https://www.docker.com/) images for this installation. (The
|
|
||||||
WordPress image includes an Apache server).
|
|
||||||
|
|
||||||
Demonstrated Kubernetes Concepts:
|
A [PersistentVolume](https://kubernetes.io/docs/concepts/storage/persistent-volumes/) (PV) is is a piece of storage in the cluster that has been provisioned by an administrator., and a [PeristentVolumeClaim](https://kubernetes.io/docs/concepts/storage/persistent-volumes/#persistentvolumeclaims) (PVC) is an set amout of storage in a PV. PersistentVolumes and PeristentVolumeClaims are independent from Pod lifecycles and preserve data through restarting, rescheduling, and even deleting Pods.
|
||||||
|
|
||||||
* [Persistent Volumes](https://kubernetes.io/docs/concepts/storage/persistent-volumes/) to
|
**Warning:** This deployment is not suitable for production use cases, as it uses single instance WordPress and MySQL Pods. Consider using [WordPress Helm Chart](https://github.com/kubernetes/charts/tree/master/stable/wordpress) to deploy WordPress in production.
|
||||||
define persistent disks (disk lifecycle not tied to the Pods).
|
{: .warning}
|
||||||
* [Services](https://kubernetes.io/docs/concepts/services-networking/service/) to enable Pods to
|
|
||||||
locate one another.
|
|
||||||
* [External Load Balancers](https://kubernetes.io/docs/concepts/services-networking/service/#type-loadbalancer)
|
|
||||||
to expose Services externally.
|
|
||||||
* [Deployments](http://kubernetes.io/docs/user-guide/deployments/) to ensure Pods
|
|
||||||
stay up and running.
|
|
||||||
* [Secrets](http://kubernetes.io/docs/user-guide/secrets/) to store sensitive
|
|
||||||
passwords.
|
|
||||||
|
|
||||||
## Quickstart
|
{% endcapture %}
|
||||||
|
|
||||||
Put your desired MySQL password in a file called `password.txt` with
|
{% capture objectives %}
|
||||||
no trailing newline. The first `tr` command will remove the newline if
|
* Create a PersistentVolume
|
||||||
your editor added one.
|
* Create a Secret
|
||||||
|
* Deploy MySQL
|
||||||
|
* Deploy WordPress
|
||||||
|
* Clean up
|
||||||
|
|
||||||
**Note:** if your cluster enforces **_selinux_** and you will be using [Host Path](#host-path) for storage, then please follow this [extra step](#selinux).
|
{% endcapture %}
|
||||||
|
|
||||||
```shell
|
{% capture prerequisites %}
|
||||||
tr --delete '\n' <password.txt >.strippedpassword.txt && mv .strippedpassword.txt password.txt
|
|
||||||
kubectl create -f https://raw.githubusercontent.com/kubernetes/examples/master/mysql-wordpress-pd/local-volumes.yaml
|
|
||||||
kubectl create secret generic mysql-pass --from-file=password.txt
|
|
||||||
kubectl create -f https://raw.githubusercontent.com/kubernetes/examples/master/mysql-wordpress-pd/mysql-deployment.yaml
|
|
||||||
kubectl create -f https://raw.githubusercontent.com/kubernetes/examples/master/mysql-wordpress-pd/wordpress-deployment.yaml
|
|
||||||
```
|
|
||||||
|
|
||||||
## Table of Contents
|
{% include task-tutorial-prereqs.md %}
|
||||||
|
|
||||||
<!-- BEGIN MUNGE: GENERATED_TOC -->
|
Download the following configuration files:
|
||||||
|
|
||||||
- [Persistent Installation of MySQL and WordPress on Kubernetes](#persistent-installation-of-mysql-and-wordpress-on-kubernetes)
|
1. [local-volumes.yaml](https://kubernetes.io/docs/tutorials/stateful-application/mysql-wordpress-persistent-volume/local-volumes.yaml)
|
||||||
- [Quickstart](#quickstart)
|
|
||||||
- [Table of Contents](#table-of-contents)
|
|
||||||
- [Cluster Requirements](#cluster-requirements)
|
|
||||||
- [Decide where you will store your data](#decide-where-you-will-store-your-data)
|
|
||||||
- [Host Path](#host-path)
|
|
||||||
- [SELinux](#selinux)
|
|
||||||
- [GCE Persistent Disk](#gce-persistent-disk)
|
|
||||||
- [Create the MySQL Password Secret](#create-the-mysql-password-secret)
|
|
||||||
- [Deploy MySQL](#deploy-mysql)
|
|
||||||
- [Deploy WordPress](#deploy-wordpress)
|
|
||||||
- [Visit your new WordPress blog](#visit-your-new-wordpress-blog)
|
|
||||||
- [Take down and restart your blog](#take-down-and-restart-your-blog)
|
|
||||||
- [Next Steps](#next-steps)
|
|
||||||
|
|
||||||
<!-- END MUNGE: GENERATED_TOC -->
|
1. [mysql-deployment.yaml](https://kubernetes.io/docs/tutorials/stateful-application/mysql-wordpress-persistent-volume/mysql-deployment.yaml)
|
||||||
|
|
||||||
## Cluster Requirements
|
1. [wordpress-deployment.yaml](https://kubernetes.io/docs/tutorials/stateful-application/mysql-wordpress-persistent-volume//wordpress-deployment.yaml)
|
||||||
|
|
||||||
Kubernetes runs in a variety of environments and is inherently
|
{% endcapture %}
|
||||||
modular. Not all clusters are the same. These are the requirements for
|
|
||||||
this example.
|
|
||||||
|
|
||||||
* Kubernetes version 1.2 is required due to using newer features, such
|
{% capture lessoncontent %}
|
||||||
at PV Claims and Deployments. Run `kubectl version` to see your
|
|
||||||
cluster version.
|
|
||||||
* [Cluster DNS](https://github.com/kubernetes/dns) will be used for service discovery.
|
|
||||||
* An [external load balancer](https://kubernetes.io/docs/concepts/services-networking/service/#type-loadbalancer)
|
|
||||||
will be used to access WordPress.
|
|
||||||
* [Persistent Volume Claims](https://kubernetes.io/docs/concepts/storage/persistent-volumes/#persistentvolumeclaims)
|
|
||||||
are used. You must create Persistent Volumes in your cluster to be
|
|
||||||
claimed. This example demonstrates how to create two types of
|
|
||||||
volumes, but any volume is sufficient.
|
|
||||||
|
|
||||||
Consult a
|
## Create a PersistentVolume
|
||||||
[Getting Started Guide](http://kubernetes.io/docs/getting-started-guides/)
|
|
||||||
to set up a cluster and the
|
|
||||||
[kubectl](http://kubernetes.io/docs/user-guide/prereqs/) command-line client.
|
|
||||||
|
|
||||||
## Decide where you will store your data
|
MySQL and Wordpress each use a PersistentVolume to store data. While Kubernetes supports many different [types of PersistentVolumes](https://kubernetes.io/docs/concepts/storage/persistent-volumes/#types-of-persistent-volumes), this tutorial covers [hostPath](https://kubernetes.io/docs/concepts/storage/volumes/#hostpath).
|
||||||
|
|
||||||
MySQL and WordPress will each use a
|
**Note:** If you have a Kubernetes cluster running on Google Container Engine, please follow [this guide](https://cloud.google.com/container-engine/docs/tutorials/persistent-disk).
|
||||||
[Persistent Volume](https://kubernetes.io/docs/concepts/storage/persistent-volumes/)
|
{: .note}
|
||||||
to store their data. We will use a Persistent Volume Claim to claim an
|
|
||||||
available persistent volume. This example covers HostPath and
|
|
||||||
GCEPersistentDisk volumes. Choose one of the two, or see
|
|
||||||
[Types of Persistent Volumes](https://kubernetes.io/docs/concepts/storage/persistent-volumes/#types-of-persistent-volumes)
|
|
||||||
for more options.
|
|
||||||
|
|
||||||
### Host Path
|
### Setting up a hostPath Volume
|
||||||
|
|
||||||
Host paths are volumes mapped to directories on the host. **These
|
A `hostPath` mounts a file or directory from the host node’s filesystem into your Pod.
|
||||||
should be used for testing or single-node clusters only**. The data
|
|
||||||
will not be moved between nodes if the pod is recreated on a new
|
|
||||||
node. If the pod is deleted and recreated on a new node, data will be
|
|
||||||
lost.
|
|
||||||
|
|
||||||
##### SELinux
|
**Warning:** Only use `hostPath` for developing and testing. With hostPath, your data lives on the node the Pod is scheduled onto and does not move between nodes. If a Pod dies and gets scheduled to another node in the cluster, the data is lost.
|
||||||
|
{: .warning}
|
||||||
|
|
||||||
On systems supporting selinux it is preferred to leave it enabled/enforcing.
|
1. Launch a terminal window in the directory you downloaded the manifest files.
|
||||||
However, docker containers mount the host path with the "_svirt_sandbox_file_t_"
|
|
||||||
label type, which is incompatible with the default label type for /tmp ("_tmp_t_"),
|
|
||||||
resulting in a permissions error when the mysql container attempts to `chown`
|
|
||||||
_/var/lib/mysql_.
|
|
||||||
Therefore, on selinx systems using host path, you should pre-create the host path
|
|
||||||
directory (/tmp/data/) and change it's selinux label type to "_svirt_sandbox_file_t_",
|
|
||||||
as follows:
|
|
||||||
|
|
||||||
```shell
|
2. Create two PersistentVolumes from the `local-volumes.yaml` file:
|
||||||
## on every node:
|
|
||||||
mkdir -p /tmp/data
|
|
||||||
chmod a+rwt /tmp/data # match /tmp permissions
|
|
||||||
chcon -Rt svirt_sandbox_file_t /tmp/data
|
|
||||||
```
|
|
||||||
|
|
||||||
Continuing with host path, create the persistent volume objects in Kubernetes using
|
kubectl create -f local-volumes.yaml
|
||||||
[local-volumes.yaml](https://git.k8s.io/examples/mysql-wordpress-pd/local-volumes.yaml):
|
|
||||||
|
|
||||||
```shell
|
{% include code.html language="yaml" file="local-volumes.yaml" ghlink="/docs/tutorials/stateful-application/mysql-wordpress-persistent-volume/local-volumes.yaml %}
|
||||||
export KUBE_REPO=https://raw.githubusercontent.com/kubernetes/examples/master
|
|
||||||
kubectl create -f $KUBE_REPO/mysql-wordpress-pd/local-volumes.yaml
|
|
||||||
```
|
|
||||||
|
|
||||||
|
{:start="3"}
|
||||||
|
3. Run the following command to verify that two 20GiB PersistentVolumes are available:
|
||||||
|
|
||||||
### GCE Persistent Disk
|
kubectl get pv
|
||||||
|
|
||||||
This storage option is applicable if you are running on
|
The response should be like this:
|
||||||
[Google Compute Engine](http://kubernetes.io/docs/getting-started-guides/gce/).
|
|
||||||
|
|
||||||
Create two persistent disks. You will need to create the disks in the
|
NAME CAPACITY ACCESSMODES RECLAIMPOLICY STATUS CLAIM STORAGECLASS REASON AGE
|
||||||
same [GCE zone](https://cloud.google.com/compute/docs/zones) as the
|
local-pv-1 20Gi RWO Retain Available 1m
|
||||||
Kubernetes cluster. The default setup script will create the cluster
|
local-pv-2 20Gi RWO Retain Available 1m
|
||||||
in the `us-central1-b` zone, as seen in the
|
|
||||||
[config-default.sh](https://git.k8s.io/kubernetes/cluster/gce/config-default.sh) file. Replace
|
|
||||||
`<zone>` below with the appropriate zone. The names `wordpress-1` and
|
|
||||||
`wordpress-2` must match the `pdName` fields we have specified in
|
|
||||||
[gce-volumes.yaml](https://git.k8s.io/examples/mysql-wordpress-pd/gce-volumes.yaml).
|
|
||||||
|
|
||||||
```shell
|
## Create a Secret for MySQL Password
|
||||||
gcloud compute disks create --size=20GB --zone=<zone> wordpress-1
|
|
||||||
gcloud compute disks create --size=20GB --zone=<zone> wordpress-2
|
|
||||||
```
|
|
||||||
|
|
||||||
Create the persistent volume objects in Kubernetes for those disks:
|
A [Secret](https://kubernetes.io/docs/concepts/configuration/secret/) is an object that stores a piece of sensitive data like a password or key. The manifest files are already configured to use a Secret, but you have to create your own Secret.
|
||||||
|
|
||||||
```shell
|
1. Create the Secret object from the following command:
|
||||||
export KUBE_REPO=https://raw.githubusercontent.com/kubernetes/examples/master
|
|
||||||
kubectl create -f $KUBE_REPO/mysql-wordpress-pd/gce-volumes.yaml
|
|
||||||
```
|
|
||||||
|
|
||||||
## Create the MySQL Password Secret
|
kubectl create secret generic mysql-pass --from-literal=password=YOUR_PASSWORD
|
||||||
|
|
||||||
|
**Note:** Replace `YOUR_PASSWORD` with the password you want to apply.
|
||||||
|
{: .note}
|
||||||
|
|
||||||
|
2. Verify that the Secret exists by running the following command:
|
||||||
|
|
||||||
Use a [Secret](http://kubernetes.io/docs/user-guide/secrets/) object
|
kubectl get secrets
|
||||||
to store the MySQL password. First create a file (in the same directory
|
|
||||||
as the wordpress sample files) called
|
|
||||||
`password.txt` and save your password in it. Make sure to not have a
|
|
||||||
trailing newline at the end of the password. The first `tr` command
|
|
||||||
will remove the newline if your editor added one. Then, create the
|
|
||||||
Secret object.
|
|
||||||
|
|
||||||
```shell
|
The response should be like this:
|
||||||
tr --delete '\n' <password.txt >.strippedpassword.txt && mv .strippedpassword.txt password.txt
|
|
||||||
kubectl create secret generic mysql-pass --from-file=password.txt
|
|
||||||
```
|
|
||||||
|
|
||||||
This secret is referenced by the MySQL and WordPress pod configuration
|
NAME TYPE DATA AGE
|
||||||
so that those pods will have access to it. The MySQL pod will set the
|
mysql-pass Opaque 1 42s
|
||||||
database password, and the WordPress pod will use the password to
|
|
||||||
access the database.
|
**Note:** To protect the Secret from exposure, neither `get` nor `describe` show its contents.
|
||||||
|
{: .note}
|
||||||
|
|
||||||
## Deploy MySQL
|
## Deploy MySQL
|
||||||
|
|
||||||
Now that the persistent disks and secrets are defined, the Kubernetes
|
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.
|
||||||
pods can be launched. Start MySQL using
|
|
||||||
[mysql-deployment.yaml](https://git.k8s.io/examples/mysql-wordpress-pd/mysql-deployment.yaml).
|
|
||||||
|
|
||||||
```shell
|
{% include code.html language="yaml" file="mysql-deployment.yaml" ghlink="/docs/tutorials/stateful-application/mysql-wordpress-persistent-volume/mysql-deployment.yaml %}
|
||||||
kubectl create -f $KUBE_REPO/mysql-wordpress-pd/mysql-deployment.yaml
|
|
||||||
```
|
|
||||||
|
|
||||||
Take a look at [mysql-deployment.yaml](https://git.k8s.io/examples/mysql-wordpress-pd/mysql-deployment.yaml), and
|
1. Deploy MySQL from the `mysql-deployment.yaml` file:
|
||||||
note that we've defined a volume mount for `/var/lib/mysql`, and then
|
|
||||||
created a Persistent Volume Claim that looks for a 20G volume. This
|
|
||||||
claim is satisfied by any volume that meets the requirements, in our
|
|
||||||
case one of the volumes we created above.
|
|
||||||
|
|
||||||
Also look at the `env` section and see that we specified the password
|
kubectl create -f mysql-deployment.yaml
|
||||||
by referencing the secret `mysql-pass` that we created above. Secrets
|
|
||||||
can have multiple key:value pairs. Ours has only one key
|
|
||||||
`password.txt` which was the name of the file we used to create the
|
|
||||||
secret. The [MySQL image](https://hub.docker.com/_/mysql/) sets the
|
|
||||||
database password using the `MYSQL_ROOT_PASSWORD` environment
|
|
||||||
variable.
|
|
||||||
|
|
||||||
It may take a short period before the new pod reaches the `Running`
|
2. Verify that the Pod is running by running the following command:
|
||||||
state. List all pods to see the status of this new pod.
|
|
||||||
|
|
||||||
```shell
|
kubectl get pods
|
||||||
kubectl get pods
|
|
||||||
```
|
|
||||||
|
|
||||||
```
|
**Note:** It can take up to a few minutes for the Pod's Status to be `RUNNING`.
|
||||||
NAME READY STATUS RESTARTS AGE
|
{: .note}
|
||||||
wordpress-mysql-cqcf4-9q8lo 1/1 Running 0 1m
|
|
||||||
```
|
|
||||||
|
|
||||||
Kubernetes logs the stderr and stdout for each pod. Take a look at the
|
The response should be like this:
|
||||||
logs for a pod by using `kubectl log`. Copy the pod name from the
|
|
||||||
`get pods` command, and then:
|
|
||||||
|
|
||||||
```shell
|
NAME READY STATUS RESTARTS AGE
|
||||||
kubectl logs <pod-name>
|
wordpress-mysql-1894417608-x5dzt 1/1 Running 0 40s
|
||||||
```
|
|
||||||
|
|
||||||
```
|
|
||||||
...
|
|
||||||
2016-02-19 16:58:05 1 [Note] InnoDB: 128 rollback segment(s) are active.
|
|
||||||
2016-02-19 16:58:05 1 [Note] InnoDB: Waiting for purge to start
|
|
||||||
2016-02-19 16:58:05 1 [Note] InnoDB: 5.6.29 started; log sequence number 1626007
|
|
||||||
2016-02-19 16:58:05 1 [Note] Server hostname (bind-address): '*'; port: 3306
|
|
||||||
2016-02-19 16:58:05 1 [Note] IPv6 is available.
|
|
||||||
2016-02-19 16:58:05 1 [Note] - '::' resolves to '::';
|
|
||||||
2016-02-19 16:58:05 1 [Note] Server socket created on IP: '::'.
|
|
||||||
2016-02-19 16:58:05 1 [Warning] 'proxies_priv' entry '@ root@wordpress-mysql-cqcf4-9q8lo' ignored in --skip-name-resolve mode.
|
|
||||||
2016-02-19 16:58:05 1 [Note] Event Scheduler: Loaded 0 events
|
|
||||||
2016-02-19 16:58:05 1 [Note] mysqld: ready for connections.
|
|
||||||
Version: '5.6.29' socket: '/var/run/mysqld/mysqld.sock' port: 3306 MySQL Community Server (GPL)
|
|
||||||
```
|
|
||||||
|
|
||||||
Also in [mysql-deployment.yaml](https://git.k8s.io/examples/mysql-wordpress-pd/mysql-deployment.yaml) we created a
|
|
||||||
service to allow other pods to reach this mysql instance. The name is
|
|
||||||
`wordpress-mysql` which resolves to the pod IP.
|
|
||||||
|
|
||||||
Up to this point one Deployment, one Pod, one PVC, one Service, one Endpoint,
|
|
||||||
two PVs, and one Secret have been created, shown below:
|
|
||||||
|
|
||||||
```shell
|
|
||||||
kubectl get deployment,pod,svc,endpoints,pvc -l app=wordpress -o wide && \
|
|
||||||
kubectl get secret mysql-pass && \
|
|
||||||
kubectl get pv
|
|
||||||
```
|
|
||||||
|
|
||||||
```shell
|
|
||||||
NAME DESIRED CURRENT UP-TO-DATE AVAILABLE AGE
|
|
||||||
deploy/wordpress-mysql 1 1 1 1 3m
|
|
||||||
NAME READY STATUS RESTARTS AGE IP NODE
|
|
||||||
po/wordpress-mysql-3040864217-40soc 1/1 Running 0 3m 172.17.0.2 127.0.0.1
|
|
||||||
NAME CLUSTER-IP EXTERNAL-IP PORT(S) AGE SELECTOR
|
|
||||||
svc/wordpress-mysql None <none> 3306/TCP 3m app=wordpress,tier=mysql
|
|
||||||
NAME ENDPOINTS AGE
|
|
||||||
ep/wordpress-mysql 172.17.0.2:3306 3m
|
|
||||||
NAME STATUS VOLUME CAPACITY ACCESSMODES AGE
|
|
||||||
pvc/mysql-pv-claim Bound local-pv-2 20Gi RWO 3m
|
|
||||||
NAME TYPE DATA AGE
|
|
||||||
mysql-pass Opaque 1 3m
|
|
||||||
NAME CAPACITY ACCESSMODES STATUS CLAIM REASON AGE
|
|
||||||
local-pv-1 20Gi RWO Available 3m
|
|
||||||
local-pv-2 20Gi RWO Bound default/mysql-pv-claim 3m
|
|
||||||
```
|
|
||||||
|
|
||||||
## Deploy WordPress
|
## Deploy WordPress
|
||||||
|
|
||||||
Next deploy WordPress using
|
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: NodePort`. This setting exposes WordPress to traffic from outside of the cluster.
|
||||||
[wordpress-deployment.yaml](https://git.k8s.io/examples/mysql-wordpress-pd/wordpress-deployment.yaml):
|
|
||||||
|
|
||||||
```shell
|
{% include code.html language="yaml" file="mysql-deployment.yaml" ghlink="/docs/tutorials/stateful-application/mysql-wordpress-persistent-volume/wordpress-deployment.yaml %}
|
||||||
kubectl create -f $KUBE_REPO/mysql-wordpress-pd/wordpress-deployment.yaml
|
|
||||||
```
|
|
||||||
|
|
||||||
Here we are using many of the same features, such as a volume claim
|
1. Create a WordPress Service and Deployment from the `wordpress-deployment.yaml` file:
|
||||||
for persistent storage and a secret for the password.
|
|
||||||
|
|
||||||
The [WordPress image](https://hub.docker.com/_/wordpress/) accepts the
|
kubectl create -f wordpress-deployment.yaml
|
||||||
database hostname through the environment variable
|
|
||||||
`WORDPRESS_DB_HOST`. We set the env value to the name of the MySQL
|
|
||||||
service we created: `wordpress-mysql`.
|
|
||||||
|
|
||||||
The WordPress service has the setting `type: LoadBalancer`. This will
|
2. Verify that the Service is running by running the following command:
|
||||||
set up the wordpress service behind an external IP.
|
|
||||||
|
|
||||||
Find the external IP for your WordPress service. **It may take a minute
|
kubectl get services wordpress
|
||||||
to have an external IP assigned to the service, depending on your
|
|
||||||
cluster environment.**
|
|
||||||
|
|
||||||
```shell
|
The response should be like this:
|
||||||
kubectl get services wordpress
|
|
||||||
```
|
|
||||||
|
|
||||||
```
|
NAME CLUSTER-IP EXTERNAL-IP PORT(S) AGE
|
||||||
NAME CLUSTER-IP EXTERNAL-IP PORT(S) AGE
|
wordpress 10.0.0.89 <pending> 80:32406/TCP 4m
|
||||||
wordpress 10.0.0.5 1.2.3.4 80/TCP 19h
|
|
||||||
```
|
|
||||||
|
|
||||||
## Visit your new WordPress blog
|
**Note:** Minikube can only expose Services through `NodePort`. <br/><br/>The `EXTERNAL-IP` is always `<pending>`.
|
||||||
|
{: .note}
|
||||||
|
|
||||||
Now, we can visit the running WordPress app. Use the external IP of
|
3. Run the following command to get the IP Address for the WordPress Service:
|
||||||
the service that you obtained above.
|
|
||||||
|
|
||||||
```
|
minikube service wordpress --url
|
||||||
http://<external-ip>
|
|
||||||
```
|
|
||||||
|
|
||||||
You should see the familiar WordPress init page.
|
The response should be like this:
|
||||||
|
|
||||||

|
http://1.2.3.4:32406
|
||||||
|
|
||||||
> Warning: Do not leave your WordPress installation on this page. If
|
4. Copy the IP address, and load the page in your browser to view your site.
|
||||||
> it is found by another user, they can set up a website on your
|
|
||||||
> instance and use it to serve potentially malicious content. You
|
|
||||||
> should either continue with the installation past the point at which
|
|
||||||
> you create your username and password, delete your instance, or set
|
|
||||||
> up a firewall to restrict access.
|
|
||||||
|
|
||||||
## Take down and restart your blog
|
You should see the WordPress set up page similar to the following screenshot.
|
||||||
|
|
||||||
Set up your WordPress blog and play around with it a bit. Then, take
|

|
||||||
down its pods and bring them back up again. Because you used
|
|
||||||
persistent disks, your blog state will be preserved.
|
|
||||||
|
|
||||||
All of the resources are labeled with `app=wordpress`, so you can
|
**Warning:** Do not leave your WordPress installation on this page. If another user finds it, they can set up a website on your instance and use it to serve malicious content. <br/><br/>Either install WordPress by creating a username and password or delete your instance.
|
||||||
easily bring them down using a label selector:
|
{: .warning}
|
||||||
|
|
||||||
```shell
|
{% endcapture %}
|
||||||
kubectl delete deployment,service -l app=wordpress
|
|
||||||
kubectl delete secret mysql-pass
|
|
||||||
```
|
|
||||||
|
|
||||||
Later, re-creating the resources with the original commands will pick
|
{% capture cleanup %}
|
||||||
up the original disks with all your data intact. Because we did not
|
|
||||||
delete the PV Claims, no other pods in the cluster could claim them
|
|
||||||
after we deleted our pods. Keeping the PV Claims also ensured
|
|
||||||
recreating the Pods did not cause the PD to switch Pods.
|
|
||||||
|
|
||||||
If you are ready to release your persistent volumes and the data on them, run:
|
1. Run the following command to delete your Secret:
|
||||||
|
|
||||||
```shell
|
kubectl delete secret mysql-pass
|
||||||
kubectl delete pvc -l app=wordpress
|
|
||||||
```
|
|
||||||
|
|
||||||
And then delete the volume objects themselves:
|
2. Run the following commands to delete all Deployments and Services:
|
||||||
|
|
||||||
```shell
|
kubectl delete deployment -l app=wordpress
|
||||||
kubectl delete pv local-pv-1 local-pv-2
|
kubectl delete service -l app=wordpress
|
||||||
```
|
|
||||||
|
|
||||||
or
|
3. Run the following commands to delete the PersistentVolumeClaims and the PersistentVolumes:
|
||||||
|
|
||||||
```shell
|
kubectl delete pvc -l app=wordpress
|
||||||
kubectl delete pv wordpress-pv-1 wordpress-pv-2
|
kubectl delete pv local-pv-1 local-pv-2
|
||||||
```
|
|
||||||
|
**Note:** Any other Type of PersistentVolume would allow you to recreate the Deployments and Services at this point without losing data, but `hostPath` loses the data as soon as the Pod stops running.
|
||||||
|
{: .note}
|
||||||
|
|
||||||
## Next Steps
|
{% endcapture %}
|
||||||
|
|
||||||
* [Introspection and Debugging](http://kubernetes.io/docs/user-guide/introspection-and-debugging/)
|
{% capture whatsnext %}
|
||||||
* [Jobs](http://kubernetes.io/docs/user-guide/jobs/) may be useful to run SQL queries.
|
|
||||||
* [Exec](http://kubernetes.io/docs/user-guide/getting-into-containers/)
|
* Learn more about [Introspection and Debugging](https://kubernetes.io/docs/tasks/debug-application-cluster/debug-application-introspection/)
|
||||||
* [Port Forwarding](http://kubernetes.io/docs/user-guide/connecting-to-applications-port-forward/)
|
* Learn more about [Jobs](https://kubernetes.io/docs/concepts/workloads/controllers/jobs-run-to-completion/)
|
||||||
|
* Learn more about [Port Forwarding](https://kubernetes.io/docs/tasks/access-application-cluster/port-forward-access-application-cluster/)
|
||||||
|
* Learn how to [Get a Shell to a Container](https://kubernetes.io/docs/tasks/debug-application-cluster/get-shell-running-container/)
|
||||||
|
|
||||||
|
{% endcapture %}
|
||||||
|
|
||||||
|
{% include templates/tutorial.md %}
|
||||||
|
|
||||||
<!-- BEGIN MUNGE: GENERATED_ANALYTICS -->
|
<!-- BEGIN MUNGE: GENERATED_ANALYTICS -->
|
||||||
[]()
|
[]()
|
||||||
|
|
|
@ -44,13 +44,11 @@ spec:
|
||||||
- image: mysql:5.6
|
- image: mysql:5.6
|
||||||
name: mysql
|
name: mysql
|
||||||
env:
|
env:
|
||||||
# $ kubectl create secret generic mysql-pass --from-file=password.txt
|
|
||||||
# make sure password.txt does not have a trailing newline
|
|
||||||
- name: MYSQL_ROOT_PASSWORD
|
- name: MYSQL_ROOT_PASSWORD
|
||||||
valueFrom:
|
valueFrom:
|
||||||
secretKeyRef:
|
secretKeyRef:
|
||||||
name: mysql-pass
|
name: mysql-pass
|
||||||
key: password.txt
|
key: password
|
||||||
ports:
|
ports:
|
||||||
- containerPort: 3306
|
- containerPort: 3306
|
||||||
name: mysql
|
name: mysql
|
||||||
|
|
|
@ -50,7 +50,7 @@ spec:
|
||||||
valueFrom:
|
valueFrom:
|
||||||
secretKeyRef:
|
secretKeyRef:
|
||||||
name: mysql-pass
|
name: mysql-pass
|
||||||
key: password.txt
|
key: password
|
||||||
ports:
|
ports:
|
||||||
- containerPort: 80
|
- containerPort: 80
|
||||||
name: wordpress
|
name: wordpress
|
||||||
|
|
Loading…
Reference in New Issue