# Deploy Kubernetes Applications
**Note:**
Tersedia versi baca di HackMD: https://hackmd.io/@mustosoft/miti-deploy-wp
## Check Nodes Status
Pertama, cek dulu status dari nodes apakah semuanya dalam state `ready`:
```bash=
kubectl get nodes
```
Hasil:

Kubernetes nodes semuanya berstatus `ready`
## Yaml Files
### MySQL
Membuat yaml file `wordpress-deployment.yaml`
```yaml=
# mysql-deployment.yaml
apiVersion: v1
kind: Service
metadata:
name: mysql
labels:
app: mysql
spec:
ports:
- port: 3306
selector:
app: mysql
clusterIP: None
---
apiVersion: apps/v1
kind: Deployment
metadata:
name: mysql
labels:
app: mysql
spec:
selector:
matchLabels:
app: mysql
strategy:
type: Recreate
template:
metadata:
labels:
app: mysql
spec:
containers:
- image: mysql:5.6
name: mysql
env:
- name: MYSQL_ROOT_PASSWORD
valueFrom:
secretKeyRef:
name: db-secrets
key: password
ports:
- containerPort: 3306
name: mysql
volumeMounts:
- name: mysql-pvc
mountPath: /var/lib/mysql
volumes:
- name: mysql-pvc
persistentVolumeClaim:
claimName: mysql-pvc
```
### Wordpress
Membuat yaml file `wordpress-deployment.yaml`
```yaml=
# wordpress-deployment.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: wordpress
labels:
app: wordpress
spec:
replicas: 3
selector:
matchLabels:
app: wordpress
template:
metadata:
labels:
app: wordpress
spec:
containers:
- name: wordpress
image: wordpress
ports:
- containerPort: 80
env:
- name: WORDPRESS_DB_HOST
value: mysql
- name: WORDPRESS_DB_USER
valueFrom:
secretKeyRef:
name: db-secrets
key: username
- name: WORDPRESS_DB_PASSWORD
valueFrom:
secretKeyRef:
name: db-secrets
key: password
volumeMounts:
- name: wordpress-pvc
mountPath: /var/www/html
volumes:
- name: wordpress-pvc
persistentVolumeClaim:
claimName: wordpress-pvc
```
### Load Balancer
Membuat yaml file `loadbalancer-service.yaml`
```yaml=
# loadbalancer-service.yaml
apiVersion: v1
kind: Service
metadata:
name: wordpress
spec:
type: LoadBalancer
selector:
app: wordpress
ports:
- name: http
protocol: TCP
port: 80
targetPort: 80
```
### Persistent Volume Claim
Membuat yaml file `pvc.yaml` untuk claims data WordPress dan MySQL
```yaml=
# pvc.yaml
kind: PersistentVolume
apiVersion: v1
metadata:
name: mysql-pv
labels:
name: mysql-pv
spec:
storageClassName: manual
capacity:
storage: 2Gi
accessModes:
- ReadWriteOnce
hostPath:
path: "/root/mysql-pv"
---
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: mysql-pvc
spec:
storageClassName: manual
accessModes:
- ReadWriteOnce
resources:
requests:
storage: 1Gi
---
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: wordpress-pvc
spec:
storageClassName: manual
accessModes:
- ReadWriteOnce
resources:
requests:
storage: 1Gi
---
kind: PersistentVolume
apiVersion: v1
metadata:
name: wordpress-pv
labels:
name: wordpress-pv
spec:
storageClassName: manual
capacity:
storage: 2Gi
accessModes:
- ReadWriteOnce
hostPath:
path: "/root/wordpress-pv"
```
## Configure Secrets
Sebelum mendeploy file yaml, configure secrets terlebih dahulu. Untuk configure secret dari username dan password:
```bash!
kubectl create secret generic db-secrets --from-literal=username=root --from-literal=password=password
```
Hasil:

## Apply Yaml Files
Berikut urutan untuk apply file yaml yang telah dibuat
### Persistent Volume Claim
```bash=
kubectl apply -f pvc.yaml
```
Hasil:

