Deploy WordPress & MySQL menggunakan Microk8s

Dah lama tak usik Kubernetes dan kali terakhir usik tahun 2019 sebab dapat arahan untuk belajar sebab akan terlibat dengan satu projek tapi tak sempat projek tersebut execute, macam-macam jadi dekat company. Aku pun dah cabut dari company tuh tapi ilmu yang aku belajar pasal Kubernetes agak bermanfaat.

Proses pembelajaran agak sukar juga sebab belajar sendiri, company tak bagi pergi kelas atau training center luar. Semua belajar atas inisiatif sendiri, setup lab sendiri, etc2. Tapi usaha nak belajar sebab minat dengan benda baru dan tak pernah tahu ada teknologi itu.

Tiba-tiba Jumaat lepas ( 16th Julai 2021 ) terasa nak revise balik Kubernetes punya experience dan sengaja buat satu ujian untuk deploy WordPress dan MySQL. Pada hemat aku ujian ini agak mudah pada mula-mula tapi penghujung dia agak mencabar sampai aku kena rujuk dengan seorang senior yang pernah bekerja di HP waktu dulu.

Hasil perbincangan dengan senior itu aku letak di penghujung post & penyelesaian masalah dia dalam code yaml nanti.

Jadi kalau betul-betul nak setup Kubernetes lengkap dengan cluster memang ambil masa juga tapi dengan microk8s pembelajaran lebih mudah dan cepat sebab cuma nak revise balik apa yang tahu. Installation guide microk8s boleh rujuk di https://microk8s.io/ dan anda pilih platform anda yang mana satu.

Lagi mudah kalau menggunakan Ubuntu itu sebabmicrok8s boleh terus beroperasi dalam Ubuntu. Jadi dia tak perlu nak build Virtual Ubuntu machine untuk dia run microk8s tuh. Di samping tuh, boleh create sedikit alias supaya boleh pendekkan command microk8s itu.

Selesai bab installation microk8s, aku rujuk ke satu repository dari IBM di sini;

https://github.com/IBM/Scalable-WordPress-deployment-on-Kubernetes

Repository IBM ini dah siap dengan YAML fail dia jadi kita cuma perlu ubah sedikit sahaja untuk deploy WordPress & MySQL ini.

Untuk sesiapa yang nak buat shortcut command (alias) boleh letak di dalam .bashrc atau profile shell untuk memudahkan kerja, di bawah aku kongsikan alias yang aku guna.

alias kubectl='microk8s kubectl'
alias admintoken='kubectl get secret -n kube-system $(kubectl get serviceaccount admin-user -n kube-system -o jsonpath="{.secrets[0].name}") -o jsonpath="{.data.token}" | base64 --decode'
alias rotoken='kubectl get secret -n kube-system $(kubectl get serviceaccount read-only-user -n kube-system -o jsonpath="{.secrets[0].name}") -o jsonpath="{.data.token}" | base64 --decode'
alias kubectlstop='sudo microk8s stop'
alias kubectlstart='sudo microk8s start'
alias kubectlreset='sudo microk8s reset'

Jadi setelah shortcut command siap, boleh terus download repository IBM tadi disini dan masuk ke dalam directory tersebut. Di dalam directory tersebut ada file YAML local-volumes.yaml kita kena create dulu volume. Bila dah siap volume creation kita verify semua information. Di sini maklumat yang aku akan pastikan adalah disk status tersebut adalah Available.

Pastikan microk8s enable dns kalau tak nanti browser tak boleh resolve IP Node.

$ microk8s enable dns
% kubectl create -f local-volumes.yaml 
persistentvolume/local-volume-1 created
persistentvolume/local-volume-2 created
% kubectl get pv -o wide
NAME             CAPACITY   ACCESS MODES   RECLAIM POLICY   STATUS      CLAIM   STORAGECLASS   REASON   AGE   VOLUMEMODE
local-volume-1   20Gi       RWO            Recycle          Available                                   4m    Filesystem
local-volume-2   20Gi       RWO            Recycle          Available                                   4m    Filesystem
% kubectl describe pv local-volume-1
Name:            local-volume-1
Labels:          type=local
Annotations:     <none>
Finalizers:      [kubernetes.io/pv-protection]
StorageClass:    
Status:          Available
Claim:           
Reclaim Policy:  Recycle
Access Modes:    RWO
VolumeMode:      Filesystem
Capacity:        20Gi
Node Affinity:   <none>
Message:         
Source:
    Type:          HostPath (bare host directory volume)
    Path:          /tmp/data/lv-1
    HostPathType:  
Events:            <none>
azmim@machine Scalable-WordPress-deployment-on-Kubernetes % kubectl describe pv local-volume-2
Name:            local-volume-2
Labels:          type=local
Annotations:     <none>
Finalizers:      [kubernetes.io/pv-protection]
StorageClass:    
Status:          Available
Claim:           
Reclaim Policy:  Recycle
Access Modes:    RWO
VolumeMode:      Filesystem
Capacity:        20Gi
Node Affinity:   <none>
Message:         
Source:
    Type:          HostPath (bare host directory volume)
    Path:          /tmp/data/lv-2
    HostPathType:  
Events:            <none>

