---
# System prepended metadata

title: Deploy Kubernetes Applications

---

# 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:

![](https://i.imgur.com/wpeuajh.png)

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:

![](https://i.imgur.com/HaPkr3r.png)

## Apply Yaml Files

Berikut urutan untuk apply file yaml yang telah dibuat

### Persistent Volume Claim

```bash=
kubectl apply -f pvc.yaml
```

Hasil:

![](https://i.imgur.com/9mVY7F5.png)


### MySQL

```bash=
kubectl apply -f mysql-deployment.yaml
```

Hasil:

![](https://i.imgur.com/j4KASht.png)


### Wordpress

```bash=
kubectl apply -f wordpress-deployment.yaml
```

Hasil:

![](https://i.imgur.com/EGMQkyp.png)


### Load Balancer

```bash=
kubectl apply -f loadbalancer-service.yaml
```

Hasil:

![](https://i.imgur.com/mTvFUk3.png)


## 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;
```

![](https://i.imgur.com/U7nI4lP.png)

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
```

![](https://i.imgur.com/pucDP5o.png)

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
```

![](https://i.imgur.com/tnoWAmW.png)

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

![](https://i.imgur.com/1P3aN0T.png)


### 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
```

![](https://i.imgur.com/a0gLeri.png)

## Check Everyting is Done

![](https://i.imgur.com/wQNic5B.png)

- 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

![](https://i.imgur.com/VFIVujC.png)

![](https://i.imgur.com/I55QCgq.png)

![](https://i.imgur.com/C1anekc.png)

![](https://i.imgur.com/PJYLEeK.png)

![](https://i.imgur.com/knw0f6u.png)

**_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.