### MySQL
```bash=
kubectl apply -f mysql-deployment.yaml
```
Hasil:

### Wordpress
```bash=
kubectl apply -f wordpress-deployment.yaml
```
Hasil:

### Load Balancer
```bash=
kubectl apply -f loadbalancer-service.yaml
```
Hasil:

## Manually Create Database "wordpress" on MySQL
Untuk wordpress dapat berjalan, kita harus buat database `wordpress` di MySQL secara manual
### Enter MySQL Pod
```bash=
kubectl exec -ti mysql-54fc4bd55b-j779g bash
```
### Connect to DB
Akses ke db dengan menggunakan `mysql` di dalam pod
```bash=
mysql -p
```
Masukkan password. Setelah itu, masukkan query untuk create database
```sql=
CREATE DATABASE wordpress;
```

Database wordpress berhasi dibuat.
## Exposing WordPress Service
Untuk bisa diakses dari luar, service wordpress yang kita buat harus di-expose ke external IP denga membuat service baru dengan command `kubectl expose`
### Check Host Network IP
Untuk mengetahui external IP yang akan kita pakai, cek terlebih dahulu IP dari host kita yang menghubungkan dengan jaringan luar. Di tutorial ini saya menggunakan IP public dan IP private, namun host tidak bisa mendeteksi IP public, yang ada hanyalah IP dari interface yang menghubungkan host kita dengan floating public IP yang sudah di-assign ke VM dari dashboard ID Cloud Host.
```bash=
ifconfig
```

Interface `ens3` inilah yang menghubungkan host dengan floating IP. Untuk dapat mengetahui IP public dari host, bisa dilakukan dengan melihat yang ada di dashboard ID Cloud Host atau dengan menggunakan perintah berikut ini:
```bash=
curl http://ipecho.net/plain; echo
```

Atau melihat floating IP yang ada di dashboard ID Cloud Host:

### Create Exposed Service
Setelah mengetahui IP public dari host kita, jalankan perintah berikut untuk membuat service yang mengekspose service wordpress kita:
```bash!
kubectl expose service wordpress --port=80 --target-port=80 --name=wordpress-https --external-ip=10.117.62.111
```

## Check Everyting is Done

- 2 nodes are ready
- 3 WordPress pods are running
- 1 MySQL pod is running
- 1 MySQL service is up
- 1 WordPress load balancer service is up
- 1 WordPress exposed service is up
- All PVs and PVCs are bounded
## Test Wordpress on Browser
Setelah semuanya tersetup dengan baik, kita test wordpress kita di browser





**_Try it_**:
http://kube.mustosoft.com/
## Kesimpulan
Kubernetes merupakan *container orchestration* yang memudahkan kita memanage infrastruktur kita. Kubernetes bersifat deklaratif, artinya, untuk melalukan serangkaian *deployment*, kita hanya perlu membuat file yang berisi konfigurasi dan kubernetes akan memenuhi semua yang kita butuhkan pada file konfigurasi tersebut.
Hambatan yang sering terjadi adalah kurangnya pengetahuan kita terhadap konsep dari segala yang berhubungan dengan kubernetes. Konsep dari kubernetes itu sendiri adalah gabungan dari beberapa konsep lainnya seperti networking, hardware, OS, Linux, dan lainnya.
Di tutorial ini, sebagian besar waktu saya digunakan untuk menyetup kubernetes cluster karena sebelumnya di tutorial setup kubernetes masih gagal. Untuk deployment sendiri tidak membutuhkan waktu yang lama karena konfigurasi dari kubernetes ini tidak jauh berbeda dengan docker compose--yang sebelumnya sudah sering saya gunakan.
Alasan saya memilih menggunakan unmanaged cloud VPS adalah agar saya dapat menyetup semuanya secara mandiri dari awal. Selain itu juga, *resource* yang saya miliki di laptop lokal saya tidak cukup untuk menjalankan dua VM. Adapun alasan tambahan yaitu, secara praktikal saya dapat sekaligus mempelajari bagaimana setup kubernetes di *bare metal* yang mendapat akses internet secara publik.