Kemudian kita dah boleh buat WordPress & MySQL deployment. Di dalam directory ada dua fail YAML yang kita akan gunakan iaitu wordpress-deployment.yaml & mysql-deployment.yaml, tapi sebelum itu kita perlu create satu fail password.txt tapi kena pastikan yang tiada newline dalam fail tu. Boleh guna cara ini.

Command openssl rand -base64 14 itu aku guna sebagai contoh sekiranya nak buat password yang lagi mudah pun boleh letak dalam fail password.txt tuh.

% tr -d '\n' <password.txt >.strippedpassword.txt && mv .strippedpassword.txt password.txt
% openssl rand -base64 14 > password.txt

Dah siap kita akan create secret untuk password MySQL & selepas itu deploy MySQL dan WordPress menggunakan YAML fail tadi.

kubectl create secret generic mysql-pass --from-file=password.txt

Sebelum deploy terdapat beberapa item yang perlu ditambah di dalam YAML fail WordPress & MySQL tersebut di bahagian env. Dah tambah boleh save fail tuh & deploy.

wordpress-deployment.yaml

          env:
            - name: WORDPRESS_DB_NAME
              value: wordpress
            - name: WORDPRESS_DB_USER
              value: root
            - name: WORDPRESS_DB_HOST
              value: wordpress-mysql
            - name: WORDPRESS_DB_PASSWORD

mysql-deployment.yaml

          env:
            - name: MYSQL_DATABASE
              value: wordpress
            - name: MYSQL_ROOT_PASSWORD
              valueFrom:
                secretKeyRef:
                  name: mysql-pass
                  key: password.txt

Deploy kedua-dua fail YAML tuh.

% kubectl create -f mysql-deployment.yaml  
service/wordpress-mysql created
persistentvolumeclaim/mysql-pv-claim created
deployment.apps/wordpress-mysql created

% kubectl create -f wordpress-deployment.yaml 
service/wordpress created
persistentvolumeclaim/wp-pv-claim created
deployment.apps/wordpress created

Dah siap deploy boleh verify samada pods running baik atau tidak dan verify services establishkan port atau tidak.

% kubectl get pods
NAME                               READY   STATUS    RESTARTS   AGE
wordpress-mysql-77cfd7bc5b-wwz6z   1/1     Running   0          10m
wordpress-5577f5f946-2gtvm         1/1     Running   0          10m

% kubectl get services
NAME              TYPE        CLUSTER-IP       EXTERNAL-IP   PORT(S)        AGE
kubernetes        ClusterIP   10.152.183.1     <none>        443/TCP        5d8h
wordpress-mysql   ClusterIP   None             <none>        3306/TCP       10m
wordpress         NodePort    10.152.183.121   <none>        80:31955/TCP   10m 

Untuk kita pastikan yang kita boleh access ke WordPress wizard page kita boleh check IP node menggunakan command di bawah dan kemudian buka browser dan access port tersebut menggunakan IP node tuh.

% kubectl get nodes -o wide
NAME          STATUS   ROLES    AGE    VERSION                    INTERNAL-IP    EXTERNAL-IP   OS-IMAGE             KERNEL-VERSION       CONTAINER-RUNTIME
microk8s-vm   Ready    <none>   5d8h   v1.21.1-3+1f02fea99e2268   192.168.64.2   <none>        Ubuntu 18.04.5 LTS   4.15.0-144-generic   containerd://1.4.4

Paste IP node dan port yang boleh dirujuk melalui command kubectl get services tadi.

Siap.

Side Note:

Sekiranya terdapat masalah seperti database connection unable to establish rujuk balik fail YAML bahagian env tadi sebab rata-rata isu yang aku jumpa masalah hampir sama.

Sekiranya perlu untuk masuk ke dalam pods WordPress untuk verify connection dari pods WordPress ke pod MySQL boleh guna command di bawah.

% kubectl get pods
NAME                               READY   STATUS    RESTARTS   AGE
wordpress-mysql-77cfd7bc5b-wwz6z   1/1     Running   0          22m
wordpress-5577f5f946-2gtvm         1/1     Running   0          22m

% kubectl exec --stdin --tty wordpress-5577f5f946-2gtvm -- /bin/bash
kubectl exec [POD] [COMMAND] is DEPRECATED and will be removed in a future version. Use kubectl exec [POD] -- [COMMAND] instead.
root@wordpress-5577f5f946-2gtvm:/var/www/html

Disebabkan image WordPress tuh sangat minimal, telnet takde jadi aku pakai curl untuk verify connection database ke pod MySQL, boleh guna command macam dekat bawah. Untuk dapatkan IP Pod MySQL boleh guna command kubectl describe <pod wordpress>

# curl -v telnet://10.1.254.83:3306
* Expire in 0 ms for 6 (transfer 0x558c94a88fb0)
*   Trying 10.1.254.83...
* TCP_NODELAY set
* Expire in 200 ms for 4 (transfer 0x558c94a88fb0)
* Connected to 10.1.254.83 (10.1.254.83) port 3306 (#0)
Warning: Binary output can mess up your terminal. Use "--output -" to tell 
Warning: curl to output it to your terminal anyway, or consider "--output 
Warning: <FILE>" to save to a file.
* Failed writing body (0 != 25)
* Closing connection 0

Harap dapat membantu.

Leave a Comment