Długo się zbierałem do nauki chociażby podstaw kubernetesa i wreszcie mi się udało. Wydawało mi się, że będzie dużo trudniej, ale ok 2 lat temu miałem pierwsze podejście do niego, gdzie ukończyłem kurs CKAD, ale po nim nie używałem K8s, więc większość zapomniałem. W tym artykule, pokaże jak wdrożyć blog WordPress na klaster kubernetes z wykorzystaniem bazy MariaDB.
Do postawienia klastra kubernetesa wykorzystałem microk8s, oraz własny serwer VPS, ale nie ma żadnych przeciwwskazań, aby wykorzystać np. AWS EKS, GKE lub inne rozwiązanie. W przypadku wykorzystania microk8s, jako klaster, będzie trzeba wpisywać dość długie polecenie np.
microk8s kubectl get pod
Więc, aby skrócić je, polecam utworzyć alias do niego, jak poniżej
alias k="microk8s kubectl"
Dzięki czemu, np. polecenie o wyświetlenie listy podów, skrócimy do prostej formy
k get pod
Co jest zdecydowanie wygodniejsze i zmniejsza ryzyko literówki 🙂
Dodatkową dobrą praktyką w kubernetesie jest nie używanie defaultowego namespace, więc polecam utworzyć sobie nowy np. development i na nim pracować. Namespace można utworzyć przy pomocy poniższego polecenie, uwzględniając oczywiście alias do polecenia
k create namespace development
Kiedy go utworzymy, należy wykonać jeszcze jedno polecenie
k config set-context --current --namespace=development
Dzięki temu, namespace development stanie się naszym domyślnym i wszystko co będziemy tworzyli od teraz, będzie tworzone właśnie w nim.
Wracając do głównego tematu artykułu, aby wszystko nam ładnie działało, potrzebujemy utworzyć:
Dla wordpress:
- Deployment – konfiguracja POD-a
- Service – który wystawi na POD-a na porcie 80
- Ingress – pozwoli nam powiązać domenę z powyższym serwisem, w moim wypadku będzie to domena learn-linux.eu
- Persistent Volumes oraz Persistent Volumes Claim – storage dla naszego WP
Więc tak, lecąc po kolei
wordpress-deployment.yml
apiVersion: apps/v1
kind: Deployment
metadata:
name: wordpress-deployment
spec:
selector:
matchLabels:
name: wordpress
template:
metadata:
labels:
name: wordpress
spec:
containers:
- name: wordpress
resources: {}
image: wordpress
ports:
- containerPort: 80
volumeMounts:
- name: wordpress-persistent-storage
mountPath: /var/www/html
env:
- name: WORDPRESS_DB_HOST
value: mariadb-service
- name: WORDPRESS_DB_USER
value: root
- name: WORDPRESS_DB_NAME
valueFrom:
configMapKeyRef:
key: database_name
name: mariadb-config
- name: WORDPRESS_DB_PASSWORD
valueFrom:
secretKeyRef:
key: db_password
name: mariadb-secret
volumes:
- name: wordpress-persistent-storage
persistentVolumeClaim:
claimName: wordpress-pv-claim
wordpress-service.yml
apiVersion: v1
kind: Service
metadata:
name: wordpress-service
spec:
type: LoadBalancer
selector:
name: wordpress
ports:
- port: 80
wordpress-ingress.yml
Tutaj leży zmienić nazwę hosta, na nazwę swojej domeny, na której checie wystawić blog
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: wordpress-ingress
labels:
name: wordpress-ingress
spec:
rules:
- host: learn-linux.eu
http:
paths:
- pathType: Prefix
path: "/"
backend:
service:
name: wordpress-service
port:
number: 80
wordpress-pv.yml
apiVersion: v1
kind: PersistentVolume
metadata:
name: wordpress-pv-volume
labels:
type: local
spec:
storageClassName: manual
capacity:
storage: 3Gi
accessModes:
- ReadWriteOnce
hostPath:
path: "/data/wordpress"
wordpress-pv-claim.yml
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: wordpress-pv-claim
spec:
storageClassName: manual
accessModes:
- ReadWriteOnce
resources:
requests:
storage: 3Gi
Dla samego bloga to cała konfiguracja, ale obecnie nie uruchomi Wam się ponieważ trzeba jeszcze skonfigurować bazę danych MariaDB, w tym celu będziemy potrzebowali trochę więcej kofiguracji, niż w przypadku WP. W przypadku bazy danych, potrzebujemy utworzyć:
- Deployment – konfiguracja POD-a
- Service – który wystawi na POD-a na porcie 3306
- Persistent Volumes oraz Persistent Volumes Claim
- Secret – w nim będziemy trzymal hasło roota do bazy danych, z tego pliku hasło będzie czytał również wordpress
- ConfigMap – tutaj będziemy trzymali nazwę bazy danych
Dlaczego baza danych nie ma ingressu?
Ponieważ nie będziemy wystawiać jej na świat i łączyć się do niej wewnętrznie będzie tylko pod z wordpressem.
Wracając do kodu dla bazy danych:
mariadb-deployment.yml
apiVersion: apps/v1
kind: Deployment
metadata:
name: mariadb-deployment
spec:
selector:
matchLabels:
name: mariadb
template:
metadata:
labels:
name: mariadb
spec:
containers:
- name: mariadb
resources: {}
image: mariadb
ports:
- containerPort: 3306
volumeMounts:
- name: mariadb-persistent-storage
mountPath: /var/lib/mysql
env:
- name: MARIADB_ROOT_PASSWORD
valueFrom:
secretKeyRef:
key: db_password
name: mariadb-secret
- name: MARIADB_DATABASE
valueFrom:
configMapKeyRef:
key: database_name
name: mariadb-config
volumes:
- name: mariadb-persistent-storage
persistentVolumeClaim:
claimName: mariadb-pv-claim
mariadb-service.yml
apiVersion: v1
kind: Service
metadata:
name: mariadb-service
spec:
clusterIP: None
selector:
name: mariadb
ports:
- port: 3306
mariadb-config.yml
Nazwę bazy danych, można zmienić z wordpress na taką jaką się chce
apiVersion: v1
kind: ConfigMap
metadata:
name: mariadb-config
data:
database_name: wordpress
mariadb-secret.yml
W przypadku Secret, wartości przypisane muszą być zakodowane przy pomocy base64, inaczej dostaniemy błąd.
Aby zakodować jakieś hasło do formatu base64, w przypadku linux, wystarczy wykonać polecenie
echo -n "bardzo_tajne_haslo" | base64
Co jako wynik poda nam hasło w base64, w przypadku powyższego hasła, będzie to YmFyZHpvX3Rham5lX2hhc2xv, jeżeli zapomnimy hasła, to mając dostęp do hasha, możemy je odkodować, wykonując poniższe polecenie
echo -n "YmFyZHpvX3Rham5lX2hhc2xv" | base64 --decode
Wynikiem będzie odkodowane hasło. Jako mini challenge, polecam odkodować hasło, które znajduje się poniżej w db_password 🙂
apiVersion: v1
kind: Secret
metadata:
name: mariadb-secret
type: Opaque
data:
db_password: YWRtaW4xMjM=
mariadb-pv.yml
apiVersion: v1
kind: PersistentVolume
metadata:
name: mariadb-pv-volume
labels:
type: local
spec:
storageClassName: manual
capacity:
storage: 3Gi
accessModes:
- ReadWriteOnce
hostPath:
path: "/data/mariadb"
mariadb-pv-claim.yml
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: mariadb-pv-claim
spec:
storageClassName: manual
accessModes:
- ReadWriteOnce
resources:
requests:
storage: 3Gi
Tak wygląda cała konfiguracja wordpressa oraz bazy danych, aby działało wszystko poprawnie na kubernetesie. Kiedy mamy już utworzoną całą konfigurację, i obecnie jesteśmy w katalogu z projektem, wystarczy wykonać w terminalu polecenie:
k apply -f .
W przypadku wykorzystania microk8s jako klastra kubernetes, należy sprawdzić, czy mamy włączone dodatki takie jak dns oraz ingress, ponieważ bez nich klaster nie będzie działał nam poprawnie. Sam natrafiłem na kilka problemów, które były spowodowane brakiem włączenia tych dodatków, ale nie ukrywam, że szukanie przyczyny nauczyło mnie na przyszłość, gdzie szukać przyczyn problemów związanych z dns oraz ingressem.
Aby sprawdzić czy mamy je włączone, należy w terminalu wykonać polecenie
microk8s status
Jeżeli mamy je aktywne, to powinno je nam pokazać w sekcji enabled. Jeżeli ich tam nie ma, to należy wykonać polecenie
microk8s enable ingress dns
I to wszystko 🙂 Mam nadzieję, że artykuł komuś się przyda i pomoże przejść bezboleśnie przez pierwsze wdrożenie na kubernetesie.