Skip to content

Commit

Permalink
Add Drupal manifest examples for Episode 4.
Browse files Browse the repository at this point in the history
  • Loading branch information
geerlingguy committed Dec 9, 2020
1 parent d6e8aa6 commit 1d8fc7d
Show file tree
Hide file tree
Showing 5 changed files with 297 additions and 2 deletions.
4 changes: 2 additions & 2 deletions episode-04/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -102,6 +102,6 @@ We are going to run through how to do everything step by step, and hopefully hav

I'm going to switch things up and deploy to a real Kubernetes cluster, in this case a cluster running on Linode (since they are still offering a [free $100 credit using this link](https://linode.com/geerling)).

### TODO
### Deploying the Drupal Kubernetes Manifests

TODO.
Please see the [README inside the k8s-manifests](k8s-manifests/README.md) for further instructions.
116 changes: 116 additions & 0 deletions episode-04/k8s-manifests/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,116 @@
# Drupal Kubernetes Deployment Manifests

This directory contains two deployment manifests, one for MariaDB, and one for Drupal (which builds a Drupal Deployment running Drupal on top of Apache + PHP).

To apply them to a Kubernetes cluster (e.g. with Minikube: `minikube start`), run the commands:

```
# Create a namespace for the Drupal site.
kubectl create namespace drupal
# Create the MySQL (MariaDB) Deployment.
kubectl apply -f mariadb.yml
# Create the Drupal (Apache + PHP) Deployment.
kubectl apply -f drupal.yml
```

You can then observe the status of the deployments:

```
kubectl get deployments -n drupal -w
```

Then press Ctrl+C to stop watching the deployment rollout.

## Working in Namespaces

If you want to do a lot of work in a particular namespace (e.g. `drupal`), you can set the current namespace context using:

```
kubectl config set-context --current --namespace=drupal
```

And you can confirm which namespace context you're in with:

```
kubectl config view | grep namespace:
```

When you're done performing actions (e.g. `kubectl get pods`) only within that namespace, run:

```
kubectl config set-context --current --namespace=""
```

## Accessing the Drupal site

After the Drupal deployment is complete, you can see access it via:

```
# In Minikube, this will open the URL directly.
minikube service -n drupal drupal
# In other clusters, get the service to get the NodePort.
kubectl get service -n drupal drupal
```

That will give you the NodePort on which the service is exposed, but what about the IP address? Well, for many commands in Kubernetes, they give a brief summary by default, but you can get a lot more information adding `-o wide`:

```
kubectl get nodes -o wide
```

Now you can take the IP address of any node, and pair that with the NodePort that maps to TCP port 80 on Drupal's service, and access the site. You should be taken to the Drupal installer UI.

And you can access the Drupal container's Apache logs with:

```
kubectl logs -n -f drupal -l app=drupal
```

Install the Drupal site using the UI, and create an Article (under Content > Add content > Article) with an image inside the Body text.

## Scaling the Drupal deployment

Go ahead and edit the Drupal deployment:

```
kubectl edit deployment -n drupal drupal
```

Set `replicas` to `3`, and save the changes.

Watch the Pods as they are deployed in the scale-up event:

```
kubectl get pods -n drupal -w
```

But oh no! It seems like these pods are stuck on 'Init'. Investigate further, with:

```
kubectl describe pod -n drupal -l app=drupal
```

You might notice a `Multi-Attach error`. It seems that our fancy Drupal deployment—which is similar to every other Drupal, Wordpress, and similar LAMP-based deployment I see in Kubernetes tutorials, has a major problem: _you can't scale it up!_

There goes one of the major advantages we _thought_ we'd get with Kubernetes... or does it? In the next episode we'll dig deeper into scaling Drupal, accessing Drupal with a Domain using Ingress, SSL, and other real-world app concerns.

## Cleaning up

When you're finished testing, one of the best advantages of using Kubernetes namespaces is the easy ability to clean up everything in the namespace.

All you have to do is delete the namespace, and Kubernetes will clean up everything inside:

```
kubectl delete namespace drupal
```

