-
-
Save geerlingguy/4613ea753d2286b6ed0cb4e3c272ce23 to your computer and use it in GitHub Desktop.
# This manifest assumes 'drupal' namespace is already present: | |
# | |
# kubectl create namespace drupal | |
# | |
# Apply the manifest with: | |
# | |
# kubectl apply -f drupal.yml | |
--- | |
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: | |
containers: | |
- name: drupal | |
image: 'drupal:8.8-apache' | |
ports: | |
- containerPort: 80 | |
livenessProbe: | |
tcpSocket: | |
port: 80 | |
initialDelaySeconds: 60 | |
readinessProbe: | |
tcpSocket: | |
port: 80 | |
initialDelaySeconds: 30 | |
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 | |
--- | |
apiVersion: extensions/v1beta1 | |
kind: Ingress | |
metadata: | |
name: drupal | |
namespace: drupal | |
spec: | |
rules: | |
- host: drupal.10.0.100.99.nip.io | |
http: | |
paths: | |
- path: / | |
backend: | |
serviceName: drupal | |
servicePort: 80 |
# This manifest assumes 'drupal' namespace is already present: | |
# | |
# kubectl create namespace drupal | |
# | |
# Apply the manifest with: | |
# | |
# kubectl apply -f mariadb.yml | |
--- | |
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: tobi312/rpi-mariadb:10.3 | |
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 |
@mkmojo - The actual Drupal deployment here is pretty secure, but would need some changes to make it more scalable (e.g. using HPA by setting up NFS for shared files volume). I mention the security issue mostly because I didn't spend hours hardening the entire K3s cluster configuration (e.g. per-Pi firewalls, any kind of intrusion monitoring, configuring things like Fail2Ban, etc.), and that's something that is not easy to cover in a short-form YouTube series (nor is it the intention of that series).
For some of those basics, I highly suggest Ansible 101 - Episode 9 - First 5 min server security with Ansible.
Also, I am planning out a Kubernetes 101 series on YouTube... sometime in the next few months :) — it will cover more topics like RBAC and resource constraints in more depth.
@mkmojo - thanks for asking that question!!
@geerlinguy - thanks for the very helpful answer!!!
I am following this using 4 Pi 4Bs (with 4 GB each). But so far everything works as is just like on the Turing Pi. Well, except that I could not for the life of me get kubectl installed on my master node. So I am just running kubectl from the Ubuntu 18 box that is also my ansible master (and that works fine). I am definitely planning to follow up on using fail2ban and ufw on my cluster.
If I want to run a daemonset (basically a service to run on every node). And I use the ingress, why I can't connect to it.
Is there a way to tell me what I could be doing wrong?
First, thank you for all you have done by posting these.
I've made mistakes at every stage of the process, especially during the hardware assembly for my cluster, but also during bare metal installation, k3s install, and container installs.
I've fixed most of the problems, but this pod (drupal) still fails to work. It installs without error, but the website always says, "The website encountered an unexpected error. Please try again later."
The only change I've made from the above code is changing the IP to one of mine.
@Jeter-work - What I'd suggest is deleting the deployment and creating it again. Sometimes when you get that error, something with Drupal's database setup went wrong, and the easiest way (if you're just setting it up fresh) is to just delete and recreate it. I actually hit that problem in my Kubernetes 101 livestream too :D
@geerlingguy - Thanks. I actually ended up doing that. Actually, I went forward, deleted everything then did them all again. I'm using a Picocluster with 10 pi 4B's. And once I finished mimicing your Turing Pi example, with HypriotOS and K3s, I decided to really get down in the weeds. I'm using 64-bit Ubuntu for ARM, and I'm going to try out two different Gluster configurations, one using the leftover space on SD cards, and one using LUNs served from a NAS. I expect the NAS to outperform the SD version, but the SD Card config will closer simulate hyperconverged infrastructure. Once I get the gluster set up, I'm going to configure K3s or MicroK8s. And as always, once I flash the cards, all steps are done with roles, and when I'm done I'll write a playbook to link all the roles and I'll do it all again until I have it automated. At some point I'm going to land on a config I like, and I'll settle the cluster into a stable config and move onto using it for other home lab stuff, firewall, pi-hole, stuff like that. Then maybe home automation?
Thanks for these. I've been following your tutorial episode 4. Unfortunately I'm pretty new to all this. I'm getting a:
error: unable to recognize "drupal.yml": no matches for kind "Ingress" in version "extensions/v1beta1"
When running the manifest.
@RossWilliamson - That should probably be extensions/v1
I think, now, and it needs a couple other formatting changes for the actual ingress resource.
@geerlingguy Thanks! I did some googling and the following seemed to work (I don't think you can do pull requests with gists so I'll paste it here). Again - I'm just learning so this worked for me but may well not be correct (I have no idea what the pathType: ImplementationSpecific does yet.)
---
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: drupal
namespace: drupal
spec:
rules:
- host: drupal.192.168.1.101.nip.io
http:
paths:
- path: /
pathType: ImplementationSpecific
backend:
service:
name: drupal
port:
number: 80
For those of you running into the image pull error for MariaDB, I changed the image to tobi312/rpi-mariadb:10.6-ubuntu and it seems to work on Raspberry Pi OS.
Hi @geerlingguy,
Thanks for sharing this and creating the Youtube video on how to deploy this to the cluster.
I have learned a lot from the pi cluster series.
Noticed that you mentioned in both this and the pi-hole deployment there are some security shortcuts taken in order to demo.
Do you think it possible to make a video on how to deploy in a secure fashion?
Thanks a lot for the awesome work!