====== Minimale Wordpress deployment op CHP4 ======
In deze handleiding leggen we uit wat er minimaal nodig is om een Wordpress applicatie uit te rollen op het OpenShift 4 cluster.
Waarschuwing: Team Hosting & Streaming levert geen ondersteuning op deze handleiding, noch het gebruik hiervan. Deze handleiding is alleen maar bedoeld om inzicht te geven hoe een Wordpress site werkend te krijgen. De Wordpress site die in deze handleiding gebruikt wordt is een schone installatie zonder verdere configuratie, plugins of themes. Deze handleiding zorgt niet voor een Wordpress applicatie die productie klaar is. Helemaal onderaan de pagina staan een paar aanpassingen die minimaal uitgevoerd moeten worden om productie klaar te zijn, maar zijn zeker niet volledig.
===== Benodigdheden =====
Voor het uitrollen heb je een aantal benodigdheden nodig:
* Een Git Repository met daarin de code van de applicatie. Deze repository moet private zijn. Voor deze handleiding is de sourcecode van Wordpress gedownload en deze in de root van de GitHub repository gezet.
* Een SSH key om de Repository te benaderen, deze key mag niet met een wachtwoord beveiligd zijn. We adviseren om hiervoor een aparte [[https://docs.github.com/en/developers/overview/managing-deploy-keys | Deploy Key]] te gebruiken.
* De wp-config.php file. Deze kan beter niet in de repository staan in verband met de database credentials.
* Nginx en PHP configuratie files, later leggen we uit wat er minimaal nodig is.
Note: in dit voorbeeld worden de configuratie bestanden in een mapje in de Git Repository opgeslagen met de naam ''config''. Het is niet verstandig om daar bestanden met credentials in op te slaan.
Verder heb je nodig:
* Een terminal
* De ''oc'' [[https://docs.openshift.com/container-platform/4.8/cli_reference/openshift_cli/getting-started-cli.html | cli]] geïnstalleerd.
* Een OpenShift account.
* We gaan er vanuit dat je de Workshop hebt gedaan, heb je deze nog niet gedaan? Doe die dan eerst, deze kun je aanvragen via een ticket bij support.npohosting.nl.
===== Voorbereidingen =====
Voordat we kunnen beginnen met het installeren van de applicatie, moeten we een aantal voorbereidingen treffen:
* Project aanmaken (als dat nog niet gedaan is).
* Database aanmaken.
* Configuratie bestanden aanmaken.
* Storage aanmaken.
* Scriptjes maken.
==== Project aanmaken ====
Het Project maken we aan via de cli. In dit voorbeeld maken we gebruik van de naam ''hens-wordpress-demo''. Zorg ervoor dat je bij het kiezen van de naam de juiste prefix (''xrtv-'') gebruikt:
oc new-project hens-wordpress-demo
Now using project "hens-wordpress-demo" on server "https://api.cluster.chp4.io:6443".
You can add applications to this project with the 'new-app' command. For example, try:
oc new-app rails-postgresql-example
to build a new example application in Ruby. Or use kubectl to deploy a simple Kubernetes application:
kubectl create deployment hello-node --image=k8s.gcr.io/serve_hostname
==== Database aanmaken ====
In deze handleiding maken we een MariaDB database aan met persistent storage op basis van de standaard OpenShift images, deze kan je aanmaken via de webinterface, of via de CLI:
oc new-app --template=mariadb-persistent -p DATABASE_SERVICE_NAME=wordpress-db -p MYSQL_USER=wp_user -p MYSQL_PASSWORD= -p MYSQL_DATABASE=wpdb -p VOLUME_CAPACITY=1Gi
--> Deploying template "openshift/mariadb-persistent" to project hens-wordpress-demo
MariaDB
---------
MariaDB database service, with persistent storage. For more information about using this template, including OpenShift considerations, see https://github.com/sclorg/mariadb-container/blob/master/10.3/root/usr/share/container-scripts/mysql/README.md.
NOTE: Scaling to more than one replica is not supported. You must have persistent volumes available in your cluster to use this template.
The following service(s) have been created in your project: test.
Username: wp_user
Password:
Database Name: wpdb
Connection URL: mysql://wordpress-db:3306/
......
==== Configuratie bestanden aanmaken ====
Er moeten 3 configuratiebestanden worden aangemaakt en een SSH key:
* Nginx configuratie
* PHP configuratie
* Wordpress configuratie
* SSH Key voor de Git Repository
Maak eerst een file aan met de naam ''default.conf'' en zet daar de onderstaande configuratie in:
# Make sure the real ip gets in the log
set_real_ip_from 10.0.0.0/8;
real_ip_header X-Forwarded-For;
real_ip_recursive on;
server {
listen 8080;
server_name localhost;
access_log /dev/stdout main;
error_log /dev/stderr;
root /var/www/html;
index index.php index.html;
location ~\.php$ {
try_files $uri =404;
fastcgi_split_path_info ^(.+\.php)(/.+)$;
fastcgi_pass php:9000;
fastcgi_index index.php;
include fastcgi.conf;
}
}
Maak daarna een file aan met de naam ''specials.ini'' en zet daar de volgende configuratie in:
extension=pdo.so
extension=pdo_mysql.so
extension=mysqlnd.so
extension=mysqli.so
extension=curl.so
extension=dom.so
extension=exif.so
extension=fileinfo.so
extension=hash.so
extension=imagick.so
extension=mbstring.so
extension=openssl.so
extension=pcre.so
extension=xml.so
extension=zip.so
Maak vervolgens van elk van deze bestande een ''configMap'':
oc create configmap nginx-config --from-file=default.conf
oc create configmap php-config --from-file=specials.ini
De 'wp-config.php' file heeft de volgende inhoud:
define( 'DB_NAME', 'wpdb' );
define( 'DB_USER', 'wp_user' );
define( 'DB_PASSWORD', '' );
define( 'DB_HOST', 'wordpress-db' )
Omdat de ''wp-config.php'' credentials bevat, namelijk die van de zojuist aangemaakte database, stoppen we die in een ''secret'':
oc create secret generic wp-config --from-file=config/wp-config.php
Voor de SSH Key maken we ook een secret aan met de naam ''wpgit'':
oc create secret generic wpgit --from-file=ssh-privatekey=wpgit --type=kubernetes.io/ssh-auth
==== Scriptjes maken ====
In verband met het deployproces wat we gebruiken, moeten er in de Repository twee scriptjes aanwezig zijn:
* deploy.sh
* run.sh
Het ''deploy.sh'' script kan gebruikt worden om zaken als ''composer'' te draaien, maar in dit voorbeeld is het bestand leeg (het moet er wel zijn). Het bestand moet in dezelfde directory staan als de ''index.php'' van Wordpress. In mijn voorbeeld is dat de root van de Git Repository:
#!/bin/sh
echo "I'm just here to do nothing at all"
Zorg ervoor dat het executable is:
chmod a+x deploy.sh
Het tweede script wat je nodig hebt is het ''run.sh'' script. Dit script kopieert uiteindelijk de data naar de DocumentRoot en is dus wel belangrijk. Maak het bestand aan met de naam ''run.sh'', net zoals de deploy.sh moet het in dezelfde directory als de ''index.php'' staan:
#!/bin/sh
docroot=/var/www/html/
if [ ! -d ${docroot} ]; then
mkdir -p ${docroot}
fi
cp -Rv /tmp/src/* ${docroot}
Maak het executable:
chmod a+x run.sh
En zorg er als laatste voor dat ze gecommit zijn in Git:
git add deploy.sh run.sh
git commit -m "" deploy.sh run.sh
git push
==== Storage aanmaken ====
Als laatste maken we een stukje persistent storage aan waar de code op komt te liggen straks. Maak hiervoor een bestandje aan met de naam ''storage.yaml'' en zet daar de volgende code in (pas de namespace aan naar je eigen namespace):
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: wordpress
namespace: hens-wordpress-demo
spec:
accessModes:
- ReadWriteMany
resources:
requests:
storage: 4Gi
storageClassName: ocs-storagecluster-cephfs
volumeMode: Filesystem
Sla dit op, en maak vervolgens de storage aan:
oc create -f storage.yaml
Verifieer vervolgens dat hij is aangemaakt:
oc get pvc
NAME STATUS VOLUME CAPACITY ACCESS MODES STORAGECLASS AGE
wordpress Bound pvc-268c5aa8-ad2a-41ba-9721-7683fa86d37a 4Gi RWX ocs-storagecluster-cephfs 24h
wordpress-db Bound pvc-56ab0f2c-36ed-42bd-9dc1-542d06aa9b0b 2Gi RWO ocs-storagecluster-cephfs 24h
===== Uitrollen applicatie ====
Als we de voorbereidingen hebben gedaan, kunnen we de applicatie gaan uitrollen. We beginnen met de PHP Pods.
==== PHP ====
Voor PHP maken we gebruik van ons eigen Docker Image: ''registry.npohosting.nl/npohosting/php-fpm:latest''. Dit Image maakt gebruik van het zogeheten ''S2I'' concept (source-2-image), dit is een proces waarbij we de Docker Image combineren met de Git Repository en daarvan een nieuw image maken die uiteindelijk wordt opgestart.
Als eerste maken we het aan met ''oc new-app'':
oc new-app registry.npohosting.nl/npohosting/php-fpm~git@github.com:tsterk/wordpress-demo.git --source-secret=wpgit --name=php
--> Found container image 9218ebc (7 days old) from registry.npohosting.nl for "registry.npohosting.nl/npohosting/php-fpm"
php-fpm
-------
PHP FPM
Tags: builder, php, php-fpm
* An image stream tag will be created as "php-fpm:latest" that will track the source image
* A source build using source code from git@github.com:tsterk/wordpress-demo.git will be created
* The resulting image will be pushed to image stream tag "php:latest"
* Every time "php-fpm:latest" changes a new build will be triggered
--> Creating resources ...
imagestream.image.openshift.io "php" created
buildconfig.build.openshift.io "php" created
deployment.apps "php" created
service "php" created
--> Success
Build scheduled, use 'oc logs -f buildconfig/php' to track its progress.
Application is not exposed. You can expose services to the outside world by executing one or more of the commands below:
'oc expose service/php'
Run 'oc status' to view your app.
Na het aanmaken, moeten we de volgende items van de ''Deployment'' aanpassen:
* Een ''command'' toevoegen.
* De configuratie inladen.
* De storage toevoegen.
Het aanpassen van de ''Deployment'' doen we met het ''oc edit'' commando:
oc edit deployment/php
Dit opent je favoriete editor (in ons voorbeeld ''vim'') met de yaml file van de Deployment. Je kan de volgende dingen toevoegen:
Het toevoegen van de ''command'' doe je binnen de ''spec'' onder ''name:php'':
args:
- /tmp/src/run.sh; /usr/libexec/s2i/run;
command:
- /bin/sh
- -c
Voor het inladen van de configuratie zet je binnen de ''spec'' onder ''terminationMessagePolicy: File'':
volumeMounts:
- mountPath: /var/www/html
name: wordpress
- mountPath: /usr/local/etc/php/conf.d
name: php-config
- mountPath: /var/www/html/wp-config.php
name: wp-config
subPath: wp-config.php
Om de storage toe te voegen zet je binnen de ''spec'' onder ''terminationGracePeriodSeconds: 30'':
volumes:
- name: wordpress
persistentVolumeClaim:
claimName: wordpress
- name: wp-config
secret:
secretName: wp-config
- configMap:
name: php-config
name: php-config
Het ''spec'' gedeelte van de ''Deployment'' ziet er als het goed is nu ongeveer zo uit:
spec:
containers:
- args:
- /tmp/src/run.sh; /usr/libexec/s2i/run;
command:
- /bin/sh
- -c
image: image-registry.openshift-image-registry.svc:5000/hens-wordpress-demo/php2@sha256:56ddb90f90828759a727eb0586b4941ef898fc6ae754953045cb770ed5920797
imagePullPolicy: IfNotPresent
name: php2
ports:
- containerPort: 9000
protocol: TCP
resources: {}
terminationMessagePath: /dev/termination-log
terminationMessagePolicy: File
volumeMounts:
- mountPath: /var/www/html
name: wordpress
- mountPath: /usr/local/etc/php/conf.d
name: php-config
- mountPath: /var/www/html/wp-config.php
name: wp-config
subPath: wp-config.php
dnsPolicy: ClusterFirst
restartPolicy: Always
schedulerName: default-scheduler
securityContext: {}
terminationGracePeriodSeconds: 30
volumes:
- name: wordpress
persistentVolumeClaim:
claimName: wordpress
- name: wp-config
secret:
secretName: wp-config
- configMap:
name: php-config
name: php-config
Als dat klopt, dan kan je de wijzigingen opslaan. Als het goed is gaat OpenShift gelijk een nieuwe Pod opstarten, controleer dit met ''oc get pods''.
oc get pods
NAME READY STATUS RESTARTS AGE
php-1-build 0/1 Completed 0 33m
php-5b8555f7bd-dfg55 1/1 Running 0 30m
php-b64899ff-gltcv 0/1 ContainerCreating 0 23s
wordpress-db-1-deploy 0/1 Completed 0 25h
wordpress-db-1-dkz4g 1/1 Running 0 25h
We zien hier een nieuwe ''ContainerCreating'' zo zien we dat het goed gaat. Deze moet uiteindelijk naar ''Running'' gaan (je moet het commando een paar keer opnieuw uitvoeren). Wanneer dat is gebeurd kan je controleren of de wijzigingen goed zijn doorgekomen:
oc exec php-b64899ff-gltcv -- ls wp-config.php
wp-config.php
Als je bovenstaand terug krijgt kan je er vanuit gaan dat het goed is gegaan en kan je door naar de nginx deployment.
==== Nginx ====
Ook nginx rollen we uit met ''oc new-app'', alleen geven we deze niet de Git repository mee:
oc new-app --name=nginx --docker-image=registry.npohosting.nl/npohosting/nginx:latest
--> Found container image ab57938 (8 days old) from registry.npohosting.nl for "registry.npohosting.nl/npohosting/nginx:latest"
nginx
-----
NGiNX
Tags: builder, webserver, nginx
* An image stream tag will be created as "nginx:latest" that will track this image
--> Creating resources ...
imagestream.image.openshift.io "nginx" created
deployment.apps "nginx" created
service "nginx" created
--> Success
Application is not exposed. You can expose services to the outside world by executing one or more of the commands below:
'oc expose service/nginx'
Run 'oc status' to view your app.
Ook bij de nginx deployment moeten we hetzelfde drietal items aanpassen in de deployment:
* Een command toevoegen.
* De configuratie inladen.
* De storage toevoegen.
We beginnen wederom met ''oc edit'':
oc edit deployment/nginx
We voegen het ''command'' toe binnen de ''spec'' onder ''name'':
command:
- /usr/libexec/s2i/run
Voor de storage zetten we binnen de ''spec'' onder ''terminationGracePeriodSeconds: 30'':
volumes:
- name: wordpress
persistentVolumeClaim:
claimName: wordpress
- configMap:
name: nginx-config
name: nginx-config
Het ''spec'' gedeelte van de ''Deployment'' ziet er als het goed is nu ongeveer zo uit:
spec:
containers:
- command:
- /usr/libexec/s2i/run
image: registry.npohosting.nl/npohosting/nginx@sha256:1b3f72a21907b945b824baef75e574c3be7135c6698d2a72764d70b8b146cd9d
imagePullPolicy: IfNotPresent
name: nginx
ports:
- containerPort: 8080
protocol: TCP
resources: {}
terminationMessagePath: /dev/termination-log
terminationMessagePolicy: File
volumeMounts:
- mountPath: /var/www/html
name: wordpress
- mountPath: /etc/nginx/conf.d
name: nginx-config
dnsPolicy: ClusterFirst
restartPolicy: Always
schedulerName: default-scheduler
securityContext: {}
terminationGracePeriodSeconds: 30
volumes:
- name: wordpress
persistentVolumeClaim:
claimName: wordpress
- configMap:
name: nginx-config
name: nginx-config
Als dat klopt, dan kan je de wijzigingen opslaan. Als het goed is gaat OpenShift gelijk een nieuwe Pod opstarten, controleer dit met ''oc get pods''
oc get pods
NAME READY STATUS RESTARTS AGE
nginx-776b8d886c-cfkp8 0/1 CrashLoopBackOff 5 5m52s
nginx-7ffd9898df-rrrxr 0/1 ContainerCreating 0 3s
php-1-build 0/1 Completed 0 45m
php-b64899ff-gltcv 1/1 Running 0 12m
wordpress-db-1-deploy 0/1 Completed 0 25h
wordpress-db-1-dkz4g 1/1 Running 0 25h
Het klopt dat je daar een Pod ziet met ''CrashLoopBackOff'' als status, dat hebben we als het goed is opgelost met onze aanpassingen. Je ziet dan ook naar verloop van tijd de Pod met ''ContainerCreating'' status (in dit voorbeeld ''nginx-7ffd9898df-rrrxr'') naar ''Running'' gaan (je zult het commando wellicht een paar keer moeten uitvoeren voor je dit ziet), wanneer dit gebeurd is, kan je het controleren:
oc exec nginx2-7ffd9898df-rrrxr -- ls /var/www/html/wp-config.php
/var/www/html/wp-config.php
Als het goed is draait nu de Wordpress applicatie, het enige wat we nu nog moeten doen is de applicatie bereikbaar maken.
==== Routes ====
In dit laatste hoofdstukje gaan we de applicatie voor de wereld bereikbaar maken. Dit doen we met het ''oc expose'' commando, waar we de service ''nginx'' exposen, controleer of die bestaat:
oc get service nginx
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
nginx ClusterIP 172.30.239.158 8080/TCP 25h
Voer het commando uit:
oc expose service nginx --hostname=wordpress-demo.apps.hens.cluster.chp4.io
Let goed op bij de ''hostname'' welke URL je gebruikt. In dit voorbeeld hebben we een subdomein van ''apps.hens.cluster.chp4.io'', maar vervang hierbij ''hens'' door de prefix van de omroep of afdeling waarvoor je bezig bent, bijvoorbeeld voor OmroepMax wordt dat ''apps.max.cluster.chp4.io''.
Je kan natuurlijk ook een eigen domeinnaam gebruiken, denk dan wel aan de DNS instellingen.
Als het goed is kan je nu naar de URL gaan. Als je een nieuwe site maakt krijg je de Wordpress installer te zien en kan je die doorlopen en krijg je aan het einde een werkende site.
===== Ter afsluiting =====
Je hebt nu een werkende Wordpress Installatie in OpenShift, maar nog lang niet productierijp. Er zijn een aantal dingen die ik niet heb laten terugkomen in deze handleiding, maar waar wel over nagedacht moet worden:
* SSL. Er staat nu geen SSL certificaat geconfigureerd. Hoe je dat zou kunnen doen, kan je hier lezen: https://hosting.omroep.nl/chp:handleiding:letsencrypt.
* Scaling. Er is nu geen enkele vorm van scaling gedaan. De Pods draaien allebei enkelvoudig. In een productie omgeving wil je gaan kijken naar autoscaling zodat je website meeschaalt met de vraag.
* Caching. Er is geen caching geconfigureerd.
* Liveness en Readiness Probers. Het kan verstandig zijn om Liveness en Readiness Probes te configureren voor de Deployment. Een Livenessprobe kijkt of een Pod nog wel goed functioneert en een Readinessprobe kijkt of een Pod volledig is opgestart. Meer informatie: https://kubernetes.io/docs/tasks/configure-pod-container/configure-liveness-readiness-startup-probes/
* Storage. We gebruiken in deze handleiding persistent storage in OpenShift, maar dit is niet de manier die we adviseren. Voor de statische data (alles wat normaal in ''wp-uploads'' staat) raden we aan om gebruik te maken van een S3 bucket met een CDN. Er zijn diverse plugins beschikbaar in Wordpress om dit te realiseren.
* Loadtesten. Het is verstandig om een loadtest op je applicaties uit te voeren zodat je kan leren of de dingen die je doet ook efficiënt werken. Zeker bij het gebruik van nieuwe technieken kan dit belangrijk zijn.
* Backups. Team Hosting & Streaming verzorgt geen backups. Het idee is dat de data van de database bij Amazon ligt waar Amazon backups van maakt; dat de code in een Git Repository staat; en de overige data in een S3 bucket. Zo heb je in principe geen persistent data in OpenShift staan.
* Monitoring. Team Hosting & Streaming verzorgt geen monitoring op applicatieniveau. We kijken of het OpenShift cluster blijft draaien, maar niet of de website of webserver het nog doet.
==== Handige Links ====
* https://docs.openshift.com/container-platform/4.8/applications/creating_applications/creating-applications-using-cli.html
* https://docs.openshift.com/container-platform/4.8/applications/deployments/what-deployments-are.html
* https://docs.openshift.com/container-platform/4.8/applications/deployments/managing-deployment-processes.html
* https://docs.openshift.com/container-platform/4.8/applications/config-maps.html
* https://docs.openshift.com/container-platform/4.8/applications/application-health.html
* https://docs.openshift.com/container-platform/4.8/applications/odc-monitoring-project-and-application-metrics-using-developer-perspective.html
* https://hosting.omroep.nl/chp:faq
* https://hosting.omroep.nl/chp:handleiding:static-cdn
* https://hosting.omroep.nl/chp:handleiding:letsencrypt