After a minute or two, all traces of Drupal should be gone. Sometimes there may be remnants, however, like persistent volumes that are 'retained' for safekeeping (if you're using Linode, for example). Go ahead and delete those with:

```
kubectl get pv | grep Released | awk '$1 {print$1}' | while read vol; do kubectl delete pv/${vol}; done
```

Confirm the volumes have been deleted in the cloud provider's UI as well; for Linode, at least, deleting the PV via Kubernetes does not trigger a delete of the underlying block storage device!
107 changes: 107 additions & 0 deletions episode-04/k8s-manifests/drupal.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,107 @@
---
kind: ConfigMap
apiVersion: v1
metadata:
name: drupal-config
namespace: drupal
data:
# Note: This is NOT secure. Don't use this in production!
settings.php: |-
<?php
$databases['default']['default'] = [
'database' => 'drupal',
'username' => 'drupal',
'password' => 'drupal',
'prefix' => '',
'host' => 'mariadb',
'port' => '3306',
'namespace' => 'Drupal\\Core\\Database\\Driver\\mysql',
'driver' => 'mysql',
];
$settings['hash_salt'] = 'OTk4MTYzYWI4N2E2MGIxNjlmYmQ2MTA4';
$settings['trusted_host_patterns'] = ['^.+$'];
$settings['config_sync_directory'] = 'sites/default/files/config_OTk4MTYzY';
---
kind: PersistentVolumeClaim
apiVersion: v1
metadata:
name: drupal-files-pvc
namespace: drupal
spec:
accessModes:
- ReadWriteOnce
resources:
requests:
storage: 1Gi

---
kind: Deployment
apiVersion: apps/v1
metadata:
name: drupal
namespace: drupal
spec:
replicas: 1
selector:
matchLabels:
app: drupal
template:
metadata:
labels:
app: drupal
spec:
initContainers:
- name: init-files
image: 'drupal:9-apache'
command: ['/bin/bash', '-c']
args: ['cp -r /var/www/html/sites/default/files /data; chown www-data:www-data /data/ -R']
volumeMounts:
- mountPath: /data
name: drupal-files
containers:
- name: drupal
image: 'drupal:9-apache'
ports:
- containerPort: 80
livenessProbe:
tcpSocket:
port: 80
initialDelaySeconds: 30
readinessProbe:
tcpSocket:
port: 80
initialDelaySeconds: 10
volumeMounts:
- mountPath: /var/www/html/sites/default/
name: drupal-settings
- mountPath: /var/www/html/sites/default/files/
name: drupal-files
resources:
limits:
cpu: '1'
memory: '512Mi'
requests:
cpu: '500m'
memory: '256Mi'
volumes:
- name: drupal-settings
configMap:
name: drupal-config
- name: drupal-files
persistentVolumeClaim:
claimName: drupal-files-pvc

---
kind: Service
apiVersion: v1
metadata:
name: drupal
namespace: drupal
spec:
type: NodePort
ports:
- port: 80
targetPort: 80
selector:
app: drupal
70 changes: 70 additions & 0 deletions episode-04/k8s-manifests/mariadb.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,70 @@
---
kind: PersistentVolumeClaim
apiVersion: v1
metadata:
name: mariadb-pvc
namespace: drupal
spec:
accessModes:
- ReadWriteOnce
resources:
requests:
storage: 1Gi

---
kind: Deployment
apiVersion: apps/v1
metadata:
name: mariadb
namespace: drupal
spec:
replicas: 1
selector:
matchLabels:
app: mariadb
template:
metadata:
labels:
app: mariadb
spec:
containers:
- name: mariadb
image: mariadb:10.5
ports:
- containerPort: 3306
env:
- name: MYSQL_DATABASE
value: drupal
- name: MYSQL_USER
value: drupal
- name: MYSQL_PASSWORD
value: drupal
- name: MYSQL_RANDOM_ROOT_PASSWORD
value: 'yes'
volumeMounts:
- mountPath: /var/lib/mysql/
name: database
resources:
limits:
cpu: '2'
memory: '512Mi'
requests:
cpu: '500m'
memory: '256Mi'
volumes:
- name: database
persistentVolumeClaim:
claimName: mariadb-pvc

---
kind: Service
apiVersion: v1
metadata:
name: mariadb
namespace: drupal
spec:
ports:
- port: 3306
targetPort: 3306
selector:
app: mariadb
2 changes: 2 additions & 0 deletions episode-05/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,4 +9,6 @@ Outline:
- Automating certificates for Drupal Ingress
- Setting up persistent files to scale Drupal's deployment
- Setting up Horizontal Pod Autoscaling
- Working with Drupal's Cron system
- Figuring out what to do with Drupal's internal ('watchdog') logs
- Options for High-Availability Databases

0 comments on commit 1d8fc7d

Please sign in to comment.